Files
nini-naderi/src/components/ProductTabs.tsx
T
Alireza HassaniandCursor 051939c6e2 Tighten storefront cards and rebuild the product page.
Match carousel cards on XL, add gallery zoom/lightbox, quantity and comments, and update the sale banner slot to 2:3.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 16:19:29 +03:30

124 lines
3.8 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { useAuthUser } from "@/lib/auth";
import { customerLoginUrl } from "@/lib/site";
type Tab = "description" | "comments";
type Props = {
descriptionHtml?: string;
summary?: string;
};
export function ProductTabs({ descriptionHtml, summary }: Props) {
const [tab, setTab] = useState<Tab>("description");
const [loginHref, setLoginHref] = useState(customerLoginUrl());
const { user, ready, isLoggedIn } = useAuthUser();
useEffect(() => {
const url = new URL(window.location.href);
if (url.searchParams.get("tab") === "comments") setTab("comments");
url.searchParams.set("tab", "comments");
setLoginHref(customerLoginUrl(url.toString()));
}, []);
return (
<div className="glass-box mt-10 rounded-3xl p-6 sm:p-8">
<div className="flex justify-center gap-2 border-b border-line pb-3">
<TabButton active={tab === "description"} onClick={() => setTab("description")}>
توضیحات
</TabButton>
<TabButton active={tab === "comments"} onClick={() => setTab("comments")}>
نظرات
</TabButton>
</div>
{tab === "description" ? (
<div className="mt-6">
{descriptionHtml ? (
<div className="rich-content" dangerouslySetInnerHTML={{ __html: descriptionHtml }} />
) : summary ? (
<p className="text-sm leading-8 text-muted">{summary}</p>
) : (
<p className="py-8 text-center text-sm text-muted">توضیحاتی برای این محصول ثبت نشده است.</p>
)}
</div>
) : (
<div className="mx-auto mt-6 max-w-xl">
{!ready ? (
<p className="py-8 text-center text-sm text-muted">در حال بررسی ورود...</p>
) : isLoggedIn ? (
<CommentForm defaultName={[user?.firstName, user?.lastName].filter(Boolean).join(" ")} />
) : (
<div className="py-8 text-center">
<p className="text-sm leading-7 text-muted">
برای ثبت دیدگاه باید وارد حساب کاربری شوید.
</p>
<a
href={loginHref}
className="mt-5 inline-flex h-11 items-center rounded-full bg-purple-700 px-6 text-sm font-bold text-white hover:bg-purple-800"
>
ورود به حساب کاربری
</a>
</div>
)}
</div>
)}
</div>
);
}
function CommentForm({ defaultName }: { defaultName?: string }) {
return (
<form
className="grid gap-3"
onSubmit={(event) => {
event.preventDefault();
}}
>
<input
type="text"
name="name"
defaultValue={defaultName}
placeholder="نام"
className="h-11 rounded-2xl border border-line bg-white/70 px-4 text-sm outline-none focus:border-purple-500"
/>
<textarea
name="comment"
rows={4}
placeholder="نظر شما"
className="rounded-2xl border border-line bg-white/70 px-4 py-3 text-sm outline-none focus:border-purple-500"
/>
<button
type="submit"
className="h-11 rounded-full bg-purple-700 text-sm font-bold text-white hover:bg-purple-800"
>
ارسال دیدگاه
</button>
</form>
);
}
function TabButton({
active,
onClick,
children,
}: {
active: boolean;
onClick: () => void;
children: string;
}) {
return (
<button
type="button"
onClick={onClick}
className={`rounded-full px-5 py-2 text-sm transition ${
active ? "bg-purple-700 text-white" : "text-muted hover:bg-purple-50 hover:text-purple-700"
}`}
>
<span className="font-bold">{children}</span>
</button>
);
}