informe-comercial-alfa/app/admin/metas/page.js

102 lines
3.4 KiB
JavaScript
Raw Normal View History

2026-09-21 23:11:53 +00:00
import { revalidatePath } from "next/cache";
import { auth } from "../../lib/auth";
import { getSystemUsers } from "../../lib/queries";
import { getMetas, getMetaGlobal, setMeta, setMetaGlobal } from "../../lib/metas";
import { EJECUTIVOS_VENTA } from "../../lib/derive";
import LoginPrompt from "../../components/LoginPrompt";
export const dynamic = "force-dynamic";
export default async function AdminMetasPage() {
const session = await auth();
if (!session?.email) return <LoginPrompt />;
if (!session.isAdmin) {
return (
<div style={{ padding: 24 }}>
<h2>Metas</h2>
<p>Esta página es solo para administradores.</p>
</div>
);
}
const allUsers = await getSystemUsers(session.accessToken);
const metas = getMetas();
const metaGlobal = getMetaGlobal();
const vendedoras = EJECUTIVOS_VENTA.map((nombre) => {
const u = allUsers.find((x) => x.name === nombre);
return { nombre, email: u?.email || null, monto: u ? metas[u.email] || 0 : 0 };
});
async function guardarMeta(formData) {
"use server";
const email = formData.get("email");
const monto = Number(formData.get("monto"));
if (email && monto >= 0) setMeta(email, monto);
revalidatePath("/admin/metas");
revalidatePath("/");
revalidatePath("/ganadas");
revalidatePath("/prevision");
revalidatePath("/tendencia");
}
async function guardarGlobal(formData) {
"use server";
const monto = Number(formData.get("metaGlobal"));
if (monto >= 0) setMetaGlobal(monto);
revalidatePath("/admin/metas");
revalidatePath("/");
revalidatePath("/ganadas");
revalidatePath("/prevision");
revalidatePath("/tendencia");
}
return (
<div style={{ padding: 24 }}>
<h2>Metas mensuales</h2>
<p className="hint">
Solo administradores. Se guardan en SQLite (sobreviven a cada publicación, ver Etapa 4 en migration.md).
</p>
<div className="panel" style={{ maxWidth: 420 }}>
<h3>Meta global del equipo</h3>
<form action={guardarGlobal} style={{ display: "flex", gap: 8, alignItems: "center" }}>
<input name="metaGlobal" type="number" step="1" min="0" defaultValue={metaGlobal} style={{ width: 120 }} />
<button type="submit" className="login-btn">
Guardar
</button>
</form>
</div>
<div className="panel" style={{ marginTop: 16, maxWidth: 520 }}>
<h3>Meta por ejecutiva</h3>
{vendedoras.map((v) => (
<div
key={v.nombre}
style={{
display: "flex",
gap: 8,
alignItems: "center",
padding: "8px 0",
borderBottom: "1px solid var(--linea)",
}}
>
<span style={{ width: 220, flexShrink: 0 }}>{v.nombre}</span>
{v.email ? (
<form action={guardarMeta} style={{ display: "flex", gap: 8, alignItems: "center" }}>
<input type="hidden" name="email" value={v.email} />
<input name="monto" type="number" step="1" min="0" defaultValue={v.monto} style={{ width: 100 }} />
<button type="submit" className="login-btn">
Guardar
</button>
</form>
) : (
<span style={{ color: "var(--pierde)" }}>No encontrada en systemusers</span>
)}
</div>
))}
</div>
</div>
);
}