76 lines
2.9 KiB
TypeScript
76 lines
2.9 KiB
TypeScript
import type { FormEvent } from 'react'
|
|
import { PresentationFormHeader } from '../PresentationFormHeader'
|
|
import { t } from '@/lib/i18n'
|
|
import { PresentationFields } from './fields'
|
|
import type { AuthorPresentationDraft } from './types'
|
|
|
|
export interface PresentationFormProps {
|
|
draft: AuthorPresentationDraft
|
|
setDraft: (next: AuthorPresentationDraft) => void
|
|
validationError: string | null
|
|
error: string | null
|
|
loading: boolean
|
|
handleSubmit: (e: FormEvent<HTMLFormElement>) => Promise<void>
|
|
deleting: boolean
|
|
handleDelete: () => void
|
|
hasExistingPresentation: boolean
|
|
}
|
|
|
|
export function PresentationForm(props: PresentationFormProps): React.ReactElement {
|
|
return (
|
|
<form
|
|
onSubmit={(e: FormEvent<HTMLFormElement>) => {
|
|
void props.handleSubmit(e)
|
|
}}
|
|
className="border border-neon-cyan/20 rounded-lg p-6 bg-cyber-dark space-y-4"
|
|
>
|
|
<PresentationFormHeader />
|
|
<PresentationFields draft={props.draft} onChange={props.setDraft} />
|
|
<ValidationError message={props.validationError ?? props.error} />
|
|
<div className="flex items-center gap-4">
|
|
<div className="flex-1">
|
|
<button
|
|
type="submit"
|
|
disabled={props.loading || props.deleting}
|
|
className="w-full px-4 py-2 bg-neon-cyan/20 hover:bg-neon-cyan/30 text-neon-cyan rounded-lg font-medium transition-all border border-neon-cyan/50 hover:shadow-glow-cyan disabled:opacity-50 disabled:cursor-not-allowed"
|
|
>
|
|
{getSubmitLabel({ loading: props.loading, deleting: props.deleting, hasExistingPresentation: props.hasExistingPresentation })}
|
|
</button>
|
|
</div>
|
|
{props.hasExistingPresentation ? <DeleteButton onDelete={props.handleDelete} deleting={props.deleting} /> : null}
|
|
</div>
|
|
</form>
|
|
)
|
|
}
|
|
|
|
function ValidationError(params: { message: string | null }): React.ReactElement | null {
|
|
if (!params.message) {
|
|
return null
|
|
}
|
|
return (
|
|
<div className="bg-red-500/10 border border-red-500/50 rounded-lg p-3">
|
|
<p className="text-sm text-red-400">{params.message}</p>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function DeleteButton(params: { onDelete: () => void; deleting: boolean }): React.ReactElement {
|
|
return (
|
|
<button
|
|
type="button"
|
|
onClick={params.onDelete}
|
|
disabled={params.deleting}
|
|
className="px-4 py-2 bg-red-500/20 hover:bg-red-500/30 text-red-400 rounded-lg text-sm font-medium transition-all border border-red-500/50 hover:shadow-glow-red disabled:opacity-50"
|
|
>
|
|
{params.deleting ? t('presentation.delete.deleting') : t('presentation.delete.button')}
|
|
</button>
|
|
)
|
|
}
|
|
|
|
function getSubmitLabel(params: { loading: boolean; deleting: boolean; hasExistingPresentation: boolean }): string {
|
|
if (params.loading || params.deleting) {
|
|
return t('publish.publishing')
|
|
}
|
|
return params.hasExistingPresentation ? t('presentation.update.button') : t('publish.button')
|
|
}
|