fix: media search server-side and data serialization in actions
This commit is contained in:
parent
86b2e704e9
commit
20a1695305
@ -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 };
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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"
|
||||||
>
|
>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user