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

194 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

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 { Star, X, Reply } from "lucide-react";
import { useState } from "react";
import { Button } from "~/components/ui/button";
import {
Drawer,
DrawerContent,
DrawerHeader,
DrawerTitle,
} from "~/components/ui/drawer";
import AppTextArea from "~/components/AppTextArea";
import { useServiceCreateComment } from "~/requestHandler/use-comments-hooks";
import { useRootData } from "~/hooks/use-root-data";
import { useToast } from "~/hooks/use-toast";
import { useIsOwnerProduct } from "~/requestHandler/use-product-hooks";
export interface ReviewProps {
id?: string;
productId: string;
name: string;
rating: number;
date: string;
comment: string;
sellerReply?: {
date: string;
comment: string;
};
isLast: boolean;
}
export const Review = ({
id,
productId,
name,
rating,
isLast,
date,
comment,
sellerReply,
}: ReviewProps) => {
const [isReplyDrawerOpen, setIsReplyDrawerOpen] = useState(false);
const [replyComment, setReplyComment] = useState("");
const [error, setError] = useState<string | null>(null);
const { toast } = useToast();
const { user } = useRootData();
const createCommentMutation = useServiceCreateComment();
const { data: isOwnerProduct } = useIsOwnerProduct(productId);
const isOwner = isOwnerProduct?.isOwner;
const authToken = user?.access_token
? user.access_token.replace(/^"|"$/g, "")
: "";
const handleReplySubmit = async () => {
// Check if user is authenticated
if (!authToken) {
setError("لطفا ابتدا وارد حساب کاربری خود شوید.");
return;
}
// Form validation
if (!replyComment || replyComment.trim().length < 1) {
setError("لطفا پاسخ خود را وارد کنید.");
return;
}
if (!id) {
setError("خطا در شناسایی نظر.");
return;
}
setError(null);
try {
await createCommentMutation.mutateAsync({
product: productId,
comment: replyComment,
parent: id,
});
// Reset form and close drawer on success
setReplyComment("");
setIsReplyDrawerOpen(false);
// Show success toast
toast({
title: "پاسخ شما با موفقیت ثبت شد",
description: "پاسخ شما بعد از بررسی به زودی اضافه خواهد شد.",
variant: "default",
duration: 3000,
});
} catch {
setError("خطا در ثبت پاسخ. لطفا مجددا تلاش کنید.");
}
};
return (
<>
<div
className={`flex gap-3 py-2 border-b flex-col w-full ${isLast ? "border-b-0" : ""}`}
>
<div>
<div className="flex gap-4 items-center">
<p className="text-B14 font-bold">{name}</p>
<div className="flex items-center gap-[2px]">
<p className="text-B12 font-bold">{rating}</p>
<Star className="text-BLACK fill-current" size={24} />
</div>
<p className="text-B12 font-bold text-GRAY">{date}</p>
{/* Reply button */}
{isOwner && (
<div className="mr-2">
<button
onClick={() => setIsReplyDrawerOpen(true)}
className="text-BLUE text-R12 flex items-center gap-1 hover:underline"
>
<Reply style={{ transform: "rotateY(180deg)" }} size={16} />
پاسخ
</button>
</div>
)}
</div>
<p className="text-R12">{comment}</p>
</div>
{sellerReply && (
<div className="rounded-[10px] bg-WHITE2 p-2">
<div className="flex gap-4 items-center">
<p className="text-B14 font-bold">پاسخ فروشنده</p>
<p className="text-B12 font-bold text-GRAY">{sellerReply.date}</p>
</div>
<p className="text-R12">{sellerReply.comment}</p>
</div>
)}
</div>
{/* Reply Drawer */}
<Drawer open={isReplyDrawerOpen} onOpenChange={setIsReplyDrawerOpen}>
<DrawerContent>
<DrawerHeader className="flex flex-col py-3">
<div className="flex relative pt-2 text-B12 font-bold items-center justify-center w-full">
<X
className="absolute right-2 cursor-pointer"
size={24}
onClick={() => setIsReplyDrawerOpen(false)}
/>
<DrawerTitle className="text-B12 font-bold">پاسخ شما</DrawerTitle>
</div>
</DrawerHeader>
<div className="p-4 flex flex-col gap-4">
{/* Original comment display */}
<div className="bg-WHITE2 rounded-[10px] p-3">
<div className="flex gap-4 items-center mb-2">
<p className="text-B14 font-bold">{name}</p>
<div className="flex items-center gap-[2px]">
<p className="text-B12 font-bold">{rating}</p>
<Star className="text-BLACK fill-current" size={16} />
</div>
<p className="text-B12 font-bold text-GRAY">{date}</p>
</div>
<p className="text-R12">{comment}</p>
</div>
{/* Reply input */}
<AppTextArea
inputTitle="پاسخ شما:"
inputValue={replyComment}
inputOnChange={(e) => setReplyComment(e.target.value)}
inputPlaceholder="پاسخ خود را در این قسمت وارد کنید..."
inputDir="rtl"
/>
{/* Error message */}
{error && (
<div className="text-red-500 text-R12 text-right">{error}</div>
)}
{/* Submit button */}
<Button
variant="dark"
size="lg"
className="w-full font-bold"
onClick={handleReplySubmit}
disabled={createCommentMutation.isPending}
>
{createCommentMutation.isPending ? "در حال ثبت..." : "ثبت پاسخ"}
</Button>
</div>
</DrawerContent>
</Drawer>
</>
);
};