Files
thrilltrack-explorer/src/components/admin/RideDataBackfill.tsx
gpt-engineer-app[bot] 314db65591 Backfill Ride Data
Add edge function and UI for ride data backfill, integrating admin UI to trigger backfill, plus supporting types and wiring to backfill_ride_data function. Includes RideDataBackfill component, admin page integration, and initial server-side function scaffold for updating rides from submissions.
2025-11-11 15:45:14 +00:00

111 lines
3.9 KiB
TypeScript

import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { supabase } from '@/lib/supabaseClient';
import { Hammer, AlertCircle, CheckCircle2 } from 'lucide-react';
import { useToast } from '@/hooks/use-toast';
export function RideDataBackfill() {
const [isRunning, setIsRunning] = useState(false);
const [result, setResult] = useState<{
success: boolean;
rides_updated: number;
manufacturer_added: number;
designer_added: number;
ride_model_added: number;
} | null>(null);
const [error, setError] = useState<string | null>(null);
const { toast } = useToast();
const handleBackfill = async () => {
setIsRunning(true);
setError(null);
setResult(null);
try {
const { data, error: invokeError } = await supabase.functions.invoke(
'backfill-ride-data'
);
if (invokeError) throw invokeError;
setResult(data);
const updates: string[] = [];
if (data.manufacturer_added > 0) updates.push(`${data.manufacturer_added} manufacturers`);
if (data.designer_added > 0) updates.push(`${data.designer_added} designers`);
if (data.ride_model_added > 0) updates.push(`${data.ride_model_added} ride models`);
toast({
title: 'Backfill Complete',
description: `Updated ${data.rides_updated} rides: ${updates.join(', ')}`,
});
} catch (err: any) {
const errorMessage = err.message || 'Failed to run backfill';
setError(errorMessage);
toast({
title: 'Backfill Failed',
description: errorMessage,
variant: 'destructive',
});
} finally {
setIsRunning(false);
}
};
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Hammer className="w-5 h-5" />
Ride Data Backfill
</CardTitle>
<CardDescription>
Backfill missing manufacturer, designer, and ride model data for approved rides from their submission data
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<Alert>
<AlertCircle className="h-4 w-4" />
<AlertDescription>
This tool will find rides missing manufacturer, designer, or ride model information and populate them using data from their approved submissions. Useful for fixing rides that were approved before relationship data was properly handled.
</AlertDescription>
</Alert>
{result && (
<Alert className="border-green-200 bg-green-50 dark:bg-green-950 dark:border-green-800">
<CheckCircle2 className="h-4 w-4 text-green-600 dark:text-green-400" />
<AlertDescription className="text-green-900 dark:text-green-100">
<div className="font-medium">Backfill completed successfully!</div>
<div className="mt-2 space-y-1">
<div>Rides updated: {result.rides_updated}</div>
<div>Manufacturers added: {result.manufacturer_added}</div>
<div>Designers added: {result.designer_added}</div>
<div>Ride models added: {result.ride_model_added}</div>
</div>
</AlertDescription>
</Alert>
)}
{error && (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
<Button
onClick={handleBackfill}
disabled={isRunning}
className="w-full"
trackingLabel="run-ride-data-backfill"
>
<Hammer className="w-4 h-4 mr-2" />
{isRunning ? 'Running Backfill...' : 'Run Ride Data Backfill'}
</Button>
</CardContent>
</Card>
);
}