diff --git a/next.config.ts b/next.config.ts index 35ec3a1..3f7e7b0 100644 --- a/next.config.ts +++ b/next.config.ts @@ -6,12 +6,11 @@ const nextConfig: NextConfig = { outputFileTracingRoot: process.cwd(), trailingSlash: true, staticPageGenerationTimeout: 300, - experimental: { - serverActions: { - bodySizeLimit: (process.env.SERVER_ACTIONS_BODY_SIZE_LIMIT as any) || '100mb', - allowedOrigins: ['almeiraproducciones.com', 'news.almeira.com.co', 'www.almeiraproducciones.com', 'localhost:3000'], - }, + serverActions: { + bodySizeLimit: (process.env.SERVER_ACTIONS_BODY_SIZE_LIMIT as any) || '100mb', + allowedOrigins: ['almeiraproducciones.com', 'news.almeira.com.co', 'www.almeiraproducciones.com', 'localhost:3000'], }, + experimental: {}, serverExternalPackages: ['isomorphic-dompurify', 'jsdom'], }; diff --git a/src/app/actions/appwrite.ts b/src/app/actions/appwrite.ts index c4da857..faf9055 100644 --- a/src/app/actions/appwrite.ts +++ b/src/app/actions/appwrite.ts @@ -120,6 +120,8 @@ export async function uploadMediaDocumentServer(formData: FormData) { .replace(/\d+$/, '') // Eliminar números al final (foto1 -> foto) .trim(); const smartTitle = cleanName.charAt(0).toUpperCase() + cleanName.slice(1); + + const isImage = file.type ? file.type.startsWith('image/') : /\\.(jpg|jpeg|png|gif|webp|svg)$/i.test(file.name); const doc = await databases.createDocument(DATABASE_ID, 'media', ID.unique(), { file_id: uploadedFile.$id, @@ -127,7 +129,7 @@ export async function uploadMediaDocumentServer(formData: FormData) { titulo: tituloBase || smartTitle || file.name, alt_text: altTextBase || smartTitle || rawName, descripcion_seo: descSeo, - tipo: file.type.startsWith('image/') ? 'imagen' : 'video' + tipo: isImage ? 'imagen' : 'video' }); results.push(doc); } diff --git a/src/app/actions/entity.ts b/src/app/actions/entity.ts index cc948c3..9c61d61 100644 --- a/src/app/actions/entity.ts +++ b/src/app/actions/entity.ts @@ -26,7 +26,21 @@ export async function getEntityConfig() { COLLECTION_ID, [Query.limit(1)] ); - return response.documents[0] ? JSON.parse(JSON.stringify(response.documents[0])) : null; + const doc = response.documents[0]; + if (doc && doc.logotipo && !doc.logotipo.startsWith('http') && !doc.logotipo.startsWith('/')) { + try { + // Si es un ID de documento de la colección media, lo resolvemos + const mediaDoc = await databases.getDocument(DATABASE_ID, 'media', doc.logotipo); + if (mediaDoc && mediaDoc.file_id) { + const bucketId = mediaDoc.bucket_id || 'media'; + doc.logotipo = `${ENDPOINT}/storage/buckets/${bucketId}/files/${mediaDoc.file_id}/view?project=${PROJECT_ID}`; + } + } catch (mediaErr) { + // Si falla (por ejemplo, si realmente era un file_id antiguo), no hacemos nada y dejamos que el frontend intente usarlo como file_id + console.warn("Could not resolve media doc for logotipo, keeping original value:", mediaErr.message); + } + } + return doc ? JSON.parse(JSON.stringify(doc)) : null; } catch (error: any) { // Silently handle 404 (collection not found) if (error?.code === 404) { diff --git a/src/components/dashboard/MediaGridSelector.tsx b/src/components/dashboard/MediaGridSelector.tsx index 98742eb..e9d39c9 100644 --- a/src/components/dashboard/MediaGridSelector.tsx +++ b/src/components/dashboard/MediaGridSelector.tsx @@ -2,7 +2,7 @@ import { useState, useEffect, useCallback, useRef } from 'react'; import { createPortal } from 'react-dom'; -import { ImageIcon, X, Search, CheckCircle2, UploadCloud, Loader2 } from 'lucide-react'; +import { ImageIcon, Video, X, Search, CheckCircle2, UploadCloud, Loader2 } from 'lucide-react'; import { databases, APPWRITE_ALMEIRA_CONFIG, endpoint, projectId } from '@/lib/appwrite'; import { uploadMediaDocumentServer, listMediaServer, getMediaServer } from '@/app/actions/appwrite'; @@ -214,6 +214,9 @@ export const MediaGridSelector = ({ ) : ( {item.titulo} )} +
+ {isVideo ?
{value === item.$id && (