feat: Quiet Luxury design system + Pipeline (ex-Lead) redesign
- 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>
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
# Design System: iamcavalli Admin & Client Portal (v1.0)
|
||||
|
||||
> "Minimalist Premium / Quiet Luxury" — the aesthetic that replaces the old
|
||||
> mixed token/hardcoded styling across ClientHub's admin area. First applied
|
||||
> to the Lead Pipeline page (Phase: Pipeline redesign); the tokens and
|
||||
> primitives documented here are the base for restyling every other section.
|
||||
|
||||
## Philosophy
|
||||
|
||||
- **Quiet, not loud.** Elevation is nearly invisible (shadow opacity ≤ 0.02),
|
||||
borders are hairline, color is used sparingly and only to carry meaning
|
||||
(status, semantics) — never for decoration.
|
||||
- **Density with air.** Generous padding (`py-4 px-6` in tables, `p-4` in
|
||||
kanban columns) paired with small type (`text-xs`, `text-[11px]`) reads as
|
||||
premium rather than cramped.
|
||||
- **Numbers are monospace.** Prices, phone numbers, dates, counts — anything
|
||||
tabular/numeric — use `font-mono` and right-alignment so columns of digits
|
||||
line up.
|
||||
- **Dual-theme by construction.** Every surface is built from semantic
|
||||
tokens (`bg-card`, `text-muted-foreground`, `border-border`, …), never raw
|
||||
Tailwind palette classes (`bg-white`, `text-slate-900`, …) or hex literals.
|
||||
This is what makes dark mode "just work" without a parallel dark stylesheet.
|
||||
- **Motion is functional.** Transitions exist to explain state change (sidebar
|
||||
collapse, hover, drag) — `duration-200`–`duration-350`,
|
||||
`ease-[cubic-bezier(0.4,0,0.2,1)]` for the sidebar specifically. No
|
||||
decorative animation.
|
||||
|
||||
## Typography
|
||||
|
||||
- **Sans**: Plus Jakarta Sans (weights 300–700), loaded via `next/font/google`
|
||||
as `--font-plus-jakarta-sans`, mapped to Tailwind's `--font-sans` in
|
||||
`@theme`. Used for all UI text.
|
||||
- **Mono**: Geist Mono, `--font-geist-mono` → `--font-mono`. Used for numeric
|
||||
data cells only (prices, phone numbers, counts, dates in tables).
|
||||
- **Scale conventions**:
|
||||
- Page title: `text-2xl font-semibold tracking-tight`
|
||||
- Page subtitle: `text-xs text-muted-foreground`
|
||||
- Table header cells: `text-[11px] font-semibold uppercase tracking-wider text-muted-foreground`
|
||||
- Table body: `text-sm`
|
||||
- Badge/pill label: `text-[10px]`–`text-xs font-semibold uppercase tracking-wide`
|
||||
|
||||
## Color Tokens
|
||||
|
||||
Raw values live in `:root` (light) / `.dark` (dark) in `src/app/globals.css`
|
||||
and are mapped to Tailwind utilities via `@theme inline`. Components must
|
||||
consume the mapped utility, never the raw hex or a Tailwind palette shade.
|
||||
|
||||
| Utility | Light | Dark | Usage |
|
||||
|---|---|---|---|
|
||||
| `bg-background` / `text-foreground` | `#ffffff` / `#1a1a1a` | `#0e1512` / `#f2f4f3` | Page canvas |
|
||||
| `bg-card` / `text-card-foreground` | `#ffffff` | `#131a16` | Cards, table, kanban cards, header bar |
|
||||
| `bg-muted` / `text-muted-foreground` | `#f9f9f9` / `#71717a` | `#171f1b` / `#9aa39e` | Subtle backgrounds, secondary text, kanban columns |
|
||||
| `bg-primary` / `text-primary-foreground` | `#1A463C` | `#3FA88C` | Primary actions, sidebar, active nav state |
|
||||
| `bg-accent` | `#DEF168` | `#DEF168` | Rare highlight accent (lime) |
|
||||
| `border-border` / `border-input` | `#e5e7eb` | `#26302b` | All hairline borders |
|
||||
| `ring-ring` | `#1A463C` | `#3FA88C` | Focus rings |
|
||||
| `bg-destructive` | `#ef4444` | `#f87171` | Destructive actions |
|
||||
|
||||
**Sidebar exception**: the sidebar stays brand green `bg-[#1A463C]` in both
|
||||
themes (it is not a themed surface — it's the constant brand anchor).
|
||||
|
||||
**Status/semantic colors** (lead stages, badges) use Tailwind's default
|
||||
palette (blue/purple/amber/orange/emerald/red) directly, each paired with an
|
||||
explicit `dark:` variant for legibility on dark surfaces — see `StatusBadge`.
|
||||
|
||||
## Elevation & Radius
|
||||
|
||||
- `--radius: 0.5rem` (base) is wired into `@theme` as `--radius-lg` (`=
|
||||
--radius`) and `--radius-xl` (`= --radius + 0.25rem`), so `rounded-lg` /
|
||||
`rounded-xl` utilities resolve consistently off one token.
|
||||
- `--shadow-card: 0 4px 20px rgba(0,0,0,0.01)` → `shadow-card` utility.
|
||||
Default resting elevation for cards, table containers, kanban cards.
|
||||
- `--shadow-card-hover: 0 8px 30px rgba(0,0,0,0.02)` → `shadow-card-hover`
|
||||
utility. Applied on hover for interactive cards.
|
||||
|
||||
## Layout Conventions
|
||||
|
||||
- **Table container**: `bg-card rounded-xl border border-border shadow-card
|
||||
overflow-hidden`.
|
||||
- **Table header row**: `bg-muted/50 border-b border-border text-[11px]
|
||||
uppercase tracking-wider text-muted-foreground`.
|
||||
- **Table body rows**: `py-4 px-6`, `divide-y divide-border`,
|
||||
`hover:bg-muted/40 transition-colors`.
|
||||
- **Kanban column**: `bg-muted/60 rounded-xl border border-border p-4`.
|
||||
- **Kanban card**: `bg-card rounded-lg border border-border shadow-sm
|
||||
hover:border-primary/30 hover:shadow-card-hover transition-all`.
|
||||
- **Page header**: title `text-2xl font-semibold tracking-tight
|
||||
text-foreground`, subtitle `text-xs text-muted-foreground mt-1`, primary
|
||||
action button `bg-primary text-primary-foreground hover:bg-primary/90`.
|
||||
|
||||
## Color/Class Migration Map (dual-theme principle)
|
||||
|
||||
When restyling any surface, replace hardcoded classes with token utilities:
|
||||
|
||||
| Old (hardcoded) | New (token) |
|
||||
|---|---|
|
||||
| `bg-white` | `bg-card` |
|
||||
| `bg-slate-50` / `bg-gray-50` | `bg-muted` |
|
||||
| `border-slate-100` / `border-slate-200` | `border-border` |
|
||||
| `text-slate-900` / `text-[#1a1a1a]` | `text-foreground` |
|
||||
| `text-slate-500` / `text-slate-400` / `text-[#71717a]` | `text-muted-foreground` |
|
||||
| `bg-brand-dark` / `text-[#1A463C]` (as action color) | `bg-primary` / `text-primary` |
|
||||
|
||||
## Motion
|
||||
|
||||
- **Sidebar collapse**: `transition-[width] duration-350
|
||||
ease-[cubic-bezier(0.4,0,0.2,1)]` on the `<aside>`; label/logo text use
|
||||
`whitespace-nowrap transition-opacity duration-200` and fade to
|
||||
`opacity-0` immediately on collapse, but only fade back in ~150ms after
|
||||
the width transition starts on expand (avoids text reflow/wrap during the
|
||||
animation).
|
||||
- **Hover states**: `transition-colors duration-150`–`duration-200` on rows,
|
||||
buttons, nav links.
|
||||
- **Kanban drag**: dragged card renders in a `DragOverlay` with
|
||||
`rotate-1 shadow-xl`; drop target column highlights via `border-primary
|
||||
bg-primary/5`.
|
||||
|
||||
## UX Rules
|
||||
|
||||
1. Numeric/tabular data is always monospace and right-aligned in tables.
|
||||
2. Every interactive control has a visible focus state (`focus:ring-1
|
||||
focus:ring-ring focus:border-primary` pattern) for keyboard accessibility.
|
||||
3. Status is always communicated redundantly — color + text label — never
|
||||
color alone.
|
||||
4. Destructive actions use `destructive` tokens, never ad-hoc red.
|
||||
5. Empty states are muted, centered, and brief ("Nessun lead trovato").
|
||||
6. Sidebar collapse state persists across page loads via `localStorage`
|
||||
(`iamcavalli:sidebar`) and is restored before paint where possible to
|
||||
avoid layout jump.
|
||||
|
||||
---
|
||||
|
||||
## Component Inventory
|
||||
|
||||
Primitives extracted from the Lead Pipeline redesign, intended for reuse
|
||||
across all future admin pages.
|
||||
|
||||
| Component | Path | Purpose |
|
||||
|---|---|---|
|
||||
| `AdminShell` | `src/components/admin/AdminShell.tsx` | Client shell holding sidebar-collapsed state (persisted to `localStorage`), renders sidebar + top header + `<main>`. Wraps all `/admin/*` pages. |
|
||||
| `AdminSidebar` | `src/components/admin/AdminSidebar.tsx` | Collapsible brand sidebar (`w-64` ↔ `w-20`), controlled by `AdminShell`. Nav items, theme toggle, sign-out. |
|
||||
| `StatusBadge` | `src/components/ui/StatusBadge.tsx` | Rounded-full status pill with a color map per lead stage, each with a `dark:` variant. Replaces the old scattered `STAGE_COLOR` maps. |
|
||||
| `SearchInput` | `src/components/ui/SearchInput.tsx` | Search-icon input, `rounded-lg border-border focus:ring-primary`. |
|
||||
| `SegmentedToggle` | `src/components/ui/SegmentedToggle.tsx` | Generic Lista/Kanban-style segmented control (`bg-muted p-1 rounded-lg`, active option `bg-card shadow-sm`). |
|
||||
| `PageHeader` | `src/components/admin/PageHeader.tsx` | Page title (`text-2xl tracking-tight`) + subtitle + action slot, token-based. |
|
||||
| `LeadTable` | `src/components/admin/leads/LeadTable.tsx` | Luxury table restyle: `bg-card rounded-xl shadow-card`, uppercase muted headers, `hover:bg-muted/40` rows, uses `StatusBadge`. |
|
||||
| `LeadsKanbanBoard` | `src/components/admin/leads/LeadsKanbanBoard.tsx` | Kanban restyle: `bg-muted/60` columns with count pills, `bg-card` cards with `hover:border-primary/30`. Uses `@dnd-kit`, keeps all 6 lead stages. |
|
||||
| `LeadsViewToggle` | `src/components/admin/leads/LeadsViewToggle.tsx` | Wires `SearchInput` + `SegmentedToggle` together with the table/kanban views. |
|
||||
@@ -0,0 +1,361 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Catalogo Servizi — Luxury Admin CRM</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>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Plus Jakarta Sans', 'sans-serif'],
|
||||
},
|
||||
colors: {
|
||||
brand: {
|
||||
dark: '#1A463C', /* Verde scuro richiesto */
|
||||
darkHover: '#13342D', /* Variante scura per hover */
|
||||
active: 'rgba(255, 255, 255, 0.08)',
|
||||
bg: '#F8F9FA',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.sidebar-transition {
|
||||
transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1), transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-brand-bg font-sans text-slate-800 antialiased min-h-screen flex overflow-x-hidden">
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<aside id="sidebar" class="w-64 bg-brand-dark text-white flex flex-col justify-between p-6 border-r border-emerald-950/20 shrink-0 sidebar-transition relative z-10">
|
||||
<div class="overflow-hidden">
|
||||
<!-- Logo e Intestazione -->
|
||||
<div class="mb-10 px-2 flex items-center justify-between">
|
||||
<span id="sidebar-logo-text" class="text-lg font-bold tracking-wider text-emerald-50 whitespace-nowrap transition-opacity duration-300">iamcavalli</span>
|
||||
</div>
|
||||
|
||||
<!-- Navigazione Principale -->
|
||||
<nav class="space-y-1">
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M4 6a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H6a2 2 0 01-2-2v-4zM14 16a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2h-2a2 2 0 01-2-2v-4z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Dashboard</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Lead</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0 text-emerald-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Clienti</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Progetti</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0 text-emerald-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Preventivi</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0 text-emerald-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M7 7h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Offerte</span>
|
||||
</a>
|
||||
<!-- Stato Attivo su Catalogo -->
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-white bg-brand-active font-medium transition-all duration-200 shadow-sm">
|
||||
<svg class="w-4 h-4 shrink-0 text-emerald-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Catalogo</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Area Inferiore Sidebar -->
|
||||
<div class="border-t border-white/10 pt-4 space-y-3 overflow-hidden">
|
||||
<div class="flex items-center justify-between px-3 py-1 text-xs text-emerald-200/50 whitespace-nowrap">
|
||||
<span class="sidebar-text transition-opacity duration-300">Tema</span>
|
||||
<button class="p-1 rounded-full bg-white/5 hover:bg-white/10 text-emerald-200 hover:text-white transition-all duration-200">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364-6.364l-.707.707M6.343 17.657l-.707.707m12.728 0l-.707-.707M6.343 6.343l-.707-.707M14 12a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2 rounded-lg text-sm text-red-300/80 hover:text-red-200 hover:bg-red-950/20 transition-all duration-200 whitespace-nowrap">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg>
|
||||
<span class="sidebar-text transition-opacity duration-300">Esci</span>
|
||||
</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- SEZIONE PRINCIPALE -->
|
||||
<div class="flex-1 flex flex-col min-w-0">
|
||||
|
||||
<!-- BARRA DI INTESTAZIONE SUPERIORE -->
|
||||
<header class="h-16 border-b border-slate-100 bg-white px-8 flex items-center justify-between shrink-0">
|
||||
<div class="flex items-center gap-4">
|
||||
<!-- Pulsante Apri/Chiudi Sidebar -->
|
||||
<button id="sidebar-toggle" class="p-2 -ml-2 rounded-lg text-slate-500 hover:bg-slate-50 hover:text-slate-800 transition-colors focus:outline-none" title="Espandi/Comprimi Sidebar">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M4 6h16M4 12h12M4 18h16"/></svg>
|
||||
</button>
|
||||
<span class="text-xs text-slate-400 font-medium">Area di Lavoro</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="text-xs font-semibold text-slate-700 bg-slate-100 px-2.5 py-1 rounded-full">Demo Account</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- AREA DEL CONTENUTO -->
|
||||
<main class="flex-1 p-8 lg:p-10 max-w-[1400px] w-full mx-auto flex flex-col gap-6 overflow-y-auto">
|
||||
|
||||
<!-- INTESTAZIONE SEZIONE -->
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-slate-900 tracking-tight">Catalogo Servizi</h1>
|
||||
<p class="text-xs text-slate-400 mt-1">Configura e gestisci le singole voci di servizio offerte</p>
|
||||
</div>
|
||||
|
||||
<!-- BARRA DI RICERCA MINIMALE -->
|
||||
<div class="relative w-full">
|
||||
<span class="absolute inset-y-0 left-0 flex items-center pl-3.5 pointer-events-none text-slate-400">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Cerca per nome, categoria, fase, tag o pacchetto..."
|
||||
class="w-full pl-10 pr-4 py-3 bg-white text-sm text-slate-800 placeholder-slate-400 border border-slate-200/80 rounded-lg focus:outline-none focus:border-brand-dark focus:ring-1 focus:ring-brand-dark transition-all duration-200"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- TABELLA CATALOGO -->
|
||||
<div class="bg-white rounded-xl border border-slate-100 shadow-[0_4px_20px_rgba(0,0,0,0.01)] overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left border-collapse table-fixed min-w-[1000px]">
|
||||
<thead>
|
||||
<tr class="border-b border-slate-100/80 bg-slate-50/50 text-slate-400 text-[11px] font-semibold uppercase tracking-wider">
|
||||
<th class="py-3 px-5 w-1/3">
|
||||
<span class="inline-flex items-center gap-1 cursor-pointer hover:text-slate-700">
|
||||
Nome
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M8 9l4-4 4 4m0 6l-4 4-4-4"/></svg>
|
||||
</span>
|
||||
</th>
|
||||
<th class="py-3 px-4 w-[110px]">
|
||||
<span class="inline-flex items-center gap-1 cursor-pointer hover:text-slate-700">
|
||||
Prezzo
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M8 9l4-4 4 4m0 6l-4 4-4-4"/></svg>
|
||||
</span>
|
||||
</th>
|
||||
<th class="py-3 px-4 w-[160px]">Offerta</th>
|
||||
<th class="py-3 px-4 w-[240px]">Fase</th>
|
||||
<th class="py-3 px-4 w-1/5">Descrizione</th>
|
||||
<th class="py-3 px-4 w-[100px] text-center">Pacchetto</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100/60 text-[13px] text-slate-700">
|
||||
|
||||
<!-- Riga 1 -->
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-3 px-5 font-medium text-slate-900 truncate">Landing Page (Metodo o Differenziante)</td>
|
||||
<td class="py-3 px-4 font-mono text-xs text-slate-600">€1.000,00</td>
|
||||
<td class="py-3 px-4">
|
||||
<span class="inline-flex items-center gap-1 px-2.5 py-0.5 rounded text-[10px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-100">
|
||||
Signature Offer
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-3 px-4">
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-medium bg-amber-50 text-amber-700 border border-amber-100">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-amber-400"></span>
|
||||
Fase 3 ➔ Esecuzione
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-3 px-4 text-slate-400 text-xs truncate">—</td>
|
||||
<td class="py-3 px-4 text-center">
|
||||
<button class="w-6 h-6 rounded-full border border-slate-200 text-slate-400 hover:text-brand-dark hover:border-brand-dark hover:bg-emerald-50/30 flex items-center justify-center mx-auto transition-all">
|
||||
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Riga 2 -->
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-3 px-5 font-medium text-slate-900 truncate">Analisi Competitor</td>
|
||||
<td class="py-3 px-4 font-mono text-xs text-slate-600">€400,00</td>
|
||||
<td class="py-3 px-4">
|
||||
<div class="flex flex-col gap-1 items-start">
|
||||
<span class="inline-flex items-center gap-1 px-2.5 py-0.5 rounded text-[10px] font-semibold bg-purple-50 text-purple-600 border border-purple-100">
|
||||
Entry Offer
|
||||
</span>
|
||||
<span class="inline-flex items-center gap-1 px-2.5 py-0.5 rounded text-[10px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-100">
|
||||
Signature Offer
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-3 px-4">
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-medium bg-blue-50 text-blue-700 border border-blue-100">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-blue-400"></span>
|
||||
Fase 2 ➔ Analisi / Strat.
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-3 px-4 text-slate-400 text-xs truncate">—</td>
|
||||
<td class="py-3 px-4 text-center">
|
||||
<button class="w-6 h-6 rounded-full border border-slate-200 text-slate-400 hover:text-brand-dark hover:border-brand-dark hover:bg-emerald-50/30 flex items-center justify-center mx-auto transition-all">
|
||||
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Riga 3 -->
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-3 px-5 font-medium text-slate-900 truncate">Art direction su direzione da prendere</td>
|
||||
<td class="py-3 px-4 font-mono text-xs text-slate-600">€2.000,00</td>
|
||||
<td class="py-3 px-4">
|
||||
<span class="inline-flex items-center gap-1 px-2.5 py-0.5 rounded text-[10px] font-semibold bg-blue-50 text-blue-600 border border-blue-100">
|
||||
Retainer Offer
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-3 px-4 text-slate-400 text-xs">—</td>
|
||||
<td class="py-3 px-4 text-slate-400 text-xs truncate">—</td>
|
||||
<td class="py-3 px-4 text-center">
|
||||
<button class="w-6 h-6 rounded-full border border-slate-200 text-slate-400 hover:text-brand-dark hover:border-brand-dark hover:bg-emerald-50/30 flex items-center justify-center mx-auto transition-all">
|
||||
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Riga 4 -->
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-3 px-5 font-medium text-slate-900 truncate">Audit iniziale (UX/UI, struttura, conversione)</td>
|
||||
<td class="py-3 px-4 font-mono text-xs text-slate-600">€500,00</td>
|
||||
<td class="py-3 px-4">
|
||||
<div class="flex flex-col gap-1 items-start">
|
||||
<span class="inline-flex items-center gap-1 px-2.5 py-0.5 rounded text-[10px] font-semibold bg-purple-50 text-purple-600 border border-purple-100">
|
||||
Entry Offer
|
||||
</span>
|
||||
<span class="inline-flex items-center gap-1 px-2.5 py-0.5 rounded text-[10px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-100">
|
||||
Signature Offer
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-3 px-4">
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-medium bg-orange-50 text-orange-700 border border-orange-100">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-orange-400"></span>
|
||||
Fase 1 ➔ Onboarding
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-3 px-4 text-slate-400 text-xs truncate">—</td>
|
||||
<td class="py-3 px-4 text-center">
|
||||
<button class="w-6 h-6 rounded-full border border-slate-200 text-slate-400 hover:text-brand-dark hover:border-brand-dark hover:bg-emerald-50/30 flex items-center justify-center mx-auto transition-all">
|
||||
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Riga 5 -->
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-3 px-5 font-medium text-slate-900 truncate">Go-live / messa online & accessi</td>
|
||||
<td class="py-3 px-4 font-mono text-xs text-slate-600">€300,00</td>
|
||||
<td class="py-3 px-4">
|
||||
<span class="inline-flex items-center gap-1 px-2.5 py-0.5 rounded text-[10px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-100">
|
||||
Signature Offer
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-3 px-4">
|
||||
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-medium bg-teal-50 text-teal-700 border border-teal-100">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-teal-400"></span>
|
||||
Fase 5 ➔ Consegna
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-3 px-4 text-slate-400 text-xs truncate">—</td>
|
||||
<td class="py-3 px-4 text-center">
|
||||
<button class="w-6 h-6 rounded-full border border-slate-200 text-slate-400 hover:text-brand-dark hover:border-brand-dark hover:bg-emerald-50/30 flex items-center justify-center mx-auto transition-all">
|
||||
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- FORM INLINE PER NUOVA RIGA ("Aggiungi servizio") -->
|
||||
<tr class="bg-slate-50/40 border-t-2 border-slate-100">
|
||||
<td class="py-4 px-5">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="+ Aggiungi servizio..."
|
||||
class="w-full bg-white border border-slate-200 rounded px-3 py-1.5 text-xs text-slate-800 placeholder-slate-400 focus:outline-none focus:border-brand-dark focus:ring-1 focus:ring-brand-dark transition-all"
|
||||
/>
|
||||
</td>
|
||||
<td class="py-4 px-4">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="0,00"
|
||||
class="w-full bg-white border border-slate-200 rounded px-3 py-1.5 text-xs font-mono text-slate-800 placeholder-slate-400 focus:outline-none focus:border-brand-dark focus:ring-1 focus:ring-brand-dark transition-all"
|
||||
/>
|
||||
</td>
|
||||
<td class="py-4 px-4 text-slate-300 text-xs select-none">Seleziona...</td>
|
||||
<td class="py-4 px-4">
|
||||
<select class="w-full bg-white border border-slate-200 rounded px-2 py-1.5 text-xs text-slate-600 focus:outline-none focus:border-brand-dark focus:ring-1 focus:ring-brand-dark transition-all">
|
||||
<option value="">Fase...</option>
|
||||
<option value="1">Fase 1</option>
|
||||
<option value="2">Fase 2</option>
|
||||
<option value="3">Fase 3</option>
|
||||
<option value="4">Fase 4</option>
|
||||
<option value="5">Fase 5</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="py-4 px-4">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Descrizione..."
|
||||
class="w-full bg-white border border-slate-200 rounded px-3 py-1.5 text-xs text-slate-800 placeholder-slate-400 focus:outline-none focus:border-brand-dark focus:ring-1 focus:ring-brand-dark transition-all"
|
||||
/>
|
||||
</td>
|
||||
<td class="py-4 px-4 text-center">
|
||||
<button class="bg-brand-dark hover:bg-brand-darkHover text-white text-xs font-medium px-4 py-1.5 rounded transition-all">
|
||||
Invia
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- FOOTER TABELLA -->
|
||||
<div class="border-t border-slate-100 px-6 py-4 flex items-center justify-between text-xs text-slate-400">
|
||||
<span>Visualizzazione di 5 servizi principali</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- SCRIPT DI LOGICA (Gestione Sidebar) -->
|
||||
<script>
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const toggleButton = document.getElementById('sidebar-toggle');
|
||||
const logoText = document.getElementById('sidebar-logo-text');
|
||||
const sidebarTexts = document.querySelectorAll('.sidebar-text');
|
||||
|
||||
toggleButton.addEventListener('click', () => {
|
||||
const isCollapsed = sidebar.classList.contains('w-20');
|
||||
|
||||
if (isCollapsed) {
|
||||
sidebar.classList.remove('w-20');
|
||||
sidebar.classList.add('w-64');
|
||||
setTimeout(() => {
|
||||
logoText.classList.remove('opacity-0');
|
||||
sidebarTexts.forEach(text => text.classList.remove('opacity-0'));
|
||||
}, 150);
|
||||
} else {
|
||||
logoText.classList.add('opacity-0');
|
||||
sidebarTexts.forEach(text => text.classList.add('opacity-0'));
|
||||
sidebar.classList.remove('w-64');
|
||||
sidebar.classList.add('w-20');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,270 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Clienti — Luxury Admin CRM</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>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Plus Jakarta Sans', 'sans-serif'],
|
||||
},
|
||||
colors: {
|
||||
brand: {
|
||||
dark: '#1A463C', /* Verde scuro richiesto */
|
||||
darkHover: '#13342D', /* Variante scura per hover */
|
||||
active: 'rgba(255, 255, 255, 0.08)',
|
||||
bg: '#F8F9FA',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.sidebar-transition {
|
||||
transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1), transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-brand-bg font-sans text-slate-800 antialiased min-h-screen flex overflow-x-hidden">
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<aside id="sidebar" class="w-64 bg-brand-dark text-white flex flex-col justify-between p-6 border-r border-emerald-950/20 shrink-0 sidebar-transition relative z-10">
|
||||
<div class="overflow-hidden">
|
||||
<!-- Logo e Intestazione -->
|
||||
<div class="mb-10 px-2 flex items-center justify-between">
|
||||
<span id="sidebar-logo-text" class="text-lg font-bold tracking-wider text-emerald-50 whitespace-nowrap transition-opacity duration-300">iamcavalli</span>
|
||||
</div>
|
||||
|
||||
<!-- Navigazione Principale -->
|
||||
<nav class="space-y-1">
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M4 6a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H6a2 2 0 01-2-2v-4zM14 16a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2h-2a2 2 0 01-2-2v-4z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Dashboard</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Lead</span>
|
||||
</a>
|
||||
<!-- Stato Attivo su Clienti -->
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-white bg-brand-active font-medium transition-all duration-200 shadow-sm">
|
||||
<svg class="w-4 h-4 shrink-0 text-emerald-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Clienti</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Progetti</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Preventivi</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M7 7h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Offerte</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Area Inferiore Sidebar -->
|
||||
<div class="border-t border-white/10 pt-4 space-y-3 overflow-hidden">
|
||||
<div class="flex items-center justify-between px-3 py-1 text-xs text-emerald-200/50 whitespace-nowrap">
|
||||
<span class="sidebar-text transition-opacity duration-300">Tema</span>
|
||||
<button class="p-1 rounded-full bg-white/5 hover:bg-white/10 text-emerald-200 hover:text-white transition-all duration-200">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364-6.364l-.707.707M6.343 17.657l-.707.707m12.728 0l-.707-.707M6.343 6.343l-.707-.707M14 12a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2 rounded-lg text-sm text-red-300/80 hover:text-red-200 hover:bg-red-950/20 transition-all duration-200 whitespace-nowrap">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg>
|
||||
<span class="sidebar-text transition-opacity duration-300">Esci</span>
|
||||
</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- SEZIONE PRINCIPALE -->
|
||||
<div class="flex-1 flex flex-col min-w-0">
|
||||
|
||||
<!-- BARRA DI INTESTAZIONE SUPERIORE -->
|
||||
<header class="h-16 border-b border-slate-100 bg-white px-8 flex items-center justify-between shrink-0">
|
||||
<div class="flex items-center gap-4">
|
||||
<!-- Pulsante Apri/Chiudi Sidebar -->
|
||||
<button id="sidebar-toggle" class="p-2 -ml-2 rounded-lg text-slate-500 hover:bg-slate-50 hover:text-slate-800 transition-colors focus:outline-none" title="Espandi/Comprimi Sidebar">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M4 6h16M4 12h12M4 18h16"/></svg>
|
||||
</button>
|
||||
<span class="text-xs text-slate-400 font-medium">Area di Lavoro</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="text-xs font-semibold text-slate-700 bg-slate-100 px-2.5 py-1 rounded-full">Demo Account</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- AREA DEL CONTENUTO DINAMICO -->
|
||||
<main class="flex-1 p-8 lg:p-10 max-w-[1400px] w-full mx-auto flex flex-col gap-8 overflow-y-auto">
|
||||
|
||||
<!-- INTESTAZIONE SEZIONE -->
|
||||
<div class="flex flex-col sm:flex-row justify-between sm:items-center gap-4">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-slate-900 tracking-tight">Clienti</h1>
|
||||
<p class="text-xs text-slate-400 mt-1">Monitora i rapporti finanziari e i dettagli dei clienti attivi</p>
|
||||
</div>
|
||||
|
||||
<!-- Pulsanti di azione -->
|
||||
<div class="flex items-center gap-4 self-start sm:self-auto">
|
||||
<button class="text-xs font-medium text-slate-500 hover:text-slate-900 transition-colors">
|
||||
Mostra archiviati
|
||||
</button>
|
||||
<button class="bg-brand-dark hover:bg-brand-darkHover text-white text-xs font-medium tracking-wide px-5 py-3 rounded-lg flex items-center gap-2 transition-all duration-200 shadow-sm">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
Nuovo cliente
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TABELLA CLIENTI -->
|
||||
<div class="bg-white rounded-xl border border-slate-100 shadow-[0_4px_20px_rgba(0,0,0,0.01)] overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead>
|
||||
<tr class="border-b border-slate-100/80 bg-slate-50/50 text-slate-400 text-[11px] font-semibold uppercase tracking-wider">
|
||||
<th class="py-4 px-6 w-1/4">Cliente</th>
|
||||
<th class="py-4 px-6 text-right">LTV</th>
|
||||
<th class="py-4 px-6 text-right">Importo Incassato</th>
|
||||
<th class="py-4 px-6 text-right">Importo da Saldare</th>
|
||||
<th class="py-4 px-6 text-right">Link Profilo</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100/60 text-sm">
|
||||
|
||||
<!-- Riga 1: George Vlad -->
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-4 px-6">
|
||||
<div class="font-semibold text-slate-950">George Vlad</div>
|
||||
<div class="text-[11px] text-slate-400 mt-0.5">Protocollo Estetico | Incarichi Online</div>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right font-medium text-slate-900">€7.000,00</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded text-xs font-semibold bg-emerald-50 text-emerald-700">
|
||||
€2.800,00
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right font-medium text-slate-600">€4.200,00</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<div class="inline-flex items-center gap-2 justify-end">
|
||||
<span class="text-xs font-mono text-slate-400 bg-slate-50 px-2 py-1 rounded border border-slate-100">/client/george-vlad-...</span>
|
||||
<button class="p-1 hover:bg-slate-100 rounded text-slate-400 hover:text-slate-700 transition-colors" title="Copia Link">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Riga 2: Gian Luca Caruso -->
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-4 px-6">
|
||||
<div class="font-semibold text-slate-950">Gian Luca Caruso</div>
|
||||
<div class="text-[11px] text-slate-400 mt-0.5">Caruso Speaker</div>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right font-medium text-slate-900">€5.000,00</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded text-xs font-semibold bg-emerald-50 text-emerald-700">
|
||||
€2.500,00
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right font-medium text-slate-600">€2.500,00</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<div class="inline-flex items-center gap-2 justify-end">
|
||||
<span class="text-xs font-mono text-slate-400 bg-slate-50 px-2 py-1 rounded border border-slate-100">/client/gian-luca-ca...</span>
|
||||
<button class="p-1 hover:bg-slate-100 rounded text-slate-400 hover:text-slate-700 transition-colors" title="Copia Link">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Riga 3: Gianfranco Barban -->
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-4 px-6">
|
||||
<div class="font-semibold text-slate-950">Gianfranco Barban</div>
|
||||
<div class="text-[11px] text-slate-400 mt-0.5">Teckell</div>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right font-medium text-slate-900">€200,00</td>
|
||||
<td class="py-4 px-6 text-right text-slate-300 font-medium">—</td>
|
||||
<td class="py-4 px-6 text-right text-slate-300 font-medium">—</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<div class="inline-flex items-center gap-2 justify-end">
|
||||
<span class="text-xs font-mono text-slate-400 bg-slate-50 px-2 py-1 rounded border border-slate-100">/client/gianfranco-b...</span>
|
||||
<button class="p-1 hover:bg-slate-100 rounded text-slate-400 hover:text-slate-700 transition-colors" title="Copia Link">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Riga 4: Mario Rossi -->
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-4 px-6">
|
||||
<div class="font-semibold text-slate-950">Mario Rossi</div>
|
||||
<div class="text-[11px] text-slate-400 mt-0.5">Rossi Inc</div>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right font-medium text-slate-900">€7.000,00</td>
|
||||
<td class="py-4 px-6 text-right text-slate-300 font-medium">—</td>
|
||||
<td class="py-4 px-6 text-right font-medium text-slate-600">€7.000,00</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<div class="inline-flex items-center gap-2 justify-end">
|
||||
<span class="text-xs font-mono text-slate-400 bg-slate-50 px-2 py-1 rounded border border-slate-100">/client/mario-rossi-...</span>
|
||||
<button class="p-1 hover:bg-slate-100 rounded text-slate-400 hover:text-slate-700 transition-colors" title="Copia Link">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Footer Tabella -->
|
||||
<div class="border-t border-slate-100 px-6 py-4 flex items-center justify-between text-xs text-slate-400">
|
||||
<span>Mostrando 4 di 4 clienti attivi</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- SCRIPT DI LOGICA (Gestione Sidebar) -->
|
||||
<script>
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const toggleButton = document.getElementById('sidebar-toggle');
|
||||
const logoText = document.getElementById('sidebar-logo-text');
|
||||
const sidebarTexts = document.querySelectorAll('.sidebar-text');
|
||||
|
||||
toggleButton.addEventListener('click', () => {
|
||||
const isCollapsed = sidebar.classList.contains('w-20');
|
||||
|
||||
if (isCollapsed) {
|
||||
sidebar.classList.remove('w-20');
|
||||
sidebar.classList.add('w-64');
|
||||
setTimeout(() => {
|
||||
logoText.classList.remove('opacity-0');
|
||||
sidebarTexts.forEach(text => text.classList.remove('opacity-0'));
|
||||
}, 150);
|
||||
} else {
|
||||
logoText.classList.add('opacity-0');
|
||||
sidebarTexts.forEach(text => text.classList.add('opacity-0'));
|
||||
sidebar.classList.remove('w-64');
|
||||
sidebar.classList.add('w-20');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,484 @@
|
||||
<!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>
|
||||
@@ -0,0 +1,405 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lead Pipeline — Luxury Redesign</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>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Plus Jakarta Sans', 'sans-serif'],
|
||||
},
|
||||
colors: {
|
||||
brand: {
|
||||
dark: '#1A463C', /* Verde scuro richiesto */
|
||||
darkHover: '#13342D', /* Variante scura per hover */
|
||||
active: 'rgba(255, 255, 255, 0.08)',
|
||||
bg: '#F8F9FA',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
/* Transizione fluida per l'apertura/chiusura della sidebar */
|
||||
.sidebar-transition {
|
||||
transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1), transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
/* Stile per l'effetto di trascinamento nel Kanban */
|
||||
.dragging {
|
||||
opacity: 0.5;
|
||||
transform: scale(0.98);
|
||||
}
|
||||
.drag-over {
|
||||
background-color: rgba(26, 70, 60, 0.03);
|
||||
border-color: rgba(26, 70, 60, 0.2);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-brand-bg font-sans text-slate-800 antialiased min-h-screen flex overflow-x-hidden">
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<aside id="sidebar" class="w-64 bg-brand-dark text-white flex flex-col justify-between p-6 border-r border-emerald-950/20 shrink-0 sidebar-transition relative z-10">
|
||||
<div class="overflow-hidden">
|
||||
<!-- Logo e Intestazione -->
|
||||
<div class="mb-10 px-2 flex items-center justify-between">
|
||||
<span id="sidebar-logo-text" class="text-lg font-bold tracking-wider text-emerald-50 whitespace-nowrap transition-opacity duration-300">iamcavalli</span>
|
||||
</div>
|
||||
|
||||
<!-- Navigazione Principale -->
|
||||
<nav class="space-y-1">
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M4 6a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H6a2 2 0 01-2-2v-4zM14 16a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2h-2a2 2 0 01-2-2v-4z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Dashboard</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-white bg-brand-active font-medium transition-all duration-200 shadow-sm">
|
||||
<svg class="w-4 h-4 shrink-0 text-emerald-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Lead</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Clienti</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Progetti</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Preventivi</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M7 7h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Offerte</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Area Inferiore Sidebar -->
|
||||
<div class="border-t border-white/10 pt-4 space-y-3 overflow-hidden">
|
||||
<div class="flex items-center justify-between px-3 py-1 text-xs text-emerald-200/50 whitespace-nowrap">
|
||||
<span class="sidebar-text transition-opacity duration-300">Tema</span>
|
||||
<button class="p-1 rounded-full bg-white/5 hover:bg-white/10 text-emerald-200 hover:text-white transition-all duration-200">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364-6.364l-.707.707M6.343 17.657l-.707.707m12.728 0l-.707-.707M6.343 6.343l-.707-.707M14 12a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2 rounded-lg text-sm text-red-300/80 hover:text-red-200 hover:bg-red-950/20 transition-all duration-200 whitespace-nowrap">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg>
|
||||
<span class="sidebar-text transition-opacity duration-300">Esci</span>
|
||||
</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- SEZIONE PRINCIPALE -->
|
||||
<div class="flex-1 flex flex-col min-w-0">
|
||||
|
||||
<!-- BARRA DI INTESTAZIONE SUPERIORE (Contiene i controlli globali) -->
|
||||
<header class="h-16 border-b border-slate-100 bg-white px-8 flex items-center justify-between shrink-0">
|
||||
<div class="flex items-center gap-4">
|
||||
<!-- Pulsante Minimal per Aprire/Chiudere la Sidebar -->
|
||||
<button id="sidebar-toggle" class="p-2 -ml-2 rounded-lg text-slate-500 hover:bg-slate-50 hover:text-slate-800 transition-colors focus:outline-none" title="Espandi/Comprimi Sidebar">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M4 6h16M4 12h12M4 18h16"/></svg>
|
||||
</button>
|
||||
<span class="text-xs text-slate-400 font-medium">Area di Lavoro</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="text-xs font-semibold text-slate-700 bg-slate-100 px-2.5 py-1 rounded-full">Demo Account</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- AREA DEL CONTENUTO DINAMICO -->
|
||||
<main class="flex-1 p-8 lg:p-10 max-w-[1400px] w-full mx-auto flex flex-col gap-8 overflow-y-auto">
|
||||
|
||||
<!-- INTESTAZIONE SEZIONE -->
|
||||
<div class="flex flex-col sm:flex-row justify-between sm:items-center gap-4">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-slate-900 tracking-tight">Lead Pipeline</h1>
|
||||
<p class="text-xs text-slate-400 mt-1">Gestisci e monitora i tuoi contatti commerciali</p>
|
||||
</div>
|
||||
|
||||
<!-- Pulsante Nuovo Lead -->
|
||||
<button class="bg-brand-dark hover:bg-brand-darkHover text-white text-xs font-medium tracking-wide px-5 py-3 rounded-lg flex items-center gap-2 transition-all duration-200 shadow-sm self-start sm:self-auto">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
Nuovo Lead
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- AZIONI: BARRA DI RICERCA & SELETTORE VISTA -->
|
||||
<div class="flex flex-col md:flex-row justify-between md:items-center gap-4">
|
||||
<!-- Barra di ricerca -->
|
||||
<div class="relative w-full md:w-80">
|
||||
<span class="absolute inset-y-0 left-0 flex items-center pl-3.5 pointer-events-none text-slate-400">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Cerca lead..."
|
||||
class="w-full pl-10 pr-4 py-2.5 bg-white text-sm text-slate-800 placeholder-slate-400 border border-slate-200/80 rounded-lg focus:outline-none focus:border-brand-dark focus:ring-1 focus:ring-brand-dark transition-all duration-200"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Selettore Vista (Lista vs Kanban) -->
|
||||
<div class="bg-slate-200/50 p-1 rounded-lg flex gap-1 self-start md:self-auto">
|
||||
<button id="btn-view-list" class="px-5 py-1.5 rounded-md text-xs font-medium bg-white text-slate-800 shadow-sm transition-all duration-200">
|
||||
Lista
|
||||
</button>
|
||||
<button id="btn-view-kanban" class="px-5 py-1.5 rounded-md text-xs font-medium text-slate-500 hover:text-slate-800 transition-all duration-200">
|
||||
Kanban
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- VISTA 1: TABELLA (Default) -->
|
||||
<div id="view-list" class="bg-white rounded-xl border border-slate-100 shadow-[0_4px_20px_rgba(0,0,0,0.01)] overflow-hidden transition-opacity duration-300">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead>
|
||||
<tr class="border-b border-slate-100/80 bg-slate-50/50 text-slate-400 text-[11px] font-semibold uppercase tracking-wider">
|
||||
<th class="py-4 px-6">Nome</th>
|
||||
<th class="py-4 px-6">Email</th>
|
||||
<th class="py-4 px-6">Telefono</th>
|
||||
<th class="py-4 px-6">Azienda</th>
|
||||
<th class="py-4 px-6 text-center">Stato</th>
|
||||
<th class="py-4 px-6">Prossima Azione</th>
|
||||
<th class="py-4 px-6 text-center">Tag</th>
|
||||
<th class="py-4 px-6 text-right">Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100/60 text-sm">
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-4 px-6 font-medium text-slate-900">Nome Cognome</td>
|
||||
<td class="py-4 px-6 text-slate-500 text-xs">test@gmail.com</td>
|
||||
<td class="py-4 px-6 text-slate-500 text-xs font-mono">+39 444 3322111</td>
|
||||
<td class="py-4 px-6 text-slate-600">Azienda Srl</td>
|
||||
<td class="py-4 px-6 text-center">
|
||||
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-[10px] font-semibold tracking-wide bg-purple-50 text-purple-600 border border-purple-100 uppercase">
|
||||
qualified
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-slate-400">—</td>
|
||||
<td class="py-4 px-6 text-center">
|
||||
<button class="inline-flex items-center justify-center w-6 h-6 rounded-full border border-dashed border-slate-200 text-slate-400 hover:text-slate-600 hover:border-slate-400 transition-all duration-200">
|
||||
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
</button>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<a href="#" class="text-xs font-medium text-brand-dark hover:text-brand-darkHover inline-flex items-center gap-1 group transition-colors">
|
||||
Dettagli
|
||||
<svg class="w-3 h-3 transform group-hover:translate-x-0.5 transition-transform" fill="none" stroke="currentColor" stroke-width="2.2" viewBox="0 0 24 24"><path d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="border-t border-slate-100 px-6 py-4 flex items-center justify-between text-xs text-slate-400">
|
||||
<span>Mostrando 1 di 1 lead</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- VISTA 2: KANBAN (Nascosta all'avvio) -->
|
||||
<div id="view-kanban" class="hidden grid grid-cols-1 md:grid-cols-4 gap-6 transition-opacity duration-300">
|
||||
|
||||
<!-- Colonna 1: Nuovo -->
|
||||
<div class="kanban-column bg-slate-50/75 rounded-xl border border-slate-100 p-4 flex flex-col gap-4 min-h-[450px]" data-status="new">
|
||||
<div class="flex items-center justify-between border-b border-slate-100 pb-2">
|
||||
<span class="text-xs font-semibold uppercase tracking-wider text-slate-500">Nuovo</span>
|
||||
<span class="text-xs font-medium bg-slate-200/60 text-slate-600 px-2 py-0.5 rounded-full count">0</span>
|
||||
</div>
|
||||
<div class="cards-container flex-1 flex flex-col gap-3">
|
||||
<!-- Esempio di lead spostabile -->
|
||||
<div id="lead-card-2" class="kanban-card bg-white p-4 rounded-lg border border-slate-200/80 shadow-sm cursor-grab active:cursor-grabbing hover:border-brand-dark/30 hover:shadow-md transition-all duration-200" draggable="true">
|
||||
<div class="flex justify-between items-start gap-2 mb-2">
|
||||
<h4 class="text-xs font-semibold text-slate-800">Marco Rossi</h4>
|
||||
<span class="text-[9px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-100 px-1.5 py-0.5 rounded uppercase">New</span>
|
||||
</div>
|
||||
<p class="text-[11px] text-slate-400 mb-3">rossi@azienda.it</p>
|
||||
<div class="flex justify-between items-center text-[10px] text-slate-500">
|
||||
<span class="font-medium">Rossi Consulting</span>
|
||||
<span>Tag +</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Colonna 2: Contattato -->
|
||||
<div class="kanban-column bg-slate-50/75 rounded-xl border border-slate-100 p-4 flex flex-col gap-4 min-h-[450px]" data-status="contacted">
|
||||
<div class="flex items-center justify-between border-b border-slate-100 pb-2">
|
||||
<span class="text-xs font-semibold uppercase tracking-wider text-slate-500">Contattato</span>
|
||||
<span class="text-xs font-medium bg-slate-200/60 text-slate-600 px-2 py-0.5 rounded-full count">0</span>
|
||||
</div>
|
||||
<div class="cards-container flex-1 flex flex-col gap-3"></div>
|
||||
</div>
|
||||
|
||||
<!-- Colonna 3: Qualificato -->
|
||||
<div class="kanban-column bg-slate-50/75 rounded-xl border border-slate-100 p-4 flex flex-col gap-4 min-h-[450px]" data-status="qualified">
|
||||
<div class="flex items-center justify-between border-b border-slate-100 pb-2">
|
||||
<span class="text-xs font-semibold uppercase tracking-wider text-slate-500">Qualificato</span>
|
||||
<span class="text-xs font-medium bg-slate-200/60 text-slate-600 px-2 py-0.5 rounded-full count">1</span>
|
||||
</div>
|
||||
<div class="cards-container flex-1 flex flex-col gap-3">
|
||||
|
||||
<!-- Lead proveniente dalla lista originale -->
|
||||
<div id="lead-card-1" class="kanban-card bg-white p-4 rounded-lg border border-slate-200/80 shadow-sm cursor-grab active:cursor-grabbing hover:border-brand-dark/30 hover:shadow-md transition-all duration-200" draggable="true">
|
||||
<div class="flex justify-between items-start gap-2 mb-2">
|
||||
<h4 class="text-xs font-semibold text-slate-800">Nome Cognome</h4>
|
||||
<span class="text-[9px] font-semibold bg-purple-50 text-purple-600 border border-purple-100 px-1.5 py-0.5 rounded uppercase">Qualified</span>
|
||||
</div>
|
||||
<p class="text-[11px] text-slate-400 mb-3">test@gmail.com</p>
|
||||
<div class="flex justify-between items-center text-[10px] text-slate-500">
|
||||
<span class="font-medium">Azienda Srl</span>
|
||||
<span>Tag +</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Colonna 4: In Trattativa -->
|
||||
<div class="kanban-column bg-slate-50/75 rounded-xl border border-slate-100 p-4 flex flex-col gap-4 min-h-[450px]" data-status="negotiation">
|
||||
<div class="flex items-center justify-between border-b border-slate-100 pb-2">
|
||||
<span class="text-xs font-semibold uppercase tracking-wider text-slate-500">Trattativa</span>
|
||||
<span class="text-xs font-medium bg-slate-200/60 text-slate-600 px-2 py-0.5 rounded-full count">0</span>
|
||||
</div>
|
||||
<div class="cards-container flex-1 flex flex-col gap-3"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- SCRIPT LOGICA (Gestione Sidebar e Kanban) -->
|
||||
<script>
|
||||
// --- GESTIONE SIDEBAR COLLASSABILE ---
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const toggleButton = document.getElementById('sidebar-toggle');
|
||||
const logoText = document.getElementById('sidebar-logo-text');
|
||||
const sidebarTexts = document.querySelectorAll('.sidebar-text');
|
||||
|
||||
toggleButton.addEventListener('click', () => {
|
||||
// Verifica lo stato attuale
|
||||
const isCollapsed = sidebar.classList.contains('w-20');
|
||||
|
||||
if (isCollapsed) {
|
||||
// Espandi
|
||||
sidebar.classList.remove('w-20');
|
||||
sidebar.classList.add('w-64');
|
||||
setTimeout(() => {
|
||||
logoText.classList.remove('opacity-0');
|
||||
sidebarTexts.forEach(text => text.classList.remove('opacity-0'));
|
||||
}, 150);
|
||||
} else {
|
||||
// Collassa
|
||||
logoText.classList.add('opacity-0');
|
||||
sidebarTexts.forEach(text => text.classList.add('opacity-0'));
|
||||
sidebar.classList.remove('w-64');
|
||||
sidebar.classList.add('w-20');
|
||||
}
|
||||
});
|
||||
|
||||
// --- INTERRUTTORE DI VISTA (LISTA / KANBAN) ---
|
||||
const btnViewList = document.getElementById('btn-view-list');
|
||||
const btnViewKanban = document.getElementById('btn-view-kanban');
|
||||
const viewList = document.getElementById('view-list');
|
||||
const viewKanban = document.getElementById('view-kanban');
|
||||
|
||||
btnViewList.addEventListener('click', () => {
|
||||
// Attiva vista Lista
|
||||
viewKanban.classList.add('hidden');
|
||||
viewList.classList.remove('hidden');
|
||||
|
||||
// Regola stili pulsanti
|
||||
btnViewList.className = "px-5 py-1.5 rounded-md text-xs font-medium bg-white text-slate-800 shadow-sm transition-all duration-200";
|
||||
btnViewKanban.className = "px-5 py-1.5 rounded-md text-xs font-medium text-slate-500 hover:text-slate-800 transition-all duration-200";
|
||||
});
|
||||
|
||||
btnViewKanban.addEventListener('click', () => {
|
||||
// Attiva vista Kanban
|
||||
viewList.classList.add('hidden');
|
||||
viewKanban.classList.remove('hidden');
|
||||
|
||||
// Regola stili pulsanti
|
||||
btnViewKanban.className = "px-5 py-1.5 rounded-md text-xs font-medium bg-white text-slate-800 shadow-sm transition-all duration-200";
|
||||
btnViewList.className = "px-5 py-1.5 rounded-md text-xs font-medium text-slate-500 hover:text-slate-800 transition-all duration-200";
|
||||
});
|
||||
|
||||
// --- FUNZIONALITÀ DRAG AND DROP KANBAN ---
|
||||
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');
|
||||
updateColumnCounts();
|
||||
});
|
||||
});
|
||||
|
||||
columns.forEach(column => {
|
||||
const container = column.querySelector('.cards-container');
|
||||
|
||||
column.addEventListener('dragover', (e) => {
|
||||
e.preventDefault();
|
||||
column.classList.add('drag-over');
|
||||
});
|
||||
|
||||
column.addEventListener('dragleave', () => {
|
||||
column.classList.remove('drag-over');
|
||||
});
|
||||
|
||||
column.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
column.classList.remove('drag-over');
|
||||
|
||||
const draggingCard = document.querySelector('.dragging');
|
||||
if (draggingCard) {
|
||||
container.appendChild(draggingCard);
|
||||
|
||||
// Cambia visivamente il badge interno dello stato in base alla destinazione
|
||||
const badge = draggingCard.querySelector('span');
|
||||
const status = column.getAttribute('data-status');
|
||||
|
||||
if (status === 'new') {
|
||||
badge.innerText = 'New';
|
||||
badge.className = 'text-[9px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-100 px-1.5 py-0.5 rounded uppercase';
|
||||
} else if (status === 'contacted') {
|
||||
badge.innerText = 'Contacted';
|
||||
badge.className = 'text-[9px] font-semibold bg-blue-50 text-blue-600 border border-blue-100 px-1.5 py-0.5 rounded uppercase';
|
||||
} else if (status === 'qualified') {
|
||||
badge.innerText = 'Qualified';
|
||||
badge.className = 'text-[9px] font-semibold bg-purple-50 text-purple-600 border border-purple-100 px-1.5 py-0.5 rounded uppercase';
|
||||
} else if (status === 'negotiation') {
|
||||
badge.innerText = 'In Trattativa';
|
||||
badge.className = 'text-[9px] font-semibold bg-amber-50 text-amber-600 border border-amber-100 px-1.5 py-0.5 rounded uppercase';
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Funzione d'appoggio per aggiornare il conteggio numerico nelle colonne
|
||||
function updateColumnCounts() {
|
||||
columns.forEach(column => {
|
||||
const countBadge = column.querySelector('.count');
|
||||
const cardCount = column.querySelector('.cards-container').children.length;
|
||||
countBadge.innerText = cardCount;
|
||||
});
|
||||
}
|
||||
|
||||
// Esegui inizialmente per impostare i corretti conteggi
|
||||
updateColumnCounts();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,366 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Offerte — Luxury Admin CRM</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>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Plus Jakarta Sans', 'sans-serif'],
|
||||
},
|
||||
colors: {
|
||||
brand: {
|
||||
dark: '#1A463C', /* Verde scuro richiesto */
|
||||
darkHover: '#13342D', /* Variante scura per hover */
|
||||
active: 'rgba(255, 255, 255, 0.08)',
|
||||
bg: '#F8F9FA',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.sidebar-transition {
|
||||
transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1), transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-brand-bg font-sans text-slate-800 antialiased min-h-screen flex overflow-x-hidden">
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<aside id="sidebar" class="w-64 bg-brand-dark text-white flex flex-col justify-between p-6 border-r border-emerald-950/20 shrink-0 sidebar-transition relative z-10">
|
||||
<div class="overflow-hidden">
|
||||
<!-- Logo e Intestazione -->
|
||||
<div class="mb-10 px-2 flex items-center justify-between">
|
||||
<span id="sidebar-logo-text" class="text-lg font-bold tracking-wider text-emerald-50 whitespace-nowrap transition-opacity duration-300">iamcavalli</span>
|
||||
</div>
|
||||
|
||||
<!-- Navigazione Principale -->
|
||||
<nav class="space-y-1">
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M4 6a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H6a2 2 0 01-2-2v-4zM14 16a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2h-2a2 2 0 01-2-2v-4z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Dashboard</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Lead</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0 text-emerald-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Clienti</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Progetti</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0 text-emerald-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Preventivi</span>
|
||||
</a>
|
||||
<!-- Stato Attivo su Offerte -->
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-white bg-brand-active font-medium transition-all duration-200 shadow-sm">
|
||||
<svg class="w-4 h-4 shrink-0 text-emerald-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M7 7h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Offerte</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Area Inferiore Sidebar -->
|
||||
<div class="border-t border-white/10 pt-4 space-y-3 overflow-hidden">
|
||||
<div class="flex items-center justify-between px-3 py-1 text-xs text-emerald-200/50 whitespace-nowrap">
|
||||
<span class="sidebar-text transition-opacity duration-300">Tema</span>
|
||||
<button class="p-1 rounded-full bg-white/5 hover:bg-white/10 text-emerald-200 hover:text-white transition-all duration-200">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364-6.364l-.707.707M6.343 17.657l-.707.707m12.728 0l-.707-.707M6.343 6.343l-.707-.707M14 12a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2 rounded-lg text-sm text-red-300/80 hover:text-red-200 hover:bg-red-950/20 transition-all duration-200 whitespace-nowrap">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg>
|
||||
<span class="sidebar-text transition-opacity duration-300">Esci</span>
|
||||
</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- SEZIONE PRINCIPALE -->
|
||||
<div class="flex-1 flex flex-col min-w-0">
|
||||
|
||||
<!-- BARRA DI INTESTAZIONE SUPERIORE -->
|
||||
<header class="h-16 border-b border-slate-100 bg-white px-8 flex items-center justify-between shrink-0">
|
||||
<div class="flex items-center gap-4">
|
||||
<!-- Pulsante Apri/Chiudi Sidebar -->
|
||||
<button id="sidebar-toggle" class="p-2 -ml-2 rounded-lg text-slate-500 hover:bg-slate-50 hover:text-slate-800 transition-colors focus:outline-none" title="Espandi/Comprimi Sidebar">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M4 6h16M4 12h12M4 18h16"/></svg>
|
||||
</button>
|
||||
<span class="text-xs text-slate-400 font-medium">Area di Lavoro</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="text-xs font-semibold text-slate-700 bg-slate-100 px-2.5 py-1 rounded-full">Demo Account</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- AREA DEL CONTENUTO -->
|
||||
<main class="flex-1 p-8 lg:p-10 max-w-[1400px] w-full mx-auto flex flex-col gap-8 overflow-y-auto">
|
||||
|
||||
<!-- INTESTAZIONE SEZIONE -->
|
||||
<div class="flex flex-col sm:flex-row justify-between sm:items-center gap-4">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-slate-900 tracking-tight">Offerte</h1>
|
||||
<p class="text-xs text-slate-400 mt-1">Configura e gestisci i pacchetti di offerta commerciali</p>
|
||||
</div>
|
||||
|
||||
<!-- Bottone Nuova Offerta -->
|
||||
<button class="bg-brand-dark hover:bg-brand-darkHover text-white text-xs font-medium tracking-wide px-5 py-3 rounded-lg flex items-center gap-2 transition-all duration-200 shadow-sm self-start sm:self-auto">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
Nuova Offerta
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- BARRA FILTRI -->
|
||||
<div class="flex flex-col lg:flex-row justify-between lg:items-center gap-4">
|
||||
<!-- Selettori Categorie di Offerta -->
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<button class="px-4 py-2 text-xs font-medium bg-brand-dark text-white rounded-lg transition-colors">
|
||||
Tutti
|
||||
</button>
|
||||
<button class="px-4 py-2 text-xs font-medium bg-white text-slate-600 hover:text-slate-900 hover:bg-slate-100/70 border border-slate-200/60 rounded-lg transition-all duration-200">
|
||||
Entry Offer
|
||||
</button>
|
||||
<button class="px-4 py-2 text-xs font-medium bg-white text-slate-600 hover:text-slate-900 hover:bg-slate-100/70 border border-slate-200/60 rounded-lg transition-all duration-200">
|
||||
Retainer Offer
|
||||
</button>
|
||||
<button class="px-4 py-2 text-xs font-medium bg-white text-slate-600 hover:text-slate-900 hover:bg-slate-100/70 border border-slate-200/60 rounded-lg transition-all duration-200">
|
||||
Signature Offer
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Checkbox Opzione Archiviati -->
|
||||
<label class="flex items-center gap-2.5 cursor-pointer group text-xs text-slate-500 hover:text-slate-800 transition-colors">
|
||||
<input type="checkbox" class="w-4 h-4 rounded text-brand-dark border-slate-300 focus:ring-brand-dark focus:ring-opacity-25 transition-all" />
|
||||
<span class="select-none font-medium">Mostra offerte archiviate</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- GRID CARDS DELLE OFFERTE -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
|
||||
<!-- Card 1: Mantenimento -->
|
||||
<div class="bg-white p-6 rounded-xl border border-slate-100 shadow-[0_4px_20px_rgba(0,0,0,0.01)] hover:shadow-[0_8px_30px_rgba(0,0,0,0.02)] transition-all duration-200 flex flex-col justify-between">
|
||||
<div>
|
||||
<div class="flex justify-between items-start gap-4 mb-4">
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-slate-900">Mantenimento</h3>
|
||||
<p class="text-[11px] text-slate-400 mt-0.5">(nei clienti già attivi)</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 rounded text-[9px] font-semibold bg-blue-50 text-blue-600 border border-blue-100 uppercase tracking-wider">
|
||||
Retainer Offer
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Listino Tabellare Opzioni -->
|
||||
<div class="border border-slate-100 rounded-lg overflow-hidden my-6">
|
||||
<table class="w-full text-[11px]">
|
||||
<thead>
|
||||
<tr class="bg-slate-50 border-b border-slate-100 text-slate-400 font-semibold uppercase">
|
||||
<th class="py-2 px-3 text-left">Tier</th>
|
||||
<th class="py-2 px-3 text-right">Servizi</th>
|
||||
<th class="py-2 px-3 text-right">Pubblico</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100 text-slate-600 font-mono">
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">A</td>
|
||||
<td class="py-2 px-3 text-right">€200,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€200,00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">B</td>
|
||||
<td class="py-2 px-3 text-right">€300,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€300,00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">C</td>
|
||||
<td class="py-2 px-3 text-right">€400,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€400,00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card 2: Sblocca Business -->
|
||||
<div class="bg-white p-6 rounded-xl border border-slate-100 shadow-[0_4px_20px_rgba(0,0,0,0.01)] hover:shadow-[0_8px_30px_rgba(0,0,0,0.02)] transition-all duration-200 flex flex-col justify-between">
|
||||
<div>
|
||||
<div class="flex justify-between items-start gap-4 mb-4">
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-slate-900">Sblocca Business</h3>
|
||||
<p class="text-[11px] text-slate-400 mt-0.5">Avviamento strategico</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 rounded text-[9px] font-semibold bg-purple-50 text-purple-600 border border-purple-100 uppercase tracking-wider">
|
||||
Entry Offer
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Listino Tabellare Opzioni -->
|
||||
<div class="border border-slate-100 rounded-lg overflow-hidden my-6">
|
||||
<table class="w-full text-[11px]">
|
||||
<thead>
|
||||
<tr class="bg-slate-50 border-b border-slate-100 text-slate-400 font-semibold uppercase">
|
||||
<th class="py-2 px-3 text-left">Tier</th>
|
||||
<th class="py-2 px-3 text-right">Servizi</th>
|
||||
<th class="py-2 px-3 text-right">Pubblico</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100 text-slate-600 font-mono">
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">A</td>
|
||||
<td class="py-2 px-3 text-right">€2.600,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€400,00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">B</td>
|
||||
<td class="py-2 px-3 text-right">€3.300,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€600,00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">C</td>
|
||||
<td class="py-2 px-3 text-right">€3.900,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€1.200,00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card 3: Web Domination -->
|
||||
<div class="bg-white p-6 rounded-xl border border-slate-100 shadow-[0_4px_20px_rgba(0,0,0,0.01)] hover:shadow-[0_8px_30px_rgba(0,0,0,0.02)] transition-all duration-200 flex flex-col justify-between">
|
||||
<div>
|
||||
<div class="flex justify-between items-start gap-4 mb-4">
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-slate-900">Web Domination</h3>
|
||||
<p class="text-[11px] text-slate-400 mt-0.5">Soluzione enterprise omnicanale</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 rounded text-[9px] font-semibold bg-amber-50 text-amber-700 border border-amber-100 uppercase tracking-wider">
|
||||
Signature Offer
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Listino Tabellare Opzioni -->
|
||||
<div class="border border-slate-100 rounded-lg overflow-hidden my-6">
|
||||
<table class="w-full text-[11px]">
|
||||
<thead>
|
||||
<tr class="bg-slate-50 border-b border-slate-100 text-slate-400 font-semibold uppercase">
|
||||
<th class="py-2 px-3 text-left">Tier</th>
|
||||
<th class="py-2 px-3 text-right">Servizi</th>
|
||||
<th class="py-2 px-3 text-right">Pubblico</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100 text-slate-600 font-mono">
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">A</td>
|
||||
<td class="py-2 px-3 text-right">€9.800,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€6.000,00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">B</td>
|
||||
<td class="py-2 px-3 text-right">€20.250,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€9.000,00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">C</td>
|
||||
<td class="py-2 px-3 text-right">€25.250,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€12.000,00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card 4: Business in Banca -->
|
||||
<div class="bg-white p-6 rounded-xl border border-slate-100 shadow-[0_4px_20px_rgba(0,0,0,0.01)] hover:shadow-[0_8px_30px_rgba(0,0,0,0.02)] transition-all duration-200 flex flex-col justify-between">
|
||||
<div>
|
||||
<div class="flex justify-between items-start gap-4 mb-4">
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-slate-900">Business in Banca</h3>
|
||||
<p class="text-[11px] text-slate-400 mt-0.5">Controllo tesoreria integrato</p>
|
||||
</div>
|
||||
<span class="px-2 py-1 rounded text-[9px] font-semibold bg-blue-50 text-blue-600 border border-blue-100 uppercase tracking-wider">
|
||||
Retainer Offer
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Listino Tabellare Opzioni -->
|
||||
<div class="border border-slate-100 rounded-lg overflow-hidden my-6">
|
||||
<table class="w-full text-[11px]">
|
||||
<thead>
|
||||
<tr class="bg-slate-50 border-b border-slate-100 text-slate-400 font-semibold uppercase">
|
||||
<th class="py-2 px-3 text-left">Tier</th>
|
||||
<th class="py-2 px-3 text-right">Servizi</th>
|
||||
<th class="py-2 px-3 text-right">Pubblico</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100 text-slate-600 font-mono">
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">A</td>
|
||||
<td class="py-2 px-3 text-right">€200,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€200,00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">B</td>
|
||||
<td class="py-2 px-3 text-right">€400,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€300,00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="py-2 px-3 font-semibold text-slate-800">C</td>
|
||||
<td class="py-2 px-3 text-right">€900,00</td>
|
||||
<td class="py-2 px-3 text-right text-slate-400">€500,00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- SCRIPT DI LOGICA (Gestione Sidebar) -->
|
||||
<script>
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const toggleButton = document.getElementById('sidebar-toggle');
|
||||
const logoText = document.getElementById('sidebar-logo-text');
|
||||
const sidebarTexts = document.querySelectorAll('.sidebar-text');
|
||||
|
||||
toggleButton.addEventListener('click', () => {
|
||||
const isCollapsed = sidebar.classList.contains('w-20');
|
||||
|
||||
if (isCollapsed) {
|
||||
sidebar.classList.remove('w-20');
|
||||
sidebar.classList.add('w-64');
|
||||
setTimeout(() => {
|
||||
logoText.classList.remove('opacity-0');
|
||||
sidebarTexts.forEach(text => text.classList.remove('opacity-0'));
|
||||
}, 150);
|
||||
} else {
|
||||
logoText.classList.add('opacity-0');
|
||||
sidebarTexts.forEach(text => text.classList.add('opacity-0'));
|
||||
sidebar.classList.remove('w-64');
|
||||
sidebar.classList.add('w-20');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,238 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Preventivi — Luxury Admin CRM</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>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Plus Jakarta Sans', 'sans-serif'],
|
||||
},
|
||||
colors: {
|
||||
brand: {
|
||||
dark: '#1A463C', /* Verde scuro richiesto */
|
||||
darkHover: '#13342D', /* Variante scura per hover */
|
||||
active: 'rgba(255, 255, 255, 0.08)',
|
||||
bg: '#F8F9FA',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.sidebar-transition {
|
||||
transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1), transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-brand-bg font-sans text-slate-800 antialiased min-h-screen flex overflow-x-hidden">
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<aside id="sidebar" class="w-64 bg-brand-dark text-white flex flex-col justify-between p-6 border-r border-emerald-950/20 shrink-0 sidebar-transition relative z-10">
|
||||
<div class="overflow-hidden">
|
||||
<!-- Logo e Intestazione -->
|
||||
<div class="mb-10 px-2 flex items-center justify-between">
|
||||
<span id="sidebar-logo-text" class="text-lg font-bold tracking-wider text-emerald-50 whitespace-nowrap transition-opacity duration-300">iamcavalli</span>
|
||||
</div>
|
||||
|
||||
<!-- Navigazione Principale -->
|
||||
<nav class="space-y-1">
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M4 6a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2H6a2 2 0 01-2-2v-4zM14 16a2 2 0 012-2h2a2 2 0 012 2v4a2 2 0 01-2 2h-2a2 2 0 01-2-2v-4z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Dashboard</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Lead</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0 text-emerald-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Clienti</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Progetti</span>
|
||||
</a>
|
||||
<!-- Stato Attivo su Preventivi -->
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-white bg-brand-active font-medium transition-all duration-200 shadow-sm">
|
||||
<svg class="w-4 h-4 shrink-0 text-emerald-400" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Preventivi</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-emerald-200/70 hover:text-white hover:bg-white/5 transition-all duration-200">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M7 7h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
||||
<span class="sidebar-text whitespace-nowrap transition-opacity duration-300">Offerte</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Area Inferiore Sidebar -->
|
||||
<div class="border-t border-white/10 pt-4 space-y-3 overflow-hidden">
|
||||
<div class="flex items-center justify-between px-3 py-1 text-xs text-emerald-200/50 whitespace-nowrap">
|
||||
<span class="sidebar-text transition-opacity duration-300">Tema</span>
|
||||
<button class="p-1 rounded-full bg-white/5 hover:bg-white/10 text-emerald-200 hover:text-white transition-all duration-200">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364-6.364l-.707.707M6.343 17.657l-.707.707m12.728 0l-.707-.707M6.343 6.343l-.707-.707M14 12a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<a href="#" class="flex items-center gap-3 px-3 py-2 rounded-lg text-sm text-red-300/80 hover:text-red-200 hover:bg-red-950/20 transition-all duration-200 whitespace-nowrap">
|
||||
<svg class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" stroke-width="1.8" viewBox="0 0 24 24"><path d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg>
|
||||
<span class="sidebar-text transition-opacity duration-300">Esci</span>
|
||||
</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- SEZIONE PRINCIPALE -->
|
||||
<div class="flex-1 flex flex-col min-w-0">
|
||||
|
||||
<!-- BARRA DI INTESTAZIONE SUPERIORE -->
|
||||
<header class="h-16 border-b border-slate-100 bg-white px-8 flex items-center justify-between shrink-0">
|
||||
<div class="flex items-center gap-4">
|
||||
<!-- Pulsante Apri/Chiudi Sidebar -->
|
||||
<button id="sidebar-toggle" class="p-2 -ml-2 rounded-lg text-slate-500 hover:bg-slate-50 hover:text-slate-800 transition-colors focus:outline-none" title="Espandi/Comprimi Sidebar">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M4 6h16M4 12h12M4 18h16"/></svg>
|
||||
</button>
|
||||
<span class="text-xs text-slate-400 font-medium">Area di Lavoro</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="text-xs font-semibold text-slate-700 bg-slate-100 px-2.5 py-1 rounded-full">Demo Account</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- AREA DEL CONTENUTO -->
|
||||
<main class="flex-1 p-8 lg:p-10 max-w-[1400px] w-full mx-auto flex flex-col gap-8 overflow-y-auto">
|
||||
|
||||
<!-- INTESTAZIONE SEZIONE -->
|
||||
<div class="flex flex-col sm:flex-row justify-between sm:items-start gap-4">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-slate-900 tracking-tight">Preventivi</h1>
|
||||
<p class="text-xs text-slate-400 mt-1">Preventivi generati con AI e pubblicati ai clienti</p>
|
||||
</div>
|
||||
|
||||
<!-- Pulsante Genera -->
|
||||
<button class="bg-brand-dark hover:bg-brand-darkHover text-white text-xs font-medium tracking-wide px-5 py-3 rounded-lg flex items-center gap-2 transition-all duration-200 shadow-sm self-start sm:self-auto">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
Genera preventivo
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- TABELLA PREVENTIVI -->
|
||||
<div class="bg-white rounded-xl border border-slate-100 shadow-[0_4px_20px_rgba(0,0,0,0.01)] overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead>
|
||||
<tr class="border-b border-slate-100/80 bg-slate-50/50 text-slate-400 text-[11px] font-semibold uppercase tracking-wider">
|
||||
<th class="py-4 px-6 w-1/3">Titolo</th>
|
||||
<th class="py-4 px-6">Lead / Cliente</th>
|
||||
<th class="py-4 px-6">Offerta</th>
|
||||
<th class="py-4 px-6 text-center">Stato</th>
|
||||
<th class="py-4 px-6">Data</th>
|
||||
<th class="py-4 px-6 text-right">Azione</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100/60 text-sm">
|
||||
|
||||
<!-- Riga 1: Pubblicato -->
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-4 px-6 font-semibold text-slate-900">
|
||||
Rossi Inc × Entry Offer
|
||||
</td>
|
||||
<td class="py-4 px-6 text-slate-600">
|
||||
Mario Rossi
|
||||
</td>
|
||||
<td class="py-4 px-6 text-slate-500 font-medium">
|
||||
Entry Offer
|
||||
</td>
|
||||
<td class="py-4 px-6 text-center">
|
||||
<!-- Badge Stato: Pubblicato -->
|
||||
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-[10px] font-semibold tracking-wide bg-sky-50 text-sky-700 border border-sky-100 uppercase">
|
||||
Pubblicato
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-slate-500 text-xs font-mono">
|
||||
26/06/2026
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<a href="#" class="text-xs font-medium text-brand-dark hover:text-brand-darkHover inline-flex items-center gap-1.5 group transition-colors">
|
||||
Apri
|
||||
<svg class="w-3.5 h-3.5 transform group-hover:translate-x-0.5 transition-transform" fill="none" stroke="currentColor" stroke-width="2.2" viewBox="0 0 24 24"><path d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3"/></svg>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Riga 2: Accettato -->
|
||||
<tr class="hover:bg-slate-50/30 transition-all duration-150">
|
||||
<td class="py-4 px-6 font-semibold text-slate-900">
|
||||
Rossi Inc × Entry Offer
|
||||
</td>
|
||||
<td class="py-4 px-6 text-slate-600">
|
||||
Mario Rossi
|
||||
</td>
|
||||
<td class="py-4 px-6 text-slate-500 font-medium">
|
||||
Entry Offer
|
||||
</td>
|
||||
<td class="py-4 px-6 text-center">
|
||||
<!-- Badge Stato: Accettato -->
|
||||
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-[10px] font-semibold tracking-wide bg-emerald-50 text-emerald-700 border border-emerald-100 uppercase">
|
||||
Accettato
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-4 px-6 text-slate-500 text-xs font-mono">
|
||||
20/06/2026
|
||||
</td>
|
||||
<td class="py-4 px-6 text-right">
|
||||
<a href="#" class="text-xs font-medium text-brand-dark hover:text-brand-darkHover inline-flex items-center gap-1.5 group transition-colors">
|
||||
Apri
|
||||
<svg class="w-3.5 h-3.5 transform group-hover:translate-x-0.5 transition-transform" fill="none" stroke="currentColor" stroke-width="2.2" viewBox="0 0 24 24"><path d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3"/></svg>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Footer Tabella -->
|
||||
<div class="border-t border-slate-100 px-6 py-4 flex items-center justify-between text-xs text-slate-400">
|
||||
<span>Mostrando 2 di 2 preventivi generati</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- SCRIPT DI LOGICA (Gestione Sidebar) -->
|
||||
<script>
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const toggleButton = document.getElementById('sidebar-toggle');
|
||||
const logoText = document.getElementById('sidebar-logo-text');
|
||||
const sidebarTexts = document.querySelectorAll('.sidebar-text');
|
||||
|
||||
toggleButton.addEventListener('click', () => {
|
||||
const isCollapsed = sidebar.classList.contains('w-20');
|
||||
|
||||
if (isCollapsed) {
|
||||
sidebar.classList.remove('w-20');
|
||||
sidebar.classList.add('w-64');
|
||||
setTimeout(() => {
|
||||
logoText.classList.remove('opacity-0');
|
||||
sidebarTexts.forEach(text => text.classList.remove('opacity-0'));
|
||||
}, 150);
|
||||
} else {
|
||||
logoText.classList.add('opacity-0');
|
||||
sidebarTexts.forEach(text => text.classList.add('opacity-0'));
|
||||
sidebar.classList.remove('w-64');
|
||||
sidebar.classList.add('w-20');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user