feat: brand color system + Kanban view (admin + client)
- Fix button contrast: add all missing shadcn tokens (primary-foreground, ring, input, muted, destructive) aligned to iamcavalli brand - NavBar: #1A463C green bar with white text - Login page: clean brand layout with iamcavalli wordmark - Admin pages: brand colors on headings, borders, links - Admin ClientRow: semantic payment badges (green/yellow/red) - Admin phases tab: Lista ↔ Kanban toggle with @dnd-kit drag & drop between Da fare / In corso / Fatto columns (optimistic updates) - Client dashboard: Timeline ↔ Kanban toggle, expandable task cards with approve button + comment form inline Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { PhasesTab } from "@/components/admin/tabs/PhasesTab";
|
||||
import { PaymentsTab } from "@/components/admin/tabs/PaymentsTab";
|
||||
import { DocumentsTab } from "@/components/admin/tabs/DocumentsTab";
|
||||
import { CommentsTab } from "@/components/admin/tabs/CommentsTab";
|
||||
import { PhasesViewToggle } from "@/components/admin/kanban/PhasesViewToggle";
|
||||
import Link from "next/link";
|
||||
|
||||
export const revalidate = 0;
|
||||
@@ -51,7 +52,11 @@ export default async function ClientDetailPage({
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="phases">
|
||||
<PhasesTab phases={phases} clientId={client.id} />
|
||||
<PhasesViewToggle
|
||||
listView={<PhasesTab phases={phases} clientId={client.id} />}
|
||||
phases={phases}
|
||||
clientId={client.id}
|
||||
/>
|
||||
</TabsContent>
|
||||
<TabsContent value="payments">
|
||||
<PaymentsTab
|
||||
|
||||
@@ -74,17 +74,23 @@ function AdminLoginForm() {
|
||||
|
||||
export default function AdminLoginPage() {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-50">
|
||||
<Card className="w-full max-w-sm">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-xl">Admin — ClientHub</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Suspense fallback={<div className="text-sm text-gray-500">Caricamento...</div>}>
|
||||
<AdminLoginForm />
|
||||
</Suspense>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<div className="min-h-screen flex items-center justify-center bg-[#f9f9f9]">
|
||||
<div className="w-full max-w-sm">
|
||||
<div className="text-center mb-8">
|
||||
<span className="text-2xl font-bold text-[#1A463C] tracking-tight">iamcavalli</span>
|
||||
<p className="text-sm text-[#71717a] mt-1">Area riservata</p>
|
||||
</div>
|
||||
<Card className="border border-[#e5e7eb] shadow-sm">
|
||||
<CardHeader className="pb-4">
|
||||
<CardTitle className="text-base font-semibold text-[#1a1a1a]">Accedi</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Suspense fallback={<div className="text-sm text-[#71717a]">Caricamento...</div>}>
|
||||
<AdminLoginForm />
|
||||
</Suspense>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
+10
-10
@@ -11,42 +11,42 @@ export default async function AdminDashboard() {
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900">Clienti</h1>
|
||||
<h1 className="text-2xl font-bold text-[#1a1a1a]">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">
|
||||
<div className="text-center py-20 text-[#71717a]">
|
||||
<p>Nessun cliente ancora.</p>
|
||||
<p className="mt-2">
|
||||
<Link
|
||||
href="/admin/clients/new"
|
||||
className="text-blue-600 hover:underline"
|
||||
className="text-[#1A463C] hover:underline font-medium"
|
||||
>
|
||||
Crea il primo cliente
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="bg-white rounded-lg border border-gray-200 overflow-hidden">
|
||||
<div className="bg-white rounded-lg border border-[#e5e7eb] overflow-hidden">
|
||||
<table className="w-full text-sm">
|
||||
<thead className="bg-gray-50 border-b border-gray-200">
|
||||
<thead className="bg-[#f9f9f9] border-b border-[#e5e7eb]">
|
||||
<tr>
|
||||
<th className="text-left py-3 px-4 font-medium text-gray-600">
|
||||
<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-gray-600">
|
||||
<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-gray-600">
|
||||
<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-gray-600">
|
||||
<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-gray-600">
|
||||
<th className="text-left py-3 px-4 font-medium text-[#71717a]">
|
||||
Link
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
+47
-15
@@ -4,28 +4,60 @@
|
||||
@source not "../../scripts/**";
|
||||
|
||||
/* =========================================================
|
||||
Design tokens — light & clean palette (Tailwind v4 @theme)
|
||||
Design tokens — iamcavalli brand palette (Tailwind v4 @theme)
|
||||
========================================================= */
|
||||
@theme inline {
|
||||
/* Colori base */
|
||||
--color-background: #ffffff;
|
||||
--color-foreground: #171717;
|
||||
|
||||
/* Font */
|
||||
--font-sans: var(--font-geist-sans), system-ui, -apple-system, BlinkMacSystemFont,
|
||||
"Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
||||
--font-mono: var(--font-geist-mono);
|
||||
|
||||
/* Palette brand iamcavalli — light & clean */
|
||||
--color-primary: #1a1a1a; /* charcoal per testo principale */
|
||||
--color-secondary: #666666; /* grigio medio per testo secondario */
|
||||
--color-tertiary: #999999; /* grigio chiaro per hint e timestamp */
|
||||
--color-bg-subtle: #f9f9f9; /* grigio molto chiaro per sfondi sezione */
|
||||
--color-border-light: #e5e5e5; /* bordo sottile */
|
||||
--color-accent: #0066cc; /* blu accent */
|
||||
--color-success: #16a34a; /* verde per done/saldato */
|
||||
--color-warning: #ca8a04; /* giallo per in_progress/inviata */
|
||||
--color-info: #2563eb; /* blu per pending/da_saldare */
|
||||
/* Base */
|
||||
--color-background: #ffffff;
|
||||
--color-foreground: #1a1a1a;
|
||||
|
||||
/* Brand primary — verde scuro iamcavalli */
|
||||
--color-primary: #1A463C;
|
||||
--color-primary-foreground: #ffffff;
|
||||
|
||||
/* Brand accent — giallo lime */
|
||||
--color-accent: #DEF168;
|
||||
--color-accent-foreground: #1A463C;
|
||||
|
||||
/* Secondary — grigio neutro */
|
||||
--color-secondary: #f4f4f5;
|
||||
--color-secondary-foreground: #1a1a1a;
|
||||
|
||||
/* Muted — per testi e sfondi secondari */
|
||||
--color-muted: #f9f9f9;
|
||||
--color-muted-foreground: #71717a;
|
||||
|
||||
/* Destructive */
|
||||
--color-destructive: #ef4444;
|
||||
--color-destructive-foreground: #ffffff;
|
||||
|
||||
/* Card */
|
||||
--color-card: #ffffff;
|
||||
--color-card-foreground: #1a1a1a;
|
||||
|
||||
/* Popover */
|
||||
--color-popover: #ffffff;
|
||||
--color-popover-foreground: #1a1a1a;
|
||||
|
||||
/* Border / Input / Ring */
|
||||
--color-border: #e5e7eb;
|
||||
--color-input: #e5e7eb;
|
||||
--color-ring: #1A463C;
|
||||
|
||||
/* Semantic — stato task/pagamenti */
|
||||
--color-success: #16a34a;
|
||||
--color-warning: #ca8a04;
|
||||
--color-info: #2563eb;
|
||||
|
||||
/* Legacy — usati inline nei componenti esistenti */
|
||||
--color-tertiary: #999999;
|
||||
--color-bg-subtle: #f9f9f9;
|
||||
--color-border-light: #e5e5e5;
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
|
||||
Reference in New Issue
Block a user