mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 04:31:16 -05:00
193 lines
6.2 KiB
TypeScript
193 lines
6.2 KiB
TypeScript
import { Badge } from '@/components/ui/badge';
|
|
import { ImageIcon, Trash2, Edit } from 'lucide-react';
|
|
|
|
interface PhotoAdditionPreviewProps {
|
|
photos: Array<{
|
|
url: string;
|
|
title?: string;
|
|
caption?: string;
|
|
}>;
|
|
compact?: boolean;
|
|
}
|
|
|
|
export function PhotoAdditionPreview({ photos, compact = false }: PhotoAdditionPreviewProps) {
|
|
if (compact) {
|
|
return (
|
|
<Badge variant="outline" className="text-green-600 dark:text-green-400">
|
|
<ImageIcon className="h-3 w-3 mr-1" />
|
|
+{photos.length} Photo{photos.length > 1 ? 's' : ''}
|
|
</Badge>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="flex flex-col gap-2 p-3 rounded-md bg-muted/50">
|
|
<div className="text-sm font-medium text-green-600 dark:text-green-400">
|
|
<ImageIcon className="h-4 w-4 inline mr-1" />
|
|
Adding {photos.length} Photo{photos.length > 1 ? 's' : ''}
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
|
|
{photos.slice(0, 6).map((photo, idx) => (
|
|
<div key={idx} className="flex flex-col gap-1">
|
|
<img
|
|
src={photo.url}
|
|
alt={photo.title || photo.caption || `Photo ${idx + 1}`}
|
|
className="w-full h-24 object-cover rounded border-2 border-green-500/50"
|
|
loading="lazy"
|
|
/>
|
|
{(photo.title || photo.caption) && (
|
|
<div className="text-xs text-muted-foreground truncate">
|
|
{photo.title || photo.caption}
|
|
</div>
|
|
)}
|
|
</div>
|
|
))}
|
|
{photos.length > 6 && (
|
|
<div className="flex items-center justify-center h-24 bg-muted rounded border-2 border-dashed">
|
|
<span className="text-sm text-muted-foreground">
|
|
+{photos.length - 6} more
|
|
</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface PhotoEditPreviewProps {
|
|
photo: {
|
|
url: string;
|
|
oldCaption?: string;
|
|
newCaption?: string;
|
|
oldTitle?: string;
|
|
newTitle?: string;
|
|
};
|
|
compact?: boolean;
|
|
}
|
|
|
|
export function PhotoEditPreview({ photo, compact = false }: PhotoEditPreviewProps) {
|
|
if (compact) {
|
|
return (
|
|
<Badge variant="outline" className="text-amber-600 dark:text-amber-400">
|
|
<Edit className="h-3 w-3 mr-1" />
|
|
Photo Edit
|
|
</Badge>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="flex flex-col gap-2 p-3 rounded-md bg-muted/50">
|
|
<div className="text-sm font-medium text-amber-600 dark:text-amber-400">
|
|
<Edit className="h-4 w-4 inline mr-1" />
|
|
Photo Metadata Edit
|
|
</div>
|
|
|
|
<div className="flex gap-3">
|
|
<img
|
|
src={photo.url}
|
|
alt="Photo being edited"
|
|
className="w-32 h-32 object-cover rounded"
|
|
loading="lazy"
|
|
/>
|
|
|
|
<div className="flex-1 flex flex-col gap-2 text-sm">
|
|
{photo.oldTitle !== photo.newTitle && (
|
|
<div>
|
|
<div className="font-medium mb-1">Title:</div>
|
|
<div className="text-red-600 dark:text-red-400 line-through">{photo.oldTitle || 'None'}</div>
|
|
<div className="text-green-600 dark:text-green-400">{photo.newTitle || 'None'}</div>
|
|
</div>
|
|
)}
|
|
|
|
{photo.oldCaption !== photo.newCaption && (
|
|
<div>
|
|
<div className="font-medium mb-1">Caption:</div>
|
|
<div className="text-red-600 dark:text-red-400 line-through">{photo.oldCaption || 'None'}</div>
|
|
<div className="text-green-600 dark:text-green-400">{photo.newCaption || 'None'}</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface PhotoDeletionPreviewProps {
|
|
photo: {
|
|
url: string;
|
|
title?: string;
|
|
caption?: string;
|
|
entity_type?: string;
|
|
entity_name?: string;
|
|
deletion_reason?: string;
|
|
};
|
|
compact?: boolean;
|
|
}
|
|
|
|
export function PhotoDeletionPreview({ photo, compact = false }: PhotoDeletionPreviewProps) {
|
|
if (compact) {
|
|
return (
|
|
<div className="flex items-center gap-2 p-2 rounded-md bg-destructive/10 border border-destructive/20">
|
|
<Trash2 className="h-4 w-4 text-destructive" />
|
|
<span className="text-sm font-medium text-destructive">Delete Photo</span>
|
|
{photo.deletion_reason && (
|
|
<span className="text-xs text-muted-foreground">- {photo.deletion_reason}</span>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="flex flex-col gap-3 p-4 rounded-lg bg-destructive/10 border-2 border-destructive/30">
|
|
<div className="flex items-center gap-2 text-destructive font-semibold">
|
|
<Trash2 className="h-5 w-5" />
|
|
<span>Photo Deletion Request</span>
|
|
</div>
|
|
|
|
<div className="flex gap-4">
|
|
{photo.url && (
|
|
<img
|
|
src={photo.url}
|
|
alt={photo.title || photo.caption || 'Photo to be deleted'}
|
|
className="w-48 h-48 object-cover rounded-lg border-2 border-destructive/40 shadow-lg"
|
|
loading="lazy"
|
|
/>
|
|
)}
|
|
|
|
<div className="flex-1 space-y-3">
|
|
{photo.title && (
|
|
<div>
|
|
<span className="text-xs font-medium text-muted-foreground">Title:</span>
|
|
<div className="font-medium">{photo.title}</div>
|
|
</div>
|
|
)}
|
|
|
|
{photo.caption && (
|
|
<div>
|
|
<span className="text-xs font-medium text-muted-foreground">Caption:</span>
|
|
<div className="text-sm">{photo.caption}</div>
|
|
</div>
|
|
)}
|
|
|
|
{photo.entity_type && photo.entity_name && (
|
|
<div>
|
|
<span className="text-xs font-medium text-muted-foreground">From Entity:</span>
|
|
<div className="text-sm">
|
|
<span className="capitalize">{photo.entity_type.replace('_', ' ')}</span> - <span className="font-medium">{photo.entity_name}</span>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{photo.deletion_reason && (
|
|
<div className="p-3 bg-destructive/20 rounded-md border border-destructive/30">
|
|
<span className="text-xs font-bold text-destructive uppercase">Deletion Reason:</span>
|
|
<p className="mt-1 text-sm font-medium">{photo.deletion_reason}</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|