'use client'; import { useState, useEffect } from 'react'; import { ImageIcon, X, Search, CheckCircle2 } from 'lucide-react'; import Link from 'next/link'; import { databases, APPWRITE_ALMEIRA_CONFIG, endpoint, projectId } from '@/lib/appwrite'; import { Query } from 'appwrite'; interface MediaPickerMiniProps { value: string; onChange: (fileId: string) => void; label: string; } export const MediaPickerMini = ({ value, onChange, label }: MediaPickerMiniProps) => { const [isOpen, setIsOpen] = useState(false); const [mediaItems, setMediaItems] = useState([]); const [searchTerm, setSearchTerm] = useState(''); const [isLoading, setIsLoading] = useState(false); useEffect(() => { if (isOpen) { fetchMedia(); } }, [isOpen]); const fetchMedia = async (search = '') => { setIsLoading(true); try { // We use the client-side databases instance for browsing media const queries = [ Query.limit(20), // Standard limit for preview Query.orderDesc('$createdAt') ]; if (search) { queries.push(Query.contains('titulo', search)); } const res = await databases.listDocuments( APPWRITE_ALMEIRA_CONFIG.databaseId, 'media', queries ); setMediaItems(res.documents); } catch (error) { console.error('Error fetching media:', error); } finally { setIsLoading(false); } }; // Debounced search useEffect(() => { if (!isOpen) return; const timer = setTimeout(() => { fetchMedia(searchTerm); }, 500); return () => clearTimeout(timer); }, [searchTerm, isOpen]); const getImageUrl = (fileId: string) => { return `${endpoint}/storage/buckets/media/files/${fileId}/view?project=${projectId}&width=200&height=200&gravity=center`; }; const filteredItems = mediaItems; return (
{value && ( )}
setIsOpen(true)} className={`relative aspect-video rounded-2xl border-2 border-dashed transition-all cursor-pointer flex flex-col items-center justify-center gap-2 overflow-hidden bg-slate-950 group ${ value ? 'border-cyan-500/50 hover:border-cyan-400' : 'border-slate-800 hover:border-slate-700' }`} > {value ? ( <> Selected
Cambiar Imagen
) : ( <>
Seleccionar Medio )}
{/* Hidden input to carry the value in the form */} {/* Modal */} {isOpen && (
setIsOpen(false)}>
{/* Modal Header */}

Biblioteca de Medios

Selecciona una imagen para esta publicación

{/* Modal Search */}
setSearchTerm(e.target.value)} className="w-full bg-slate-950 border border-slate-800 rounded-2xl pl-12 pr-6 py-4 text-white focus:outline-none focus:border-cyan-500 transition-all font-medium" />
{/* Modal Content */}
{isLoading ? (
Cargando Galería...
) : filteredItems.length > 0 ? (
{filteredItems.map((item) => (
{ onChange(item.file_id); setIsOpen(false); }} className={`group relative aspect-square rounded-2xl border-2 transition-all cursor-pointer overflow-hidden bg-slate-950 ${ value === item.file_id ? 'border-cyan-500 shadow-xl shadow-cyan-500/20' : 'border-slate-800 hover:border-slate-600 shadow-lg' }`} > {item.titulo}
{item.titulo}
{value === item.file_id && (
)}
))}
) : (

Sin Resultados

No encontramos imágenes con ese título.

)}
{/* Modal Footer */}
{filteredItems.length} Elementos Disponibles Subir Nuevo Archivo
)}
); };