'use client'; import { useState, useEffect } from 'react'; import { Upload, X, Image as ImageIcon, Settings, AlertCircle } from 'lucide-react'; import { Button } from '@/components/ui/button'; import Link from 'next/link'; interface Field { id: string; label: string; apiIdentifier: string; type: string; isRequired: boolean; } interface DynamicFieldRendererProps { field: Field; value: any; onChange: (value: any) => void; } interface ImageDropZoneProps { fieldId: string; isUploading: boolean; onFileSelect: (file: File) => void; } function ImageDropZone({ fieldId, isUploading, onFileSelect }: ImageDropZoneProps) { const [isDragOver, setIsDragOver] = useState(false); const handleDragOver = (e: React.DragEvent) => { e.preventDefault(); setIsDragOver(true); }; const handleDragLeave = (e: React.DragEvent) => { e.preventDefault(); setIsDragOver(false); }; const handleDrop = (e: React.DragEvent) => { e.preventDefault(); setIsDragOver(false); const files = Array.from(e.dataTransfer.files); const imageFile = files.find(file => file.type.startsWith('image/')); if (imageFile) { onFileSelect(imageFile); } }; const handleFileChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { onFileSelect(file); } }; return (
!isUploading && document.getElementById(`file-${fieldId}`)?.click()} > {/* Loading overlay */} {isUploading && (

Subiendo imagen...

Esto puede tomar unos segundos

)}
{/* Icon with animation */}
{/* Main text */}

{isDragOver ? '¡Suelta la imagen aquí!' : 'Subir imagen'}

{isDragOver ? 'Suelta el archivo para subirlo' : 'Arrastra y suelta una imagen o haz clic para seleccionar' }

{/* Action button */}
{isDragOver ? 'Soltar archivo' : 'Seleccionar archivo'}
{/* File info */}

Formatos soportados: PNG, JPG, GIF, WebP

Tamaño máximo: 10MB

Se almacenará en AWS S3

{/* Hidden file input */}
); } export function DynamicFieldRenderer({ field, value, onChange }: DynamicFieldRendererProps) { const [isUploading, setIsUploading] = useState(false); const [s3Configured, setS3Configured] = useState(null); const [isCheckingS3, setIsCheckingS3] = useState(true); // Verificar si S3 está configurado cuando el componente se monta useEffect(() => { const checkS3Configuration = async () => { try { const response = await fetch('/api/plugins/s3'); const data = await response.json(); setS3Configured(data.success && data.config !== null); } catch (error) { console.error('Error checking S3 configuration:', error); setS3Configured(false); } finally { setIsCheckingS3(false); } }; // Solo verificar S3 si el campo es de tipo MEDIA if (field.type === 'MEDIA') { checkS3Configuration(); } else { setIsCheckingS3(false); } }, [field.type]); const handleFileUpload = async (file: File) => { setIsUploading(true); try { const formData = new FormData(); formData.append('file', file); formData.append('folder', 'content'); const response = await fetch('/api/upload', { method: 'POST', body: formData, }); if (response.ok) { const result = await response.json(); onChange({ url: result.url, fileName: result.fileName, size: result.size, type: result.type }); } else { const errorData = await response.json(); throw new Error(errorData.error || 'Error al subir el archivo'); } } catch (error) { console.error('Error uploading file:', error); // Mostrar error más específico const errorMessage = error instanceof Error ? error.message : 'Error desconocido al subir el archivo'; // Si el error es de S3 no configurado, actualizar el estado if (errorMessage.includes('S3 no está configurado')) { setS3Configured(false); } alert(`Error: ${errorMessage}`); } finally { setIsUploading(false); } }; switch (field.type) { case 'TEXT': return ( onChange(e.target.value)} className="w-full px-3 py-2 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder={`Ingresa ${field.label.toLowerCase()}`} /> ); case 'RICH_TEXT': return (