2026-01-14 00:50:05 +01:00

144 lines
3.9 KiB
TypeScript

import React from 'react'
import { Button, ErrorState, Input, Textarea, Card } from '@/components/ui'
import { t } from '@/lib/i18n'
import type { ReviewFormController } from './useReviewFormController'
export function ReviewFormView(params: { ctrl: ReviewFormController; onCancel?: () => void }): React.ReactElement {
return (
<Card variant="default" className="space-y-4">
<form
onSubmit={(e) => void params.ctrl.handleSubmit(e)}
className="space-y-4"
>
<ReviewFormHeader />
<ReviewFormFields ctrl={params.ctrl} />
{params.ctrl.error ? <ErrorBox message={params.ctrl.error} /> : null}
<ReviewFormActions loading={params.ctrl.loading} onCancel={params.onCancel} />
</form>
</Card>
)
}
function ReviewFormHeader(): React.ReactElement {
return <h3 className="text-lg font-semibold text-neon-cyan">{t('review.form.title')}</h3>
}
function ReviewFormFields(params: { ctrl: ReviewFormController }): React.ReactElement {
return (
<>
<TextInput
id="review-title"
label={t('review.form.title.label')}
value={params.ctrl.title}
onChange={params.ctrl.setTitle}
placeholder={t('review.form.title.placeholder')}
optionalLabel={`(${t('common.optional')})`}
/>
<TextAreaInput
id="review-content"
label={t('review.form.content.label')}
value={params.ctrl.content}
onChange={params.ctrl.setContent}
placeholder={t('review.form.content.placeholder')}
rows={6}
required
requiredMark
/>
<TextAreaInput
id="review-text"
label={t('review.form.text.label')}
value={params.ctrl.text}
onChange={params.ctrl.setText}
placeholder={t('review.form.text.placeholder')}
rows={3}
helpText={t('review.form.text.help')}
optionalLabel={`(${t('common.optional')})`}
/>
</>
)
}
function ReviewFormActions(params: { loading: boolean; onCancel?: (() => void) | undefined }): React.ReactElement {
return (
<div className="flex gap-2">
<Button
type="submit"
variant="success"
disabled={params.loading}
loading={params.loading}
>
{params.loading ? t('common.loading') : t('review.form.submit')}
</Button>
{params.onCancel && (
<Button
type="button"
variant="ghost"
onClick={params.onCancel}
>
{t('common.cancel')}
</Button>
)}
</div>
)
}
function ErrorBox({ message }: { message: string }): React.ReactElement {
return <ErrorState message={message} />
}
function TextInput(params: {
id: string
label: string
value: string
onChange: (value: string) => void
placeholder: string
optionalLabel?: string
}): React.ReactElement {
const labelText = params.optionalLabel ? `${params.label} ${params.optionalLabel}` : params.label
return (
<Input
id={params.id}
type="text"
label={labelText}
value={params.value}
onChange={(e) => params.onChange(e.target.value)}
placeholder={params.placeholder}
/>
)
}
function TextAreaInput(params: {
id: string
label: string
value: string
onChange: (value: string) => void
placeholder: string
rows: number
required?: boolean
requiredMark?: boolean
optionalLabel?: string
helpText?: string
}): React.ReactElement {
let labelText = params.label
if (params.requiredMark) {
labelText = `${labelText} *`
}
if (params.optionalLabel) {
labelText = `${labelText} ${params.optionalLabel}`
}
return (
<Textarea
id={params.id}
label={labelText}
value={params.value}
onChange={(e) => params.onChange(e.target.value)}
placeholder={params.placeholder}
rows={params.rows}
required={params.required}
{...(params.helpText ? { helperText: params.helpText } : {})}
/>
)
}