import React, { useState } from 'react'; import { Card, CardContent } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Calendar } from '@/components/ui/calendar'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { X, Eye, GripVertical, Edit3, CalendarIcon } from 'lucide-react'; import { cn } from '@/lib/utils'; import { format } from 'date-fns'; export interface PhotoWithCaption { url: string; // Object URL for preview, Cloudflare URL after upload file?: File; // The actual file to upload later caption: string; title?: string; date?: Date; // Optional date for the photo order: number; uploadStatus?: 'pending' | 'uploading' | 'uploaded' | 'failed'; cloudflare_id?: string; // Cloudflare Image ID after upload } interface PhotoCaptionEditorProps { photos: PhotoWithCaption[]; onPhotosChange: (photos: PhotoWithCaption[]) => void; onRemovePhoto: (index: number) => void; maxCaptionLength?: number; className?: string; } export function PhotoCaptionEditor({ photos, onPhotosChange, onRemovePhoto, maxCaptionLength = 200, className = '', }: PhotoCaptionEditorProps) { const [editingIndex, setEditingIndex] = useState(null); const updatePhotoCaption = (index: number, caption: string) => { const updatedPhotos = photos.map((photo, i) => i === index ? { ...photo, caption } : photo ); onPhotosChange(updatedPhotos); }; const updatePhotoTitle = (index: number, title: string) => { const updatedPhotos = photos.map((photo, i) => i === index ? { ...photo, title } : photo ); onPhotosChange(updatedPhotos); }; const updatePhotoDate = (index: number, date: Date | undefined) => { const updatedPhotos = photos.map((photo, i) => i === index ? { ...photo, date } : photo ); onPhotosChange(updatedPhotos); }; const movePhoto = (fromIndex: number, toIndex: number) => { const updatedPhotos = [...photos]; const [movedPhoto] = updatedPhotos.splice(fromIndex, 1); updatedPhotos.splice(toIndex, 0, movedPhoto); // Update order values const reorderedPhotos = updatedPhotos.map((photo, index) => ({ ...photo, order: index, })); onPhotosChange(reorderedPhotos); }; if (photos.length === 0) { return null; } return (
{photos.length} photo{photos.length !== 1 ? 's' : ''}
{photos.map((photo, index) => (
{/* Photo preview */}
{photo.title
{/* Caption editing */}
Photo {index + 1}
{editingIndex === index ? (
updatePhotoTitle(index, e.target.value)} placeholder="Photo title" maxLength={100} className="h-8 text-sm" />
updatePhotoDate(index, date)} disabled={(date) => date > new Date()} initialFocus className={cn("p-3 pointer-events-auto")} /> {photo.date && (
)}
updatePhotoCaption(index, e.target.value)} placeholder="Add a caption to help viewers understand this photo..." maxLength={maxCaptionLength} className="h-8 text-sm" />

{photo.caption.length}/{maxCaptionLength} characters

) : (
{photo.title && (

{photo.title}

)} {photo.date && (

{format(photo.date, "PPP")}

)}

{photo.caption || ( No caption added )}

)}
))}
); }