fix: media search server-side and data serialization in actions

This commit is contained in:
Carlos (Almeira) 2026-03-30 09:18:02 -05:00
parent 86b2e704e9
commit 20a1695305
3 changed files with 28 additions and 9 deletions

View File

@ -80,7 +80,8 @@ export async function uploadMediaServer(formData: FormData) {
} }
revalidatePath('/dashboard/media'); revalidatePath('/dashboard/media');
return { success: true, count: results.length, data: results }; // Sanitizar documentos para evitar problemas de serialización en Next.js
return { success: true, count: results.length, data: results.map(doc => ({ ...doc })) };
} catch (error: any) { } catch (error: any) {
console.error('Error uploading media:', error); console.error('Error uploading media:', error);
return { success: false, error: error.message }; return { success: false, error: error.message };
@ -116,7 +117,8 @@ export async function uploadMediaDocumentServer(formData: FormData) {
revalidatePath('/dashboard/media'); revalidatePath('/dashboard/media');
revalidatePath('/'); revalidatePath('/');
return { success: true, count: results.length, data: results }; // Sanitizar para Next.js
return { success: true, count: results.length, data: results.map(doc => ({ ...doc })) };
} catch (error: any) { } catch (error: any) {
console.error('Error uploading media and creating document:', error); console.error('Error uploading media and creating document:', error);
return { success: false, error: error.message }; return { success: false, error: error.message };

View File

@ -80,8 +80,8 @@ export default async function NewsTicker() {
Query.limit(5) Query.limit(5)
]); ]);
} catch (queryError: any) { } catch (queryError: any) {
// If 'status' attribute is missing, try fetching without it but still limited // El atributo 'status' puede no estar todavía en el esquema de Appwrite (Modo Gracia)
console.warn("WhatsApp 'status' query failed, trying fallback fetch:", queryError.message); // Usamos fallback de todos los mensajes limitados si falla el filtro
waRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'whatsapp_messages', [ waRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'whatsapp_messages', [
Query.orderDesc('$createdAt'), Query.orderDesc('$createdAt'),
Query.limit(5) Query.limit(5)

View File

@ -48,15 +48,21 @@ export const MediaGridSelector = ({
if (isOpen) fetchMedia(); if (isOpen) fetchMedia();
}, [isOpen]); }, [isOpen]);
const fetchMedia = async (more = false) => { const fetchMedia = async (more = false, search = '') => {
setIsLoading(true); setIsLoading(true);
try { try {
const currentOffset = more ? mediaItems.length : 0; const currentOffset = more ? mediaItems.length : 0;
const res = await databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'media', [ const queries = [
Query.limit(20), Query.limit(20),
Query.offset(currentOffset), Query.offset(currentOffset),
Query.orderDesc('$createdAt') Query.orderDesc('$createdAt')
]); ];
if (search) {
queries.push(Query.contains('titulo', search));
}
const res = await databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'media', queries);
if (more) { if (more) {
setMediaItems(prev => [...prev, ...res.documents]); setMediaItems(prev => [...prev, ...res.documents]);
@ -72,6 +78,17 @@ export const MediaGridSelector = ({
} }
}; };
// Handle Search Debouncing
useEffect(() => {
if (!isOpen) return;
const timer = setTimeout(() => {
fetchMedia(false, searchTerm);
}, 500);
return () => clearTimeout(timer);
}, [searchTerm, isOpen]);
useEffect(() => { useEffect(() => {
// If we have a value but haven't loaded its document, fetch just that one // If we have a value but haven't loaded its document, fetch just that one
if (value && mode === 'field' && !mediaItems.some(m => m.$id === value)) { if (value && mode === 'field' && !mediaItems.some(m => m.$id === value)) {
@ -118,7 +135,7 @@ export const MediaGridSelector = ({
if (onClose) onClose(); if (onClose) onClose();
}, [onClose]); }, [onClose]);
const filteredItems = mediaItems.filter(item => item.titulo.toLowerCase().includes(searchTerm.toLowerCase())); const filteredItems = mediaItems;
// Render modal structure // Render modal structure
const renderModal = () => { const renderModal = () => {
@ -218,7 +235,7 @@ export const MediaGridSelector = ({
{hasMore && ( {hasMore && (
<button <button
onClick={() => fetchMedia(true)} onClick={() => fetchMedia(true, searchTerm)}
disabled={isLoading} disabled={isLoading}
className="text-[10px] font-black uppercase tracking-widest text-cyan-500 hover:text-cyan-400 disabled:opacity-50 transition-colors flex items-center gap-2" className="text-[10px] font-black uppercase tracking-widest text-cyan-500 hover:text-cyan-400 disabled:opacity-50 transition-colors flex items-center gap-2"
> >