chore: merge partial 02-02 worktree (task 1 complete)

This commit is contained in:
Simone Cavalli
2026-05-15 16:16:25 +02:00
3 changed files with 100 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
import { NavBar } from "@/components/admin/NavBar";
export default function AdminLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="min-h-screen bg-gray-50">
<NavBar />
<main className="max-w-5xl mx-auto px-6 py-8">{children}</main>
</div>
);
}
+29
View File
@@ -0,0 +1,29 @@
"use client";
import Link from "next/link";
import { signOut } from "next-auth/react";
import { Button } from "@/components/ui/button";
export function NavBar() {
return (
<nav className="border-b border-gray-200 bg-white px-6 py-3 flex items-center justify-between">
<div className="flex items-center gap-6">
<span className="font-semibold text-gray-900">ClientHub</span>
<Link
href="/admin"
className="text-sm text-gray-600 hover:text-gray-900 transition-colors"
>
Clienti
</Link>
</div>
<Button
variant="ghost"
size="sm"
onClick={() => signOut({ callbackUrl: "/admin/login" })}
className="text-sm text-gray-500"
>
Esci
</Button>
</nav>
);
}
+57
View File
@@ -0,0 +1,57 @@
import { db } from "@/db";
import { clients, payments } from "@/db/schema";
import { eq } from "drizzle-orm";
export type ClientWithPayments = {
id: string;
name: string;
brand_name: string;
token: string;
accepted_total: string;
created_at: Date;
payments: Array<{
id: string;
label: string;
status: string;
amount: string;
}>;
};
export async function getAllClientsWithPayments(): Promise<ClientWithPayments[]> {
const allClients = await db
.select()
.from(clients)
.orderBy(clients.created_at);
if (allClients.length === 0) return [];
const allPayments = await db
.select()
.from(payments);
return allClients.map((c) => ({
id: c.id,
name: c.name,
brand_name: c.brand_name,
token: c.token,
accepted_total: c.accepted_total ?? "0",
created_at: c.created_at,
payments: allPayments
.filter((p) => p.client_id === c.id)
.map((p) => ({
id: p.id,
label: p.label,
status: p.status,
amount: p.amount,
})),
}));
}
export async function getClientById(id: string) {
const rows = await db
.select()
.from(clients)
.where(eq(clients.id, id))
.limit(1);
return rows[0] ?? null;
}