fix: resolve entity logo media URL, robust media upload, and UI media grid icons
This commit is contained in:
parent
84d48ad096
commit
7432e8432b
@ -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'],
|
||||
};
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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 = ({
|
||||
) : (
|
||||
<img src={url} alt={item.titulo} title={item.titulo} className="w-full h-full object-cover transition-transform group-hover:scale-110" loading="lazy" />
|
||||
)}
|
||||
<div className="absolute top-2 left-2 bg-slate-900/80 backdrop-blur-md rounded-lg p-1.5 shadow-lg border border-slate-700/50">
|
||||
{isVideo ? <Video size={14} className="text-cyan-400" /> : <ImageIcon size={14} className="text-pink-400" />}
|
||||
</div>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-cyan-500/20 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" />
|
||||
{value === item.$id && (
|
||||
<div className="absolute top-2 right-2 bg-cyan-500 text-white rounded-full p-1 shadow-lg">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user