Añade personalización SEO/Quiénes somos y testimonios gestionables por reformista
- 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>
This commit is contained in:
36
mvp/b2c/src/app/panel/opiniones/actions.ts
Normal file
36
mvp/b2c/src/app/panel/opiniones/actions.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
'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');
|
||||
}
|
||||
Reference in New Issue
Block a user