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;
|
title: string;
|
||||||
body: string;
|
body: string;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
|
reviewer_name: string | null;
|
||||||
profiles: { name: string | null } | null;
|
profiles: { name: string | null } | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ export function ProductReviews({ productId, type }: ProductReviewsProps) {
|
|||||||
const fetchReviews = async () => {
|
const fetchReviews = async () => {
|
||||||
let query = supabase
|
let query = supabase
|
||||||
.from('reviews')
|
.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);
|
.eq('is_approved', true);
|
||||||
|
|
||||||
if (productId) {
|
if (productId) {
|
||||||
@@ -74,7 +75,7 @@ export function ProductReviews({ productId, type }: ProductReviewsProps) {
|
|||||||
rating={review.rating}
|
rating={review.rating}
|
||||||
title={review.title}
|
title={review.title}
|
||||||
body={review.body}
|
body={review.body}
|
||||||
authorName={review.profiles?.name || 'Anonymous'}
|
authorName={review.reviewer_name || review.profiles?.name || 'Anonymous'}
|
||||||
date={review.created_at}
|
date={review.created_at}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog';
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@@ -33,6 +33,22 @@ export function ReviewModal({
|
|||||||
const [title, setTitle] = useState('');
|
const [title, setTitle] = useState('');
|
||||||
const [body, setBody] = useState('');
|
const [body, setBody] = useState('');
|
||||||
const [submitting, setSubmitting] = useState(false);
|
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 () => {
|
const handleSubmit = async () => {
|
||||||
if (rating === 0) {
|
if (rating === 0) {
|
||||||
@@ -54,6 +70,7 @@ export function ReviewModal({
|
|||||||
title: title.trim(),
|
title: title.trim(),
|
||||||
body: body.trim() || null,
|
body: body.trim() || null,
|
||||||
is_approved: false,
|
is_approved: false,
|
||||||
|
reviewer_name: userName || null,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ export default function ProductDetail() {
|
|||||||
.select('id')
|
.select('id')
|
||||||
.eq('user_id', user.id)
|
.eq('user_id', user.id)
|
||||||
.eq('product_id', product.id)
|
.eq('product_id', product.id)
|
||||||
|
.eq('is_approved', true)
|
||||||
.limit(1);
|
.limit(1);
|
||||||
|
|
||||||
setHasReviewed(!!(data && data.length > 0));
|
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