import { useState } from 'react'; import { Badge } from '@/components/ui/badge'; import { MeasurementDisplay } from '@/components/ui/measurement-display'; import { SpeedDisplay } from '@/components/ui/speed-display'; import { MapPin, ArrowRight, Calendar, ExternalLink } from 'lucide-react'; import type { FieldChange } from '@/lib/submissionChangeDetection'; import { formatFieldValue } from '@/lib/submissionChangeDetection'; interface SpecialFieldDisplayProps { change: FieldChange; compact?: boolean; } export function SpecialFieldDisplay({ change, compact = false }: SpecialFieldDisplayProps) { const fieldName = change.field.toLowerCase(); // Detect field type if (fieldName.includes('speed') || fieldName === 'max_speed_kmh') { return ; } if (fieldName.includes('height') || fieldName.includes('length') || fieldName === 'max_height_meters' || fieldName === 'length_meters' || fieldName === 'drop_height_meters') { return ; } if (fieldName === 'status') { return ; } if (fieldName.includes('date') && !fieldName.includes('updated') && !fieldName.includes('created')) { return ; } if (fieldName.includes('_id') && fieldName !== 'id' && fieldName !== 'user_id' && fieldName !== 'entity_id') { return ; } if (fieldName === 'latitude' || fieldName === 'longitude') { return ; } // Fallback to null, will be handled by regular FieldDiff return null; } function SpeedFieldDisplay({ change, compact }: { change: FieldChange; compact: boolean }) { if (compact) { return ( Speed ); } const formatFieldName = (name: string) => name.replace(/_/g, ' ').replace(/([A-Z])/g, ' $1').trim() .replace(/^./, str => str.toUpperCase()); return (
{formatFieldName(change.field)}
{change.changeType === 'modified' && (
)} {change.changeType === 'added' && (
+
)} {change.changeType === 'removed' && (
)}
); } function MeasurementFieldDisplay({ change, compact }: { change: FieldChange; compact: boolean }) { if (compact) { return ( Measurement ); } const formatFieldName = (name: string) => name.replace(/_/g, ' ').replace(/([A-Z])/g, ' $1').trim() .replace(/^./, str => str.toUpperCase()); return (
{formatFieldName(change.field)}
{change.changeType === 'modified' && (
)} {change.changeType === 'added' && (
+
)} {change.changeType === 'removed' && (
)}
); } function StatusFieldDisplay({ change, compact }: { change: FieldChange; compact: boolean }) { const getStatusColor = (status: string) => { const statusLower = String(status).toLowerCase(); if (statusLower === 'operating' || statusLower === 'active') return 'bg-green-500/10 text-green-600 dark:text-green-400 border-green-500/20'; if (statusLower === 'closed' || statusLower === 'inactive') return 'bg-red-500/10 text-red-600 dark:text-red-400 border-red-500/20'; if (statusLower === 'under_construction' || statusLower === 'pending') return 'bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/20'; return 'bg-muted/30 text-muted-foreground'; }; if (compact) { return ( Status ); } const formatFieldName = (name: string) => name.replace(/_/g, ' ').replace(/([A-Z])/g, ' $1').trim() .replace(/^./, str => str.toUpperCase()); return (
{formatFieldName(change.field)}
{change.changeType === 'modified' && (
{formatFieldValue(change.oldValue)} {formatFieldValue(change.newValue)}
)} {change.changeType === 'added' && ( {formatFieldValue(change.newValue)} )} {change.changeType === 'removed' && ( {formatFieldValue(change.oldValue)} )}
); } function DateFieldDisplay({ change, compact }: { change: FieldChange; compact: boolean }) { // Extract precision from metadata const precision = change.metadata?.precision; const oldPrecision = change.metadata?.oldPrecision; const newPrecision = change.metadata?.newPrecision; if (compact) { return ( Date ); } const formatFieldName = (name: string) => name.replace(/_/g, ' ').replace(/([A-Z])/g, ' $1').trim() .replace(/^./, str => str.toUpperCase()); return (
{formatFieldName(change.field)} {precision && ( {precision === 'year' ? 'Year Only' : precision === 'month' ? 'Month & Year' : 'Full Date'} )}
{change.changeType === 'modified' && (
{formatFieldValue(change.oldValue, oldPrecision || precision)} {formatFieldValue(change.newValue, newPrecision || precision)}
)} {change.changeType === 'added' && (
+ {formatFieldValue(change.newValue, precision)}
)} {change.changeType === 'removed' && (
{formatFieldValue(change.oldValue, precision)}
)}
); } function RelationshipFieldDisplay({ change, compact }: { change: FieldChange; compact: boolean }) { // This would ideally fetch entity names, but for now we show IDs with better formatting const formatFieldName = (name: string) => name.replace(/_id$/, '').replace(/_/g, ' ').trim() .replace(/^./, str => str.toUpperCase()); if (compact) { return ( {formatFieldName(change.field)} ); } return (
{formatFieldName(change.field)}
{change.changeType === 'modified' && (
{String(change.oldValue).slice(0, 8)}... {String(change.newValue).slice(0, 8)}...
)} {change.changeType === 'added' && (
+ {String(change.newValue).slice(0, 8)}...
)} {change.changeType === 'removed' && (
{String(change.oldValue).slice(0, 8)}...
)}
); } function CoordinateFieldDisplay({ change, compact }: { change: FieldChange; compact: boolean }) { if (compact) { return ( Coordinates ); } const formatFieldName = (name: string) => name.replace(/_/g, ' ').replace(/([A-Z])/g, ' $1').trim() .replace(/^./, str => str.toUpperCase()); return (
{formatFieldName(change.field)}
{change.changeType === 'modified' && (
{Number(change.oldValue).toFixed(6)}° {Number(change.newValue).toFixed(6)}°
)} {change.changeType === 'added' && (
+ {Number(change.newValue).toFixed(6)}°
)} {change.changeType === 'removed' && (
{Number(change.oldValue).toFixed(6)}°
)}
); }