86e1499e8f
- Design system foundations: Plus Jakarta Sans font, shadow-card/radius tokens in @theme, design-reference/DESIGN-SYSTEM.md with component inventory - Collapsible admin shell (AdminShell): smooth w-64<->w-20 sidebar, new top header with "Admin" + avatar placeholder, localStorage-persisted state - Rename route /admin/leads -> /admin/pipeline (redirect stubs preserved), nav label Lead -> Pipeline; DB table unchanged - Reusable primitives: StatusBadge, SearchInput, SegmentedToggle (dual-theme) - Luxury restyle of lead table, kanban (6 stages + @dnd-kit intact), PageHeader - Tokenize editable-cell / option-multi-select for dark-mode legibility Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
484 lines
24 KiB
Plaintext
484 lines
24 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="it">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Rossi Inc — Client Portal</title>
|
|
<!-- Google Fonts: Plus Jakarta Sans -->
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
<!-- Tailwind CSS CDN -->
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<!-- Canvas Confetti per micro-interazioni celebrative -->
|
|
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js"></script>
|
|
<script>
|
|
tailwind.config = {
|
|
theme: {
|
|
extend: {
|
|
fontFamily: {
|
|
sans: ['Plus Jakarta Sans', 'sans-serif'],
|
|
},
|
|
colors: {
|
|
brand: {
|
|
dark: '#1A463C', /* Verde lusso */
|
|
darkHover: '#13342D',
|
|
lightBg: '#F8F9FA',
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<style>
|
|
.smooth-transition {
|
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
}
|
|
/* Stili per il Dragging del Kanban */
|
|
.dragging {
|
|
opacity: 0.4;
|
|
transform: scale(0.98);
|
|
}
|
|
.drag-over-zone {
|
|
background-color: rgba(26, 70, 60, 0.03);
|
|
border-color: rgba(26, 70, 60, 0.2);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="bg-brand-lightBg font-sans text-slate-800 antialiased min-h-screen pb-16">
|
|
|
|
<!-- HEADER PORTALE -->
|
|
<header class="bg-white border-b border-slate-100 px-8 py-5 sticky top-0 z-50 shadow-sm flex flex-col md:flex-row justify-between items-center gap-4">
|
|
<div class="flex items-center gap-3 w-full md:w-auto">
|
|
<span class="text-xs font-bold uppercase tracking-widest text-slate-400">iamcavalli</span>
|
|
<span class="text-slate-300">|</span>
|
|
<span class="text-xs font-medium text-slate-500">Client Portal</span>
|
|
</div>
|
|
|
|
<!-- Rossi Inc al Centro -->
|
|
<div class="text-center">
|
|
<h1 class="text-xl font-bold text-slate-900 tracking-tight">Rossi Inc</h1>
|
|
</div>
|
|
|
|
<div class="hidden md:flex items-center gap-2 text-[11px] text-emerald-700 bg-emerald-50 px-3 py-1 rounded-full border border-emerald-100">
|
|
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
|
Area Riservata Protetta
|
|
</div>
|
|
</header>
|
|
|
|
<!-- STEP PROGRESS TIMELINE UNIFICATA -->
|
|
<div class="bg-white border-b border-slate-100 py-8 px-6">
|
|
<div class="max-w-[1200px] mx-auto relative">
|
|
<!-- Linea di connessione di fondo -->
|
|
<div class="absolute top-[15px] left-[5%] right-[5%] h-1 bg-slate-100 rounded-full z-0">
|
|
<!-- Riempimento dinamico fisso basato sul progresso reale del progetto -->
|
|
<div class="bg-brand-dark h-full rounded-full smooth-transition" style="width: 35%;"></div>
|
|
</div>
|
|
|
|
<!-- Contenitore Nodi Milestone -->
|
|
<div class="relative z-10 grid grid-cols-5 gap-4">
|
|
|
|
<!-- Step 1 -->
|
|
<div class="flex flex-col items-center text-center">
|
|
<div class="w-8 h-8 rounded-full bg-brand-dark text-white flex items-center justify-center text-xs font-bold shadow-md border-4 border-white smooth-transition">
|
|
✓
|
|
</div>
|
|
<span class="text-[11px] font-bold text-slate-900 mt-2">Step 1</span>
|
|
<span class="text-[10px] text-slate-400 font-medium">Onboarding</span>
|
|
<span class="text-[9px] font-bold text-emerald-600 mt-1 uppercase">Completed</span>
|
|
</div>
|
|
|
|
<!-- Step 2 -->
|
|
<div class="flex flex-col items-center text-center">
|
|
<div class="w-8 h-8 rounded-full bg-white text-brand-dark border-4 border-brand-dark flex items-center justify-center text-xs font-bold shadow-md smooth-transition">
|
|
2
|
|
</div>
|
|
<span class="text-[11px] font-bold text-slate-900 mt-2">Step 2</span>
|
|
<span class="text-[10px] text-slate-500 font-medium">Analisi</span>
|
|
<span class="text-[9px] font-bold text-amber-600 mt-1 uppercase">In Progress</span>
|
|
</div>
|
|
|
|
<!-- Step 3 -->
|
|
<div class="flex flex-col items-center text-center">
|
|
<div class="w-8 h-8 rounded-full bg-slate-100 text-slate-400 border-4 border-white flex items-center justify-center text-xs font-semibold smooth-transition">
|
|
3
|
|
</div>
|
|
<span class="text-[11px] font-bold text-slate-500 mt-2">Step 3</span>
|
|
<span class="text-[10px] text-slate-400 font-medium">Esecuzione</span>
|
|
<span class="text-[9px] font-bold text-slate-400 mt-1 uppercase">Pending</span>
|
|
</div>
|
|
|
|
<!-- Step 4 -->
|
|
<div class="flex flex-col items-center text-center">
|
|
<div class="w-8 h-8 rounded-full bg-slate-100 text-slate-400 border-4 border-white flex items-center justify-center text-xs font-semibold smooth-transition">
|
|
4
|
|
</div>
|
|
<span class="text-[11px] font-bold text-slate-500 mt-2">Step 4</span>
|
|
<span class="text-[10px] text-slate-400 font-medium">Raffinamento</span>
|
|
<span class="text-[9px] font-bold text-slate-400 mt-1 uppercase">Pending</span>
|
|
</div>
|
|
|
|
<!-- Step 5 -->
|
|
<div class="flex flex-col items-center text-center">
|
|
<div class="w-8 h-8 rounded-full bg-slate-100 text-slate-400 border-4 border-white flex items-center justify-center text-xs font-semibold smooth-transition">
|
|
5
|
|
</div>
|
|
<span class="text-[11px] font-bold text-slate-500 mt-2">Step 5</span>
|
|
<span class="text-[10px] text-slate-400 font-medium">Consegna</span>
|
|
<span class="text-[9px] font-bold text-slate-400 mt-1 uppercase">Pending</span>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- SEZIONE PRINCIPALE CONTENUTO -->
|
|
<main class="max-w-[1400px] mx-auto px-6 mt-10 grid grid-cols-1 lg:grid-cols-4 gap-8">
|
|
|
|
<!-- COLONNA DI SINISTRA (Informazioni statiche di riepilogo) -->
|
|
<div class="lg:col-span-1 flex flex-col gap-6">
|
|
|
|
<!-- Offerte Attive -->
|
|
<div class="bg-white rounded-xl border border-slate-100 p-5 shadow-sm">
|
|
<h3 class="text-xs font-bold uppercase tracking-wider text-slate-400 mb-4">Offerte Attive</h3>
|
|
<div class="border-l-2 border-brand-dark pl-3">
|
|
<h4 class="text-sm font-bold text-slate-900">Web Domination</h4>
|
|
<div class="flex justify-between items-center text-xs mt-2 text-slate-500">
|
|
<span>Prezzo finale</span>
|
|
<span class="font-bold text-brand-dark">€7.000,00</span>
|
|
</div>
|
|
</div>
|
|
<div class="mt-4 pt-4 border-t border-slate-100">
|
|
<button onclick="toggleAccordion('compreso-content')" class="flex justify-between items-center w-full text-xs font-semibold text-slate-600 hover:text-slate-950">
|
|
<span>Cosa è compreso</span>
|
|
<svg id="compreso-arrow" class="w-4 h-4 transform transition-transform" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M19.5 8.25l-7.5 7.5-7.5-7.5"/></svg>
|
|
</button>
|
|
<div id="compreso-content" class="hidden mt-2 text-[11px] text-slate-500 space-y-1">
|
|
<p>• Strategia e architettura Web</p>
|
|
<p>• Sviluppo custom Webflow</p>
|
|
<p>• Ottimizzazione SEO specialistica</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Pagamenti -->
|
|
<div class="bg-white rounded-xl border border-slate-100 p-5 shadow-sm">
|
|
<h3 class="text-xs font-bold uppercase tracking-wider text-slate-400 mb-4">Pagamenti</h3>
|
|
<div class="space-y-2">
|
|
<div class="flex justify-between items-center p-3 rounded-lg border border-slate-100 text-xs">
|
|
<span class="font-semibold text-slate-700">Saldo 50%</span>
|
|
<span class="px-2 py-1 rounded text-[10px] font-bold bg-amber-50 text-amber-700 border border-amber-100 uppercase">Da Saldare</span>
|
|
</div>
|
|
<div class="flex justify-between items-center p-3 rounded-lg border border-slate-100 text-xs">
|
|
<span class="font-semibold text-slate-700">Acconto 50%</span>
|
|
<span class="px-2 py-1 rounded text-[10px] font-bold bg-emerald-50 text-emerald-700 border border-emerald-100 uppercase">Saldato</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Documenti -->
|
|
<div class="bg-white rounded-xl border border-slate-100 p-5 shadow-sm">
|
|
<h3 class="text-xs font-bold uppercase tracking-wider text-slate-400 mb-4">Documenti & File</h3>
|
|
<div class="space-y-2">
|
|
<a href="#" class="flex items-center justify-between p-3 rounded-lg border border-slate-100 text-xs hover:border-slate-300 transition-colors">
|
|
<span class="text-slate-700 font-medium">Brief Progetto</span>
|
|
<svg class="w-4 h-4 text-slate-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"/></svg>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- COLONNA DI DESTRA (Area di lavoro commutabile) -->
|
|
<div class="lg:col-span-3 flex flex-col gap-6">
|
|
|
|
<!-- CONTROLLI DELLA VISTA -->
|
|
<div class="flex justify-between items-center">
|
|
<h2 id="view-title" class="text-lg font-bold text-slate-900 tracking-tight">Fasi del Progetto</h2>
|
|
<div class="bg-slate-200/50 p-1 rounded-lg flex gap-1">
|
|
<button id="btn-timeline" class="px-5 py-1.5 bg-white rounded-md text-[11px] font-semibold text-slate-800 shadow-sm transition-all duration-200">
|
|
Timeline
|
|
</button>
|
|
<button id="btn-kanban" class="px-5 py-1.5 rounded-md text-[11px] font-semibold text-slate-500 hover:text-slate-800 transition-all duration-200">
|
|
Kanban
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ================= VISTA 1: TIMELINE (Read-only da backend) ================= -->
|
|
<div id="view-timeline" class="space-y-6">
|
|
|
|
<!-- FASE 1: COMPLETATA -->
|
|
<div class="bg-white rounded-xl border border-slate-100 p-6 shadow-sm">
|
|
<div class="flex justify-between items-center mb-3">
|
|
<h3 class="text-sm font-bold text-slate-900">Fase 1 ➔ Onboarding / Setup</h3>
|
|
<span class="px-2.5 py-0.5 rounded text-[10px] font-bold bg-emerald-50 text-emerald-700 border border-emerald-100 uppercase">Completata</span>
|
|
</div>
|
|
<div class="w-full bg-slate-100 h-1.5 rounded-full overflow-hidden mb-4">
|
|
<div class="bg-emerald-600 h-full" style="width: 100%;"></div>
|
|
</div>
|
|
<ul class="space-y-2.5 text-xs text-slate-600 pt-2 border-t border-slate-50">
|
|
<li class="flex items-center gap-3">
|
|
<span class="w-5 h-5 rounded-full bg-emerald-50 text-emerald-600 flex items-center justify-center text-[10px] font-bold">✓</span>
|
|
<span class="line-through text-slate-400">Audit iniziale (UX/UI, struttura, conversione)</span>
|
|
</li>
|
|
<li class="flex items-center gap-3">
|
|
<span class="w-5 h-5 rounded-full bg-emerald-50 text-emerald-600 flex items-center justify-center text-[10px] font-bold">✓</span>
|
|
<span class="line-through text-slate-400">Raccolta e Mappatura Materiali</span>
|
|
</li>
|
|
<li class="flex items-center gap-3">
|
|
<span class="w-5 h-5 rounded-full bg-emerald-50 text-emerald-600 flex items-center justify-center text-[10px] font-bold">✓</span>
|
|
<span class="line-through text-slate-400">Workshop 1° fase</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- FASE 2: IN CORSO -->
|
|
<div class="bg-white rounded-xl border border-slate-100 p-6 shadow-sm">
|
|
<div class="flex justify-between items-center mb-3">
|
|
<h3 class="text-sm font-bold text-slate-900">Fase 2 ➔ Analisi / Strategia</h3>
|
|
<span class="px-2.5 py-0.5 rounded text-[10px] font-bold bg-amber-50 text-amber-700 border border-amber-100 uppercase">In corso</span>
|
|
</div>
|
|
<div class="w-full bg-slate-100 h-1.5 rounded-full overflow-hidden mb-4">
|
|
<div class="bg-amber-500 h-full" style="width: 30%;"></div>
|
|
</div>
|
|
<ul class="space-y-2.5 text-xs text-slate-600 pt-2 border-t border-slate-50">
|
|
<li class="flex items-center gap-3">
|
|
<span class="w-5 h-5 rounded-full border-2 border-slate-200 bg-white flex items-center justify-center"></span>
|
|
<span>Analisi Competitor</span>
|
|
</li>
|
|
<li class="flex items-center gap-3">
|
|
<span class="w-5 h-5 rounded-full border-2 border-slate-200 bg-white flex items-center justify-center"></span>
|
|
<span>Architettura informativa (Sitemap)</span>
|
|
</li>
|
|
<li class="flex items-center gap-3">
|
|
<span class="w-5 h-5 rounded-full border-2 border-slate-200 bg-white flex items-center justify-center"></span>
|
|
<span>Brand Identity - Visual Identity</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- FASE 3: DA INIZIARE -->
|
|
<div class="bg-white rounded-xl border border-slate-100 p-6 shadow-sm">
|
|
<div class="flex justify-between items-center mb-3">
|
|
<h3 class="text-sm font-bold text-slate-900">Fase 3 ➔ Esecuzione / Core</h3>
|
|
<span class="px-2.5 py-0.5 rounded text-[10px] font-bold bg-slate-100 text-slate-500 border border-slate-200 uppercase">Da iniziare</span>
|
|
</div>
|
|
<div class="w-full bg-slate-100 h-1.5 rounded-full overflow-hidden mb-4">
|
|
<div class="bg-slate-300 h-full" style="width: 0%;"></div>
|
|
</div>
|
|
<ul class="space-y-2.5 text-xs text-slate-600 pt-2 border-t border-slate-50">
|
|
<li class="flex items-center gap-3">
|
|
<span class="w-5 h-5 rounded-full border-2 border-slate-200 bg-white flex items-center justify-center"></span>
|
|
<span>Homepage Figma & Webflow development</span>
|
|
</li>
|
|
<li class="flex items-center gap-3">
|
|
<span class="w-5 h-5 rounded-full border-2 border-slate-200 bg-white flex items-center justify-center"></span>
|
|
<span>Configurazione CMS Blog e sezioni dinamiche</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- FASE 4: DA INIZIARE -->
|
|
<div class="bg-white rounded-xl border border-slate-100 p-6 shadow-sm">
|
|
<div class="flex justify-between items-center mb-3">
|
|
<h3 class="text-sm font-bold text-slate-900">Fase 4 ➔ Raffinamento / Extra</h3>
|
|
<span class="px-2.5 py-0.5 rounded text-[10px] font-bold bg-slate-100 text-slate-500 border border-slate-200 uppercase">Da iniziare</span>
|
|
</div>
|
|
<div class="w-full bg-slate-100 h-1.5 rounded-full overflow-hidden mb-4">
|
|
<div class="bg-slate-300 h-full" style="width: 0%;"></div>
|
|
</div>
|
|
<ul class="space-y-2.5 text-xs text-slate-600 pt-2 border-t border-slate-50">
|
|
<li class="flex items-center gap-3">
|
|
<span class="w-5 h-5 rounded-full border-2 border-slate-200 bg-white flex items-center justify-center"></span>
|
|
<span>Ottimizzazione Web Core Vitals</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- FASE 5: DA INIZIARE -->
|
|
<div class="bg-white rounded-xl border border-slate-100 p-6 shadow-sm">
|
|
<div class="flex justify-between items-center mb-3">
|
|
<h3 class="text-sm font-bold text-slate-900">Fase 5 ➔ Onboarding / Consegna</h3>
|
|
<span class="px-2.5 py-0.5 rounded text-[10px] font-bold bg-slate-100 text-slate-500 border border-slate-200 uppercase">Da iniziare</span>
|
|
</div>
|
|
<div class="w-full bg-slate-100 h-1.5 rounded-full overflow-hidden mb-4">
|
|
<div class="bg-slate-300 h-full" style="width: 0%;"></div>
|
|
</div>
|
|
<ul class="space-y-2.5 text-xs text-slate-600 pt-2 border-t border-slate-50">
|
|
<li class="flex items-center gap-3">
|
|
<span class="w-5 h-5 rounded-full border-2 border-slate-200 bg-white flex items-center justify-center"></span>
|
|
<span>Rilascio e puntamento DNS live</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- ================= VISTA 2: KANBAN ATTIVO & TRASCINABILE ================= -->
|
|
<div id="view-kanban" class="hidden grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
|
|
<!-- COLONNA: DA FARE -->
|
|
<div class="kanban-column bg-slate-50/80 border border-slate-100 rounded-xl p-4 flex flex-col gap-4 min-h-[500px]" data-status="todo">
|
|
<div class="flex justify-between items-center border-b border-slate-200/60 pb-2">
|
|
<span class="text-xs font-bold text-slate-500 uppercase tracking-wider">Da Fare</span>
|
|
<span class="count-pill bg-slate-200 text-slate-600 text-[10px] font-bold px-2 py-0.5 rounded-full">3</span>
|
|
</div>
|
|
<div class="cards-dropzone flex-1 flex flex-col gap-3">
|
|
<!-- Card 1 -->
|
|
<div class="kanban-card bg-white p-4 rounded-lg border border-slate-200/60 shadow-sm cursor-grab active:cursor-grabbing hover:shadow transition-all" draggable="true" id="task-1">
|
|
<span class="text-[9px] font-semibold text-slate-400 block mb-1">FASE 2</span>
|
|
<p class="text-xs font-medium text-slate-800">Analisi Competitor</p>
|
|
</div>
|
|
<!-- Card 2 -->
|
|
<div class="kanban-card bg-white p-4 rounded-lg border border-slate-200/60 shadow-sm cursor-grab active:cursor-grabbing hover:shadow transition-all" draggable="true" id="task-2">
|
|
<span class="text-[9px] font-semibold text-slate-400 block mb-1">FASE 2</span>
|
|
<p class="text-xs font-medium text-slate-800">Architettura Informativa (Sitemap)</p>
|
|
</div>
|
|
<!-- Card 3 -->
|
|
<div class="kanban-card bg-white p-4 rounded-lg border border-slate-200/60 shadow-sm cursor-grab active:cursor-grabbing hover:shadow transition-all" draggable="true" id="task-3">
|
|
<span class="text-[9px] font-semibold text-slate-400 block mb-1">FASE 2</span>
|
|
<p class="text-xs font-medium text-slate-800">Brand Identity - Visual Identity</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- COLONNA: IN CORSO -->
|
|
<div class="kanban-column bg-slate-50/80 border border-slate-100 rounded-xl p-4 flex flex-col gap-4 min-h-[500px]" data-status="inprogress">
|
|
<div class="flex justify-between items-center border-b border-slate-200/60 pb-2">
|
|
<span class="text-xs font-bold text-slate-500 uppercase tracking-wider">In Corso</span>
|
|
<span class="count-pill bg-slate-200 text-slate-600 text-[10px] font-bold px-2 py-0.5 rounded-full">1</span>
|
|
</div>
|
|
<div class="cards-dropzone flex-1 flex flex-col gap-3">
|
|
<!-- Card 4 -->
|
|
<div class="kanban-card bg-white p-4 rounded-lg border border-slate-200/60 shadow-sm cursor-grab active:cursor-grabbing hover:shadow transition-all" draggable="true" id="task-4">
|
|
<span class="text-[9px] font-semibold text-slate-400 block mb-1">FASE 2</span>
|
|
<p class="text-xs font-medium text-slate-800">Direzione Creativa & Moodboard</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- COLONNA: FATTO -->
|
|
<div class="kanban-column bg-slate-50/80 border border-slate-100 rounded-xl p-4 flex flex-col gap-4 min-h-[500px]" data-status="done">
|
|
<div class="flex justify-between items-center border-b border-slate-200/60 pb-2">
|
|
<span class="text-xs font-bold text-slate-500 uppercase tracking-wider">Fatto</span>
|
|
<span class="count-pill bg-slate-200 text-slate-600 text-[10px] font-bold px-2 py-0.5 rounded-full">2</span>
|
|
</div>
|
|
<div class="cards-dropzone flex-1 flex flex-col gap-3">
|
|
<!-- Card 5 -->
|
|
<div class="kanban-card bg-white p-4 rounded-lg border border-slate-200/60 shadow-sm cursor-grab active:cursor-grabbing hover:shadow transition-all" draggable="true" id="task-5">
|
|
<span class="text-[9px] font-semibold text-slate-400 block mb-1">FASE 1</span>
|
|
<p class="text-xs font-medium text-slate-800">Kickoff strategico iniziale</p>
|
|
</div>
|
|
<!-- Card 6 -->
|
|
<div class="kanban-card bg-white p-4 rounded-lg border border-slate-200/60 shadow-sm cursor-grab active:cursor-grabbing hover:shadow transition-all" draggable="true" id="task-6">
|
|
<span class="text-[9px] font-semibold text-slate-400 block mb-1">FASE 1</span>
|
|
<p class="text-xs font-medium text-slate-800">Setup Repository & Strumenti</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</main>
|
|
|
|
<footer class="text-center text-xs text-slate-400 py-10">
|
|
Questa è la tua dashboard privata — non condividere il link.
|
|
</footer>
|
|
|
|
<!-- SCRIPT DI LOGICA INTERATTIVA -->
|
|
<script>
|
|
// Accordion Control
|
|
function toggleAccordion(id) {
|
|
const el = document.getElementById(id);
|
|
const arrow = document.getElementById('compreso-arrow');
|
|
el.classList.toggle('hidden');
|
|
arrow.classList.toggle('rotate-180');
|
|
}
|
|
|
|
// Swapping delle viste (Timeline / Kanban)
|
|
const btnTimeline = document.getElementById('btn-timeline');
|
|
const btnKanban = document.getElementById('btn-kanban');
|
|
const viewTimeline = document.getElementById('view-timeline');
|
|
const viewKanban = document.getElementById('view-kanban');
|
|
|
|
btnTimeline.addEventListener('click', () => {
|
|
viewKanban.classList.add('hidden');
|
|
viewTimeline.classList.remove('hidden');
|
|
btnTimeline.className = "px-5 py-1.5 bg-white rounded-md text-[11px] font-semibold text-slate-800 shadow-sm transition-all duration-200";
|
|
btnKanban.className = "px-5 py-1.5 rounded-md text-[11px] font-semibold text-slate-500 hover:text-slate-800 transition-all duration-200";
|
|
});
|
|
|
|
btnKanban.addEventListener('click', () => {
|
|
viewTimeline.classList.add('hidden');
|
|
viewKanban.classList.remove('hidden');
|
|
btnKanban.className = "px-5 py-1.5 bg-white rounded-md text-[11px] font-semibold text-slate-800 shadow-sm transition-all duration-200";
|
|
btnTimeline.className = "px-5 py-1.5 rounded-md text-[11px] font-semibold text-slate-500 hover:text-slate-800 transition-all duration-200";
|
|
|
|
// Inizializza Drag & Drop quando viene aperta la vista Kanban
|
|
initializeKanbanDragAndDrop();
|
|
});
|
|
|
|
// Logica Drag & Drop per il Kanban
|
|
function initializeKanbanDragAndDrop() {
|
|
const cards = document.querySelectorAll('.kanban-card');
|
|
const columns = document.querySelectorAll('.kanban-column');
|
|
|
|
cards.forEach(card => {
|
|
card.addEventListener('dragstart', () => {
|
|
card.classList.add('dragging');
|
|
});
|
|
|
|
card.addEventListener('dragend', () => {
|
|
card.classList.remove('dragging');
|
|
updateCounts();
|
|
});
|
|
});
|
|
|
|
columns.forEach(column => {
|
|
const dropzone = column.querySelector('.cards-dropzone');
|
|
|
|
column.addEventListener('dragover', (e) => {
|
|
e.preventDefault();
|
|
column.classList.add('drag-over-zone');
|
|
});
|
|
|
|
column.addEventListener('dragleave', () => {
|
|
column.classList.remove('drag-over-zone');
|
|
});
|
|
|
|
column.addEventListener('drop', (e) => {
|
|
e.preventDefault();
|
|
column.classList.remove('drag-over-zone');
|
|
const draggingCard = document.querySelector('.dragging');
|
|
if (draggingCard) {
|
|
dropzone.appendChild(draggingCard);
|
|
|
|
// Se lanciato nella colonna "Fatto" (done), triggera una micro-celebrazione
|
|
if (column.getAttribute('data-status') === 'done' && typeof confetti === 'function') {
|
|
confetti({
|
|
particleCount: 50,
|
|
spread: 50,
|
|
origin: { y: 0.8 }
|
|
});
|
|
}
|
|
}
|
|
updateCounts();
|
|
});
|
|
});
|
|
}
|
|
|
|
// Aggiornamento dei contatori delle colonne del Kanban
|
|
function updateCounts() {
|
|
const columns = document.querySelectorAll('.kanban-column');
|
|
columns.forEach(col => {
|
|
const countPill = col.querySelector('.count-pill');
|
|
const count = col.querySelector('.cards-dropzone').children.length;
|
|
countPill.innerText = count;
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |