almeira-web/src/app/actions/entity.ts

149 lines
6.6 KiB
TypeScript

'use server'
import { Client, Databases, ID, Query } from 'node-appwrite';
import { databaseId } from '@/lib/appwrite';
import { revalidatePath } from 'next/cache';
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
const DATABASE_ID = databaseId;
const COLLECTION_ID = 'entity_config';
async function getAdminClient() {
const client = new Client()
.setEndpoint(ENDPOINT)
.setProject(PROJECT_ID)
.setKey(process.env.APPWRITE_API_KEY || '');
return new Databases(client);
}
export async function getEntityConfig() {
try {
const databases = await getAdminClient();
const response = await databases.listDocuments(
DATABASE_ID,
COLLECTION_ID,
[Query.limit(1)]
);
return response.documents[0] ? JSON.parse(JSON.stringify(response.documents[0])) : null;
} catch (error: any) {
// Silently handle 404 (collection not found)
if (error?.code === 404) {
return null;
}
console.error('Error fetching entity config:', error);
return null;
}
}
// ALIAS PARA COMPATIBILIDAD CON DASHBOARD
export const getEntity = getEntityConfig;
export async function updateEntityConfig(data: any) {
try {
const databases = await getAdminClient();
const existing = await getEntityConfig();
let parsedData: any = data;
if (typeof FormData !== 'undefined' && data instanceof FormData) {
parsedData = {};
// Los checkboxes no vienen en el FormData si no están marcados.
// Manejamos explícitamente los booleanos conocidos aquí para que puedan actualizarse a false,
// y para que se envíen como boolean en lugar de string "true".
parsedData['mostrar_texto_logo'] = data.has('mostrar_texto_logo');
for (const [key, value] of Array.from(data.entries())) {
// Ignorar claves tratadas explícitamente y claves internas
if (key === 'mostrar_texto_logo' || key.startsWith('$ACTION') || key === '$id' || key === '$collectionId' || key === '$databaseId') {
continue;
}
if (typeof value === 'object' && 'size' in value && 'name' in value) {
const file = value as File;
if (file.size > 0) {
try {
const { uploadMediaServer } = await import('@/app/actions/appwrite');
const tempForm = new FormData();
tempForm.append('files', file);
const uploadRes = await uploadMediaServer(tempForm);
if (uploadRes.success && uploadRes.data && uploadRes.data[0]) {
const m = uploadRes.data[0];
parsedData[key] = `${ENDPOINT}/storage/buckets/${m.bucketId || 'media'}/files/${m.$id}/view?project=${PROJECT_ID}`;
}
} catch (uploadErr) {
console.error('Error uploading file for entity config:', uploadErr);
}
}
} else {
// Solo incluir el campo si tiene valor real (evita errores en Appwrite con campos vacíos opcionales)
if (value !== '' && value !== null && value !== undefined) {
parsedData[key] = value;
}
}
}
}
if (!parsedData || Object.keys(parsedData).length === 0) {
console.warn('updateEntityConfig: Data is empty, skipping update.');
return existing;
}
const SINGLETON_ID = existing?.$id || 'main_profile_singleton';
if (existing) {
const result = await databases.updateDocument(
DATABASE_ID,
COLLECTION_ID,
existing.$id,
parsedData
);
revalidatePath('/');
return result;
} else {
try {
const result = await databases.createDocument(
DATABASE_ID,
COLLECTION_ID,
SINGLETON_ID,
parsedData
);
revalidatePath('/');
return result;
} catch (createErr: any) {
// If the collection genuinely does not exist, auto-create it natively
if (createErr?.code === 404 && createErr?.type === 'collection_not_found') {
console.log('Colección entity_config no existe. Creando automáticamente...');
await databases.createCollection(DATABASE_ID, COLLECTION_ID, 'Configuración de Entidad');
await new Promise(r => setTimeout(r, 1500)); // Propagate
// Create minimal schema attributes lazily, Appwrite handles conflicts on re-runs
const textAttrs = ['razon_social', 'logotipo', 'ciudad', 'direccion', 'numero_contacto', 'numero_whatsapp', 'email', 'sitio_web', 'tv_url', 'radio_url', 'facebook_url', 'instagram_url', 'x_url', 'youtube_url', 'telegram_url'];
for (const a of textAttrs) {
try { await databases.createStringAttribute(DATABASE_ID, COLLECTION_ID, a, 500, false); } catch (e) {}
}
try { await databases.createBooleanAttribute(DATABASE_ID, COLLECTION_ID, 'mostrar_texto_logo', false, false); } catch(e){}
console.log('Atributos inyectados. Esperando 3 segundos...');
await new Promise(r => setTimeout(r, 3500)); // Wait for attributes to be Available
const result = await databases.createDocument(DATABASE_ID, COLLECTION_ID, SINGLETON_ID, parsedData);
revalidatePath('/');
return result;
} else {
throw createErr;
}
}
}
} catch (error: any) {
console.error('Error updating entity config:', error);
// Devolver un objeto de error estructurado en lugar de relanzar para evitar crash de la página
return {
success: false,
error: error?.message || 'Error desconocido al guardar la configuración de la entidad.'
};
}
}
// ALIAS PARA COMPATIBILIDAD CON DASHBOARD
export const updateEntity = updateEntityConfig;