Fix review system: display real names and check approval status
Changes: - ProductReviews.tsx: Use LEFT JOIN and fetch reviewer_name field - ReviewModal.tsx: Store reviewer_name at submission time - ProductDetail.tsx: Check is_approved=true in checkUserReview() - Add migration for reviewer_name column and approval index This fixes two issues: 1. Reviews now show real account names instead of "Anonymous" 2. Members no longer see "menunggu moderasi" after approval 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ interface Review {
|
||||
title: string;
|
||||
body: string;
|
||||
created_at: string;
|
||||
reviewer_name: string | null;
|
||||
profiles: { name: string | null } | null;
|
||||
}
|
||||
|
||||
@@ -29,7 +30,7 @@ export function ProductReviews({ productId, type }: ProductReviewsProps) {
|
||||
const fetchReviews = async () => {
|
||||
let query = supabase
|
||||
.from('reviews')
|
||||
.select('id, rating, title, body, created_at, profiles:user_id (name)')
|
||||
.select('id, rating, title, body, created_at, reviewer_name, profiles!user_id (name)')
|
||||
.eq('is_approved', true);
|
||||
|
||||
if (productId) {
|
||||
@@ -74,7 +75,7 @@ export function ProductReviews({ productId, type }: ProductReviewsProps) {
|
||||
rating={review.rating}
|
||||
title={review.title}
|
||||
body={review.body}
|
||||
authorName={review.profiles?.name || 'Anonymous'}
|
||||
authorName={review.reviewer_name || review.profiles?.name || 'Anonymous'}
|
||||
date={review.created_at}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog';
|
||||
import { Button } from '@/components/ui/button';
|
||||
@@ -33,6 +33,22 @@ export function ReviewModal({
|
||||
const [title, setTitle] = useState('');
|
||||
const [body, setBody] = useState('');
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [userName, setUserName] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchUserName = async () => {
|
||||
if (!userId) return;
|
||||
const { data } = await supabase
|
||||
.from('profiles')
|
||||
.select('name')
|
||||
.eq('id', userId)
|
||||
.single();
|
||||
if (data?.name) {
|
||||
setUserName(data.name);
|
||||
}
|
||||
};
|
||||
fetchUserName();
|
||||
}, [userId]);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (rating === 0) {
|
||||
@@ -54,6 +70,7 @@ export function ReviewModal({
|
||||
title: title.trim(),
|
||||
body: body.trim() || null,
|
||||
is_approved: false,
|
||||
reviewer_name: userName || null,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
|
||||
@@ -168,6 +168,7 @@ export default function ProductDetail() {
|
||||
.select('id')
|
||||
.eq('user_id', user.id)
|
||||
.eq('product_id', product.id)
|
||||
.eq('is_approved', true)
|
||||
.limit(1);
|
||||
|
||||
setHasReviewed(!!(data && data.length > 0));
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
-- Add reviewer_name column to store display name at submission time
|
||||
-- This ensures reviews always show the author's name even if profile is deleted later
|
||||
ALTER TABLE reviews
|
||||
ADD COLUMN reviewer_name TEXT;
|
||||
|
||||
-- Create index for efficient approval status queries
|
||||
CREATE INDEX idx_reviews_is_approved ON reviews(is_approved);
|
||||
Reference in New Issue
Block a user