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>
124 lines
3.8 KiB
TypeScript
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>
|
|
);
|
|
}
|