admin/components/events/create/FaqEditor.tsx
alisaza e1eaf5eff5 feat: initial ghabilee-admin backoffice app
Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js
app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
2026-09-05 13:12:59 +03:30

93 lines
2.9 KiB
TypeScript

'use client'
import { zodResolver } from '@hookform/resolvers/zod'
import { FormProvider, useForm } from 'react-hook-form'
import type { FaqItem } from '@/components/events/create/types'
import Button from '@/components/formElements/Button'
import TrashIcon from '@/components/icons/TrashIcon'
import { EventWizardFaqFormValidation, type EventWizardFaqFormValues } from '@/validation/eventWizard'
import { createClientId } from '@/lib/createClientId'
import { showFormValidationToast } from '@/lib/formValidationToast'
import { texts } from '@/texts'
import ConsumerButton from '@/components/consumer/ConsumerButton'
import ConsumerInput from '@/components/consumer/ConsumerInput'
interface FaqEditorProps {
items: FaqItem[]
onChange: (items: FaqItem[]) => void
}
/** Adds and removes optional common questions without coupling to wizard state. */
export default function FaqEditor({ items, onChange }: FaqEditorProps) {
const form = useForm<EventWizardFaqFormValues>({
resolver: zodResolver(EventWizardFaqFormValidation),
defaultValues: { answer: '', question: '' },
})
const addFaq = () => {
void form.handleSubmit((values) => {
onChange([
...items,
{
answer: values.answer,
id: createClientId(),
question: values.question,
},
])
form.reset({ answer: '', question: '' })
}, showFormValidationToast)()
}
return (
<div className="flex flex-col gap-2">
{items.map((item) => (
<article
key={item.id}
className="rounded-consumer-control bg-secondary-50 p-3"
>
<div className="w-full flex items-start justify-between">
<div className="min-w-0">
<p className="text-sm font-medium text-consumer-text">{item.question}</p>
<p className="mt-1 text-xs leading-5 text-secondary-20">{item.answer}</p>
</div>
<Button
iconOnly
aria-label={texts.common.delete}
className="size-8 shrink-0 rounded-lg text-tertiary-900 hover:bg-white/70"
variant="light"
onClick={() => {
onChange(items.filter((faq) => faq.id !== item.id))
}}
>
<TrashIcon className="size-4 text-fourth" />
</Button>
</div>
</article>
))}
<FormProvider {...form}>
<div className="grid gap-2">
<ConsumerInput
generalType="input"
label={texts.events.questionLabel}
name="question"
/>
<ConsumerInput
generalType="input"
label={texts.common.reply}
name="answer"
/>
<ConsumerButton
fill="gray"
size="xs"
onClick={addFaq}
>
{texts.events.addQuestion}
</ConsumerButton>
</div>
</FormProvider>
</div>
)
}