netgescon-master/docs/bug/Problemi da risolvere/allineamento pagina ..html
Pikappa2 480e7eafbd 🎯 NETGESCON - Setup iniziale repository completo
📋 Commit iniziale con:
-  Documentazione unificata in docs/
-  Codice Laravel in netgescon-laravel/
-  Script automazione in scripts/
-  Configurazione sync rsync
-  Struttura organizzata e pulita

🔄 Versione: 2025.07.19-1644
🎯 Sistema pronto per Git distribuito
2025-07-19 16:44:47 +02:00

2727 lines
103 KiB
HTML

<!DOCTYPE html>
<html lang="it" data-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="qUrAesdwCj5zjeCLqxIQTApVoYIlahfwGZBFLKFf">
<title>Dashboard Admin - Sistema Gestione Condominiale</title>
<link rel="icon" type="image/x-icon" href="http://127.0.0.1:8000/favicon.ico">
<link rel="apple-touch-icon" sizes="180x180" href="http://127.0.0.1:8000/icons/apple-touch-icon.png">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
/* Layout Base NetGesCon - Versione Migliorata */
.netgescon-container {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.netgescon-body {
flex: 1;
display: flex;
min-height: 0; /* Importante per flexbox */
width: 100%;
}
.netgescon-content {
flex: 1 1 auto;
min-width: 0; /* Previene overflow orizzontale */
padding: 1rem;
background-color: #f8f9fa;
overflow-x: hidden;
width: 100%; /* Occupa tutto lo spazio disponibile */
}
.content-wrapper {
flex: 1;
width: 100%;
max-width: 100%;
}
/* Correzioni sidebar - Dimensioni fisse */
.sidebar-container {
width: 280px;
min-width: 280px;
max-width: 280px;
flex-shrink: 0;
}
.netgescon-sidebar {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
flex-shrink: 0 !important;
min-height: 100vh;
position: relative;
}
/* Assicura che il main content occupi tutto lo spazio */
main.netgescon-content {
flex: 1 1 auto;
display: flex;
flex-direction: column;
min-width: 0;
}
/* Container dashboard specifico */
.space-y-6 > * + * {
margin-top: 1.5rem;
}
/* Responsive */
@media (max-width: 768px) {
.netgescon-body {
flex-direction: column;
}
.sidebar-container {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
}
.netgescon-sidebar {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
min-height: auto;
}
.netgescon-content {
width: 100% !important;
padding: 0.5rem;
}
}
/* Prevenire caratteri spuri */
body::before {
content: '';
display: none;
}
/* Debug layout (rimuovere in produzione) */
.debug-layout .netgescon-sidebar {
border: 2px solid red;
}
.debug-layout .netgescon-content {
border: 2px solid blue;
}
</style>
<style>
:root {
--netgescon-primary: #007bff;
--netgescon-secondary: #6c757d;
--netgescon-sidebar-bg: #f8f9fa;
--netgescon-content-bg: #ffffff;
}
</style>
</head>
<body class="netgescon-app " data-user-role="guest">
<div id="netgesconLoader" class="netgescon-loader">
<div class="loader-content">
<div class="loader-icon">
<i class="fas fa-building fa-3x text-primary"></i>
</div>
<div class="loader-spinner">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Caricamento...</span>
</div>
</div>
<div class="loader-text">
<h5 class="mb-1">NetGesCon</h5>
<p class="text-muted mb-0">Caricamento in corso...</p>
</div>
</div>
</div>
<div class="netgescon-container d-flex flex-column min-vh-100">
<header class="netgescon-header default bg-white shadow-sm" role="banner">
<div class="container-fluid">
<div class="row align-items-center py-2">
<div class="col-auto">
<div class="netgescon-brand d-flex align-items-center">
<button class="btn btn-outline-secondary d-md-none me-2"
type="button"
data-bs-toggle="offcanvas"
data-bs-target="#netgesconSidebar"
aria-label="Toggle menu"
title="Apri/Chiudi menu">
<i class="fas fa-bars"></i>
</button>
<a href="http://127.0.0.1:8000/dashboard" class="netgescon-logo d-flex align-items-center text-decoration-none">
<div class="logo-icon d-flex align-items-center justify-content-center me-2"
style="width: 40px; height: 40px;">
<i class="fas fa-building text-primary" style="font-size: calc(40px * 0.6);"></i>
</div>
<div class="brand-text ">
<h1 class="mb-0 fw-bold text-primary" style="font-size: 1.25rem;">
Laravel
</h1>
<small class="text-muted d-none d-xl-block">Sistema Gestione Condominiale</small>
</div>
</a>
<span class="badge bg-warning text-dark ms-2 d-none d-lg-inline">
DEV
</span>
</div>
</div>
<div class="col d-none d-md-block">
<div class="netgescon-search position-relative">
<form action="#" method="GET" class="search-form" title="Ricerca globale (in sviluppo)">
<div class="input-group">
<span class="input-group-text bg-transparent border-end-0">
<i class="fas fa-search text-muted"></i>
</span>
<input type="text"
name="q"
class="form-control border-start-0 ps-0"
placeholder="Cerca in NetGesCon..."
value=""
autocomplete="off"
id="globalSearch"
data-bs-toggle="dropdown"
aria-expanded="false">
<button class="btn btn-outline-secondary dropdown-toggle"
type="button"
data-bs-toggle="dropdown"
aria-label="Filtri di ricerca">
<i class="fas fa-filter"></i>
</button>
</div>
<ul class="dropdown-menu dropdown-menu-end search-filters">
<li><h6 class="dropdown-header">Filtra per categoria</h6></li>
<li>
<label class="dropdown-item">
<input type="checkbox" name="filters[]" value="stabili" class="form-check-input me-2">
Stabili
</label>
</li>
<li>
<label class="dropdown-item">
<input type="checkbox" name="filters[]" value="condomini" class="form-check-input me-2">
Condomini
</label>
</li>
<li>
<label class="dropdown-item">
<input type="checkbox" name="filters[]" value="documenti" class="form-check-input me-2">
Documenti
</label>
</li>
<li><hr class="dropdown-divider"></li>
<li>
<button type="submit" class="dropdown-item text-primary">
<i class="fas fa-search me-2"></i>Cerca
</button>
</li>
</ul>
</form>
<div class="search-results dropdown-menu w-100 d-none" id="searchResults">
<div class="p-3 text-center">
<div class="spinner-border spinner-border-sm" role="status">
<span class="visually-hidden">Caricamento...</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-auto">
<div class="d-flex align-items-center gap-2">
<div class="d-md-none">
<button type="button"
class="btn btn-outline-secondary"
data-bs-toggle="modal"
data-bs-target="#searchMobileModal"
aria-label="Apri ricerca">
<i class="fas fa-search"></i>
</button>
<div class="modal fade" id="searchMobileModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header border-0">
<h5 class="modal-title">Cerca in NetGesCon</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Chiudi"></button>
</div>
<div class="modal-body pt-0">
<form action="#" method="GET" title="Ricerca globale (in sviluppo)">
<div class="mb-3">
<input type="text"
name="q"
class="form-control form-control-lg"
placeholder="Cerca stabili, condomini, documenti..."
value=""
autofocus>
</div>
<div class="mb-3">
<h6 class="mb-2">Filtri rapidi:</h6>
<div class="d-flex flex-wrap gap-2">
<button type="button" class="btn btn-outline-primary btn-sm filter-btn" data-filter="stabili">
<i class="fas fa-building me-1"></i>Stabili
</button>
<button type="button" class="btn btn-outline-success btn-sm filter-btn" data-filter="condomini">
<i class="fas fa-users me-1"></i>Condomini
</button>
<button type="button" class="btn btn-outline-info btn-sm filter-btn" data-filter="documenti">
<i class="fas fa-file me-1"></i>Documenti
</button>
<button type="button" class="btn btn-outline-warning btn-sm filter-btn" data-filter="tickets">
<i class="fas fa-ticket-alt me-1"></i>Tickets
</button>
</div>
</div>
<button type="submit" class="btn btn-primary btn-lg w-100">
<i class="fas fa-search me-2"></i>Cerca
</button>
</form>
<div class="mt-4">
<h6 class="text-muted">Ricerche recenti:</h6>
<div class="list-group list-group-flush">
<a href="#" class="list-group-item list-group-item-action">
<i class="fas fa-building text-muted me-2"></i>Condominio Via Roma 123
</a>
<a href="#" class="list-group-item list-group-item-action">
<i class="fas fa-file text-muted me-2"></i>Verbale assemblea 2024
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="netgescon-notifications dropdown">
<button class="btn btn-outline-secondary position-relative"
type="button"
data-bs-toggle="dropdown"
aria-expanded="false"
aria-label="Notifiche (2 non lette)"
title="Notifiche">
<i class="fas fa-bell"></i>
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
2
<span class="visually-hidden">notifiche non lette</span>
</span>
</button>
<div class="dropdown-menu dropdown-menu-end notifications-dropdown">
<div class="dropdown-header d-flex justify-content-between align-items-center">
<h6 class="mb-0">Notifiche</h6>
<button type="button" class="btn btn-sm btn-link p-0" id="markAllRead">
<small>Segna tutte lette</small>
</button>
</div>
<div class="notifications-list">
<a href="http://127.0.0.1:8000/admin/tickets/123"
class="dropdown-item notification-item unread"
data-notification-id="1">
<div class="d-flex align-items-start">
<div class="notification-icon me-3">
<i class="fas fa-ticket-alt text-warning"></i>
</div>
<div class="notification-content flex-grow-1">
<div class="notification-title fw-semibold">Nuovo ticket apertp</div>
<div class="notification-message text-muted small">Ticket #123 - Problema ascensore</div>
<div class="notification-time text-muted small">
<i class="fas fa-clock me-1"></i>2 min fa
</div>
</div>
<div class="notification-unread">
<span class="badge bg-primary rounded-circle">&nbsp;</span>
</div>
</div>
</a>
<a href="#"
class="dropdown-item notification-item unread"
data-notification-id="2">
<div class="d-flex align-items-start">
<div class="notification-icon me-3">
<i class="fas fa-database text-success"></i>
</div>
<div class="notification-content flex-grow-1">
<div class="notification-title fw-semibold">Backup completato</div>
<div class="notification-message text-muted small">Backup automatico database eseguito con successo</div>
<div class="notification-time text-muted small">
<i class="fas fa-clock me-1"></i>1 ora fa
</div>
</div>
<div class="notification-unread">
<span class="badge bg-primary rounded-circle">&nbsp;</span>
</div>
</div>
</a>
</div>
</div>
</div>
<div class="netgescon-user-menu dropdown">
<button class="btn btn-outline-secondary d-flex align-items-center"
type="button"
data-bs-toggle="dropdown"
aria-expanded="false"
aria-label="Menu utente">
<div class="user-avatar me-2 position-relative" style="width: 40px; height: 40px;">
<div class="avatar-placeholder rounded-circle w-100 h-100 d-flex align-items-center justify-content-center bg-primary text-white">
A
</div>
<span class="position-absolute bottom-0 end-0 status-indicator bg-success border border-white rounded-circle"
title="Online"></span>
</div>
<span class="d-none d-md-inline">Amministratore Test</span>
<i class="fas fa-chevron-down ms-2 small"></i>
</button>
<ul class="dropdown-menu dropdown-menu-end user-dropdown">
<li class="dropdown-header user-info">
<div class="d-flex align-items-center">
<div class="user-avatar-large me-3">
<div class="avatar-placeholder rounded-circle bg-primary text-white d-flex align-items-center justify-content-center"
style="width: 50px; height: 50px; font-size: 1.25rem;">
A
</div>
</div>
<div>
<div class="fw-semibold">Amministratore Test</div>
<small class="text-muted">admin@example.com</small>
<div>
<span class="badge bg-secondary small">amministratore</span>
</div>
</div>
</div>
</li>
<li><hr class="dropdown-divider"></li>
<li>
<a class="dropdown-item" href="http://127.0.0.1:8000/profile">
<i class="fas fa-user me-2"></i>Il mio profilo
</a>
</li>
<li>
<a class="dropdown-item" href="http://127.0.0.1:8000/profile" title="Impostazioni profilo">
<i class="fas fa-cog me-2"></i>Impostazioni
</a>
</li>
<li>
<a class="dropdown-item" href="#" title="Notifiche (in sviluppo)">
<i class="fas fa-bell me-2"></i>Notifiche
</a>
</li>
<li><hr class="dropdown-divider"></li>
<li>
<button type="button" class="dropdown-item" id="themeToggle">
<i class="fas fa-moon me-2" id="themeIcon"></i>
<span id="themeText">Tema scuro</span>
</button>
</li>
<li>
<a class="dropdown-item" href="#" title="Centro aiuto (in sviluppo)">
<i class="fas fa-question-circle me-2"></i>Aiuto
</a>
</li>
<li><hr class="dropdown-divider"></li>
<li>
<form method="POST" action="http://127.0.0.1:8000/logout" class="d-inline">
<input type="hidden" name="_token" value="qUrAesdwCj5zjeCLqxIQTApVoYIlahfwGZBFLKFf" autocomplete="off"> <button type="submit" class="dropdown-item text-danger">
<i class="fas fa-sign-out-alt me-2"></i>Logout
</button>
</form>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</header>
<div class="netgescon-body d-flex">
<div class="sidebar-container">
<div class="netgescon-sidebar d-flex flex-column h-100" id="netgesconSidebar">
<div class="p-3 border-bottom border-primary">
<div class="text-center">
<h5 class="fw-bold text-primary mb-1">🏢 NetGesCon</h5>
<small class="text-muted d-block">v2.1.0 - Sistema Gestione Condominiale</small>
<div class="mt-2">
<small class="text-success">
<i class="fas fa-user-circle me-1"></i>Amministratore Test
</small>
<br>
<small class="text-muted">
Amministratore
<i class="fas fa-crown text-warning ms-1"></i>
</small>
</div>
</div>
</div>
<div class="p-2 border-bottom border-primary bg-light">
<div class="text-center">
<div class="fw-bold text-dark" id="current-datetime">
<i class="fas fa-clock me-1"></i><span id="datetime-display"></span>
</div>
<div class="mt-2">
<div class="row g-1">
<div class="col-4">
<small class="text-info">
<i class="fas fa-building"></i> 0
</small>
</div>
<div class="col-4">
<small class="text-primary">
<i class="fas fa-users"></i> 3
</small>
</div>
<div class="col-4">
<small class="text-warning">
<i class="fas fa-ticket-simple"></i> 1
</small>
</div>
</div>
</div>
<div class="mt-2">
<div class="alert alert-danger py-1 mb-1 small">
<i class="fas fa-exclamation-triangle me-1"></i>
1 ticket urgenti
</div>
</div>
<div class="mt-2">
<div class="news-ticker bg-primary text-white p-1 rounded small" onclick="openNewsPage()" style="cursor: pointer;">
<i class="fas fa-newspaper me-1"></i>
<span id="news-text">📊 Sistema attivo: 0 stabili gestiti • 3 condomini • Ultimo aggiornamento: 22:26</span>
</div>
</div>
</div>
</div>
<script>
// Aggiorna data e ora
function updateDateTime() {
const now = new Date();
const options = {
weekday: 'short',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
};
const element = document.getElementById('datetime-display');
if (element) {
element.textContent = now.toLocaleDateString('it-IT', options);
}
}
// Aggiorna ogni minuto
updateDateTime();
setInterval(updateDateTime, 60000);
// News ticker animation
function animateNews() {
const newsText = document.getElementById('news-text');
if (newsText) {
const news = [
'🌤️ Meteo: Sereno 18°C • 📈 FTSE MIB +0.5% • 🏛️ Nuove agevolazioni fiscali 2025',
'⚡ BREAKING: Nuovo decreto condomini • 💰 EURO/USD 1.095 • 🏠 Mercato immobiliare +2.3%',
'🎯 Scadenza F24: 16/01 • 📊 Inflazione 0.8% • 🔧 Bonus ristrutturazioni prorogato'
];
let index = 0;
setInterval(() => {
index = (index + 1) % news.length;
newsText.textContent = news[index];
}, 10000);
}
}
// Avvia animazione news
animateNews();
// Funzione per aprire pagina news
function openNewsPage() {
window.open('https://www.ansa.it/sito/notizie/economia/economia.html', '_blank');
}
</script>
<li class="nav-item mb-1">
<div class="alert alert-danger alert-dismissible fade show mx-2 py-2" role="alert">
<strong><i class="fas fa-exclamation-triangle me-1"></i>Tickets Urgenti!</strong>
<br><small>1 ticket richiedono attenzione immediata</small>
<a href="http://127.0.0.1:8000/admin/tickets?priorita=alta" class="btn btn-sm btn-outline-danger mt-1 w-100">
<i class="fas fa-eye me-1"></i>Visualizza Urgenti
</a>
<button type="button" class="btn-close btn-close-small" data-bs-dismiss="alert"></button>
</div>
</li>
<li class="nav-item mb-1">
<div class="card bg-light border-0 mx-2">
<div class="card-header bg-primary text-white py-1">
<small><i class="fas fa-bolt me-1"></i>Azioni Rapide</small>
</div>
<div class="card-body p-2">
<div class="d-grid gap-1">
<a href="http://127.0.0.1:8000/admin/tickets/create" class="btn btn-sm btn-outline-primary" title="Crea nuovo ticket di supporto">
<i class="fas fa-plus me-1"></i>Nuovo Ticket
</a>
<a href="http://127.0.0.1:8000/admin/soggetti/create" class="btn btn-sm btn-outline-success" title="Aggiungi nuovo condomino">
<i class="fas fa-user-plus me-1"></i>Nuovo Condomino
</a>
<a href="http://127.0.0.1:8000/admin/stabili/create" class="btn btn-sm btn-outline-info" title="Registra nuovo stabile">
<i class="fas fa-building me-1"></i>Nuovo Stabile
</a>
<a href="http://127.0.0.1:8000/admin/rate" class="btn btn-sm btn-outline-warning" title="Gestisci rate condominiali">
<i class="fas fa-receipt me-1"></i>Gestisci Rate
</a>
</div>
</div>
</div>
</li>
<li class="nav-item mb-1">
<div class="card bg-gradient border-0 mx-2" style="background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%);">
<div class="card-body p-2 text-center">
<div class="text-white">
<small class="fw-bold d-block">Sistema NetGesCon</small>
<div class="row g-0 mt-1">
<div class="col-6">
<small><i class="fas fa-building"></i><br>0 Stabili</small>
</div>
<div class="col-6">
<small><i class="fas fa-users"></i><br>3 Condomini</small>
</div>
</div>
<small class="text-light mt-1 d-block">
Ultimo aggiornamento: 22:26
</small>
</div>
</div>
</div>
</li>
<nav class="sidebar-nav flex-fill overflow-auto" role="navigation" aria-label="Menu principale NetGesCon">
<ul class="nav nav-pills flex-column p-2">
<li class="nav-item mb-1">
<a class="nav-link d-flex align-items-center text-dark "
href="http://127.0.0.1:8000/admin">
<i class="fas fa-tachometer-alt me-2"></i>
<span>Dashboard</span>
<span class="badge bg-danger ms-auto">1</span>
</a>
</li>
<li class="nav-item mb-1">
<a class="nav-link d-flex align-items-center justify-content-between text-dark "
data-bs-toggle="collapse" href="#stabiliMenu" role="button"
aria-expanded="false"
aria-controls="stabiliMenu">
<div class="d-flex align-items-center">
<i class="fas fa-building me-2"></i>
<span>Stabili</span>
</div>
<i class="fas fa-chevron-down"></i>
</a>
<div class="collapse " id="stabiliMenu">
<ul class="nav nav-pills flex-column ms-3">
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/stabili">
<i class="fas fa-list me-2"></i>Elenco Stabili
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/stabili/create">
<i class="fas fa-plus me-2"></i>Nuovo Stabile
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/stabili">
<i class="fas fa-home me-2"></i>Unità Immobiliari
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/tabelle-millesimali">
<i class="fas fa-percentage me-2"></i>Tabelle Millesimi
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/anagrafica-condominiale">
<i class="fas fa-id-card me-2"></i>Anagrafica Condominiale
</a>
</li>
</ul>
</div>
</li>
<li class="nav-item mb-1">
<a class="nav-link d-flex align-items-center justify-content-between text-dark "
data-bs-toggle="collapse" href="#condominiMenu" role="button"
aria-expanded="false"
aria-controls="condominiMenu">
<div class="d-flex align-items-center">
<i class="fas fa-users me-2"></i>
<span>Condomini</span>
<span class="badge bg-info ms-2">3</span>
</div>
<i class="fas fa-chevron-down"></i>
</a>
<div class="collapse " id="condominiMenu">
<ul class="nav nav-pills flex-column ms-3">
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/soggetti">
<i class="fas fa-list me-2"></i>Elenco Condomini
<span class="badge bg-primary ms-2">3</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/soggetti/create">
<i class="fas fa-user-plus me-2"></i>Nuovo Condomino
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/rubrica">
<i class="fas fa-address-book me-2"></i>Rubrica Completa
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="http://127.0.0.1:8000/admin/soggetti?tipo=proprietario">
<i class="fas fa-home me-2"></i>Proprietari
<span class="badge bg-success ms-2">2</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="http://127.0.0.1:8000/admin/soggetti?tipo=inquilino">
<i class="fas fa-users-cog me-2"></i>Inquilini
<span class="badge bg-warning text-dark ms-2">1</span>
</a>
</li>
</ul>
</div>
</li>
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="#" onclick="loadCondominiSection('millesimi')">
<i class="fas fa-percentage me-2"></i>Tabelle Millesimi
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="#" onclick="loadCondominiSection('rubrica')">
<i class="fas fa-address-book me-2"></i>Rubrica Completa
</a>
</li>
</ul>
</div>
</li>
<script>
function loadCondominiSection(section) {
alert(`Caricamento sezione Condomini: ${section}\n\nQui verrà mostrata la dashboard specifica per: ${section}`);
}
</script>
<li class="nav-item mb-1">
<a class="nav-link d-flex align-items-center justify-content-between text-dark "
data-bs-toggle="collapse" href="#contabilitaMenu" role="button"
aria-expanded="false"
aria-controls="contabilitaMenu">
<div class="d-flex align-items-center">
<i class="fas fa-calculator me-2"></i>
<span>Contabilità</span>
</div>
<i class="fas fa-chevron-down"></i>
</a>
<div class="collapse " id="contabilitaMenu">
<ul class="nav nav-pills flex-column ms-3">
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/rate">
<i class="fas fa-receipt me-2"></i>Rate e Incassi
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/bilanci">
<i class="fas fa-chart-line me-2"></i>Bilanci
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/movimenti-bancari">
<i class="fas fa-university me-2"></i>Movimenti Bancari
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark "
href="http://127.0.0.1:8000/admin/contabilita">
<i class="fas fa-search me-2"></i>Revisioni Contabili
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="#" onclick="alert('Funzione in sviluppo: Estratti Conto')">
<i class="fas fa-file-alt me-2"></i>Estratti Conto
</a>
</li>
</ul>
</div>
</li>
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="#" onclick="loadContabilitaSection('revisioni')">
<i class="fas fa-search me-2"></i>Revisioni Contabili
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="#" onclick="loadContabilitaSection('estratti')">
<i class="fas fa-university me-2"></i>Estratti Conto
</a>
</li>
</ul>
</div>
</li>
<script>
function loadContabilitaSection(section) {
alert(`Caricamento sezione Contabilità: ${section}\n\nQui verrà mostrata la dashboard specifica per: ${section}`);
}
</script>
<li class="nav-item mb-1">
<a class="nav-link d-flex align-items-center justify-content-between text-dark"
data-bs-toggle="collapse" href="#fiscaleMenu" role="button">
<div class="d-flex align-items-center">
<i class="fas fa-file-invoice-dollar me-2"></i>
<span>Fiscale</span>
</div>
<i class="fas fa-chevron-down"></i>
</a>
<div class="collapse" id="fiscaleMenu">
<ul class="nav nav-pills flex-column ms-3">
<li class="nav-item">
<a class="nav-link text-dark" href="#" onclick="loadFiscaleSection('f24')">
<i class="fas fa-file-alt me-2"></i>F24 e Versamenti
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="#" onclick="loadFiscaleSection('ritenute')">
<i class="fas fa-percentage me-2"></i>Ritenute d'Acconto
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="#" onclick="loadFiscaleSection('cartelle')">
<i class="fas fa-exclamation-triangle me-2"></i>Cartelle Esattoriali
</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="#" onclick="loadFiscaleSection('certificazioni')">
<i class="fas fa-certificate me-2"></i>Certificazioni
</a>
</li>
</ul>
</div>
</li>
<script>
function loadFiscaleSection(section) {
alert(`Caricamento sezione Fiscale: ${section}\n\nQui verrà mostrata la dashboard specifica per: ${section}`);
}
</script>
<li class="nav-item mb-1">
<a class="nav-link d-flex align-items-center text-dark "
href="http://127.0.0.1:8000/admin/assemblee">
<i class="fas fa-users-cog me-2"></i>
<span>Assemblee</span>
</a>
</li>
<li class="nav-item mb-1">
<a class="nav-link d-flex align-items-center text-dark" href="#" onclick="alert('Funzione in sviluppo: Comunicazioni\n\n- Email/PEC massiva\n- Raccomandate\n- SMS\n- Avvisi condominiali')">
<i class="fas fa-envelope me-2"></i>
<span>Comunicazioni</span>
</a>
</li>
<li class="nav-item mb-1">
<a class="nav-link d-flex align-items-center text-dark "
href="http://127.0.0.1:8000/admin/tickets">
<i class="fas fa-ticket-simple me-2"></i>
<span>Tickets</span>
<span class="badge bg-info ms-2">1</span>
<span class="badge bg-danger ms-2">1</span>
<small class="text-danger">urgenti</small>
</a>
</li>
<li class="nav-item mb-1">
<a class="nav-link d-flex align-items-center text-dark "
href="http://127.0.0.1:8000/admin/contratti-locazione">
<i class="fas fa-key me-2"></i>
<span>Affitti</span>
</a>
</li>
<li class="nav-item mb-1">
<a class="nav-link d-flex align-items-center text-dark" href="#" onclick="alert('Funzione in sviluppo: Pratiche\n\n- Pratiche legali\n- Pratiche assicurative\n- Pratiche edilizie\n- Archivio pratiche')">
<i class="fas fa-folder-open me-2"></i>
<span>Pratiche</span>
</a>
</li>
<li class="nav-item mb-1">
<a class="nav-link d-flex align-items-center text-dark" href="#" onclick="alert('Funzione in sviluppo: Consumi\n\n- Letture contatori\n- Ripartizione spese\n- Analisi consumi\n- Bollette')">
<i class="fas fa-tint me-2"></i>
<span>Consumi</span>
</a>
</li>
</ul>
</nav>
<div class="p-2 border-top border-primary text-center">
<div class="mb-2">
<small class="text-dark fw-bold">
<i class="fas fa-user-circle me-1"></i>Amministratore Test
</small>
<br>
<small class="text-muted">
<i class="fas fa-shield-alt me-1"></i>Amministratore
</small>
</div>
<small class="text-muted">
© 2025 NetGesCon - v2.1.0<br>
<a href="#" class="text-decoration-none" onclick="openSupport()">Supporto</a>
<a href="#" class="text-decoration-none" onclick="openContacts()">Contatti</a>
<a href="#" class="text-decoration-none" onclick="openWebsite()">www.netgescon.it</a>
</small>
</div>
<script>
function openSupport() {
alert('Centro Assistenza NetGesCon\n\nEmail: supporto@netgescon.it\nTel: 06.123456789\nOrari: Lun-Ven 9:00-18:00');
}
function openContacts() {
alert('Contatti NetGesCon\n\nNetGesCon S.r.l.\nVia Roma 123, 00100 Roma\nP.IVA: 12345678901\ninfo@netgescon.it');
}
function openWebsite() {
window.open('https://www.netgescon.it', '_blank');
}
</script>
</div>
<style>
/* NetGesCon Sidebar Styles */
.netgescon-sidebar {
background: linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%);
border-right: 2px solid #007bff;
box-shadow: 2px 0 10px rgba(0,123,255,0.1);
min-height: 100vh;
width: 280px;
}
.netgescon-sidebar .nav-link {
border-radius: 8px;
margin: 2px 0;
padding: 8px 12px;
transition: all 0.3s ease;
}
.netgescon-sidebar .nav-link:hover {
background-color: rgba(0,123,255,0.1);
transform: translateX(5px);
}
.netgescon-sidebar .nav-link.active {
background-color: #007bff !important;
color: white !important;
font-weight: bold;
box-shadow: 0 2px 5px rgba(0,123,255,0.3);
}
.netgescon-sidebar .collapse .nav-link {
padding: 6px 12px;
font-size: 0.9em;
}
.netgescon-sidebar .collapse .nav-link:hover {
background-color: rgba(0,123,255,0.05);
color: #007bff;
}
/* Header styles */
.netgescon-sidebar .border-bottom {
border-color: #007bff !important;
}
/* Footer styles */
.netgescon-sidebar .border-top {
border-color: #007bff !important;
}
/* Dark mode support */
.dark .netgescon-sidebar {
background: linear-gradient(180deg, #1f2937 0%, #111827 100%);
border-color: #4b5563;
}
.dark .netgescon-sidebar .nav-link {
color: #d1d5db;
}
.dark .netgescon-sidebar .nav-link:hover {
background-color: rgba(55, 65, 81, 0.3);
color: #d1d5db;
}
/* Responsive */
@media (max-width: 768px) {
.netgescon-sidebar {
position: fixed;
top: 0;
left: -100%;
width: 280px;
z-index: 1050;
transition: left 0.3s ease;
}
.netgescon-sidebar.show {
left: 0;
}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Gestione toggle menu collassabili
const collapseElements = document.querySelectorAll('[data-bs-toggle="collapse"]');
collapseElements.forEach(element => {
element.addEventListener('click', function() {
const icon = this.querySelector('.fa-chevron-down, .fa-chevron-up');
if (icon) {
icon.classList.toggle('fa-chevron-down');
icon.classList.toggle('fa-chevron-up');
}
});
});
// Gestione menu attivo
const navLinks = document.querySelectorAll('.netgescon-sidebar .nav-link[href]');
const currentPath = window.location.pathname;
navLinks.forEach(link => {
if (link.getAttribute('href') === currentPath) {
link.classList.add('active');
// Espandi il menu parent se è collassato
const parentCollapse = link.closest('.collapse');
if (parentCollapse) {
parentCollapse.classList.add('show');
const toggleButton = document.querySelector(`[href="#${parentCollapse.id}"]`);
if (toggleButton) {
toggleButton.setAttribute('aria-expanded', 'true');
}
}
}
});
// Aggiorna data e ora ogni minuto
function updateDateTime() {
const now = new Date();
const dateElement = document.getElementById('current-date');
const timeElement = document.getElementById('current-time');
if (dateElement) {
dateElement.textContent = now.toLocaleDateString('it-IT');
}
if (timeElement) {
timeElement.textContent = now.toLocaleTimeString('it-IT', { hour: '2-digit', minute: '2-digit' });
}
}
updateDateTime();
setInterval(updateDateTime, 60000);
// News ticker animation
const newsTicker = document.querySelector('.news-ticker');
if (newsTicker) {
newsTicker.addEventListener('animationend', function() {
this.style.animation = 'none';
setTimeout(() => {
this.style.animation = 'scroll-left 30s linear infinite';
}, 50);
});
}
// Aggiorna data e ora display
function updateDateTimeDisplay() {
const now = new Date();
const options = {
weekday: 'short',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
};
const dateTimeDisplay = document.getElementById('datetime-display');
if (dateTimeDisplay) {
dateTimeDisplay.textContent = now.toLocaleDateString('it-IT', options);
}
}
// Aggiorna ogni minuto
updateDateTimeDisplay();
setInterval(updateDateTimeDisplay, 60000);
// News ticker animation
function animateNews() {
const newsText = document.getElementById('news-text');
if (newsText) {
const news = [
'🌤️ Meteo: Sereno 18°C • 📈 FTSE MIB +0.5% • 🏛️ Nuove agevolazioni fiscali 2025',
'⚡ BREAKING: Nuovo decreto condomini • 💰 EURO/USD 1.095 • 🏠 Mercato immobiliare +2.3%',
'🎯 Scadenza F24: 16/01 • 📊 Inflazione 0.8% • 🔧 Bonus ristrutturazioni prorogato'
];
let index = 0;
setInterval(() => {
index = (index + 1) % news.length;
newsText.textContent = news[index];
}, 10000);
}
}
// Avvia animazione news
animateNews();
// Funzione per aprire pagina news
function openNewsPage() {
window.open('https://www.ansa.it/sito/notizie/economia/economia.html', '_blank');
}
});
</script>
</div>
<main class="netgescon-content d-flex flex-column" role="main">
<nav aria-label="breadcrumb" class="netgescon-breadcrumb">
<ol class="breadcrumb mb-0">
<li class="breadcrumb-item">
<a href="http://127.0.0.1:8000/dashboard" class="text-decoration-none">
<i class="fas fa-home me-1"></i>Home
</a>
</li>
<li class="breadcrumb-item active">
<span class="text-muted">Dashboard</span>
</li>
</ol>
</nav>
<div class="netgescon-alerts position-relative">
<div id="dynamic-alerts"></div>
</div>
<div class="content-wrapper flex-grow-1">
<div class="space-y-6">
<!-- Header Dashboard -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
<div class="flex items-center">
<div class="flex-shrink-0">
<i class="fas fa-user-shield text-blue-500 text-3xl mr-4"></i>
</div>
<div class="flex-1">
<h1 class="text-3xl font-bold text-gray-800 dark:text-white">
Dashboard Amministratore
</h1>
<p class="text-gray-600 dark:text-gray-300 mt-2">
Benvenuto nel pannello di gestione condominiale
</p>
</div>
<!-- Info utente corrente -->
<div class="flex-shrink-0 text-right">
<p class="text-sm text-gray-500 dark:text-gray-400">
Benvenuto, <strong>Amministratore Test</strong>
</p>
<p class="text-xs text-gray-400 dark:text-gray-500">
12/07/2025 22:26
</p>
</div>
</div>
</div>
</div>
<!-- Statistiche Principali -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<!-- Stabili Totali -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg cursor-pointer hover:shadow-lg transition-shadow"
onclick="window.location.href='http://127.0.0.1:8000/admin/stabili'" >
<div class="p-6">
<div class="flex items-center">
<!-- Icona -->
<div class="flex-shrink-0">
<div class="w-12 h-12 text-blue-500 bg-blue-100 rounded-full flex items-center justify-center">
<i class="fas fa-building text-xl"></i>
</div>
</div>
<!-- Contenuto -->
<div class="ml-5 w-0 flex-1">
<dl>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">
Stabili Totali
</dt>
<dd class="text-2xl font-bold text-gray-900 dark:text-white">
12
</dd>
<dd class="text-xs text-gray-500 dark:text-gray-400 mt-1">
Stabili gestiti
</dd>
</dl>
</div>
<!-- Freccia se c'è un link -->
<div class="flex-shrink-0 ml-4">
<i class="fas fa-chevron-right text-gray-400"></i>
</div>
</div>
</div>
</div>
<!-- Condomini -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg cursor-pointer hover:shadow-lg transition-shadow"
onclick="window.location.href='http://127.0.0.1:8000/admin/soggetti'" >
<div class="p-6">
<div class="flex items-center">
<!-- Icona -->
<div class="flex-shrink-0">
<div class="w-12 h-12 text-green-500 bg-green-100 rounded-full flex items-center justify-center">
<i class="fas fa-users text-xl"></i>
</div>
</div>
<!-- Contenuto -->
<div class="ml-5 w-0 flex-1">
<dl>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">
Condomini
</dt>
<dd class="text-2xl font-bold text-gray-900 dark:text-white">
248
</dd>
<dd class="text-xs text-gray-500 dark:text-gray-400 mt-1">
Condomini registrati
</dd>
</dl>
</div>
<!-- Freccia se c'è un link -->
<div class="flex-shrink-0 ml-4">
<i class="fas fa-chevron-right text-gray-400"></i>
</div>
</div>
</div>
</div>
<!-- Tickets Aperti -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg cursor-pointer hover:shadow-lg transition-shadow"
onclick="window.location.href='http://127.0.0.1:8000/admin/tickets'" >
<div class="p-6">
<div class="flex items-center">
<!-- Icona -->
<div class="flex-shrink-0">
<div class="w-12 h-12 text-yellow-500 bg-yellow-100 rounded-full flex items-center justify-center">
<i class="fas fa-ticket-alt text-xl"></i>
</div>
</div>
<!-- Contenuto -->
<div class="ml-5 w-0 flex-1">
<dl>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">
Tickets Aperti
</dt>
<dd class="text-2xl font-bold text-gray-900 dark:text-white">
7
</dd>
<dd class="text-xs text-gray-500 dark:text-gray-400 mt-1">
Richieste in corso
</dd>
</dl>
</div>
<!-- Freccia se c'è un link -->
<div class="flex-shrink-0 ml-4">
<i class="fas fa-chevron-right text-gray-400"></i>
</div>
</div>
</div>
</div>
<!-- Assemblee del Mese -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg cursor-pointer hover:shadow-lg transition-shadow"
onclick="window.location.href='http://127.0.0.1:8000/admin/assemblee'" >
<div class="p-6">
<div class="flex items-center">
<!-- Icona -->
<div class="flex-shrink-0">
<div class="w-12 h-12 text-indigo-500 bg-indigo-100 rounded-full flex items-center justify-center">
<i class="fas fa-calendar-alt text-xl"></i>
</div>
</div>
<!-- Contenuto -->
<div class="ml-5 w-0 flex-1">
<dl>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400 truncate">
Assemblee
</dt>
<dd class="text-2xl font-bold text-gray-900 dark:text-white">
0
</dd>
<dd class="text-xs text-gray-500 dark:text-gray-400 mt-1">
Questo mese
</dd>
</dl>
</div>
<!-- Freccia se c'è un link -->
<div class="flex-shrink-0 ml-4">
<i class="fas fa-chevron-right text-gray-400"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Azioni Rapide -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-6">Azioni Rapide</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<!-- Nuovo Condomino -->
<a href="http://127.0.0.1:8000/admin/soggetti/create"
class="block bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-6 shadow-sm transition-all duration-200 hover:bg-green-50 dark:hover:bg-green-900/20 border-green-200">
<div class="flex items-start">
<!-- Icona -->
<div class="flex-shrink-0">
<i class="fas fa-user-plus text-2xl text-gray-600 dark:text-gray-400"></i>
</div>
<!-- Contenuto -->
<div class="ml-4 flex-1">
<div class="flex items-center justify-between">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
Nuovo Condomino
</h3>
<!-- Badge opzionale -->
</div>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
Registra un nuovo condomino nel sistema
</p>
</div>
<!-- Freccia -->
<div class="flex-shrink-0 ml-4">
<i class="fas fa-chevron-right text-gray-400"></i>
</div>
</div>
</a>
<!-- Nuova Assemblea -->
<a href="http://127.0.0.1:8000/admin/assemblee/create"
class="block bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-6 shadow-sm transition-all duration-200 hover:bg-blue-50 dark:hover:bg-blue-900/20 border-blue-200">
<div class="flex items-start">
<!-- Icona -->
<div class="flex-shrink-0">
<i class="fas fa-calendar-plus text-2xl text-gray-600 dark:text-gray-400"></i>
</div>
<!-- Contenuto -->
<div class="ml-4 flex-1">
<div class="flex items-center justify-between">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
Nuova Assemblea
</h3>
<!-- Badge opzionale -->
</div>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
Pianifica una nuova assemblea condominiale
</p>
</div>
<!-- Freccia -->
<div class="flex-shrink-0 ml-4">
<i class="fas fa-chevron-right text-gray-400"></i>
</div>
</div>
</a>
<!-- Gestione Rate -->
<a href="http://127.0.0.1:8000/admin/rate"
class="block bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-6 shadow-sm transition-all duration-200 hover:bg-yellow-50 dark:hover:bg-yellow-900/20 border-yellow-200">
<div class="flex items-start">
<!-- Icona -->
<div class="flex-shrink-0">
<i class="fas fa-euro-sign text-2xl text-gray-600 dark:text-gray-400"></i>
</div>
<!-- Contenuto -->
<div class="ml-4 flex-1">
<div class="flex items-center justify-between">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
Gestione Rate
</h3>
<!-- Badge opzionale -->
</div>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
Configura e gestisci le rate condominiali
</p>
</div>
<!-- Freccia -->
<div class="flex-shrink-0 ml-4">
<i class="fas fa-chevron-right text-gray-400"></i>
</div>
</div>
</a>
<!-- Tickets -->
<a href="http://127.0.0.1:8000/admin/tickets"
class="block bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-6 shadow-sm transition-all duration-200 hover:bg-indigo-50 dark:hover:bg-indigo-900/20 border-indigo-200">
<div class="flex items-start">
<!-- Icona -->
<div class="flex-shrink-0">
<i class="fas fa-headset text-2xl text-gray-600 dark:text-gray-400"></i>
</div>
<!-- Contenuto -->
<div class="ml-4 flex-1">
<div class="flex items-center justify-between">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
Gestione Tickets
</h3>
<!-- Badge opzionale -->
</div>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
Visualizza e gestisci le richieste dei condomini
</p>
</div>
<!-- Freccia -->
<div class="flex-shrink-0 ml-4">
<i class="fas fa-chevron-right text-gray-400"></i>
</div>
</div>
</a>
<!-- Documenti -->
<a href="http://127.0.0.1:8000/admin/documenti"
class="block bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-6 shadow-sm transition-all duration-200 hover:bg-red-50 dark:hover:bg-red-900/20 border-red-200">
<div class="flex items-start">
<!-- Icona -->
<div class="flex-shrink-0">
<i class="fas fa-file-invoice text-2xl text-gray-600 dark:text-gray-400"></i>
</div>
<!-- Contenuto -->
<div class="ml-4 flex-1">
<div class="flex items-center justify-between">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
Documenti
</h3>
<!-- Badge opzionale -->
</div>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
Gestisci documenti e archivio
</p>
</div>
<!-- Freccia -->
<div class="flex-shrink-0 ml-4">
<i class="fas fa-chevron-right text-gray-400"></i>
</div>
</div>
</a>
<!-- Rate Condominiali -->
<a href="http://127.0.0.1:8000/admin/rate"
class="block bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-6 shadow-sm transition-all duration-200 hover:bg-yellow-50 dark:hover:bg-yellow-900/20 border-yellow-200">
<div class="flex items-start">
<!-- Icona -->
<div class="flex-shrink-0">
<i class="fas fa-money-check text-2xl text-gray-600 dark:text-gray-400"></i>
</div>
<!-- Contenuto -->
<div class="ml-4 flex-1">
<div class="flex items-center justify-between">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
Rate Condominiali
</h3>
<!-- Badge opzionale -->
</div>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
Gestisci rate e incassi
</p>
</div>
<!-- Freccia -->
<div class="flex-shrink-0 ml-4">
<i class="fas fa-chevron-right text-gray-400"></i>
</div>
</div>
</a>
</div>
</div>
</div>
<!-- Layout a due colonne per contenuti aggiuntivi -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Attività Recenti -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6">
<div class="flex items-center justify-between mb-6">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Attività Recenti</h3>
<a href="http://127.0.0.1:8000/admin"
class="text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400">
Dashboard
</a>
</div>
<div class="space-y-4">
<!-- Nuovo Ticket -->
<div class="flex items-start space-x-3 py-3 border-b border-gray-200 dark:border-gray-700 last:border-b-0">
<div class="flex-shrink-0">
<div class="w-8 h-8 bg-yellow-100 rounded-full flex items-center justify-center">
<i class="fas fa-ticket-alt text-yellow-600 text-sm"></i>
</div>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm text-gray-900 dark:text-white">
<span class="font-medium">Nuovo ticket ricevuto</span>
</p>
<p class="text-xs text-gray-500 dark:text-gray-400">
Stabile A - Problema ascensore - 30 min fa
</p>
</div>
</div>
<!-- Pagamento Ricevuto -->
<div class="flex items-start space-x-3 py-3 border-b border-gray-200 dark:border-gray-700 last:border-b-0">
<div class="flex-shrink-0">
<div class="w-8 h-8 bg-green-100 rounded-full flex items-center justify-center">
<i class="fas fa-euro-sign text-green-600 text-sm"></i>
</div>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm text-gray-900 dark:text-white">
<span class="font-medium">Pagamento ricevuto</span>
</p>
<p class="text-xs text-gray-500 dark:text-gray-400">
Mario Rossi - €500,00 - 2 ore fa
</p>
</div>
</div>
<!-- Nuovo Condomino -->
<div class="flex items-start space-x-3 py-3 border-b border-gray-200 dark:border-gray-700 last:border-b-0">
<div class="flex-shrink-0">
<div class="w-8 h-8 bg-blue-100 rounded-full flex items-center justify-center">
<i class="fas fa-user-plus text-blue-600 text-sm"></i>
</div>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm text-gray-900 dark:text-white">
<span class="font-medium">Nuovo condomino registrato</span>
</p>
<p class="text-xs text-gray-500 dark:text-gray-400">
Giulia Bianchi - Appartamento 12 - 1 giorno fa
</p>
</div>
</div>
<!-- Assemblea Programmata -->
<div class="flex items-start space-x-3 py-3 border-b border-gray-200 dark:border-gray-700 last:border-b-0">
<div class="flex-shrink-0">
<div class="w-8 h-8 bg-purple-100 rounded-full flex items-center justify-center">
<i class="fas fa-calendar-plus text-purple-600 text-sm"></i>
</div>
</div>
<div class="flex-1 min-w-0">
<p class="text-sm text-gray-900 dark:text-white">
<span class="font-medium">Assemblea programmata</span>
</p>
<p class="text-xs text-gray-500 dark:text-gray-400">
15 Marzo 2024 - Bilancio annuale - 2 giorni fa
</p>
</div>
</div>
</div>
</div>
</div>
<!-- Ultimi Tickets -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6">
<div class="flex items-center justify-between mb-6">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Ultimi Tickets</h3>
<a href="http://127.0.0.1:8000/admin/tickets"
class="text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400">
Visualizza tutti
</a>
</div>
<div class="space-y-4">
<div class="text-center py-8">
<div class="w-16 h-16 bg-gray-100 dark:bg-gray-700 rounded-full flex items-center justify-center mx-auto mb-4">
<i class="fas fa-ticket-alt text-gray-400 text-2xl"></i>
</div>
<p class="text-gray-500 dark:text-gray-400">Nessun ticket recente</p>
</div>
</div>
</div>
</div>
</div>
<!-- Grafico Fatturato (placeholder) -->
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-6">Andamento Fatturato</h3>
<div class="text-center py-12">
<div class="w-20 h-20 bg-gray-100 dark:bg-gray-700 rounded-full flex items-center justify-center mx-auto mb-4">
<i class="fas fa-chart-line text-gray-400 text-3xl"></i>
</div>
<p class="text-gray-500 dark:text-gray-400">Grafico fatturato (da implementare)</p>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
<footer class="netgescon-footer default mt-auto bg-light border-top" role="contentinfo">
<div class="container-fluid">
<div class="row py-3">
<div class="col-lg-4 col-md-6 mb-3 mb-lg-0">
<div class="footer-brand">
<h6 class="fw-bold text-primary mb-2">
<i class="fas fa-building me-2"></i>NetGesCon
</h6>
<p class="text-muted small mb-2">
Sistema completo per la gestione condominiale professionale.
</p>
<div class="version-info">
<small class="text-muted">
<i class="fas fa-code-branch me-1"></i>
Versione 1.0.0
<span class="badge bg-warning text-dark ms-1">
LOCAL
</span>
</small>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6 mb-3 mb-lg-0">
<h6 class="fw-bold mb-3">Link Utili</h6>
<div class="row">
<div class="col-6">
<ul class="list-unstyled footer-links">
<li><a href="#" class="text-muted small" title="Centro Aiuto - Funzionalità in sviluppo">Centro Aiuto</a></li>
<li><a href="#" class="text-muted small" title="Documentazione - Funzionalità in sviluppo">Documentazione</a></li>
<li><a href="#" class="text-muted small" title="Privacy Policy - Funzionalità in sviluppo">Privacy Policy</a></li>
<li><a href="#" class="text-muted small" title="Termini d'uso - Funzionalità in sviluppo">Termini d'uso</a></li>
</ul>
</div>
<div class="col-6">
<ul class="list-unstyled footer-links">
<li><a href="#" class="text-muted small" title="Contatti - Funzionalità in sviluppo">Contatti</a></li>
<li><a href="#" class="text-muted small" title="Chi siamo - Funzionalità in sviluppo">Chi siamo</a></li>
<li><a href="#" class="text-muted small" title="Novità - Funzionalità in sviluppo">Novità</a></li>
<li><a href="#" class="text-muted small" title="Stato Sistema - Funzionalità in sviluppo">Stato Sistema</a></li>
</ul>
</div>
</div>
</div>
<div class="col-lg-4 col-md-12">
<h6 class="fw-bold mb-3">Informazioni</h6>
<div class="info-box">
<small class="text-muted d-block mb-2">
<i class="fas fa-clock me-1"></i>
Ultimo aggiornamento: 12/07/2025 22:26
</small>
<small class="text-muted d-block mb-2">
<i class="fas fa-server me-1"></i>
Server: local
</small>
<small class="text-muted d-block">
<i class="fas fa-user me-1"></i>
Connesso come: Amministratore Test
</small>
</div>
</div>
</div>
<div class="border-top pt-3 mt-3">
<div class="row align-items-center">
<div class="col-md-6">
<small class="text-muted">
© 2025 NetGesCon. Tutti i diritti riservati.
</small>
</div>
<div class="col-md-6 text-end">
<div class="social-links">
<button type="button" class="btn btn-sm btn-outline-secondary ms-2" id="backToTop" title="Torna su">
<i class="fas fa-arrow-up"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</footer>
</div>
<div class="modal fade" id="confirmModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmModalTitle">Conferma</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Chiudi"></button>
</div>
<div class="modal-body">
<div class="d-flex align-items-start">
<i class="fas fa-question-circle text-warning fa-2x me-3 mt-1"></i>
<div>
<p id="confirmModalMessage" class="mb-0">Sei sicuro di voler procedere?</p>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
<button type="button" class="btn btn-primary" id="confirmModalConfirm">Conferma</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="deleteModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-danger text-white">
<h5 class="modal-title">
<i class="fas fa-trash me-2"></i>Conferma Eliminazione
</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Chiudi"></button>
</div>
<div class="modal-body">
<div class="d-flex align-items-start">
<i class="fas fa-exclamation-triangle text-danger fa-2x me-3 mt-1"></i>
<div>
<p class="mb-2"><strong>Attenzione!</strong></p>
<p id="deleteModalMessage" class="mb-3">Questa azione non può essere annullata.</p>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="deleteConfirmCheck">
<label class="form-check-label" for="deleteConfirmCheck">
Ho compreso che questa azione è irreversibile
</label>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
<button type="button" class="btn btn-danger" id="deleteModalConfirm" disabled>
<i class="fas fa-trash me-1"></i>Elimina
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="loadingModal" tabindex="-1" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-body text-center py-4">
<div class="spinner-border text-primary mb-3" role="status">
<span class="visually-hidden">Caricamento...</span>
</div>
<p id="loadingModalMessage" class="mb-0">Operazione in corso...</p>
</div>
</div>
</div>
</div>
<div class="modal fade" id="infoModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="infoModalTitle">
<i class="fas fa-info-circle text-info me-2"></i>Informazioni
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Chiudi"></button>
</div>
<div class="modal-body">
<div id="infoModalContent">
<!-- Contenuto dinamico -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="helpModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="fas fa-question-circle text-primary me-2"></i>Aiuto
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Chiudi"></button>
</div>
<div class="modal-body">
<div id="helpModalContent">
<div class="text-center py-4">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Caricamento...</span>
</div>
<p class="mt-2">Caricamento contenuto aiuto...</p>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Chiudi</button>
<a href="#" class="btn btn-primary disabled" title="Centro Aiuto - Funzionalità in sviluppo">
<i class="fas fa-external-link-alt me-1"></i>Centro Aiuto
</a>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Rimuovi eventuali caratteri spuri dal body
const textNodes = [];
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
null,
false
);
let node;
while (node = walker.nextNode()) {
if (node.parentNode === document.body && node.textContent.trim() === '>') {
textNodes.push(node);
}
}
textNodes.forEach(node => {
if (node.textContent.trim() === '>' || node.textContent.trim() === '') {
node.remove();
}
});
// Debug layout e correzioni automatiche
const sidebar = document.querySelector('.netgescon-sidebar');
const content = document.querySelector('.netgescon-content');
const body = document.querySelector('.netgescon-body');
if (sidebar && content && body) {
// Assicura dimensioni corrette
const sidebarWidth = sidebar.offsetWidth;
const bodyWidth = body.offsetWidth;
const contentWidth = bodyWidth - sidebarWidth;
console.log('NetGesCon Layout Debug:');
console.log('- Sidebar width:', sidebarWidth, 'px');
console.log('- Body width:', bodyWidth, 'px');
console.log('- Content calculated width:', contentWidth, 'px');
console.log('- Content actual width:', content.offsetWidth, 'px');
// Forza larghezza corretta se necessario
if (content.offsetWidth < contentWidth - 50) {
console.log('Correzione automatica larghezza content...');
content.style.width = '100%';
content.style.flex = '1 1 auto';
}
}
console.log('NetGesCon Layout inizializzato correttamente');
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const loader = document.getElementById('netgesconLoader');
// Nascondi loader dopo caricamento pagina
function hideLoader() {
if (loader) {
loader.classList.add('hidden');
setTimeout(() => {
loader.style.display = 'none';
}, 500);
}
}
// Nascondi dopo caricamento completo
if (document.readyState === 'complete') {
hideLoader();
} else {
window.addEventListener('load', hideLoader);
}
// Timeout di sicurezza (massimo 10 secondi)
setTimeout(hideLoader, 10000);
});
// Funzione globale per mostrare/nascondere loader
window.showLoader = function() {
const loader = document.getElementById('netgesconLoader');
if (loader) {
loader.style.display = 'flex';
loader.classList.remove('hidden');
}
};
window.hideLoader = function() {
const loader = document.getElementById('netgesconLoader');
if (loader) {
loader.classList.add('hidden');
setTimeout(() => {
loader.style.display = 'none';
}, 500);
}
};
</script>
<script src="http://127.0.0.1:8000/js/sidebar.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Aggiungi tooltips ai breadcrumb su mobile
const breadcrumbItems = document.querySelectorAll('.netgescon-breadcrumb .breadcrumb-item a');
breadcrumbItems.forEach(item => {
item.addEventListener('mouseenter', function() {
// Aggiungi logica per tooltip se necessario
});
});
// Salva breadcrumb per navigazione indietro
const currentBreadcrumb = document.querySelector('.netgescon-breadcrumb');
if (currentBreadcrumb) {
const breadcrumbData = Array.from(currentBreadcrumb.querySelectorAll('.breadcrumb-item')).map(item => {
const link = item.querySelector('a');
return {
name: item.textContent.trim(),
url: link ? link.href : null,
active: item.classList.contains('active')
};
});
sessionStorage.setItem('lastBreadcrumb', JSON.stringify(breadcrumbData));
}
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Auto-dismiss alerts
const autoDismissAlerts = document.querySelectorAll('[data-auto-dismiss]');
autoDismissAlerts.forEach(alert => {
const duration = parseInt(alert.dataset.autoDismiss) * 1000;
// Imposta durata CSS
alert.style.setProperty('--duration', alert.dataset.autoDismiss + 's');
setTimeout(() => {
const bsAlert = new bootstrap.Alert(alert);
bsAlert.close();
}, duration);
});
// Funzione globale per creare alert dinamici
window.showAlert = function(message, type = 'info', autoDismiss = true) {
const alertContainer = document.getElementById('dynamic-alerts');
if (!alertContainer) return;
const icons = {
'success': 'fas fa-check-circle',
'error': 'fas fa-times-circle',
'warning': 'fas fa-exclamation-triangle',
'info': 'fas fa-info-circle',
'primary': 'fas fa-star',
'secondary': 'fas fa-bell'
};
const icon = icons[type] || icons.info;
const alertId = 'alert-' + Date.now();
const alertHtml = `
<div class="alert alert-${type} alert-dismissible fade show"
id="${alertId}"
role="alert"
${autoDismiss ? 'data-auto-dismiss="5"' : ''}>
<div class="d-flex align-items-start">
<i class="${icon} me-2 mt-1"></i>
<div class="flex-grow-1">${message}</div>
</div>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Chiudi"></button>
</div>
`;
alertContainer.insertAdjacentHTML('beforeend', alertHtml);
// Auto-dismiss se richiesto
if (autoDismiss) {
const alertElement = document.getElementById(alertId);
alertElement.style.setProperty('--duration', '5s');
setTimeout(() => {
const bsAlert = new bootstrap.Alert(alertElement);
bsAlert.close();
}, 5000);
}
};
// Funzioni helper
window.showSuccess = (message) => window.showAlert(message, 'success');
window.showError = (message) => window.showAlert(message, 'error');
window.showWarning = (message) => window.showAlert(message, 'warning');
window.showInfo = (message) => window.showAlert(message, 'info');
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Pulsante torna su
const backToTopBtn = document.getElementById('backToTop');
if (backToTopBtn) {
// Mostra/nascondi in base allo scroll
window.addEventListener('scroll', function() {
if (window.pageYOffset > 300) {
backToTopBtn.style.opacity = '1';
backToTopBtn.style.visibility = 'visible';
} else {
backToTopBtn.style.opacity = '0';
backToTopBtn.style.visibility = 'hidden';
}
});
// Click handler
backToTopBtn.addEventListener('click', function() {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
// Stile iniziale
backToTopBtn.style.transition = 'all 0.3s ease';
backToTopBtn.style.opacity = '0';
backToTopBtn.style.visibility = 'hidden';
}
// Analytics footer links (se configurato)
const footerLinks = document.querySelectorAll('.footer-links a');
footerLinks.forEach(link => {
link.addEventListener('click', function() {
// Traccia click sui link del footer
if (typeof gtag !== 'undefined') {
gtag('event', 'click', {
event_category: 'footer',
event_label: this.textContent.trim()
});
}
});
});
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Helper per modal di conferma
window.showConfirmModal = function(title, message, onConfirm, confirmText = 'Conferma') {
const modal = new bootstrap.Modal(document.getElementById('confirmModal'));
document.getElementById('confirmModalTitle').textContent = title;
document.getElementById('confirmModalMessage').textContent = message;
document.getElementById('confirmModalConfirm').textContent = confirmText;
// Rimuovi eventuali listener precedenti
const newConfirmBtn = document.getElementById('confirmModalConfirm').cloneNode(true);
document.getElementById('confirmModalConfirm').parentNode.replaceChild(newConfirmBtn, document.getElementById('confirmModalConfirm'));
// Aggiungi nuovo listener
document.getElementById('confirmModalConfirm').addEventListener('click', function() {
modal.hide();
if (typeof onConfirm === 'function') {
onConfirm();
}
});
modal.show();
};
// Helper per modal di eliminazione
window.showDeleteModal = function(message, onDelete) {
const modal = new bootstrap.Modal(document.getElementById('deleteModal'));
const checkbox = document.getElementById('deleteConfirmCheck');
const confirmBtn = document.getElementById('deleteModalConfirm');
document.getElementById('deleteModalMessage').textContent = message;
checkbox.checked = false;
confirmBtn.disabled = true;
// Gestione checkbox
checkbox.addEventListener('change', function() {
confirmBtn.disabled = !this.checked;
});
// Rimuovi eventuali listener precedenti
const newDeleteBtn = confirmBtn.cloneNode(true);
confirmBtn.parentNode.replaceChild(newDeleteBtn, confirmBtn);
// Aggiungi nuovo listener
document.getElementById('deleteModalConfirm').addEventListener('click', function() {
modal.hide();
if (typeof onDelete === 'function') {
onDelete();
}
});
modal.show();
};
// Helper per modal di loading
window.showLoadingModal = function(message = 'Operazione in corso...') {
document.getElementById('loadingModalMessage').textContent = message;
const modal = new bootstrap.Modal(document.getElementById('loadingModal'));
modal.show();
return modal;
};
window.hideLoadingModal = function() {
const modal = bootstrap.Modal.getInstance(document.getElementById('loadingModal'));
if (modal) {
modal.hide();
}
};
// Helper per modal info
window.showInfoModal = function(title, content) {
document.getElementById('infoModalTitle').innerHTML = '<i class="fas fa-info-circle text-info me-2"></i>' + title;
document.getElementById('infoModalContent').innerHTML = content;
const modal = new bootstrap.Modal(document.getElementById('infoModal'));
modal.show();
};
// Helper per modal aiuto
window.showHelpModal = function(topic = null) {
const modal = new bootstrap.Modal(document.getElementById('helpModal'));
const content = document.getElementById('helpModalContent');
// Reset content
content.innerHTML = `
<div class="text-center py-4">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Caricamento...</span>
</div>
<p class="mt-2">Caricamento contenuto aiuto...</p>
</div>
`;
modal.show();
// Carica contenuto aiuto - URL placeholder (funzionalità in sviluppo)
const url = '#'; // topic ? `#help-topic=${topic}` : '#help-general';
// Simula contenuto non disponibile
setTimeout(() => {
content.innerHTML = `
<div class="alert alert-warning">
<i class="fas fa-exclamation-triangle me-2"></i>
Contenuto di aiuto non disponibile - Funzionalità in sviluppo.
<a href="#" class="alert-link disabled" title="Centro Aiuto - Funzionalità in sviluppo">
Centro Aiuto
</a>
</div>
`;
}, 500);
};
// Auto-setup per elementi con attributi data
document.querySelectorAll('[data-confirm]').forEach(element => {
element.addEventListener('click', function(e) {
e.preventDefault();
const message = this.dataset.confirm;
const action = () => {
if (this.tagName === 'A') {
window.location.href = this.href;
} else if (this.tagName === 'FORM' || this.closest('form')) {
(this.closest('form') || this).submit();
}
};
showConfirmModal('Conferma', message, action);
});
});
document.querySelectorAll('[data-delete]').forEach(element => {
element.addEventListener('click', function(e) {
e.preventDefault();
const message = this.dataset.delete;
const action = () => {
if (this.tagName === 'A') {
window.location.href = this.href;
} else if (this.tagName === 'FORM' || this.closest('form')) {
(this.closest('form') || this).submit();
}
};
showDeleteModal(message, action);
});
});
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('globalSearch');
const searchResults = document.getElementById('searchResults');
let searchTimeout;
if (searchInput) {
// Ricerca in tempo reale
searchInput.addEventListener('input', function() {
const query = this.value.trim();
clearTimeout(searchTimeout);
if (query.length < 2) {
searchResults.classList.add('d-none');
return;
}
searchTimeout = setTimeout(() => {
performSearch(query);
}, 300);
});
// Nascondi risultati quando si clicca fuori
document.addEventListener('click', function(e) {
if (!searchInput.contains(e.target) && !searchResults.contains(e.target)) {
searchResults.classList.add('d-none');
}
});
}
function performSearch(query) {
fetch(`#?q=${encodeURIComponent(query)}`, {
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
}
})
.then(response => response.json())
.then(data => {
displaySearchResults(data);
})
.catch(error => {
console.error('Errore ricerca:', error);
});
}
function displaySearchResults(results) {
if (!results || results.length === 0) {
searchResults.innerHTML = '<div class="p-3 text-muted">Nessun risultato trovato</div>';
} else {
searchResults.innerHTML = results.map(result => `
<a href="${result.url}" class="search-result-item d-block text-decoration-none">
<div class="d-flex align-items-center">
<i class="${result.icon} text-muted me-2"></i>
<div>
<div class="fw-semibold">${result.title}</div>
<small class="text-muted">${result.category}</small>
</div>
</div>
</a>
`).join('');
}
searchResults.classList.remove('d-none');
}
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Gestione filtri rapidi mobile
const filterButtons = document.querySelectorAll('.filter-btn');
const searchInput = document.querySelector('#searchMobileModal input[name="q"]');
filterButtons.forEach(button => {
button.addEventListener('click', function() {
const filter = this.dataset.filter;
// Toggle stato attivo
this.classList.toggle('active');
// Aggiorna placeholder in base ai filtri selezionati
const activeFilters = Array.from(document.querySelectorAll('.filter-btn.active'))
.map(btn => btn.textContent.trim());
if (activeFilters.length > 0) {
searchInput.placeholder = `Cerca in: ${activeFilters.join(', ')}`;
} else {
searchInput.placeholder = 'Cerca stabili, condomini, documenti...';
}
});
});
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Segna tutte le notifiche come lette
const markAllReadBtn = document.getElementById('markAllRead');
if (markAllReadBtn) {
markAllReadBtn.addEventListener('click', function() {
fetch('#', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Rimuovi badge e classi unread
document.querySelector('.badge.bg-danger')?.remove();
document.querySelectorAll('.notification-item.unread').forEach(item => {
item.classList.remove('unread');
item.querySelector('.notification-unread')?.remove();
});
this.remove();
}
})
.catch(error => console.error('Errore:', error));
});
}
// Segna singola notifica come letta al click
document.querySelectorAll('.notification-item').forEach(item => {
item.addEventListener('click', function() {
const notificationId = this.dataset.notificationId;
if (this.classList.contains('unread')) {
fetch(`#`, {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
'Content-Type': 'application/json',
},
body: JSON.stringify({ id: notificationId })
})
.then(response => response.json())
.then(data => {
if (data.success) {
this.classList.remove('unread');
this.querySelector('.notification-unread')?.remove();
// Aggiorna contatore
const badge = document.querySelector('.badge.bg-danger');
if (badge) {
const count = parseInt(badge.textContent) - 1;
if (count <= 0) {
badge.remove();
} else {
badge.textContent = count > 99 ? '99+' : count;
}
}
}
})
.catch(error => console.error('Errore:', error));
}
});
});
// Aggiornamenti real-time (WebSocket o polling)
function checkNewNotifications() {
fetch('#', {
headers: {
'X-Requested-With': 'XMLHttpRequest',
}
})
.then(response => response.json())
.then(data => {
if (data.hasNew) {
// Aggiorna badge o ricarica dropdown
location.reload(); // Temporaneo - implementare aggiornamento dinamico
}
})
.catch(error => console.error('Errore check notifiche:', error));
}
// Check ogni 30 secondi
setInterval(checkNewNotifications, 30000);
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Toggle tema
const themeToggle = document.getElementById('themeToggle');
const themeIcon = document.getElementById('themeIcon');
const themeText = document.getElementById('themeText');
if (themeToggle) {
// Stato iniziale
const isDark = document.documentElement.classList.contains('dark') ||
localStorage.getItem('theme') === 'dark';
updateThemeButton(isDark);
themeToggle.addEventListener('click', function() {
const currentTheme = localStorage.getItem('theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
localStorage.setItem('theme', newTheme);
document.documentElement.classList.toggle('dark', newTheme === 'dark');
updateThemeButton(newTheme === 'dark');
// Notifica cambio tema
if (typeof window.updateTheme === 'function') {
window.updateTheme(newTheme);
}
});
}
function updateThemeButton(isDark) {
if (themeIcon && themeText) {
if (isDark) {
themeIcon.className = 'fas fa-sun me-2';
themeText.textContent = 'Tema chiaro';
} else {
themeIcon.className = 'fas fa-moon me-2';
themeText.textContent = 'Tema scuro';
}
}
}
// Conferma logout
const logoutForm = document.querySelector('form[action*="logout"]');
if (logoutForm) {
logoutForm.addEventListener('submit', function(e) {
if (!confirm('Sei sicuro di voler uscire?')) {
e.preventDefault();
}
});
}
});
</script>
</body>
</html>