79 lines
2.6 KiB
TypeScript
79 lines
2.6 KiB
TypeScript
import type { FormEvent } from 'react'
|
|
import { PresentationFormHeader } from '../PresentationFormHeader'
|
|
import { Button, Card, ErrorState } from '../ui'
|
|
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 (
|
|
<Card variant="default" className="space-y-4">
|
|
<form
|
|
onSubmit={(e: FormEvent<HTMLFormElement>) => {
|
|
void props.handleSubmit(e)
|
|
}}
|
|
className="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"
|
|
variant="primary"
|
|
disabled={props.loading || props.deleting}
|
|
loading={props.loading || props.deleting}
|
|
className="w-full"
|
|
>
|
|
{getSubmitLabel({ loading: props.loading, deleting: props.deleting, hasExistingPresentation: props.hasExistingPresentation })}
|
|
</Button>
|
|
</div>
|
|
{props.hasExistingPresentation ? <DeleteButton onDelete={props.handleDelete} deleting={props.deleting} /> : null}
|
|
</div>
|
|
</form>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
function ValidationError(params: { message: string | null }): React.ReactElement | null {
|
|
if (!params.message) {
|
|
return null
|
|
}
|
|
return <ErrorState message={params.message} />
|
|
}
|
|
|
|
function DeleteButton(params: { onDelete: () => void; deleting: boolean }): React.ReactElement {
|
|
return (
|
|
<Button
|
|
type="button"
|
|
variant="danger"
|
|
onClick={params.onDelete}
|
|
disabled={params.deleting}
|
|
loading={params.deleting}
|
|
size="small"
|
|
>
|
|
{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')
|
|
}
|