- Panel/empresa: title y meta description SEO personalizables; foto, texto y años de experiencia para el bloque "Quiénes somos" (toggle on/off). - Funnel por slug: metadata SEO desde el tenant, bloque "Quiénes somos" y testimonios servidos desde DB (sustituye los hardcodeados). - Flujo de opiniones: el reformista solicita la opinión desde la ficha de un lead ganado; el cliente la deja en un funnel dedicado /opinion/[id] con estrellas + texto + fotos; entra como pendiente y el reformista la modera (publicar/ocultar/eliminar) en /panel/opiniones antes de mostrarla. - Schema: columnas SEO/about en tenants, testimonioSolicitadoAt en leads, enum testimonio_estado, tablas testimonios + testimonio_fotos (migración 0006). - Seed: opiniones demo (2 publicadas, 1 pendiente) y contenido "Quiénes somos". Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
'use server';
|
|
|
|
import { and, eq } from 'drizzle-orm';
|
|
import { revalidatePath } from 'next/cache';
|
|
import { db } from '@/db';
|
|
import { testimonios } from '@/db/schema';
|
|
import { getCurrentTenantId as getTenantId } from '@/lib/auth/current-user';
|
|
|
|
type TestimonioEstado = (typeof testimonios.estado.enumValues)[number];
|
|
|
|
async function setEstado(testimonioId: string, estado: TestimonioEstado) {
|
|
const tenantId = await getTenantId();
|
|
const [updated] = await db
|
|
.update(testimonios)
|
|
.set({ estado })
|
|
.where(and(eq(testimonios.id, testimonioId), eq(testimonios.tenantId, tenantId)))
|
|
.returning({ id: testimonios.id });
|
|
if (!updated) throw new Error('Opinión no encontrada.');
|
|
revalidatePath('/panel/opiniones');
|
|
}
|
|
|
|
export async function publicarTestimonio(testimonioId: string) {
|
|
await setEstado(testimonioId, 'publicado');
|
|
}
|
|
|
|
export async function ocultarTestimonio(testimonioId: string) {
|
|
await setEstado(testimonioId, 'oculto');
|
|
}
|
|
|
|
export async function eliminarTestimonio(testimonioId: string) {
|
|
const tenantId = await getTenantId();
|
|
await db
|
|
.delete(testimonios)
|
|
.where(and(eq(testimonios.id, testimonioId), eq(testimonios.tenantId, tenantId)));
|
|
revalidatePath('/panel/opiniones');
|
|
}
|