);
};
export const ReviewSection = ({
productId,
isOwner = false,
}: {
productId: string;
isOwner?: boolean;
}) => {
// Get product ID from the URL if not provided
const resolvedProductId =
productId || window.location.pathname.split("/").pop() || "";
// Get total comment count using the same service
const { data } = useServiceGetComments(1, resolvedProductId);
const commentCount = data?.count || 0;
return (
نظر خریداران {commentCount ? `(${commentCount})` : null}
{!isOwner && }
);
};
const SubmitReviewDrawer = ({ productId }: { productId: string }) => {
const [submitReviewDrawer, setSubmitReviewDrawer] = useState(false);
const [rating, setRating] = useState(null);
const [comment, setComment] = useState("");
const [hoverRating, setHoverRating] = useState(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const [error, setError] = useState(null);
const { toast } = useToast();
const [isLoginModalOpen, setIsLoginModalOpen] = useState(false);
const textareaRef = useRef(null);
const drawerContentRef = useRef(null);
const [keyboardHeight, setKeyboardHeight] = useState(0);
// Get authentication token from localStorage
const { user } = useRootData();
const authToken = user?.access_token
? user.access_token.replace(/^"|"$/g, "")
: "";
// Get the mutations
const createCommentMutation = useServiceCreateComment();
const submitRatingMutation = useServiceSubmitRating();
// Handle keyboard open/close using visualViewport API
useEffect(() => {
if (!submitReviewDrawer) return;
const viewport = window.visualViewport;
if (!viewport) return;
const handleViewportResize = () => {
// Calculate keyboard height from the difference between window height and viewport height
const newKeyboardHeight = window.innerHeight - viewport.height;
setKeyboardHeight(Math.max(0, newKeyboardHeight));
// Scroll textarea into view when keyboard opens
if (newKeyboardHeight > 0 && textareaRef.current) {
setTimeout(() => {
textareaRef.current?.scrollIntoView({
behavior: "smooth",
block: "center",
});
}, 100);
}
};
viewport.addEventListener("resize", handleViewportResize);
viewport.addEventListener("scroll", handleViewportResize);
return () => {
viewport.removeEventListener("resize", handleViewportResize);
viewport.removeEventListener("scroll", handleViewportResize);
};
}, [submitReviewDrawer]);
// Handle star rating click
const handleRatingClick = (newRating: number) => {
setRating(newRating);
};
// Handle star hover effects
const handleRatingHover = (hoveredRating: number | null) => {
setHoverRating(hoveredRating);
};
// Handle comment input change
const handleCommentChange = (e: React.ChangeEvent) => {
setComment(e.target.value);
};
// Handle form submission
const handleSubmit = async () => {
// Check if user is authenticated
if (!authToken) {
setError("لطفا ابتدا وارد حساب کاربری خود شوید.");
return;
}
// Form validation
if (!rating) {
setError("لطفا به این محصول امتیاز دهید.");
return;
}
if (!comment || comment.trim().length < 1) {
setError("لطفا نظر خود را درباره این محصول بنویسید.");
return;
}
setError(null);
setIsSubmitting(true);
try {
// Submit rating first
await submitRatingMutation.mutateAsync({
product_id: productId,
rating: rating,
});
// Then submit comment
await createCommentMutation.mutateAsync({
product: productId,
comment: comment,
parent: null,
});
// Reset form and close drawer on success
setComment("");
setRating(null);
setSubmitReviewDrawer(false);
// Show success toast
toast({
title: "نظر شما با موفقیت ثبت شد",
description: "نظر شما بعد از بررسی به زودی اضافه خواهد شد.",
});
} catch {
console.error("Error submitting review:");
setError("خطا در ثبت نظر. لطفا مجددا تلاش کنید.");
} finally {
setIsSubmitting(false);
}
};
// Determine the star fill based on rating and hover state
const getStarFill = (starPosition: number) => {
const currentRating = hoverRating !== null ? hoverRating : rating;
return currentRating !== null && starPosition <= currentRating
? "fill-current"
: "";
};
return (
<>