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:
Simone Cavalli
2026-05-15 23:14:29 +02:00
parent 80d93993a9
commit 7af917fe80
13 changed files with 684 additions and 50 deletions
@@ -0,0 +1,56 @@
"use client";
import { useState, type ReactNode } from "react";
import { ClientKanban } from "./ClientKanban";
import type { ClientView } from "@/lib/client-view";
import type { Comment } from "@/db/schema";
export function PhaseViewToggle({
timelineView,
phases,
token,
comments,
}: {
timelineView: ReactNode;
phases: ClientView["phases"];
token: string;
comments: Comment[];
}) {
const [view, setView] = useState<"timeline" | "kanban">("timeline");
return (
<div>
<div className="flex items-center justify-between mb-6">
<h2 className="text-xl font-bold text-[#1a1a1a]">Fasi del Progetto</h2>
<div className="flex items-center gap-1 bg-[#f4f4f5] rounded-lg p-1">
<button
onClick={() => setView("timeline")}
className={`px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${
view === "timeline"
? "bg-white text-[#1A463C] shadow-sm"
: "text-[#71717a] hover:text-[#1a1a1a]"
}`}
>
Timeline
</button>
<button
onClick={() => setView("kanban")}
className={`px-3 py-1.5 rounded-md text-xs font-semibold transition-all ${
view === "kanban"
? "bg-white text-[#1A463C] shadow-sm"
: "text-[#71717a] hover:text-[#1a1a1a]"
}`}
>
Kanban
</button>
</div>
</div>
{view === "timeline" ? (
timelineView
) : (
<ClientKanban phases={phases} token={token} comments={comments} />
)}
</div>
);
}