import { Button, Spinner } from '@ifrc-go/ui'; import styles from '../../pages/UploadPage/UploadPage.module.css'; interface FullSizeImageModalProps { isOpen: boolean; imageUrl: string | null; preview: string | null; selectedImageData?: { file: File; index: number } | null; onClose: () => void; isLoading?: boolean; } export function FullSizeImageModal({ isOpen, imageUrl, preview, selectedImageData, onClose, isLoading = false }: FullSizeImageModalProps) { if (!isOpen) return null; // Determine which image to show let imageSrc: string | undefined; let imageAlt: string; if (selectedImageData) { // Show specific image from multi-upload imageSrc = URL.createObjectURL(selectedImageData.file); imageAlt = `Image ${selectedImageData.index + 1}: ${selectedImageData.file.name}`; } else { // Show single image (backward compatibility) imageSrc = imageUrl || preview || undefined; imageAlt = "Full size map"; } return (
e.stopPropagation()}>
{isLoading ? (

Loading image...

) : ( {imageAlt} )}
); } interface RatingWarningModalProps { isOpen: boolean; onClose: () => void; } export function RatingWarningModal({ isOpen, onClose }: RatingWarningModalProps) { if (!isOpen) return null; return (
e.stopPropagation()}>

Please Confirm Your Ratings

You must confirm your performance ratings before submitting. Please go back to the rating section and click "Confirm Ratings".

); } interface DeleteConfirmModalProps { isOpen: boolean; onConfirm: () => void; onCancel: () => void; } export function DeleteConfirmModal({ isOpen, onConfirm, onCancel }: DeleteConfirmModalProps) { if (!isOpen) return null; return (
e.stopPropagation()}>

Delete Image?

This action cannot be undone. Are you sure you want to delete this uploaded image?

); } interface NavigationConfirmModalProps { isOpen: boolean; onConfirm: () => void; onCancel: () => void; } export function NavigationConfirmModal({ isOpen, onConfirm, onCancel }: NavigationConfirmModalProps) { if (!isOpen) return null; return (
e.stopPropagation()}>

Leave Page?

Your uploaded image will be deleted if you leave this page. Are you sure you want to continue?

); } interface FallbackNotificationModalProps { isOpen: boolean; fallbackInfo: { originalModel: string; fallbackModel: string; reason: string; } | null; onClose: () => void; } export function FallbackNotificationModal({ isOpen, fallbackInfo, onClose }: FallbackNotificationModalProps) { if (!isOpen || !fallbackInfo) return null; // Parse the reason to make it more user-friendly const parseReason = (reason: string): string => { if (reason.includes("quota") || reason.includes("credits")) { return "API quota exceeded - you've used up your monthly free credits"; } else if (reason.includes("rate") || reason.includes("429")) { return "Rate limit exceeded - too many requests"; } else if (reason.includes("loading") || reason.includes("503")) { return "Model is currently loading or unavailable"; } else if (reason.includes("network") || reason.includes("timeout")) { return "Network connection issue"; } else if (reason.includes("MODEL_UNAVAILABLE")) { return "Model service is temporarily unavailable"; } else { return reason; } }; const userFriendlyReason = parseReason(fallbackInfo.reason); return (
e.stopPropagation()}>

⚠️ Model Changed

{fallbackInfo.originalModel} is currently unavailable. We've automatically switched to {fallbackInfo.fallbackModel} to complete your request.

Reason:

{userFriendlyReason}

); } interface PreprocessingNotificationModalProps { isOpen: boolean; preprocessingInfo: { original_filename: string; processed_filename: string; original_mime_type: string; processed_mime_type: string; was_preprocessed: boolean; error?: string; } | null; onClose: () => void; } export function PreprocessingNotificationModal({ isOpen, preprocessingInfo, onClose }: PreprocessingNotificationModalProps) { if (!isOpen || !preprocessingInfo) return null; return (
e.stopPropagation()}>

File Converted

Your file {preprocessingInfo.original_filename} has been converted from {preprocessingInfo.original_mime_type} to {preprocessingInfo.processed_mime_type} for optimal processing.

This conversion ensures your file is in the best format for our AI models to analyze.

); } interface PreprocessingModalProps { isOpen: boolean; isPreprocessing: boolean; preprocessingProgress: string; onConfirm: () => void; onCancel: () => void; } export function PreprocessingModal({ isOpen, isPreprocessing, preprocessingProgress, onConfirm, onCancel }: PreprocessingModalProps) { if (!isOpen) return null; return (
e.stopPropagation()}>

File Conversion Required

The file you selected will be converted to PNG format. This ensures optimal compatibility and processing by our AI models.

{!isPreprocessing && (
)} {isPreprocessing && (

{preprocessingProgress}

)}
); } interface UnsupportedFormatModalProps { isOpen: boolean; unsupportedFile: File | null; onClose: () => void; } export function UnsupportedFormatModal({ isOpen, unsupportedFile, onClose }: UnsupportedFormatModalProps) { if (!isOpen || !unsupportedFile) return null; return (
e.stopPropagation()}>

Unsupported File Format

The file {unsupportedFile.name} is not supported for upload.

Supported formats:
• Images: JPEG, PNG, TIFF, HEIC, WebP, GIF
• Documents: PDF (will be converted to image)

Recommendation: Convert your file to JPEG or PNG format for best compatibility.

); } interface FileSizeWarningModalProps { isOpen: boolean; oversizedFile: File | null; onClose: () => void; onCancel: () => void; } export function FileSizeWarningModal({ isOpen, oversizedFile, onClose, onCancel }: FileSizeWarningModalProps) { if (!isOpen || !oversizedFile) return null; return (
e.stopPropagation()}>

File Size Warning

The file {oversizedFile.name} is large ({(oversizedFile.size / (1024 * 1024)).toFixed(1)}MB).

Warning: This file size might exceed the limits of the AI models we use.

You can still proceed, but consider using a smaller file if you encounter issues.

); }