feat: client edit/delete/archive + time tracker + analytics time section
Schema: - clients.archived boolean (default false) - time_entries table (client_id, started_at, ended_at, duration_seconds) Client management: - /admin/clients/[id]/edit — form pre-compilato con nome, brand, brief - ClientActions: Modifica / Archivia / Elimina con doppia conferma - setClientArchived: toggle archiviazione senza perdere dati - deleteClient: elimina con cascade, redirect a /admin - Admin list: toggle "Mostra archiviati" via ?archived=1, righe archiviate opache Time tracker: - startTimer: crea sessione, ferma automaticamente quella precedente - stopTimer: chiude sessione, calcola duration_seconds - TimerCell: ▶/⏹ per ogni cliente, contatore live in secondi, totale cumulativo - Una sola sessione attiva alla volta su tutta la lista Analytics: - Sezione "Fatturato" (invariata) + sezione "Tempo tracciato" separata - Ore totali per anno + barre orizzontali per cliente - getTotalTrackedHours, getTimeByClient queries Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+32
-28
@@ -3,15 +3,29 @@ import { getAllClientsWithPayments } from "@/lib/admin-queries";
|
||||
import { ClientRow } from "@/components/admin/ClientRow";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
export const revalidate = 0; // always fresh — admin needs real-time data
|
||||
export const revalidate = 0;
|
||||
|
||||
export default async function AdminDashboard() {
|
||||
const clients = await getAllClientsWithPayments();
|
||||
export default async function AdminDashboard({
|
||||
searchParams,
|
||||
}: {
|
||||
searchParams: Promise<{ archived?: string }>;
|
||||
}) {
|
||||
const { archived } = await searchParams;
|
||||
const showArchived = archived === "1";
|
||||
const clients = await getAllClientsWithPayments(showArchived);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h1 className="text-2xl font-bold text-[#1a1a1a]">Clienti</h1>
|
||||
<div className="flex items-center gap-4">
|
||||
<h1 className="text-2xl font-bold text-[#1a1a1a]">Clienti</h1>
|
||||
<a
|
||||
href={showArchived ? "/admin" : "/admin?archived=1"}
|
||||
className="text-xs text-[#71717a] hover:text-[#1A463C] underline underline-offset-2"
|
||||
>
|
||||
{showArchived ? "Nascondi archiviati" : "Mostra archiviati"}
|
||||
</a>
|
||||
</div>
|
||||
<Button asChild>
|
||||
<Link href="/admin/clients/new">+ Nuovo cliente</Link>
|
||||
</Button>
|
||||
@@ -19,36 +33,26 @@ export default async function AdminDashboard() {
|
||||
|
||||
{clients.length === 0 ? (
|
||||
<div className="text-center py-20 text-[#71717a]">
|
||||
<p>Nessun cliente ancora.</p>
|
||||
<p className="mt-2">
|
||||
<Link
|
||||
href="/admin/clients/new"
|
||||
className="text-[#1A463C] hover:underline font-medium"
|
||||
>
|
||||
Crea il primo cliente
|
||||
</Link>
|
||||
</p>
|
||||
<p>{showArchived ? "Nessun cliente archiviato." : "Nessun cliente ancora."}</p>
|
||||
{!showArchived && (
|
||||
<p className="mt-2">
|
||||
<Link href="/admin/clients/new" className="text-[#1A463C] hover:underline font-medium">
|
||||
Crea il primo cliente
|
||||
</Link>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="bg-white rounded-lg border border-[#e5e7eb] overflow-hidden">
|
||||
<table className="w-full text-sm">
|
||||
<thead className="bg-[#f9f9f9] border-b border-[#e5e7eb]">
|
||||
<tr>
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">
|
||||
Cliente
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">
|
||||
Totale
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">
|
||||
Acconto
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">
|
||||
Saldo
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">
|
||||
Link
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">Cliente</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">Totale</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">Acconto</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">Saldo</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">Timer</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">Link</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
Reference in New Issue
Block a user