| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="UTF-8"> |
| <title>Outil de Détection de Fraudes</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| |
| <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> |
| |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| body { |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
| background-color: #f8f9fa; |
| } |
| #sidebar { |
| height: 100vh; |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 220px; |
| background: linear-gradient(180deg, #2c3e50 0%, #1a1a2e 100%); |
| color: #fff; |
| padding-top: 20px; |
| box-shadow: 2px 0 10px rgba(0,0,0,0.1); |
| } |
| #sidebar .nav-link { |
| color: #e2e8f0; |
| padding: 12px 20px; |
| margin: 2px 0; |
| border-radius: 4px; |
| transition: all 0.3s ease; |
| } |
| #sidebar .nav-link:hover { |
| background: rgba(255,255,255,0.1); |
| transform: translateX(5px); |
| } |
| #sidebar .nav-link.active { |
| background: rgba(255,255,255,0.15); |
| border-left: 4px solid #4299e1; |
| } |
| #content { |
| margin-left: 240px; |
| padding: 30px; |
| background-color: white; |
| min-height: 100vh; |
| box-shadow: -2px 0 10px rgba(0,0,0,0.05); |
| } |
| .section { |
| display: none; |
| animation: fadeIn 0.3s ease; |
| } |
| @keyframes fadeIn { |
| from { opacity: 0; transform: translateY(10px); } |
| to { opacity: 1; transform: translateY(0); } |
| } |
| |
| |
| .enhanced-table { |
| width: 100%; |
| border-collapse: separate; |
| border-spacing: 0; |
| margin: 20px 0; |
| box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); |
| border-radius: 8px; |
| overflow: hidden; |
| } |
| .enhanced-table thead th { |
| background-color: #2c3e50; |
| color: white; |
| padding: 12px 15px; |
| text-align: left; |
| font-weight: 600; |
| position: sticky; |
| top: 0; |
| } |
| .enhanced-table tbody tr { |
| transition: all 0.2s ease; |
| } |
| .enhanced-table tbody tr:hover { |
| background-color: rgba(66, 153, 225, 0.1); |
| } |
| .enhanced-table tbody td { |
| padding: 12px 15px; |
| border-bottom: 1px solid #e2e8f0; |
| vertical-align: middle; |
| } |
| .enhanced-table tbody tr:last-child td { |
| border-bottom: none; |
| } |
| |
| |
| ::-webkit-scrollbar { |
| width: 8px; |
| height: 8px; |
| } |
| ::-webkit-scrollbar-track { |
| background: #f1f1f1; |
| } |
| ::-webkit-scrollbar-thumb { |
| background: #cbd5e0; |
| border-radius: 4px; |
| } |
| ::-webkit-scrollbar-thumb:hover { |
| background: #a0aec0; |
| } |
| |
| |
| .nav-tabs .nav-link { |
| color: #4a5568; |
| font-weight: 500; |
| border: none; |
| padding: 12px 20px; |
| margin-right: 5px; |
| } |
| .nav-tabs .nav-link.active { |
| color: #2c3e50; |
| border-bottom: 3px solid #2c3e50; |
| background-color: transparent; |
| } |
| .nav-tabs .nav-link:hover:not(.active) { |
| border-bottom: 3px solid #e2e8f0; |
| } |
| |
| |
| .btn { |
| transition: all 0.2s ease; |
| font-weight: 500; |
| padding: 8px 16px; |
| } |
| .btn-primary { |
| background-color: #2c3e50; |
| border-color: #2c3e50; |
| } |
| .btn-primary:hover { |
| background-color: #1a1a2e; |
| border-color: #1a1a2e; |
| transform: translateY(-2px); |
| } |
| |
| |
| .card { |
| border: none; |
| border-radius: 8px; |
| box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); |
| transition: all 0.3s ease; |
| } |
| .card:hover { |
| transform: translateY(-3px); |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); |
| } |
| |
| |
| @media (max-width: 992px) { |
| #sidebar { |
| width: 180px; |
| } |
| #content { |
| margin-left: 200px; |
| } |
| } |
| @media (max-width: 768px) { |
| #sidebar { |
| width: 100%; |
| height: auto; |
| position: relative; |
| } |
| #content { |
| margin-left: 0; |
| } |
| } |
| </style> |
| |
| <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css"> |
| </head> |
| <body> |
| <div class="container-fluid"> |
| <div class="row"> |
| |
| <nav id="sidebar" class="col-md-2 d-none d-md-block sidebar"> |
| <div class="sidebar-sticky"> |
| <div class="text-center mb-4"> |
| <h4 class="font-bold text-xl text-white">IRS Enquête</h4> |
| <p class="text-xs text-gray-300">Outil de Détection de Fraudes</p> |
| </div> |
| <ul class="nav flex-column"> |
| <li class="nav-item"><a class="nav-link" href="#" onclick="showSection('home')"><i class="fas fa-home mr-2"></i>Accueil</a></li> |
| <li class="nav-item"><a class="nav-link" href="#" onclick="showSection('import')"><i class="fas fa-file-import mr-2"></i>Importer CSV</a></li> |
| <li class="nav-item"><a class="nav-link" href="#" onclick="showSection('filter')"><i class="fas fa-filter mr-2"></i>Filtrer & Rapport</a></li> |
| <li class="nav-item"><a class="nav-link active" href="#" onclick="showSection('lecture')"><i class="fas fa-book-reader mr-2"></i>Lecture</a></li> |
| <li class="nav-item"><a class="nav-link" href="#" onclick="showSection('export')"><i class="fas fa-file-export mr-2"></i>Exporter Rapport</a></li> |
| <li class="nav-item"><a class="nav-link" href="#" onclick="showSection('favorites')"><i class="fas fa-star mr-2"></i>Favoris</a></li> |
| <li class="nav-item"><a class="nav-link" href="#" onclick="showSection('logs')"><i class="fas fa-clipboard-list mr-2"></i>Logs</a></li> |
| </ul> |
| </div> |
| </nav> |
|
|
| |
| <main id="content" class="col-md-9 ml-sm-auto col-lg-10 px-4"> |
| |
| <div id="section-home" class="section"> |
| <div class="flex items-center mb-6"> |
| <h2 class="text-2xl font-bold text-gray-800">Accueil</h2> |
| <span class="ml-2 text-blue-500"><i class="fas fa-home"></i></span> |
| </div> |
| <div class="bg-white rounded-lg shadow p-6"> |
| <p class="text-gray-700">Bienvenue dans l'outil de détection de fraudes IRS Enquête. Utilisez le menu pour naviguer entre les fonctionnalités.</p> |
| <div class="mt-4 grid grid-cols-1 md:grid-cols-3 gap-4"> |
| <div class="bg-blue-50 p-4 rounded-lg border border-blue-100"> |
| <h3 class="font-semibold text-blue-800"><i class="fas fa-file-import mr-2"></i>Importation</h3> |
| <p class="text-sm text-blue-600 mt-2">Importez vos fichiers CSV pour commencer l'analyse.</p> |
| </div> |
| <div class="bg-green-50 p-4 rounded-lg border border-green-100"> |
| <h3 class="font-semibold text-green-800"><i class="fas fa-filter mr-2"></i>Filtrage</h3> |
| <p class="text-sm text-green-600 mt-2">Filtrez les données selon différents critères.</p> |
| </div> |
| <div class="bg-purple-50 p-4 rounded-lg border border-purple-100"> |
| <h3 class="font-semibold text-purple-800"><i class="fas fa-chart-bar mr-2"></i>Analyse</h3> |
| <p class="text-sm text-purple-600 mt-2">Visualisez les résultats sous forme de tableaux et graphiques.</p> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="section-import" class="section"> |
| <div class="flex items-center mb-6"> |
| <h2 class="text-2xl font-bold text-gray-800">Importer CSV</h2> |
| <span class="ml-2 text-blue-500"><i class="fas fa-file-import"></i></span> |
| </div> |
| <div class="bg-white rounded-lg shadow p-6"> |
| <div class="form-group"> |
| <label for="csvInput" class="font-medium text-gray-700">Collez le contenu du CSV (séparateur ;) :</label> |
| <textarea class="form-control mt-1" id="csvInput" rows="10" style="border-radius: 6px; border: 1px solid #e2e8f0;"></textarea> |
| </div> |
| <button class="btn btn-primary mt-3" onclick="importCSV()"> |
| <i class="fas fa-upload mr-2"></i>Importer |
| </button> |
| <div id="importResult" class="mt-4"></div> |
| </div> |
| </div> |
|
|
| |
| <div id="section-filter" class="section"> |
| <div class="flex items-center mb-6"> |
| <h2 class="text-2xl font-bold text-gray-800">Filtrer & Générer Rapport</h2> |
| <span class="ml-2 text-blue-500"><i class="fas fa-filter"></i></span> |
| </div> |
| <div class="bg-white rounded-lg shadow p-6"> |
| <form id="filterForm"> |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
| <div class="form-group"> |
| <label for="dateDebut" class="font-medium text-gray-700">Date début :</label> |
| <input type="date" class="form-control mt-1" id="dateDebut" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| <div class="form-group"> |
| <label for="dateFin" class="font-medium text-gray-700">Date fin :</label> |
| <input type="date" class="form-control mt-1" id="dateFin" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| </div> |
| |
| <div class="form-group mt-4"> |
| <label for="filterText" class="font-medium text-gray-700">Filtrer par Raison (séparez plusieurs critères par ";") :</label> |
| <input type="text" class="form-control mt-1" id="filterText" placeholder="ex: Paiement facture;Transfère" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| |
| <div class="form-group mt-4"> |
| <label for="filterIndicator" class="font-medium text-gray-700">Filtrer par Indicateur (Initiateur) :</label> |
| <input type="text" class="form-control mt-1" id="filterIndicator" placeholder="ex: 68484" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| |
| <div class="form-group mt-4"> |
| <label class="font-medium text-gray-700">Filtrer par Montant :</label> |
| <div class="space-y-3 mt-2"> |
| <div class="form-check"> |
| <input class="form-check-input" type="radio" name="amountFilterMode" id="amountNone" value="none" checked> |
| <label class="form-check-label ml-2 text-gray-700" for="amountNone">Aucun filtre</label> |
| </div> |
| <div class="form-check"> |
| <input class="form-check-input" type="radio" name="amountFilterMode" id="amountGreaterRadio" value="greater"> |
| <label class="form-check-label ml-2 text-gray-700" for="amountGreaterRadio">Montant supérieur à</label> |
| <input type="number" class="form-control mt-1 ml-4" id="amountGreater" placeholder="Valeur" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| <div class="form-check"> |
| <input class="form-check-input" type="radio" name="amountFilterMode" id="amountLessRadio" value="less"> |
| <label class="form-check-label ml-2 text-gray-700" for="amountLessRadio">Montant inférieur à</label> |
| <input type="number" class="form-control mt-1 ml-4" id="amountLess" placeholder="Valeur" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| <div class="form-check"> |
| <input class="form-check-input" type="radio" name="amountFilterMode" id="amountBetweenRadio" value="between"> |
| <label class="form-check-label ml-2 text-gray-700" for="amountBetweenRadio">Montant entre</label> |
| <div class="flex items-center mt-1 ml-4"> |
| <input type="number" class="form-control mr-2" id="amountMin" placeholder="Min" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| <span class="text-gray-500 mx-1">et</span> |
| <input type="number" class="form-control ml-2" id="amountMax" placeholder="Max" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| <div class="flex flex-wrap gap-3 mt-6"> |
| <button type="button" class="btn btn-primary" onclick="generateReport()"> |
| <i class="fas fa-file-alt mr-2"></i>Générer Rapport complet |
| </button> |
| <button type="button" class="btn btn-danger" onclick="resetReportsUI()"> |
| <i class="fas fa-redo mr-2"></i>Remise à zéro des rapports |
| </button> |
| </div> |
| </form> |
| <div id="reportResult" class="mt-6"></div> |
| </div> |
| </div> |
|
|
| |
| <div id="section-lecture" class="section"> |
| <div class="flex items-center mb-6"> |
| <h2 class="text-2xl font-bold text-gray-800">Lecture des Rapports</h2> |
| <span class="ml-2 text-blue-500"><i class="fas fa-book-reader"></i></span> |
| </div> |
| |
| |
| <ul class="nav nav-tabs" id="lectureTabs" role="tablist"> |
| <li class="nav-item"> |
| <a class="nav-link active" id="tab-rapport" data-toggle="tab" href="#view-rapport" role="tab"> |
| <i class="fas fa-file-alt mr-2"></i>Rapport |
| </a> |
| </li> |
| <li class="nav-item"> |
| <a class="nav-link" id="tab-group" data-toggle="tab" href="#view-group" role="tab"> |
| <i class="fas fa-users mr-2"></i>Par groupe |
| </a> |
| </li> |
| <li class="nav-item"> |
| <a class="nav-link" id="tab-indicator" data-toggle="tab" href="#view-indicator" role="tab"> |
| <i class="fas fa-chart-line mr-2"></i>Par indicateur |
| </a> |
| </li> |
| <li class="nav-item"> |
| <a class="nav-link" id="tab-graphs" data-toggle="tab" href="#view-graphs" role="tab"> |
| <i class="fas fa-chart-pie mr-2"></i>Graphiques |
| </a> |
| </li> |
| </ul> |
| |
| <div class="tab-content bg-white rounded-b-lg rounded-tr-lg shadow p-6" id="lectureTabsContent"> |
| <div class="tab-pane fade show active" id="view-rapport" role="tabpanel"> |
| <button class="btn btn-info mb-4" onclick="loadReportData()"> |
| <i class="fas fa-sync-alt mr-2"></i>Rafraîchir Rapport |
| </button> |
| <div id="reportDataDiv" class="mt-2 overflow-x-auto"> |
| |
| </div> |
| </div> |
| <div class="tab-pane fade" id="view-group" role="tabpanel"> |
| <button class="btn btn-info mb-4" onclick="loadGroupData()"> |
| <i class="fas fa-sync-alt mr-2"></i>Rafraîchir Par groupe |
| </button> |
| <div id="groupDataDiv" class="mt-2 overflow-x-auto"> |
| |
| </div> |
| </div> |
| <div class="tab-pane fade" id="view-indicator" role="tabpanel"> |
| <button class="btn btn-info mb-4" onclick="loadIndicatorData()"> |
| <i class="fas fa-sync-alt mr-2"></i>Rafraîchir Par indicateur |
| </button> |
| <div id="indicatorDataDiv" class="mt-2 overflow-x-auto"> |
| |
| </div> |
| </div> |
| <div class="tab-pane fade" id="view-graphs" role="tabpanel"> |
| <button class="btn btn-info mb-4" onclick="loadGraphs()"> |
| <i class="fas fa-sync-alt mr-2"></i>Rafraîchir Graphiques |
| </button> |
| <div id="graphsDiv" class="mt-2"> |
| |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="section-export" class="section"> |
| <div class="flex items-center mb-6"> |
| <h2 class="text-2xl font-bold text-gray-800">Exporter Rapport</h2> |
| <span class="ml-2 text-blue-500"><i class="fas fa-file-export"></i></span> |
| </div> |
| <div class="bg-white rounded-lg shadow p-6"> |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> |
| <button class="btn btn-secondary" onclick="exportReportsCSVZipUI()"> |
| <i class="fas fa-file-csv mr-2"></i>Exporter Rapport en CSV (ZIP) |
| </button> |
| <button class="btn btn-secondary" onclick="exportReportsPDFZipUI()"> |
| <i class="fas fa-file-pdf mr-2"></i>Exporter Rapport en PDF (ZIP) |
| </button> |
| </div> |
| <div id="exportResult" class="mt-4"></div> |
| </div> |
| </div> |
|
|
| |
| <div id="section-favorites" class="section"> |
| <div class="flex items-center mb-6"> |
| <h2 class="text-2xl font-bold text-gray-800">Favoris</h2> |
| <span class="ml-2 text-blue-500"><i class="fas fa-star"></i></span> |
| </div> |
| <div class="bg-white rounded-lg shadow p-6"> |
| <form id="favoriteForm"> |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
| <div class="form-group"> |
| <label for="favName" class="font-medium text-gray-700">Nom du favori :</label> |
| <input type="text" class="form-control mt-1" id="favName" required style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| <div class="form-group"> |
| <label for="favDateDebut" class="font-medium text-gray-700">Date début :</label> |
| <input type="date" class="form-control mt-1" id="favDateDebut" required style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| <div class="form-group"> |
| <label for="favDateFin" class="font-medium text-gray-700">Date fin :</label> |
| <input type="date" class="form-control mt-1" id="favDateFin" required style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| <div class="form-group"> |
| <label for="favFilterText" class="font-medium text-gray-700">Filtrer par Raison :</label> |
| <input type="text" class="form-control mt-1" id="favFilterText" placeholder="ex: Paiement facture;Transfère" required style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| </div> |
| |
| <div class="form-group mt-4"> |
| <label class="font-medium text-gray-700">Filtrer par Montant :</label> |
| <div class="space-y-3 mt-2"> |
| <div class="form-check"> |
| <input class="form-check-input" type="radio" name="favAmountFilterMode" id="favAmountNone" value="none" checked> |
| <label class="form-check-label ml-2 text-gray-700" for="favAmountNone">Aucun filtre</label> |
| </div> |
| <div class="form-check"> |
| <input class="form-check-input" type="radio" name="favAmountFilterMode" id="favAmountGreater" value="greater"> |
| <label class="form-check-label ml-2 text-gray-700" for="favAmountGreater">Montant supérieur à</label> |
| <input type="number" class="form-control mt-1 ml-4" id="favAmountGreaterVal" placeholder="Valeur" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| <div class="form-check"> |
| <input class="form-check-input" type="radio" name="favAmountFilterMode" id="favAmountLess" value="less"> |
| <label class="form-check-label ml-2 text-gray-700" for="favAmountLess">Montant inférieur à</label> |
| <input type="number" class="form-control mt-1 ml-4" id="favAmountLessVal" placeholder="Valeur" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| <div class="form-check"> |
| <input class="form-check-input" type="radio" name="favAmountFilterMode" id="favAmountBetween" value="between"> |
| <label class="form-check-label ml-2 text-gray-700" for="favAmountBetween">Montant entre</label> |
| <div class="flex items-center mt-1 ml-4"> |
| <input type="number" class="form-control mr-2" id="favAmountMin" placeholder="Min" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| <span class="text-gray-500 mx-1">et</span> |
| <input type="number" class="form-control ml-2" id="favAmountMax" placeholder="Max" style="border-radius: 6px; border: 1px solid #e2e8f0;"> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| <button type="button" class="btn btn-primary mt-4" onclick="saveFavorite()"> |
| <i class="fas fa-save mr-2"></i>Enregistrer Favori |
| </button> |
| </form> |
| |
| <hr class="my-6 border-gray-200"> |
| |
| <div class="flex items-center justify-between mb-4"> |
| <h4 class="font-bold text-lg text-gray-800">Liste des Favoris</h4> |
| <button class="btn btn-secondary" onclick="loadFavorites()"> |
| <i class="fas fa-sync-alt mr-2"></i>Charger Favoris |
| </button> |
| </div> |
| <div id="favoritesList" class="overflow-x-auto"></div> |
| </div> |
| </div> |
|
|
| |
| <div id="section-logs" class="section"> |
| <div class="flex items-center mb-6"> |
| <h2 class="text-2xl font-bold text-gray-800">Logs</h2> |
| <span class="ml-2 text-blue-500"><i class="fas fa-clipboard-list"></i></span> |
| </div> |
| <div class="bg-white rounded-lg shadow p-6"> |
| <div class="flex items-center justify-between mb-4"> |
| <h4 class="font-bold text-lg text-gray-800">Historique des activités</h4> |
| <button class="btn btn-secondary" onclick="loadLogs()"> |
| <i class="fas fa-sync-alt mr-2"></i>Charger Logs |
| </button> |
| </div> |
| <div id="logsList" class="overflow-x-auto"></div> |
| </div> |
| </div> |
| </main> |
| </div> |
| </div> |
|
|
| |
| <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> |
| <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script> |
| <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> |
|
|
| |
| <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script> |
|
|
| <script> |
| |
| function showNotification(elementId, message, type) { |
| var alertClass = { |
| 'success': 'bg-green-100 border-green-400 text-green-700', |
| 'danger': 'bg-red-100 border-red-400 text-red-700', |
| 'info': 'bg-blue-100 border-blue-400 text-blue-700', |
| 'warning': 'bg-yellow-100 border-yellow-400 text-yellow-700' |
| }; |
| |
| var notification = document.createElement('div'); |
| notification.className = `border-l-4 p-4 mb-4 rounded ${alertClass[type]}`; |
| notification.innerHTML = ` |
| <div class="flex items-center"> |
| <div class="flex-shrink-0"> |
| ${type === 'success' ? '<i class="fas fa-check-circle text-green-500"></i>' : |
| type === 'danger' ? '<i class="fas fa-exclamation-circle text-red-500"></i>' : |
| type === 'info' ? '<i class="fas fa-info-circle text-blue-500"></i>' : |
| '<i class="fas fa-exclamation-triangle text-yellow-500"></i>'} |
| </div> |
| <div class="ml-3"> |
| <p class="text-sm">${message}</p> |
| </div> |
| <div class="ml-auto pl-3"> |
| <button type="button" class="text-gray-500 hover:text-gray-700" onclick="this.parentElement.parentElement.remove()"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| </div> |
| `; |
| |
| document.getElementById(elementId).appendChild(notification); |
| } |
| |
| |
| function showSection(section) { |
| var sections = document.querySelectorAll('.section'); |
| sections.forEach(function(sec) { sec.style.display = 'none'; }); |
| document.getElementById('section-' + section).style.display = 'block'; |
| |
| |
| document.querySelectorAll('#sidebar .nav-link').forEach(function(link) { |
| link.classList.remove('active'); |
| }); |
| document.querySelector(`#sidebar .nav-link[onclick="showSection('${section}')"]`).classList.add('active'); |
| } |
| showSection('home'); |
| |
| |
| function importCSV() { |
| var csvText = document.getElementById('csvInput').value; |
| google.script.run.withSuccessHandler(function(response) { |
| showNotification('importResult', response, "success"); |
| }).withFailureHandler(function(error) { |
| showNotification('importResult', "Erreur : " + error.message, "danger"); |
| }).importCSVData(csvText); |
| } |
| |
| |
| function generateReport() { |
| var criteria = { |
| dateDebut: document.getElementById('dateDebut').value, |
| dateFin: document.getElementById('dateFin').value, |
| filterText: document.getElementById('filterText').value, |
| filterIndicator: document.getElementById('filterIndicator').value, |
| amountFilterMode: document.querySelector('input[name="amountFilterMode"]:checked').value, |
| amountGreater: document.getElementById('amountGreater').value, |
| amountLess: document.getElementById('amountLess').value, |
| amountMin: document.getElementById('amountMin').value, |
| amountMax: document.getElementById('amountMax').value |
| }; |
| google.script.run.withSuccessHandler(function(response) { |
| showNotification('reportResult', response, "success"); |
| }).withFailureHandler(function(error) { |
| showNotification('reportResult', "Erreur : " + error.message, "danger"); |
| }).filterAndGenerateReport(criteria); |
| } |
| |
| |
| function resetReportsUI() { |
| google.script.run.withSuccessHandler(function(response) { |
| showNotification('reportResult', response, "info"); |
| }).withFailureHandler(function(error) { |
| showNotification('reportResult', "Erreur lors de la remise à zéro : " + error.message, "danger"); |
| }).resetReports(); |
| } |
| |
| |
| function exportReportsCSVZipUI() { |
| google.script.run.withSuccessHandler(function(base64Zip) { |
| var link = document.createElement("a"); |
| link.href = "data:application/zip;base64," + base64Zip; |
| link.download = "Rapports_CSV.zip"; |
| link.click(); |
| showNotification('exportResult', "Export CSV (ZIP) réussi.", "success"); |
| }).withFailureHandler(function(error) { |
| showNotification('exportResult', "Erreur lors de l'export CSV (ZIP) : " + error.message, "danger"); |
| }).exportReportsCSVAsBase64(); |
| } |
| |
| |
| function exportReportsPDFZipUI() { |
| google.script.run.withSuccessHandler(function(base64Zip) { |
| var link = document.createElement("a"); |
| link.href = "data:application/zip;base64," + base64Zip; |
| link.download = "Rapports_PDF.zip"; |
| link.click(); |
| showNotification('exportResult', "Export PDF (ZIP) réussi.", "success"); |
| }).withFailureHandler(function(error) { |
| showNotification('exportResult', "Erreur lors de l'export PDF (ZIP) : " + error.message, "danger"); |
| }).exportReportsPDFZipAsBase64(); |
| } |
| |
| |
| function saveFavorite() { |
| var fav = { |
| name: document.getElementById('favName').value, |
| dateDebut: document.getElementById('favDateDebut').value, |
| dateFin: document.getElementById('favDateFin').value, |
| filterText: document.getElementById('favFilterText').value, |
| amountFilterMode: document.querySelector('input[name="favAmountFilterMode"]:checked').value, |
| amountGreater: document.getElementById('favAmountGreaterVal').value, |
| amountLess: document.getElementById('favAmountLessVal').value, |
| amountMin: document.getElementById('favAmountMin').value, |
| amountMax: document.getElementById('favAmountMax').value |
| }; |
| google.script.run.withSuccessHandler(function(response) { |
| showNotification('favoritesList', response, "success"); |
| loadFavorites(); |
| }).withFailureHandler(function(error) { |
| showNotification('favoritesList', "Erreur : " + error.message, "danger"); |
| }).saveFavorite(fav); |
| } |
| |
| function loadFavorites() { |
| google.script.run.withSuccessHandler(function(data) { |
| if (!data || data.length <= 1) { |
| document.getElementById('favoritesList').innerHTML = '<p class="text-gray-500">Aucun favori enregistré.</p>'; |
| return; |
| } |
| |
| var html = '<table class="enhanced-table"><thead><tr><th>Date</th><th>Nom</th><th>Date Début</th><th>Date Fin</th><th>Filtre Raison</th><th>Mode Montant</th><th>Valeur(s)</th></tr></thead><tbody>'; |
| |
| for (var i = 1; i < data.length; i++) { |
| html += '<tr>'; |
| for (var j = 0; j < data[i].length; j++) { |
| html += '<td>' + (data[i][j] || '') + '</td>'; |
| } |
| html += '</tr>'; |
| } |
| |
| html += '</tbody></table>'; |
| document.getElementById('favoritesList').innerHTML = html; |
| |
| |
| $('#favoritesList table').DataTable({ |
| "pageLength": 10, |
| "ordering": true, |
| "searching": true, |
| "language": { "url": "//cdn.datatables.net/plug-ins/1.10.21/i18n/French.json" } |
| }); |
| }).getFavorites(); |
| } |
| |
| function loadLogs() { |
| google.script.run.withSuccessHandler(function(data) { |
| if (!data || data.length <= 1) { |
| document.getElementById('logsList').innerHTML = '<p class="text-gray-500">Aucun log disponible.</p>'; |
| return; |
| } |
| |
| var html = '<table class="enhanced-table"><thead><tr><th>Date</th><th>Action</th><th>Détails</th></tr></thead><tbody>'; |
| |
| for (var i = 1; i < data.length; i++) { |
| html += '<tr>'; |
| for (var j = 0; j < data[i].length; j++) { |
| html += '<td>' + (data[i][j] || '') + '</td>'; |
| } |
| html += '</tr>'; |
| } |
| |
| html += '</tbody></table>'; |
| document.getElementById('logsList').innerHTML = html; |
| |
| |
| $('#logsList table').DataTable({ |
| "pageLength": 10, |
| "ordering": true, |
| "searching": true, |
| "language": { "url": "//cdn.datatables.net/plug-ins/1.10.21/i18n/French.json" } |
| }); |
| }).getLogs(); |
| } |
| |
| |
| var reportDataCache = []; |
| function loadReportData() { |
| google.script.run.withSuccessHandler(function(data) { |
| reportDataCache = data; |
| var html = generateEnhancedTableHTML(reportDataCache); |
| document.getElementById('reportDataDiv').innerHTML = html; |
| $('#reportDataDiv table').DataTable({ |
| "pageLength": 100, |
| "ordering": true, |
| "searching": true, |
| "language": { "url": "//cdn.datatables.net/plug-ins/1.10.21/i18n/French.json" } |
| }); |
| }).getReportData(); |
| } |
| |
| function loadGroupData() { |
| google.script.run.withSuccessHandler(function(data) { |
| var html = generateEnhancedTableHTML(data); |
| document.getElementById('groupDataDiv').innerHTML = html; |
| $('#groupDataDiv table').DataTable({ |
| "pageLength": 100, |
| "ordering": true, |
| "searching": true, |
| "language": { "url": "//cdn.datatables.net/plug-ins/1.10.21/i18n/French.json" } |
| }); |
| }).getGroupData(); |
| } |
| |
| function loadIndicatorData() { |
| google.script.run.withSuccessHandler(function(data) { |
| var html = generateEnhancedTableHTML(data); |
| document.getElementById('indicatorDataDiv').innerHTML = html; |
| $('#indicatorDataDiv table').DataTable({ |
| "pageLength": 100, |
| "ordering": true, |
| "searching": true, |
| "language": { "url": "//cdn.datatables.net/plug-ins/1.10.21/i18n/French.json" } |
| }); |
| }).getIndicatorData(); |
| } |
| |
| function generateEnhancedTableHTML(data) { |
| if (!data || data.length === 0) return "<div class='bg-gray-50 p-4 rounded-lg border border-gray-200 text-center text-gray-500'>Aucune donnée disponible.</div>"; |
| |
| var html = "<table class='enhanced-table'><thead><tr>"; |
| |
| |
| data[0].forEach(function(header) { |
| html += "<th class='text-left'>" + header + "</th>"; |
| }); |
| |
| html += "</tr></thead><tbody>"; |
| |
| |
| for (var i = 1; i < data.length; i++) { |
| html += "<tr>"; |
| data[i].forEach(function(cell) { |
| |
| if (!isNaN(parseFloat(cell)) && cell.toString().indexOf('.') !== -1) { |
| html += "<td class='text-right font-medium'>" + parseFloat(cell).toFixed(2) + "</td>"; |
| } else { |
| html += "<td>" + (cell || '') + "</td>"; |
| } |
| }); |
| html += "</tr>"; |
| } |
| |
| html += "</tbody></table>"; |
| return html; |
| } |
| |
| |
| function loadGraphs() { |
| google.script.run.withSuccessHandler(function(html) { |
| document.getElementById('graphsDiv').innerHTML = html; |
| }).withFailureHandler(function(error) { |
| showNotification('exportResult', "Erreur lors du chargement des graphiques : " + error.message, "danger"); |
| }).getGraphsHTML(); |
| } |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=gtkh/test5" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |