diff --git a/src/App.tsx b/src/App.tsx index 48ed432e..2027bce0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,9 +13,13 @@ import ParkDetail from "./pages/ParkDetail"; import RideDetail from "./pages/RideDetail"; import Rides from "./pages/Rides"; import Manufacturers from "./pages/Manufacturers"; +import ManufacturerDetail from "./pages/ManufacturerDetail"; import Designers from "./pages/Designers"; +import DesignerDetail from "./pages/DesignerDetail"; import ParkOwners from "./pages/ParkOwners"; +import PropertyOwnerDetail from "./pages/PropertyOwnerDetail"; import Operators from "./pages/Operators"; +import OperatorDetail from "./pages/OperatorDetail"; import Auth from "./pages/Auth"; import Profile from "./pages/Profile"; import UserSettings from "./pages/UserSettings"; @@ -46,9 +50,13 @@ function AppContent() { } /> } /> } /> + } /> } /> + } /> } /> + } /> } /> + } /> } /> } /> } /> diff --git a/src/components/admin/DesignerForm.tsx b/src/components/admin/DesignerForm.tsx new file mode 100644 index 00000000..4f489092 --- /dev/null +++ b/src/components/admin/DesignerForm.tsx @@ -0,0 +1,207 @@ +import { useForm } from 'react-hook-form'; +import { zodResolver } from '@hookform/resolvers/zod'; +import * as z from 'zod'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Textarea } from '@/components/ui/textarea'; +import { Label } from '@/components/ui/label'; +import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { Ruler, Save, X } from 'lucide-react'; +import { Combobox } from '@/components/ui/combobox'; +import { useCompanyHeadquarters } from '@/hooks/useAutocompleteData'; + +const designerSchema = z.object({ + name: z.string().min(1, 'Name is required'), + slug: z.string().min(1, 'Slug is required'), + description: z.string().optional(), + person_type: z.enum(['company', 'individual', 'firm', 'organization']), + website_url: z.string().url().optional().or(z.literal('')), + founded_year: z.number().min(1800).max(new Date().getFullYear()).optional(), + headquarters_location: z.string().optional() +}); + +type DesignerFormData = z.infer; + +interface DesignerFormProps { + onSubmit: (data: DesignerFormData) => void; + onCancel: () => void; + initialData?: Partial; +} + +export function DesignerForm({ onSubmit, onCancel, initialData }: DesignerFormProps) { + const { headquarters } = useCompanyHeadquarters(); + + const { + register, + handleSubmit, + setValue, + watch, + formState: { errors } + } = useForm({ + resolver: zodResolver(designerSchema), + defaultValues: { + name: initialData?.name || '', + slug: initialData?.slug || '', + description: initialData?.description || '', + person_type: initialData?.person_type || 'company', + website_url: initialData?.website_url || '', + founded_year: initialData?.founded_year || undefined, + headquarters_location: initialData?.headquarters_location || '' + } + }); + + const generateSlug = (name: string) => { + return name + .toLowerCase() + .replace(/[^a-z0-9\s-]/g, '') + .replace(/\s+/g, '-') + .replace(/-+/g, '-') + .trim(); + }; + + const handleNameChange = (e: React.ChangeEvent) => { + const name = e.target.value; + const slug = generateSlug(name); + setValue('slug', slug); + }; + + return ( + + + + + {initialData ? 'Edit Designer' : 'Create New Designer'} + + + +
+ {/* Basic Information */} +
+
+ + { + register('name').onChange(e); + handleNameChange(e); + }} + placeholder="Enter designer name" + /> + {errors.name && ( +

{errors.name.message}

+ )} +
+ +
+ + + {errors.slug && ( +

{errors.slug.message}

+ )} +
+
+ + {/* Description */} +
+ +