238 lines
6.4 KiB
TypeScript
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>
|
|
);
|
|
}
|