mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-28 07:47:04 -05:00
Implement the plan to enhance the display of timeline event submissions in the moderation queue. This includes fixing the database function to fetch timeline event data, creating a new `RichTimelineEventDisplay` component, and updating the `SubmissionItemsList` and `TimelineEventPreview` components to leverage this new display. The goal is to provide moderators with complete and contextually rich information for timeline events.
130 lines
4.4 KiB
TypeScript
130 lines
4.4 KiB
TypeScript
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Calendar, Tag, Building2, MapPin } from 'lucide-react';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { FlexibleDateDisplay } from '@/components/ui/flexible-date-display';
|
|
import type { TimelineSubmissionData } from '@/types/timeline';
|
|
import { useEffect, useState } from 'react';
|
|
import { supabase } from '@/lib/supabaseClient';
|
|
|
|
interface TimelineEventPreviewProps {
|
|
data: TimelineSubmissionData;
|
|
}
|
|
|
|
export function TimelineEventPreview({ data }: TimelineEventPreviewProps) {
|
|
const [entityName, setEntityName] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (!data?.entity_id || !data?.entity_type) return;
|
|
|
|
const fetchEntityName = async () => {
|
|
const table = data.entity_type === 'park' ? 'parks' : 'rides';
|
|
const { data: entity } = await supabase
|
|
.from(table)
|
|
.select('name')
|
|
.eq('id', data.entity_id)
|
|
.single();
|
|
setEntityName(entity?.name || null);
|
|
};
|
|
|
|
fetchEntityName();
|
|
}, [data?.entity_id, data?.entity_type]);
|
|
|
|
const formatEventType = (type: string) => {
|
|
return type.replace(/_/g, ' ').replace(/\b\w/g, (l) => l.toUpperCase());
|
|
};
|
|
|
|
const getEventTypeColor = (type: string) => {
|
|
const colors: Record<string, string> = {
|
|
opening: 'bg-green-600',
|
|
closure: 'bg-red-600',
|
|
reopening: 'bg-blue-600',
|
|
renovation: 'bg-purple-600',
|
|
expansion: 'bg-indigo-600',
|
|
acquisition: 'bg-amber-600',
|
|
name_change: 'bg-cyan-600',
|
|
operator_change: 'bg-orange-600',
|
|
owner_change: 'bg-orange-600',
|
|
location_change: 'bg-pink-600',
|
|
status_change: 'bg-yellow-600',
|
|
milestone: 'bg-emerald-600',
|
|
};
|
|
return colors[type] || 'bg-gray-600';
|
|
};
|
|
|
|
return (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2">
|
|
<Calendar className="h-4 w-4" />
|
|
{data.title}
|
|
</CardTitle>
|
|
<div className="flex items-center gap-2 mt-2 flex-wrap">
|
|
<Badge className={`${getEventTypeColor(data.event_type)} text-white text-xs`}>
|
|
{formatEventType(data.event_type)}
|
|
</Badge>
|
|
<Badge variant="outline" className="text-xs">
|
|
{data.entity_type}
|
|
</Badge>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
{entityName && (
|
|
<div className="flex items-center gap-2 text-sm">
|
|
<Building2 className="h-4 w-4 text-muted-foreground" />
|
|
<span className="font-medium">Entity:</span>
|
|
<span className="text-foreground">{entityName}</span>
|
|
</div>
|
|
)}
|
|
|
|
<div className="grid grid-cols-2 gap-4 text-sm">
|
|
<div>
|
|
<span className="font-medium">Event Date:</span>
|
|
<p className="text-muted-foreground flex items-center gap-1 mt-1">
|
|
<Calendar className="h-3 w-3" />
|
|
<FlexibleDateDisplay
|
|
date={data.event_date}
|
|
precision={data.event_date_precision}
|
|
/>
|
|
</p>
|
|
<p className="text-xs text-muted-foreground mt-0.5">
|
|
Precision: {data.event_date_precision}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{(data.from_value || data.to_value) && (
|
|
<div className="flex items-center gap-2 text-sm">
|
|
<span className="font-medium">Change:</span>
|
|
<span className="text-muted-foreground">
|
|
{data.from_value || '—'} → {data.to_value || '—'}
|
|
</span>
|
|
</div>
|
|
)}
|
|
|
|
{(data.from_entity_id || data.to_entity_id) && (
|
|
<div className="text-xs text-muted-foreground">
|
|
<Tag className="h-3 w-3 inline mr-1" />
|
|
Related entities: {data.from_entity_id ? 'From entity' : ''} {data.to_entity_id ? 'To entity' : ''}
|
|
</div>
|
|
)}
|
|
|
|
{(data.from_location_id || data.to_location_id) && (
|
|
<div className="text-xs text-muted-foreground">
|
|
<MapPin className="h-3 w-3 inline mr-1" />
|
|
Location change involved
|
|
</div>
|
|
)}
|
|
|
|
{data.description && (
|
|
<div>
|
|
<span className="font-medium text-sm">Description:</span>
|
|
<p className="text-sm text-muted-foreground mt-1">
|
|
{data.description}
|
|
</p>
|
|
</div>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|