import { MetaFunction, LoaderFunctionArgs, json } from "@remix-run/node"; import { useLoaderData, useNavigate, Link } from "@remix-run/react"; import { Layers, Trash2, Loader2, Edit2, X, ShoppingBag, Sparkles, MoreVertical, } from "lucide-react"; import { useState, useEffect } from "react"; import { Button } from "~/components/ui/button"; import { Skeleton } from "~/components/ui/skeleton"; import { Dialog, DialogContent, DialogOverlay } from "~/components/ui/dialog"; import { Input } from "~/components/ui/input"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu"; import { useUserCollection, useDeleteCollection, useRemoveProductFromCollection, useUpdateCollection, } from "../requestHandler/use-user-collection-hooks"; import { UserCollection, ProductDetail } from "src/api/types"; import { useQuery } from "@tanstack/react-query"; import ProfilePagesHeader from "~/components/ProfilePagesHeader"; import AIPromoteModal from "~/components/AIPromoteModal"; export async function loader({ params }: LoaderFunctionArgs) { const { id } = params; return json({ collectionId: id }); } export default function SetDetail() { const { collectionId } = useLoaderData(); const navigate = useNavigate(); const { data: collection, isLoading, refetch, } = useUserCollection(collectionId || ""); const [deleteModalOpen, setDeleteModalOpen] = useState(false); const [editModalOpen, setEditModalOpen] = useState(false); const [removeProductId, setRemoveProductId] = useState(null); const [aiModalOpen, setAiModalOpen] = useState(false); if (!collectionId) { return (

ست یافت نشد

); } return (
{/* Header */} setEditModalOpen(true)} className="gap-2" > ویرایش setDeleteModalOpen(true)} className="gap-2 text-RED focus:text-RED" > حذف ست ) : undefined } /> {/* Content */}
{isLoading ? (
{[1, 2, 3].map((i) => ( ))}
) : collection ? (
{/* Hero Section with Product Images Grid */}
{/* Product Images Grid Preview */} {collection.products && collection.products.length > 0 && (
)} {/* Collection Info & AI Try-on */}
{/* Collection Header */}

{collection.title}

{collection.description && (

{collection.description}

)}
{collection.products?.length || 0} محصول
{/* AI Try-on Section */} {collection.products && collection.products.length > 0 && ( <>
{/* Tip message */}
💡

نکته: از هر دسته فقط یک محصول اضافه کنید (یک پیراهن، یک شلوار، یک کفش)

{/* AI Button */} )}
{/* Products List */}
{collection.products && collection.products.length > 0 ? (

محصولات این ست

{collection.products.length} عدد
{collection.products.map((productId) => ( setRemoveProductId(productId)} /> ))}
) : (

این ست خالی است

محصولی به این ست اضافه نشده است

)}
) : (

ست یافت نشد

)}
{/* Delete collection modal */} { navigate("/profile/sets"); }} /> {/* Edit collection modal */} { refetch(); setEditModalOpen(false); }} /> {/* Remove product modal */} !open && setRemoveProductId(null)} collectionId={collectionId} productId={removeProductId} isLastProduct={(collection?.products?.length || 0) === 1} onSuccess={(wasLastProduct) => { setRemoveProductId(null); if (wasLastProduct) { navigate("/profile/sets"); } else { refetch(); } }} /> {/* AI Promote Modal */} setAiModalOpen(false)} collectionId={collectionId} />
); } // Product Images Preview Grid const ProductImagesPreview = ({ productIds, totalCount, }: { productIds: string[]; totalCount: number; }) => { const extraCount = totalCount - 4; return (
{productIds.map((productId, index) => ( 0} remainingCount={extraCount} /> ))}
); }; const ProductImageThumbnail = ({ productId, isLast, remainingCount, }: { productId: string; isLast?: boolean; remainingCount?: number; }) => { const { data: product, isLoading } = useQuery({ queryKey: ["product-thumb", productId], queryFn: async (): Promise => { const response = await fetch( `${ typeof window !== "undefined" ? import.meta.env.VITE_API_BASE_URL || "https://api.prod.vitrown.com" : process.env.VITE_API_BASE_URL || "https://api.prod.vitrown.com" }/api/product/v1/products/${productId}/` ); if (!response.ok) throw new Error("Failed to fetch product"); return response.json(); }, enabled: !!productId, staleTime: 5 * 60 * 1000, }); if (isLoading) { return ; } return (
{product?.imageUrls?.[0] ? ( ) : (
)} {isLast && remainingCount && remainingCount > 0 && (
+{remainingCount}
)}
); }; // Product item component const ProductItem = ({ productId, onRemove, }: { productId: string; onRemove: () => void; }) => { const { data: product, isLoading } = useQuery({ queryKey: ["product-basic", productId], queryFn: async (): Promise => { const response = await fetch( `${ typeof window !== "undefined" ? import.meta.env.VITE_API_BASE_URL || "https://api.prod.vitrown.com" : process.env.VITE_API_BASE_URL || "https://api.prod.vitrown.com" }/api/product/v1/products/${productId}/` ); if (!response.ok) throw new Error("Failed to fetch product"); return response.json(); }, enabled: !!productId, staleTime: 5 * 60 * 1000, }); if (isLoading) { return ; } if (!product) { return null; } return (
{product.imageUrls?.[0] ? ( {product.title} ) : (
)}

