mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 08:11:13 -05:00
Fix submission deletion and preserve filters
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect, useImperativeHandle, forwardRef } from 'react';
|
||||||
import { CheckCircle, XCircle, Eye, Calendar, User, Filter, MessageSquare, FileText, Image, X, Trash2 } from 'lucide-react';
|
import { CheckCircle, XCircle, Eye, Calendar, User, Filter, MessageSquare, FileText, Image, X, Trash2 } from 'lucide-react';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
@@ -28,7 +28,11 @@ interface ModerationItem {
|
|||||||
type EntityFilter = 'all' | 'reviews' | 'submissions' | 'photos';
|
type EntityFilter = 'all' | 'reviews' | 'submissions' | 'photos';
|
||||||
type StatusFilter = 'all' | 'pending' | 'flagged' | 'approved' | 'rejected';
|
type StatusFilter = 'all' | 'pending' | 'flagged' | 'approved' | 'rejected';
|
||||||
|
|
||||||
export function ModerationQueue() {
|
export interface ModerationQueueRef {
|
||||||
|
refresh: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
|
||||||
const [items, setItems] = useState<ModerationItem[]>([]);
|
const [items, setItems] = useState<ModerationItem[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [actionLoading, setActionLoading] = useState<string | null>(null);
|
const [actionLoading, setActionLoading] = useState<string | null>(null);
|
||||||
@@ -38,6 +42,13 @@ export function ModerationQueue() {
|
|||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { isAdmin, isSuperuser } = useUserRole();
|
const { isAdmin, isSuperuser } = useUserRole();
|
||||||
|
|
||||||
|
// Expose refresh method via ref
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
refresh: () => {
|
||||||
|
fetchItems(activeEntityFilter, activeStatusFilter);
|
||||||
|
}
|
||||||
|
}), [activeEntityFilter, activeStatusFilter]);
|
||||||
|
|
||||||
const fetchItems = async (entityFilter: EntityFilter = 'all', statusFilter: StatusFilter = 'pending') => {
|
const fetchItems = async (entityFilter: EntityFilter = 'all', statusFilter: StatusFilter = 'pending') => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -292,8 +303,14 @@ export function ModerationQueue() {
|
|||||||
const photoIds: string[] = [];
|
const photoIds: string[] = [];
|
||||||
if (item.content?.photos && Array.isArray(item.content.photos)) {
|
if (item.content?.photos && Array.isArray(item.content.photos)) {
|
||||||
for (const photo of item.content.photos) {
|
for (const photo of item.content.photos) {
|
||||||
if (photo.imageId) {
|
if (photo.url) {
|
||||||
photoIds.push(photo.imageId);
|
// Extract UUID from blob URL: blob:https://domain/[uuid]
|
||||||
|
const urlParts = photo.url.split('/');
|
||||||
|
const imageId = urlParts[urlParts.length - 1];
|
||||||
|
// Basic UUID validation (should be at least 32 characters)
|
||||||
|
if (imageId && imageId.length >= 32) {
|
||||||
|
photoIds.push(imageId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -755,4 +772,4 @@ export function ModerationQueue() {
|
|||||||
<QueueContent />
|
<QueueContent />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState, useCallback } from 'react';
|
import { useRef, useEffect, useCallback } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Shield, Users, FileText, Flag, AlertCircle } from 'lucide-react';
|
import { Shield, Users, FileText, Flag, AlertCircle } from 'lucide-react';
|
||||||
import { useUserRole } from '@/hooks/useUserRole';
|
import { useUserRole } from '@/hooks/useUserRole';
|
||||||
@@ -6,7 +6,7 @@ import { useAuth } from '@/hooks/useAuth';
|
|||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||||
import { ModerationQueue } from '@/components/moderation/ModerationQueue';
|
import { ModerationQueue, ModerationQueueRef } from '@/components/moderation/ModerationQueue';
|
||||||
import { ReportsQueue } from '@/components/moderation/ReportsQueue';
|
import { ReportsQueue } from '@/components/moderation/ReportsQueue';
|
||||||
import { UserManagement } from '@/components/admin/UserManagement';
|
import { UserManagement } from '@/components/admin/UserManagement';
|
||||||
import { AdminHeader } from '@/components/layout/AdminHeader';
|
import { AdminHeader } from '@/components/layout/AdminHeader';
|
||||||
@@ -15,10 +15,10 @@ export default function Admin() {
|
|||||||
const { user, loading: authLoading } = useAuth();
|
const { user, loading: authLoading } = useAuth();
|
||||||
const { isModerator, loading: roleLoading } = useUserRole();
|
const { isModerator, loading: roleLoading } = useUserRole();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [refreshKey, setRefreshKey] = useState(0);
|
const moderationQueueRef = useRef<ModerationQueueRef>(null);
|
||||||
|
|
||||||
const handleRefresh = useCallback(() => {
|
const handleRefresh = useCallback(() => {
|
||||||
setRefreshKey(prev => prev + 1);
|
moderationQueueRef.current?.refresh();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -128,11 +128,11 @@ export default function Admin() {
|
|||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
<TabsContent value="queue">
|
<TabsContent value="queue">
|
||||||
<ModerationQueue key={`moderation-queue-${refreshKey}`} />
|
<ModerationQueue ref={moderationQueueRef} />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="reports">
|
<TabsContent value="reports">
|
||||||
<ReportsQueue key={`reports-queue-${refreshKey}`} />
|
<ReportsQueue />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@@ -150,7 +150,7 @@ export default function Admin() {
|
|||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<UserManagement key={`user-management-${refreshKey}`} />
|
<UserManagement />
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user