Files
v2.admin.gaertan.art/src/components/commissions/customCards/NewCustomCardForm.tsx

182 lines
6.1 KiB
TypeScript

"use client";
import type { CommissionCustomCardImageItem } from "@/actions/commissions/customCards/images";
import { createCommissionCustomCard } from "@/actions/commissions/customCards/newCard";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import type { CommissionExtra, CommissionOption, Tag } from "@/generated/prisma/client";
import {
commissionCustomCardSchema,
type CommissionCustomCardValues,
} from "@/schemas/commissionCustomCard";
import { zodResolver } from "@hookform/resolvers/zod";
import { useRouter } from "next/navigation";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { CommissionExtraField } from "../types/form/CommissionExtraField";
import { CommissionOptionField } from "../types/form/CommissionOptionField";
import { CustomCardImagePicker } from "./CustomCardImagePicker";
import MultipleSelector from "@/components/ui/multiselect";
type Props = {
options: CommissionOption[];
extras: CommissionExtra[];
images: CommissionCustomCardImageItem[];
tags: Tag[];
};
export default function NewCustomCardForm({ options, extras, images, tags }: Props) {
const router = useRouter();
const form = useForm<CommissionCustomCardValues>({
resolver: zodResolver(commissionCustomCardSchema),
defaultValues: {
name: "",
description: "",
isVisible: true,
isSpecialOffer: false,
referenceImageUrl: null,
tagIds: [],
options: [],
extras: [],
},
});
async function onSubmit(values: CommissionCustomCardValues) {
try {
const created = await createCommissionCustomCard(values);
console.log("Commission custom card created:", created);
toast("Custom commission card created.");
router.push("/commissions/custom-cards");
} catch (err) {
console.error(err);
toast("Failed to create custom commission card.");
}
}
return (
<div className="flex flex-col gap-8">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>The name of the custom commission card.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="description"
render={({ field }) => (
<FormItem>
<FormLabel>Description</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>Optional description.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="isVisible"
render={({ field }) => (
<FormItem className="flex items-center justify-between rounded-lg border p-4">
<div className="space-y-0.5">
<FormLabel>Visible on app</FormLabel>
<FormDescription>Controls whether the card is shown.</FormDescription>
</div>
<FormControl>
<Switch checked={field.value} onCheckedChange={field.onChange} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="isSpecialOffer"
render={({ field }) => (
<FormItem className="flex items-center justify-between rounded-lg border p-4">
<div className="space-y-0.5">
<FormLabel>Special offer</FormLabel>
<FormDescription>Adds a special offer badge on the app.</FormDescription>
</div>
<FormControl>
<Switch checked={field.value} onCheckedChange={field.onChange} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="referenceImageUrl"
render={() => <CustomCardImagePicker form={form} initialImages={images} />}
/>
<FormField
control={form.control}
name="tagIds"
render={({ field }) => {
const selectedIds = field.value ?? [];
const selectedOptions = tags
.filter((t) => selectedIds.includes(t.id))
.map((t) => ({ label: t.name, value: t.id }));
return (
<FormItem>
<FormLabel>Tags</FormLabel>
<FormControl>
<MultipleSelector
options={tags.map((t) => ({ label: t.name, value: t.id }))}
placeholder="Select tags for this custom card"
hidePlaceholderWhenSelected
selectFirstItem
value={selectedOptions}
onChange={(options) => field.onChange(options.map((o) => o.value))}
/>
</FormControl>
<FormDescription>
Used to link this custom card to tagged artworks.
</FormDescription>
<FormMessage />
</FormItem>
);
}}
/>
<CommissionOptionField options={options} />
<CommissionExtraField extras={extras} />
<div className="flex flex-col gap-4">
<Button type="submit">Submit</Button>
<Button type="reset" variant="secondary" onClick={() => router.back()}>
Cancel
</Button>
</div>
</form>
</Form>
</div>
);
}