{product.title}

{product.basePrice && (

{Number(product.basePrice).toLocaleString("fa-IR")} تومان

)}
); }; const DeleteSetModal = ({ open, onOpenChange, collection, onSuccess, }: { open: boolean; onOpenChange: (open: boolean) => void; collection: UserCollection | null; onSuccess: () => void; }) => { const { mutate: deleteCollection, isPending } = useDeleteCollection(); const handleDelete = () => { if (!collection?.id) return; deleteCollection(collection.id, { onSuccess: () => { onSuccess(); }, }); }; return (

حذف ست

آیا از حذف ست "{collection?.title}" مطمئن هستید؟

); }; const EditSetModal = ({ open, onOpenChange, collection, onSuccess, }: { open: boolean; onOpenChange: (open: boolean) => void; collection: UserCollection | null; onSuccess: () => void; }) => { const [title, setTitle] = useState(""); const [description, setDescription] = useState(""); const { mutate: updateCollection, isPending } = useUpdateCollection(); useEffect(() => { if (collection) { setTitle(collection.title || ""); setDescription(collection.description || ""); } }, [collection]); const handleUpdate = () => { if (!collection?.id || !title.trim()) return; updateCollection( { collectionId: collection.id, data: { title: title.trim(), description: description.trim() || undefined, }, }, { onSuccess: () => { onSuccess(); }, } ); }; return (

ویرایش ست

setTitle(e.target.value)} className="w-full" maxLength={100} />
setDescription(e.target.value)} className="w-full" maxLength={500} />
); }; const RemoveProductModal = ({ open, onOpenChange, collectionId, productId, isLastProduct, onSuccess, }: { open: boolean; onOpenChange: (open: boolean) => void; collectionId: string; productId: string | null; isLastProduct: boolean; onSuccess: (wasLastProduct: boolean) => void; }) => { const { mutate: removeProduct, isPending } = useRemoveProductFromCollection(); const handleRemove = () => { if (!collectionId || !productId) return; removeProduct( { collectionId, productId }, { onSuccess: () => { onSuccess(isLastProduct); }, } ); }; return (

حذف محصول از ست

{isLastProduct ? "این آخرین محصول این ست است. با حذف آن، کل ست حذف خواهد شد." : "آیا از حذف این محصول از ست مطمئن هستید؟"}

); }; export const meta: MetaFunction = () => { return [ { title: "جزئیات ست | ویترون" }, { name: "description", content: "مشاهده جزئیات ست" }, { name: "robots", content: "noindex, follow" }, ]; };