Add moderation queue tables

This commit is contained in:
gpt-engineer-app[bot]
2025-09-28 18:06:00 +00:00
parent 64c29348ce
commit ff5d7ebea6
11 changed files with 1542 additions and 3 deletions

View File

@@ -0,0 +1,148 @@
import { useState } from 'react';
import { Flag, AlertTriangle } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Textarea } from '@/components/ui/textarea';
import { Label } from '@/components/ui/label';
import { supabase } from '@/integrations/supabase/client';
import { useAuth } from '@/hooks/useAuth';
import { useToast } from '@/hooks/use-toast';
interface ReportButtonProps {
entityType: 'review' | 'profile' | 'content_submission';
entityId: string;
className?: string;
}
const REPORT_TYPES = [
{ value: 'spam', label: 'Spam' },
{ value: 'inappropriate', label: 'Inappropriate Content' },
{ value: 'harassment', label: 'Harassment' },
{ value: 'fake_info', label: 'Fake Information' },
{ value: 'offensive', label: 'Offensive Language' },
];
export function ReportButton({ entityType, entityId, className }: ReportButtonProps) {
const [open, setOpen] = useState(false);
const [reportType, setReportType] = useState('');
const [reason, setReason] = useState('');
const [loading, setLoading] = useState(false);
const { user } = useAuth();
const { toast } = useToast();
const handleSubmit = async () => {
if (!user || !reportType) return;
setLoading(true);
try {
const { error } = await supabase.from('reports').insert({
reporter_id: user.id,
reported_entity_type: entityType,
reported_entity_id: entityId,
report_type: reportType,
reason: reason.trim() || null,
});
if (error) throw error;
toast({
title: "Report Submitted",
description: "Thank you for your report. We'll review it shortly.",
});
setOpen(false);
setReportType('');
setReason('');
} catch (error) {
console.error('Error submitting report:', error);
toast({
title: "Error",
description: "Failed to submit report. Please try again.",
variant: "destructive",
});
} finally {
setLoading(false);
}
};
if (!user) return null;
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button variant="ghost" size="sm" className={className}>
<Flag className="w-4 h-4 mr-2" />
Report
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<AlertTriangle className="w-5 h-5 text-destructive" />
Report Content
</DialogTitle>
<DialogDescription>
Help us maintain a safe community by reporting inappropriate content.
</DialogDescription>
</DialogHeader>
<div className="space-y-4">
<div>
<Label htmlFor="report-type">Reason for report</Label>
<Select value={reportType} onValueChange={setReportType}>
<SelectTrigger>
<SelectValue placeholder="Select a reason" />
</SelectTrigger>
<SelectContent>
{REPORT_TYPES.map((type) => (
<SelectItem key={type.value} value={type.value}>
{type.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div>
<Label htmlFor="reason">Additional details (optional)</Label>
<Textarea
id="reason"
placeholder="Provide additional context about your report..."
value={reason}
onChange={(e) => setReason(e.target.value)}
rows={3}
/>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setOpen(false)}>
Cancel
</Button>
<Button
onClick={handleSubmit}
disabled={!reportType || loading}
variant="destructive"
>
{loading ? 'Submitting...' : 'Submit Report'}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}