mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-22 15:51:12 -05:00
Refactor code structure and remove redundant changes
This commit is contained in:
166
src-old/components/moderation/EditHistoryAccordion.tsx
Normal file
166
src-old/components/moderation/EditHistoryAccordion.tsx
Normal file
@@ -0,0 +1,166 @@
|
||||
import { useState } from 'react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { fetchEditHistory } from '@/lib/submissionItemsService';
|
||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||
import { Alert, AlertDescription } from '@/components/ui/alert';
|
||||
import { EditHistoryEntry } from './EditHistoryEntry';
|
||||
import { History, Loader2, AlertCircle } from 'lucide-react';
|
||||
|
||||
interface EditHistoryRecord {
|
||||
id: string;
|
||||
item_id: string;
|
||||
edited_at: string;
|
||||
edit_reason: string | null;
|
||||
changed_fields: string[];
|
||||
field_changes?: Array<{
|
||||
id: string;
|
||||
field_name: string;
|
||||
old_value: string | null;
|
||||
new_value: string | null;
|
||||
}>;
|
||||
editor?: {
|
||||
username: string;
|
||||
avatar_url?: string | null;
|
||||
} | null;
|
||||
}
|
||||
|
||||
interface EditHistoryAccordionProps {
|
||||
submissionId: string;
|
||||
}
|
||||
|
||||
const INITIAL_LOAD = 20;
|
||||
const LOAD_MORE_INCREMENT = 10;
|
||||
|
||||
export function EditHistoryAccordion({ submissionId }: EditHistoryAccordionProps) {
|
||||
const [limit, setLimit] = useState(INITIAL_LOAD);
|
||||
|
||||
const { data: editHistory, isLoading, error } = useQuery({
|
||||
queryKey: ['edit-history', submissionId, limit],
|
||||
queryFn: async () => {
|
||||
const { supabase } = await import('@/integrations/supabase/client');
|
||||
|
||||
// Fetch edit history with user profiles
|
||||
const { data, error } = await supabase
|
||||
.from('item_edit_history')
|
||||
.select(`
|
||||
id,
|
||||
item_id,
|
||||
edited_at,
|
||||
edit_reason,
|
||||
changed_fields,
|
||||
field_changes:item_field_changes(
|
||||
id,
|
||||
field_name,
|
||||
old_value,
|
||||
new_value
|
||||
),
|
||||
editor:profiles!item_edit_history_edited_by_fkey(
|
||||
username,
|
||||
avatar_url
|
||||
)
|
||||
`)
|
||||
.eq('item_id', submissionId)
|
||||
.order('edited_at', { ascending: false })
|
||||
.limit(limit);
|
||||
|
||||
if (error) throw error;
|
||||
return (data || []) as unknown as EditHistoryRecord[];
|
||||
},
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
});
|
||||
|
||||
const loadMore = () => {
|
||||
setLimit(prev => prev + LOAD_MORE_INCREMENT);
|
||||
};
|
||||
|
||||
const hasMore = editHistory && editHistory.length === limit;
|
||||
|
||||
return (
|
||||
<Accordion type="single" collapsible className="w-full">
|
||||
<AccordionItem value="edit-history">
|
||||
<AccordionTrigger className="hover:no-underline">
|
||||
<div className="flex items-center gap-2">
|
||||
<History className="h-4 w-4" />
|
||||
<span>Edit History</span>
|
||||
{editHistory && editHistory.length > 0 && (
|
||||
<span className="text-xs text-muted-foreground">
|
||||
({editHistory.length} edit{editHistory.length !== 1 ? 's' : ''})
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
{isLoading && (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{error && (
|
||||
<Alert variant="destructive">
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
<AlertDescription>
|
||||
Failed to load edit history: {error instanceof Error ? error.message : 'Unknown error'}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{!isLoading && !error && editHistory && editHistory.length === 0 && (
|
||||
<Alert>
|
||||
<AlertDescription>
|
||||
No edit history found for this submission.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{!isLoading && !error && editHistory && editHistory.length > 0 && (
|
||||
<div className="space-y-4">
|
||||
<ScrollArea className="h-[400px] pr-4">
|
||||
<div className="space-y-3">
|
||||
{editHistory.map((entry: EditHistoryRecord) => {
|
||||
// Transform relational field_changes into beforeData/afterData objects
|
||||
const beforeData: Record<string, unknown> = {};
|
||||
const afterData: Record<string, unknown> = {};
|
||||
|
||||
entry.field_changes?.forEach(change => {
|
||||
beforeData[change.field_name] = change.old_value;
|
||||
afterData[change.field_name] = change.new_value;
|
||||
});
|
||||
|
||||
return (
|
||||
<EditHistoryEntry
|
||||
key={entry.id}
|
||||
editId={entry.id}
|
||||
editorName={entry.editor?.username || 'Unknown User'}
|
||||
editorAvatar={entry.editor?.avatar_url || undefined}
|
||||
timestamp={entry.edited_at}
|
||||
changedFields={entry.changed_fields || []}
|
||||
editReason={entry.edit_reason || undefined}
|
||||
beforeData={beforeData}
|
||||
afterData={afterData}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</ScrollArea>
|
||||
|
||||
{hasMore && (
|
||||
<div className="flex justify-center pt-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={loadMore}
|
||||
>
|
||||
Load More
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user