Vitron-Front/app/components/sets/CreateSetModal.tsx
2026-04-29 01:44:16 +03:30

132 lines
4.0 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState } from "react";
import { Loader2, Layers } from "lucide-react";
import { Dialog, DialogContent, DialogOverlay } from "~/components/ui/dialog";
import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import { useCreateCollection } from "../../requestHandler/use-user-collection-hooks";
import { UserCollection } from "../../../src/api/types";
interface CreateSetModalProps {
isOpen: boolean;
onOpenChange: (open: boolean) => void;
productId: string;
onSuccess: (collection: UserCollection) => void;
}
export const CreateSetModal = ({
isOpen,
onOpenChange,
productId,
onSuccess,
}: CreateSetModalProps) => {
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const { mutate: createCollection, isPending } = useCreateCollection();
const handleCreate = () => {
if (!title.trim()) return;
createCollection(
{
title: title.trim(),
description: description.trim() || undefined,
productIds: [productId],
},
{
onSuccess: (data) => {
setTitle("");
setDescription("");
onSuccess(data);
},
}
);
};
const handleClose = () => {
setTitle("");
setDescription("");
onOpenChange(false);
};
return (
<Dialog open={isOpen} onOpenChange={handleClose}>
<DialogOverlay />
<DialogContent className="p-4 bg-WHITE rounded-[15px] w-[calc(100%-40px)]">
<div className="flex flex-col gap-6">
<div className="flex flex-col gap-3 items-center w-full">
<div className="w-16 h-16 rounded-full bg-PRIMARY/10 flex items-center justify-center">
<Layers size={32} className="text-PRIMARY" />
</div>
<p className="text-B14 font-bold mt-1">ایجاد ست جدید</p>
<p className="text-R12 text-GRAY text-center">
یک ست جدید بسازید و محصولات مورد علاقهتان را در آن جمعآوری کنید
</p>
</div>
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<label htmlFor="title" className="text-R12 text-BLACK">
نام ست *
</label>
<Input
id="title"
placeholder="مثلا: ست تابستانی"
value={title}
onChange={(e) => setTitle(e.target.value)}
className="w-full"
maxLength={100}
/>
</div>
<div className="flex flex-col gap-2">
<label
htmlFor="description"
id="description"
className="text-R12 text-BLACK"
>
توضیحات (اختیاری)
</label>
<Input
placeholder="توضیحات مختصر درباره این ست..."
value={description}
onChange={(e) => setDescription(e.target.value)}
className="w-full"
maxLength={500}
/>
</div>
</div>
<div className="flex flex-row gap-4 w-full">
<Button
className="w-[100%]"
size="sm"
variant="dark"
onClick={handleClose}
disabled={isPending}
>
انصراف
</Button>
<Button
className="w-[100%]"
variant="primary"
size="sm"
onClick={handleCreate}
disabled={!title.trim() || isPending}
>
{isPending ? (
<>
<Loader2 className="h-4 w-4 animate-spin ml-2" />
در حال ایجاد...
</>
) : (
"ایجاد ست"
)}
</Button>
</div>
</div>
</DialogContent>
</Dialog>
);
};