# UI_COMPONENTS.md - NetGesCon Laravel **Creato**: 8 Luglio 2025 **Ultimo aggiornamento**: 8 Luglio 2025 **Versione**: 1.0 ## 🎯 **SCOPO DEL DOCUMENTO** Documentazione dei componenti UI, layout responsive, design system e architettura frontend per facilitare lo sviluppo dell'interfaccia utente e garantire coerenza visiva. --- ## 🎨 **DESIGN SYSTEM E TEMA** ### **Palette Colori Principale**: ```css :root { /* Colori Brand */ --primary: #2563eb; /* Blu principale */ --primary-dark: #1d4ed8; /* Blu scuro */ --primary-light: #3b82f6; /* Blu chiaro */ /* Colori Funzionali */ --success: #059669; /* Verde successo */ --warning: #d97706; /* Arancione warning */ --error: #dc2626; /* Rosso errore */ --info: #0284c7; /* Blu info */ /* Colori Neutri */ --gray-50: #f9fafb; --gray-100: #f3f4f6; --gray-200: #e5e7eb; --gray-300: #d1d5db; --gray-400: #9ca3af; --gray-500: #6b7280; --gray-600: #4b5563; --gray-700: #374151; --gray-800: #1f2937; --gray-900: #111827; /* Background & Text */ --bg-primary: #ffffff; --bg-secondary: #f8fafc; --text-primary: #1f2937; --text-secondary: #6b7280; --text-muted: #9ca3af; } ``` ### **Typography Scale**: ```css .text-xs { font-size: 0.75rem; } /* 12px */ .text-sm { font-size: 0.875rem; } /* 14px */ .text-base { font-size: 1rem; } /* 16px */ .text-lg { font-size: 1.125rem; } /* 18px */ .text-xl { font-size: 1.25rem; } /* 20px */ .text-2xl { font-size: 1.5rem; } /* 24px */ .text-3xl { font-size: 1.875rem; } /* 30px */ .text-4xl { font-size: 2.25rem; } /* 36px */ .font-light { font-weight: 300; } .font-normal { font-weight: 400; } .font-medium { font-weight: 500; } .font-semibold { font-weight: 600; } .font-bold { font-weight: 700; } ``` ### **Spacing System**: ```css .space-1 { margin/padding: 0.25rem; } /* 4px */ .space-2 { margin/padding: 0.5rem; } /* 8px */ .space-3 { margin/padding: 0.75rem; } /* 12px */ .space-4 { margin/padding: 1rem; } /* 16px */ .space-5 { margin/padding: 1.25rem; } /* 20px */ .space-6 { margin/padding: 1.5rem; } /* 24px */ .space-8 { margin/padding: 2rem; } /* 32px */ .space-10 { margin/padding: 2.5rem; } /* 40px */ .space-12 { margin/padding: 3rem; } /* 48px */ ``` --- ## πŸ“± **LAYOUT RESPONSIVE E BREAKPOINT** ### **Breakpoint Standard**: ```css /* Mobile First Approach */ .container { width: 100%; margin: 0 auto; padding: 0 1rem; } /* Small devices (landscape phones, 576px and up) */ @media (min-width: 576px) { .container { max-width: 540px; } } /* Medium devices (tablets, 768px and up) */ @media (min-width: 768px) { .container { max-width: 720px; } .sidebar { display: block; } } /* Large devices (desktops, 992px and up) */ @media (min-width: 992px) { .container { max-width: 960px; } } /* Extra large devices (large desktops, 1200px and up) */ @media (min-width: 1200px) { .container { max-width: 1140px; } } /* XXL devices (larger desktops, 1400px and up) */ @media (min-width: 1400px) { .container { max-width: 1320px; } } ``` ### **Grid System**: ```html
Colonna 1
Colonna 2
Colonna 3
Sidebar
Main Content
``` --- ## 🧩 **COMPONENTI BASE** ### **Button Component**: ```html ``` ### **Input Component**: ```html ``` ### **Card Component**: ```html ``` --- ## πŸ—οΈ **LAYOUT PRINCIPAL** ### **App Layout**: ```html ``` ### **Sidebar Component**: ```html ``` --- ## πŸ“„ **PAGINE SPECIFICHE** ### **Dashboard Page**: ```html ``` ### **Lista Stabili Page**: ```html ``` --- ## πŸ”§ **UTILITIES E HELPERS** ### **Vue Composables**: ```javascript // composables/useApi.js import { ref, reactive } from 'vue'; import { useToast } from './useToast'; export function useApi() { const loading = ref(false); const error = ref(null); const toast = useToast(); const request = async (method, url, data = null) => { loading.value = true; error.value = null; try { const response = await axios[method](url, data); return response.data; } catch (err) { error.value = err.response?.data?.message || 'Errore di rete'; toast.error(error.value); throw err; } finally { loading.value = false; } }; return { loading: readonly(loading), error: readonly(error), get: (url) => request('get', url), post: (url, data) => request('post', url, data), put: (url, data) => request('put', url, data), delete: (url) => request('delete', url) }; } // composables/usePermissions.js export function usePermissions() { const user = computed(() => store.state.auth.user); const hasPermission = (permission) => { return user.value?.permissions?.includes(permission) || false; }; const hasRole = (role) => { return user.value?.role === role; }; const canAccess = (requiredPermissions) => { if (!Array.isArray(requiredPermissions)) { return hasPermission(requiredPermissions); } return requiredPermissions.some(permission => hasPermission(permission)); }; return { hasPermission, hasRole, canAccess }; } ``` ### **Utility Functions**: ```javascript // utils/formatters.js export const formatCurrency = (value) => { return new Intl.NumberFormat('it-IT', { style: 'currency', currency: 'EUR' }).format(value); }; export const formatDate = (date, options = {}) => { const defaultOptions = { year: 'numeric', month: 'long', day: 'numeric' }; return new Intl.DateTimeFormat('it-IT', { ...defaultOptions, ...options }).format(new Date(date)); }; export const formatPercentage = (value, decimals = 2) => { return `${parseFloat(value).toFixed(decimals)}%`; }; // utils/validators.js export const validateCodiceFiscale = (cf) => { const regex = /^[A-Z]{6}[0-9]{2}[A-Z][0-9]{2}[A-Z][0-9]{3}[A-Z]$/; return regex.test(cf.toUpperCase()); }; export const validatePartitaIva = (piva) => { const regex = /^[0-9]{11}$/; return regex.test(piva.replace(/\D/g, '')); }; export const validateEmail = (email) => { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return regex.test(email); }; ``` --- ## 🎯 **RIFERIMENTI INCROCIATI** - **DATABASE_SCHEMA.md**: ↗️ Struttura dati per binding componenti - **DATA_ARCHITECTURE.md**: ↗️ Modelli Eloquent per props e computed - **API_ENDPOINTS.md**: ↗️ Endpoint per chiamate AJAX e form submission - **PROGRESS_LOG.md**: ↗️ Stato implementazione componenti e pagine - **DEVELOPMENT_IDEAS.md**: *(DA CREARE)* ↗️ Idee UI/UX e miglioramenti frontend --- *Documento creato: 8 Luglio 2025 - Guida completa UI/UX NetGesCon*