diff --git a/src/app/actions/appwrite.ts b/src/app/actions/appwrite.ts index 31568fa..75667cc 100644 --- a/src/app/actions/appwrite.ts +++ b/src/app/actions/appwrite.ts @@ -1,177 +1,32 @@ -'use server' +import { Client, Account, Databases, Storage } from 'appwrite'; -import { Client, Databases, Storage, ID, Query } from 'node-appwrite'; -import { APPWRITE_ALMEIRA_CONFIG } from '@/lib/appwrite'; -import { revalidatePath } from 'next/cache'; -import { SCHEMA_MAP, collectionMap } from '@/lib/schema'; +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'; -// Using local endpoint and the key we set locally -const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'http://localhost/v1'; -const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69bedced002971103d13'; -const API_KEY = process.env.APPWRITE_API_KEY || 'standard_2350cc147ace39b0e3fb2c42d1447bc00effb4d5e6115cd682b0d215297a3b35b2ce82e312bd35cff1b738d5eb3462c5b28887937acf217eca6c2143aa0bf4e85ab183350db830901edc0d80d17755d1de5524b945d0c4cb11871af8d33df7f7cdbdfea4237dfc8a47e3c71ac79b3e5172834cc09d451d687a3db74e839ec7a7'; +export const client = new Client(); -export async function createDocumentServer(collectionId: string, data: any) { - try { - const client = new Client() - .setEndpoint(ENDPOINT) - .setProject(PROJECT_ID) - .setKey(API_KEY); +client + .setEndpoint(ENDPOINT) + .setProject(PROJECT_ID); - const databases = new Databases(client); +export const account = new Account(client); +export const databases = new Databases(client); +export const storage = new Storage(client); - for(const key in data) { - if(data[key] === 'true') data[key] = true; - if(data[key] === 'false') data[key] = false; - if(data[key] === '' && typeof data[key] === 'string') delete data[key]; +export const APPWRITE_ALMEIRA_CONFIG = { + endpoint: ENDPOINT, + projectId: PROJECT_ID, + databaseId: 'main', + collections: { + posts: 'posts', + media: 'media', + events: 'events', + classifieds: 'classifieds', + entity: 'entity_config' + }, + buckets: { + media: 'media' } +}; - const doc = await databases.createDocument( - APPWRITE_ALMEIRA_CONFIG.databaseId, - collectionId, - ID.unique(), - data - ); - - revalidatePath('/dashboard/[entity]', 'page'); - return { success: true, doc }; - } catch (error: any) { - console.error("Create error:", error); - return { success: false, error: error.message }; - } -} - -export async function updateDocumentServer(collectionId: string, documentId: string, data: any) { - try { - const client = new Client().setEndpoint(ENDPOINT).setProject(PROJECT_ID).setKey(API_KEY); - const databases = new Databases(client); - - for(const key in data) { - if(data[key] === 'true') data[key] = true; - if(data[key] === 'false') data[key] = false; - if(data[key] === '' && typeof data[key] === 'string') data[key] = null; // Send null to clear optional strings - } - - const doc = await databases.updateDocument( - APPWRITE_ALMEIRA_CONFIG.databaseId, - collectionId, - documentId, - data - ); - - revalidatePath('/dashboard/[entity]', 'page'); - return { success: true, doc }; - } catch (error: any) { - console.error("Update error:", error); - return { success: false, error: error.message }; - } -} - -export async function deleteDocumentServer(collectionId: string, documentId: string, entityAlias: string) { - try { - const client = new Client().setEndpoint(ENDPOINT).setProject(PROJECT_ID).setKey(API_KEY); - const databases = new Databases(client); - - // Dynamic Relational Restriction Check - // We scan all collections in SCHEMA_MAP to see if any holds a relation to the collection we are trying to delete from - for (const [colAlias, fields] of Object.entries(SCHEMA_MAP)) { - const referencingFields = fields.filter(f => f.type === 'relation' && f.relationCollection === entityAlias); - - for (const refField of referencingFields) { - const checkColId = collectionMap[colAlias]; - if (!checkColId) continue; - - const list = await databases.listDocuments( - APPWRITE_ALMEIRA_CONFIG.databaseId, - checkColId, - [Query.equal(refField.name, documentId), Query.limit(1)] - ); - - if (list.total > 0) { - return { - success: false, - error: `No se puede eliminar. Existen registros en '${colAlias.replace(/_/g, ' ')}' que dependen de este dato.` - }; - } - } - } - - // No relation found preventing deletion, proceed safely! - await databases.deleteDocument( - APPWRITE_ALMEIRA_CONFIG.databaseId, - collectionId, - documentId - ); - - revalidatePath('/dashboard/[entity]', 'page'); - return { success: true }; - } catch (error: any) { - console.error("Delete error:", error); - return { success: false, error: error.message }; - } -} - -export async function uploadMediaServer(formData: FormData) { - try { - const client = new Client().setEndpoint(ENDPOINT).setProject(PROJECT_ID).setKey(API_KEY); - const databases = new Databases(client); - - const files = formData.getAll('files') as File[]; - if (!files || files.length === 0) throw new Error("No hay archivos para subir"); - - const manualTitulo = formData.get('titulo') as string; - const manualAlt = formData.get('alt_text') as string; - const manualDesc = formData.get('descripcion_seo') as string; - - for (const file of files) { - if (!file || file.size === 0) continue; - - // Native Fetch REST call to upload the file bypassing node-appwrite buffer overload - const appwriteFormData = new FormData(); - appwriteFormData.append('fileId', 'unique()'); - appwriteFormData.append('file', file); - - const uploadResponse = await fetch(`${ENDPOINT}/storage/buckets/media_bucket/files`, { - method: 'POST', - headers: { - 'X-Appwrite-Project': PROJECT_ID, - 'X-Appwrite-Key': API_KEY - }, - body: appwriteFormData - }); - - if (!uploadResponse.ok) { - const errBody = await uploadResponse.text(); - throw new Error(`Error subiendo al Bucket: ${errBody}`); - } - - const uploadData = await uploadResponse.json(); - - // Limpiar el nombre del archivo - let cleanName = file.name.replace(/\.[^/.]+$/, ""); - cleanName = cleanName.replace(/[-_]/g, ' '); - cleanName = cleanName.replace(/[0-9]+$/g, ''); - cleanName = cleanName.replace(/\s+/g, ' ').trim(); - if (!cleanName) cleanName = 'Multimedia'; - - await databases.createDocument( - APPWRITE_ALMEIRA_CONFIG.databaseId, - 'media', - ID.unique(), - { - file_id: uploadData.$id, - bucket_id: 'media_bucket', - titulo: manualTitulo || cleanName, - alt_text: manualAlt || cleanName, - descripcion_seo: manualDesc || cleanName, - tipo: file.type.startsWith('video') ? 'video' : 'imagen' - } - ); - } - - revalidatePath('/dashboard/media'); - return { success: true }; - } catch(error: any) { - console.error("Upload Error:", error); - return { success: false, error: error.message }; - } -} +export { ID } from 'appwrite'; diff --git a/src/app/actions/entity.ts b/src/app/actions/entity.ts index c64a860..f8698f6 100644 --- a/src/app/actions/entity.ts +++ b/src/app/actions/entity.ts @@ -1,80 +1,58 @@ 'use server' -import { Client, Databases } from 'node-appwrite'; -import { revalidatePath } from 'next/cache'; +import { Client, Databases, ID, Query } from 'node-appwrite'; +import { cookies } from 'next/headers'; -const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'http://localhost/v1'; -const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69bedced002971103d13'; -const API_KEY = process.env.APPWRITE_API_KEY || ''; +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 = 'main'; +const COLLECTION_ID = 'entity_config'; -export async function getEntity() { +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 client = new Client().setEndpoint(ENDPOINT).setProject(PROJECT_ID).setKey(API_KEY); - const databases = new Databases(client); - - const doc = await databases.getDocument('almeira', 'entidad', 'default'); - return JSON.parse(JSON.stringify(doc)); + const databases = await getAdminClient(); + const response = await databases.listDocuments( + DATABASE_ID, + COLLECTION_ID, + [Query.limit(1)] + ); + return response.documents[0] || null; } catch (error) { - console.error("Error fetching entity:", error); + console.error('Error fetching entity config:', error); return null; } } -export async function updateEntity(formData: FormData) { +export async function updateEntityConfig(data: any) { try { - const client = new Client().setEndpoint(ENDPOINT).setProject(PROJECT_ID).setKey(API_KEY); - const databases = new Databases(client); + const databases = await getAdminClient(); + const existing = await getEntityConfig(); - const data: any = { - razon_social: formData.get('razon_social') as string || '', - direccion: formData.get('direccion') as string || null, - numero_contacto: formData.get('numero_contacto') as string || null, - numero_whatsapp: formData.get('numero_whatsapp') as string || null, - ciudad: formData.get('ciudad') as string || null, - sitio_web: formData.get('sitio_web') as string || null, - email: formData.get('email') as string || null, - facebook_url: formData.get('facebook_url') as string || null, - youtube_url: formData.get('youtube_url') as string || null, - instagram_url: formData.get('instagram_url') as string || null, - x_url: formData.get('x_url') as string || null, - telegram_url: formData.get('telegram_url') as string || null, - tv_url: formData.get('tv_url') as string || null, - radio_url: formData.get('radio_url') as string || null, - mostrar_texto_logo: formData.get('mostrar_texto_logo') === 'true' - }; - - const file = formData.get('logotipo') as File; - if (file && file.size > 0) { - const appwriteFormData = new FormData(); - appwriteFormData.append('fileId', 'unique()'); - appwriteFormData.append('file', file); - - const uploadResponse = await fetch(`${ENDPOINT}/storage/buckets/media_bucket/files`, { - method: 'POST', - headers: { - 'X-Appwrite-Project': PROJECT_ID, - 'X-Appwrite-Key': API_KEY - }, - body: appwriteFormData as unknown as BodyInit - }); - - if (uploadResponse.ok) { - const uploadData = await uploadResponse.json(); - data.logotipo = `${ENDPOINT}/storage/buckets/media_bucket/files/${uploadData.$id}/view?project=${PROJECT_ID}`; - } else { - throw new Error("No se pudo subir la imagen"); - } + if (existing) { + return await databases.updateDocument( + DATABASE_ID, + COLLECTION_ID, + existing.$id, + data + ); + } else { + return await databases.createDocument( + DATABASE_ID, + COLLECTION_ID, + ID.unique(), + data + ); } - - // Netear nulls si algo está vacío de lo requerido - if (!data.razon_social) data.razon_social = 'Almeira Producciones'; - - await databases.updateDocument('almeira', 'entidad', 'default', data); - - revalidatePath('/', 'layout'); - return { success: true }; - } catch (error: any) { - console.error("Entity Update Error:", error); - return { success: false, error: error.message }; + } catch (error) { + console.error('Error updating entity config:', error); + throw error; } } diff --git a/src/app/actions/profile.ts b/src/app/actions/profile.ts index 3de7e15..be8e331 100644 --- a/src/app/actions/profile.ts +++ b/src/app/actions/profile.ts @@ -7,7 +7,7 @@ import { Client, Databases, Users, ID, Query } from 'node-appwrite'; function getAdminServices() { const client = new Client() .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1') - .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69bedced002971103d13') + .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c') .setKey(process.env.APPWRITE_API_KEY || ''); return {