//src/app/hq-command/dashboard/applications/actions.ts "use server"; import { prisma } from "@/lib/prisma"; import { revalidatePath } from "next/cache"; import { unstable_noStore as noStore } from "next/cache"; // 馃敟 ANTI-CACH脡 // 馃敟 IMPORTAMOS EL TRADUCTOR DE IA import { translateContentForCMS } from "@/lib/aiTranslator"; import { ensureAssetFolders } from "@/lib/assetFolders"; const generateSlug = (title: string) => { return title.toLowerCase().trim().replace(/[^\w\s-]/g, '').replace(/[\s_-]+/g, '-').replace(/^-+|-+$/g, ''); }; // 1. OBTENER LA LISTA DE APLICACIONES export async function getApplications() { noStore(); try { const apps = await prisma.application.findMany({ orderBy: [{ order: "asc" }, { createdAt: "asc" }] }); return { success: true, apps }; } catch (error) { return { error: "Failed to fetch applications." }; } } // 2. OBTENER UNA APLICACI脫N ESPEC脥FICA export async function getApplicationBySlug(slug: string) { try { const app = await prisma.application.findUnique({ where: { slug } }); if (!app) return { error: "Application not found." }; return { success: true, app }; } catch (error) { return { error: "Failed to fetch application details." }; } } // 3. CREAR NUEVA APLICACI脫N (隆Ahora con IA!) export async function createApplication(formData: FormData) { try { const title = formData.get("title") as string; const subtitle = formData.get("subtitle") as string; const category = formData.get("category") as string; // Capturamos el switch de IA const autoTranslate = formData.get("autoTranslate") === "on"; const shortDescription = "New application ready to be configured."; const slug = generateSlug(title); let translationsJson = "{}"; // 馃敟 LA MAGIA DE LA IA EN LA CREACI脫N 馃敟 if (autoTranslate) { const aiResult = await translateContentForCMS({ title, subtitle, category, shortDescription }); if (aiResult) translationsJson = JSON.stringify(aiResult); } await prisma.application.create({ data: { slug, title, subtitle, category, shortDescription, heroDescription: "", sectionsJson: "[]", advantagesJson: "[]", datasheetJson: "{}", dashboardMetricsJson: "[]", isActive: true, translationsJson } }); // Pre-create the asset bucket folders so the editor's first upload // (videos, renders, gallery, datasheet) lands somewhere that exists. ensureAssetFolders("applications", slug); revalidatePath("/hq-command/dashboard/applications"); revalidatePath("/[locale]", "layout"); return { success: true }; } catch (error) { return { error: "Failed to create application. Title might already exist." }; } } // 4. ACTUALIZAR TODA LA INFORMACI脫N (隆Traduciendo JSONs completos!) export async function updateApplicationData(formData: FormData) { try { const slug = formData.get("slug") as string; const title = formData.get("title") as string; const subtitle = formData.get("subtitle") as string; const category = formData.get("category") as string; const shortDescription = formData.get("shortDescription") as string; const heroDescription = formData.get("heroDescription") as string; const sectionsJson = formData.get("sectionsJson") as string; const advantagesJson = formData.get("advantagesJson") as string; const datasheetJson = formData.get("datasheetJson") as string || "{}"; const dashboardMetricsJson = formData.get("dashboardMetricsJson") as string || "[]"; const autoTranslate = formData.get("autoTranslate") === "on"; let updateData: any = { title, subtitle, category, shortDescription, heroDescription, sectionsJson, advantagesJson, datasheetJson, dashboardMetricsJson }; // 馃敟 LA MAGIA DE LA IA PARA EL CONTENIDO PROFUNDO 馃敟 // Nota: Le mandamos los JSON stringificados. GPT-4o los traducir谩 y nos los devolver谩 con la misma estructura. if (autoTranslate) { const aiResult = await translateContentForCMS({ title, subtitle, category, shortDescription, heroDescription, sectionsJson, advantagesJson, dashboardMetricsJson }); if (aiResult) { updateData.translationsJson = JSON.stringify(aiResult); } } await prisma.application.update({ where: { slug }, data: updateData }); revalidatePath(`/applications/${slug}`); revalidatePath("/hq-command/dashboard/applications"); revalidatePath("/[locale]", "layout"); return { success: true }; } catch (error) { console.error("Update Error:", error); return { error: "Failed to update application data." }; } } // 5. OCULTAR / MOSTRAR APLICACI脫N export async function toggleApplication(slug: string, currentStatus: boolean) { try { await prisma.application.update({ where: { slug }, data: { isActive: !currentStatus } }); revalidatePath("/hq-command/dashboard/applications"); revalidatePath("/[locale]", "layout"); return { success: true }; } catch (e) { return { error: "Failed to toggle status." }; } } // 6. ELIMINAR APLICACI脫N export async function deleteApplication(slug: string) { try { await prisma.application.delete({ where: { slug } }); revalidatePath("/hq-command/dashboard/applications"); revalidatePath("/[locale]", "layout"); return { success: true }; } catch (e) { return { error: "Failed to delete application." }; } } // 6b. REORDENAR APLICACIONES (drag-to-reorder, mismo patr贸n que HeroSlide) // Recibe la lista de slugs en el nuevo orden y renumera el campo `order` // en una sola transacci贸n at贸mica. export async function reorderApplications(orderedSlugs: string[]) { try { await prisma.$transaction( orderedSlugs.map((slug, idx) => prisma.application.update({ where: { slug }, data: { order: idx } }) ) ); revalidatePath("/hq-command/dashboard/applications"); revalidatePath("/[locale]", "layout"); return { success: true }; } catch (e) { return { error: "Failed to reorder applications." }; } } // 7. LA SEMILLA: AUTO-POBLAR LA BASE DE DATOS (Intacto) export async function seedInitialApplications() { // ... Tu c贸digo actual de la semilla se queda exactamente igual ... // (Para mantener este mensaje limpio, asume que la funci贸n de seedInitialApplications() que ya tienes va aqu铆) }