feat(05-03): add getClientActiveOffers query + active offers section on client detail page

- Add ClientActiveOfferSummary type to admin-queries.ts
- Add getClientActiveOffers() function joining project_offers with offer_micros
- Only selects public_name (never internal_name) per CLAUDE.md constraint
- Update /admin/clients/[id] to fetch active offers in parallel with project data
- Add Offerte Attive section at bottom of client detail page
This commit is contained in:
2026-05-30 16:28:09 +02:00
parent 0c09d44b68
commit 20f4fd8603
2 changed files with 71 additions and 2 deletions
+28 -2
View File
@@ -1,5 +1,5 @@
import { notFound } from "next/navigation";
import { getClientWithProjects } from "@/lib/admin-queries";
import { getClientWithProjects, getClientActiveOffers } from "@/lib/admin-queries";
import { ClientActions } from "@/components/admin/ClientActions";
import Link from "next/link";
@@ -11,7 +11,10 @@ export default async function ClientDetailPage({
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const data = await getClientWithProjects(id);
const [data, activeOffers] = await Promise.all([
getClientWithProjects(id),
getClientActiveOffers(id),
]);
if (!data) notFound();
const { projects, ...client } = data;
@@ -105,6 +108,29 @@ export default async function ClientDetailPage({
</div>
</div>
)}
{activeOffers.length > 0 && (
<div className="mt-8">
<p className="text-xs text-[#71717a] font-semibold uppercase tracking-wider mb-3">
Offerte Attive ({activeOffers.length})
</p>
<div className="bg-white rounded-xl border border-[#e5e7eb] divide-y divide-[#e5e7eb]">
{activeOffers.map((offer) => (
<div key={offer.offer_id} className="flex items-center justify-between px-4 py-3">
<div>
<p className="text-sm font-medium text-[#1a1a1a]">{offer.public_name}</p>
<p className="text-xs text-[#71717a]">{offer.project_name}</p>
</div>
{offer.accepted_total && (
<span className="text-sm font-mono text-[#1a1a1a]">
&euro;{parseFloat(offer.accepted_total).toLocaleString("it-IT", { minimumFractionDigits: 2 })}
</span>
)}
</div>
))}
</div>
</div>
)}
</div>
);
}