"use client"; import Image from "next/image"; import Link from "next/link"; import { useMemo, useState } from "react"; import { useCart } from "@/app/providers/cart-provider"; import { useAuth } from "@/app/providers/auth-provider"; import { useToast } from "@/app/providers/toast-provider"; import { submitComment } from "@/lib/meshkee/api"; import { formatPrice, storeItemName, storeItemPrice, } from "@/lib/meshkee/format"; import type { Comment, Product, StoreItemVariant, TechnicalInfo, } from "@/lib/meshkee/types"; import { customerLoginUrl, storeItemHref } from "@/lib/meshkee/urls"; type TabKey = "description" | "technical" | "comments"; export function StoreDetailClient({ variant, product, technical, comments: initialComments, similar, }: { variant: StoreItemVariant; product: Product; technical: TechnicalInfo; comments: Comment[]; similar: StoreItemVariant[]; }) { const name = storeItemName(variant); const price = storeItemPrice(variant); const images = useMemo(() => { const list = (product.images ?? []) .map((image) => image.url) .filter(Boolean); const fallback = variant.productImage || product.thumbnailUrl || product.image; if (fallback && !list.includes(fallback)) list.unshift(fallback); return list; }, [product, variant]); const [activeImage, setActiveImage] = useState(images[0] || ""); const [lightboxOpen, setLightboxOpen] = useState(false); const [tab, setTab] = useState("description"); const [quantity, setQuantity] = useState(1); const [comments, setComments] = useState(initialComments); const [commentText, setCommentText] = useState(""); const [submitting, setSubmitting] = useState(false); const { addItem } = useCart(); const { isAuthenticated, user, getAccessToken } = useAuth(); const { showToast } = useToast(); const techRows = useMemo(() => { const fields = technical.form?.fields ?? []; if (!fields.length || !technical.values?.length) return []; return [...fields] .sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0)) .map((field) => { const value = technical.values.find((entry) => entry.fieldId === field.id); if (!value) return null; let display = value.textValue ?? ""; if (value.optionId) { display = field.options?.find((option) => option.id === value.optionId)?.labelFa || field.options?.find((option) => option.id === value.optionId)?.label || display; } if (value.optionIds?.length) { display = value.optionIds .map( (id) => field.options?.find((option) => option.id === id)?.labelFa || field.options?.find((option) => option.id === id)?.label || id, ) .join("، "); } if (!display) return null; return { label: field.labelFa || field.label || field.key || "ویژگی", value: display, }; }) .filter(Boolean) as Array<{ label: string; value: string }>; }, [technical]); async function handleAddToCart() { await addItem({ storeItemVariantId: variant.id, name, price, quantity, image: activeImage || variant.productImage, slug: product.slug || undefined, }); } async function handleCommentSubmit(event: React.FormEvent) { event.preventDefault(); if (!isAuthenticated || !user) return; const authorName = [user.firstName, user.lastName].filter(Boolean).join(" ").trim() || "کاربر"; setSubmitting(true); try { await submitComment( { entityType: "product", entityId: product.id, authorName, authorEmail: user.email || undefined, text: commentText.trim(), }, getAccessToken(), ); setComments((prev) => [ { id: `local-${Date.now()}`, authorName, text: commentText.trim(), createdAt: new Date().toISOString(), }, ...prev, ]); setCommentText(""); showToast("نظر شما ارسال شد و پس از تایید نمایش داده می‌شود"); } catch (error) { showToast(error instanceof Error ? error.message : "ارسال نظر ناموفق بود"); } finally { setSubmitting(false); } } return (
{images.length > 1 ? (
{images.map((image) => ( ))}
) : null}

{variant.label || product.categoryNameFa || "Store Item"}

{name}

{formatPrice(price)} {variant.selections?.length ? (
    {variant.selections.map((selection, index) => (
  • {selection.variationName}: {selection.value}
  • ))}
) : null}
{( [ ["description", "توضیحات"], ["technical", "اطلاعات فنی"], ["comments", "نظرات"], ] as const ).map(([key, label]) => ( ))}
{tab === "description" ? ( product.descriptionHtml ? (
) : (

توضیحاتی ثبت نشده است.

) ) : null} {tab === "technical" ? ( techRows.length ? ( {techRows.map((row) => ( ))}
{row.label} {row.value}
) : (

اطلاعات فنی موجود نیست.

) ) : null} {tab === "comments" ? (
{isAuthenticated ? (
void handleCommentSubmit(event)}>