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

210 lines
7.4 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 { useNavigate } from "@remix-run/react";
import { X, Plus, Check, Loader2, Layers, ChevronLeft } from "lucide-react";
import {
Drawer,
DrawerContent,
DrawerHeader,
DrawerTitle,
} from "~/components/ui/drawer";
import { Button } from "~/components/ui/button";
import { Skeleton } from "~/components/ui/skeleton";
import {
useUserCollections,
useAddProductsToCollection,
} from "../../requestHandler/use-user-collection-hooks";
import { CreateSetModal } from "./CreateSetModal";
import { SetSuccessModal } from "./SetSuccessModal";
import { UserCollection } from "src/api/types";
interface AddToSetDrawerProps {
isOpen: boolean;
onOpenChange: (open: boolean) => void;
productId: string;
}
export const AddToSetDrawer = ({
isOpen,
onOpenChange,
productId,
}: AddToSetDrawerProps) => {
const navigate = useNavigate();
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const [isSuccessModalOpen, setIsSuccessModalOpen] = useState(false);
const [selectedSet, setSelectedSet] = useState<UserCollection | null>(null);
const [addingToSetId, setAddingToSetId] = useState<string | null>(null);
const { data: collections, isLoading } = useUserCollections();
const handleGoToSetDetail = (e: React.MouseEvent, collectionId: string) => {
e.stopPropagation();
onOpenChange(false);
navigate(`/profile/sets/${collectionId}`);
};
const { mutate: addToCollection, isPending: isAddingToCollection } =
useAddProductsToCollection();
const handleAddToSet = (collectionId: string) => {
setAddingToSetId(collectionId);
// Find the collection to show in success modal
const collection = collections?.find((c) => c.id === collectionId);
addToCollection(
{ collectionId, productIds: [productId] },
{
onSuccess: () => {
setAddingToSetId(null);
onOpenChange(false);
// Show success modal with the collection
if (collection) {
setSelectedSet(collection);
setIsSuccessModalOpen(true);
}
},
onError: () => {
setAddingToSetId(null);
},
}
);
};
const handleCreateSetSuccess = (newSet: UserCollection) => {
setSelectedSet(newSet);
setIsCreateModalOpen(false);
onOpenChange(false);
setIsSuccessModalOpen(true);
};
const isProductInCollection = (collection: UserCollection) => {
return collection.products?.includes(productId) || false;
};
return (
<>
<Drawer open={isOpen} onOpenChange={onOpenChange}>
<DrawerContent>
<DrawerHeader className="flex flex-col">
<div className="flex relative items-center justify-center w-full">
<X
className="absolute right-0 cursor-pointer hover:bg-BLACK/5 rounded-full p-1 transition-colors"
size={28}
onClick={() => onOpenChange(false)}
/>
<div className="flex flex-col items-center gap-2">
<DrawerTitle className="text-B16 font-bold">
افزودن به ست
</DrawerTitle>
</div>
</div>
</DrawerHeader>
<div className="px-4 pb-4 flex flex-col gap-3 max-h-[60vh] overflow-y-auto">
<p className="text-R12 text-GRAY text-center mb-2">
این محصول را به یکی از ستهای خود اضافه کنید
</p>
{isLoading ? (
<div className="flex flex-col gap-3">
{[1, 2, 3].map((i) => (
<Skeleton key={i} className="h-16 w-full rounded-xl" />
))}
</div>
) : collections && collections.length > 0 ? (
<div className="flex flex-col gap-3">
{collections.map((collection) => {
const isInCollection = isProductInCollection(collection);
const isAdding = addingToSetId === collection.id;
return (
<button
key={collection.id}
className={`flex items-center gap-4 p-4 rounded-xl transition-colors ${
isInCollection
? "bg-GREEN/10 cursor-default"
: "bg-BLACK/5 hover:bg-BLACK/10"
}`}
onClick={() =>
!isInCollection &&
!isAdding &&
handleAddToSet(collection.id!)
}
disabled={isInCollection || isAdding}
>
<div
className={`w-12 h-12 rounded-full flex items-center justify-center ${
isInCollection ? "bg-GREEN" : "bg-PRIMARY"
}`}
>
{isInCollection ? (
<Check size={24} className="text-BLACK" />
) : (
<Layers size={24} className="text-BLACK" />
)}
</div>
<div className="flex flex-col items-start flex-1">
<span className="text-B14 font-bold text-BLACK">
{collection.title}
</span>
<span className="text-R12 text-GRAY">
{isInCollection
? "این محصول از قبل در این ست وجود دارد"
: `${collection.products?.length || 0} محصول`}
</span>
</div>
{isAdding ? (
<Loader2 className="h-5 w-5 animate-spin text-PRIMARY" />
) : (
<button
onClick={(e) => handleGoToSetDetail(e, collection.id!)}
className="p-2 rounded-full hover:bg-BLACK/10 transition-colors"
title="مشاهده ست"
>
<ChevronLeft size={20} className="text-GRAY" />
</button>
)}
</button>
);
})}
</div>
) : (
<div className="flex flex-col items-center py-8 text-center">
<Layers size={48} className="text-GRAY mb-4" />
<p className="text-B14 text-GRAY">هنوز ستی ایجاد نکردهاید</p>
<p className="text-R12 text-GRAY mt-1">
اولین ست خود را بسازید
</p>
</div>
)}
{/* Create new set button */}
<Button
variant="dark"
size="xl"
className="w-full mt-4 gap-2"
onClick={() => setIsCreateModalOpen(true)}
>
<Plus size={18} />
ایجاد ست جدید
</Button>
</div>
</DrawerContent>
</Drawer>
<CreateSetModal
isOpen={isCreateModalOpen}
onOpenChange={setIsCreateModalOpen}
productId={productId}
onSuccess={handleCreateSetSuccess}
/>
<SetSuccessModal
isOpen={isSuccessModalOpen}
onOpenChange={setIsSuccessModalOpen}
collection={selectedSet}
/>
</>
);
};