diff --git a/frontend/src/features/offerings/components/OfferingForm.tsx b/frontend/src/features/offerings/components/OfferingForm.tsx index 37df333..d5ebd8b 100644 --- a/frontend/src/features/offerings/components/OfferingForm.tsx +++ b/frontend/src/features/offerings/components/OfferingForm.tsx @@ -1,7 +1,8 @@ +import { useState } from 'react'; import { useForm, useWatch } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { useTranslation } from 'react-i18next'; -import { Plus, Trash2 } from 'lucide-react'; +import { Check, Pencil, Plus, Trash2, X } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; @@ -23,7 +24,8 @@ export function OfferingForm({ initialValues, onSubmit, isSubmitting }: Offering control, handleSubmit, setValue, - formState: { errors }, + resetField, + formState: { errors, dirtyFields }, } = useForm({ resolver: zodResolver(offeringFormSchema), mode: 'onTouched', @@ -35,12 +37,35 @@ export function OfferingForm({ initialValues, onSubmit, isSubmitting }: Offering features: [''], ctaLabel: '', featured: false, + slug: '', }, }); // useFieldArray requires object-shaped array items — features is a plain string[], // so add/remove are handled directly via setValue instead. const features = useWatch({ control, name: 'features' }); + const slug = useWatch({ control, name: 'slug' }); + const [isEditingSlug, setIsEditingSlug] = useState(false); + + function confirmSlugEdit() { + setIsEditingSlug(false); + } + + function cancelSlugEdit() { + resetField('slug'); + setIsEditingSlug(false); + } + + // Slug is auto-generated from the title server-side unless explicitly overridden here — + // only send it along when the admin actually touched this field, so an untouched slug + // keeps auto-regenerating when the title changes (see OfferingsService.UpdateAsync). + function submitWithSlugPolicy(values: OfferingFormData) { + const payload = { ...values }; + if (!dirtyFields.slug) { + delete payload.slug; + } + onSubmit(payload); + } function addFeature() { setValue('features', [...features, ''], { shouldValidate: true }); @@ -51,13 +76,68 @@ export function OfferingForm({ initialValues, onSubmit, isSubmitting }: Offering } return ( -
+
{errors.title && }
+
+ + {isEditingSlug ? ( +
+ + + +
+ ) : ( +
+ + {slug && slug.length > 0 ? slug : t('offerings.form.slugAutoHint')} + + +
+ )} + {errors.slug && } +
+