swag-shop/frontend/src/pages/shop/components/shop-about-form.tsx

238 lines
6.4 KiB
TypeScript

import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage
} from "@/components/ui/form";
import { Textarea } from "@/components/ui/textarea";
import { PhoneInput } from "@/components/ui/phone-number-input";
import { Input } from "@/components/ui/input";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { ScrollArea } from "@/components/ui/scroll-area";
import { useShop } from "@/hooks/useShop";
import { useEffect } from "react";
import { toast } from "@/hooks/useToast";
const shopAboutSchema = z.object({
name: z.string().min(1, "Name is required"),
description: z.string().min(1, "Description is required"),
currency: z.string().min(1, "Currency is required"),
contact_email: z.string().email("Invalid email"),
contact_phone_number: z.string().min(1, "Phone number is required"),
address: z.object({
street: z.string(),
city: z.string(),
state: z.string().nullable().optional(),
postal_code: z.string(),
country: z.string()
}),
status: z.enum(["active", "inactive", "suspended"])
});
type ShopAboutFormValues = z.infer<typeof shopAboutSchema>;
export function ShopAboutForm() {
const { shop, isLoading, updateShop } = useShop();
const form = useForm<ShopAboutFormValues>({
resolver: zodResolver(shopAboutSchema),
defaultValues: shop ?? undefined,
mode: "onChange"
});
useEffect(() => {
if (shop) form.reset(shop);
}, [shop, form]);
function onSubmit(data: ShopAboutFormValues) {
updateShop(data);
toast({title: "Saved shop data"})
}
if (isLoading) return <div className="p-4">Loading...</div>;
if (!shop) return <div className="p-4">No shop found</div>;
return (
<ScrollArea
orientation="horizontal"
type="always"
className="hidden w-full min-w-40 bg-background px-1 md:block">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<Card>
<CardHeader>
<CardTitle className="text-xl">Basic Details</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Shop Name</FormLabel>
<FormControl>
<Input placeholder="Enter shop name" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="currency"
render={({ field }) => (
<FormItem>
<FormLabel>Currency</FormLabel>
<FormControl>
<Input placeholder="e.g., USD" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="description"
render={({ field }) => (
<FormItem>
<FormLabel>Description</FormLabel>
<FormControl>
<Textarea placeholder="Describe your shop" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="text-xl">Contact Information</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-2 gap-4">
<FormField
control={form.control}
name="contact_email"
render={({ field }) => (
<FormItem>
<FormLabel>Contact Email</FormLabel>
<FormControl>
<Input
type="email"
placeholder="user@example.com"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="contact_phone_number"
render={({ field }) => (
<FormItem>
<FormLabel>Phone Number</FormLabel>
<FormControl>
<PhoneInput {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="text-xl">Address</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<FormField
control={form.control}
name="address.street"
render={({ field }) => (
<FormItem>
<FormLabel>Street Address</FormLabel>
<FormControl>
<Input placeholder="123 Shop Street" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="grid grid-cols-2 gap-4">
<FormField
control={form.control}
name="address.city"
render={({ field }) => (
<FormItem>
<FormLabel>City</FormLabel>
<FormControl>
<Input placeholder="City" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="address.state"
render={({ field }) => (
<FormItem>
<FormLabel>State/Province</FormLabel>
<FormControl>
<Input placeholder="State" {...field} value={field.value ?? ""} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="address.postal_code"
render={({ field }) => (
<FormItem>
<FormLabel>Postal Code</FormLabel>
<FormControl>
<Input placeholder="Postal Code" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="address.country"
render={({ field }) => (
<FormItem>
<FormLabel>Country</FormLabel>
<FormControl>
<Input placeholder="Country" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</CardContent>
</Card>
<div className="flex justify-end gap-4">
<Button variant="outline">Cancel</Button>
<Button type="submit">Save Changes</Button>
</div>
</form>
</Form>
</ScrollArea>
);
}