feat(02-02): add admin client list page and create-client flow
- /admin page: Server Component fetching all clients with payment badges - ClientRow component with Acconto/Saldo status badges and secret link - /admin/clients/new: form wired to createClient Server Action - createClient action: Zod validation, inserts client + 2 payment stubs (Acconto 50%, Saldo 50%) - Token auto-generated server-side via nanoid $defaultFn - Redirects to /admin/clients/[id] after creation; revalidates /admin
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import Link from "next/link";
|
||||
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 default async function AdminDashboard() {
|
||||
const clients = await getAllClientsWithPayments();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900">Clienti</h1>
|
||||
<Button asChild>
|
||||
<Link href="/admin/clients/new">+ Nuovo cliente</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{clients.length === 0 ? (
|
||||
<div className="text-center py-20 text-gray-400">
|
||||
<p>Nessun cliente ancora.</p>
|
||||
<p className="mt-2">
|
||||
<Link
|
||||
href="/admin/clients/new"
|
||||
className="text-blue-600 hover:underline"
|
||||
>
|
||||
Crea il primo cliente
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="bg-white rounded-lg border border-gray-200 overflow-hidden">
|
||||
<table className="w-full text-sm">
|
||||
<thead className="bg-gray-50 border-b border-gray-200">
|
||||
<tr>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-600">
|
||||
Cliente
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-600">
|
||||
Totale
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-600">
|
||||
Acconto
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-600">
|
||||
Saldo
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-600">
|
||||
Link
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{clients.map((client) => (
|
||||
<ClientRow key={client.id} client={client} />
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user