From 39b8b641162d4b00d6f110175e6ca2a1977d4d83 Mon Sep 17 00:00:00 2001 From: "fefe.clochette" Date: Mon, 23 Mar 2026 18:44:23 +0100 Subject: [PATCH] input --- modules/budget/budget.css | 35 ++- modules/budget/includes/api/save-savings.php | 27 ++ modules/budget/views/budget_prev.php | 154 ++++------- modules/budget/views/epargne.php | 256 ++++++++++--------- 4 files changed, 242 insertions(+), 230 deletions(-) diff --git a/modules/budget/budget.css b/modules/budget/budget.css index 473a681..9dac249 100644 --- a/modules/budget/budget.css +++ b/modules/budget/budget.css @@ -213,7 +213,7 @@ font-size: 1.1rem; } -.btn-icon:hover:hover { +.btn-icon:hover { background: #e2e8f0; transform: scale(1.1); } @@ -558,7 +558,7 @@ input[type="number"] { } } -/* --- 10. BUDGET PREVISIONNEL (TIMELINE 2025) --- */ +/* --- 10. BUDGET PREVISIONNEL (TIMELINE) --- */ .prev-container { display: flex; @@ -1111,3 +1111,34 @@ input[type="month"].pf-input { border: 1px solid #cbd5e1; border-radius: var(--radius-s); } + +/* ============================================================================ + 14. EPARGNE (epargne.php) + ============================================================================ */ + +/* Style compact pour les inputs intégrés au tableau d'épargne */ +.epargne-inline-input { + width: 100%; + min-width: 60px; + max-width: 85px; + border: 1px solid transparent; + background: transparent; + text-align: center; + padding: 2px 4px; + border-radius: 4px; + transition: 0.2s; + font-size: 0.85rem; + margin: 0 auto; +} + +.epargne-inline-input:hover { + border-color: #cbd5e1; + background: #f8fafc; +} + +.epargne-inline-input:focus { + border-color: var(--primary); + background: #fff; + outline: none; + box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.1); +} diff --git a/modules/budget/includes/api/save-savings.php b/modules/budget/includes/api/save-savings.php index 001d7fd..7bdede2 100644 --- a/modules/budget/includes/api/save-savings.php +++ b/modules/budget/includes/api/save-savings.php @@ -3,6 +3,33 @@ require __DIR__ . '/../../../../includes/auth.php'; require __DIR__ . '/../../../../includes/db.php'; require_login(); +// ================================================================= +// MISE À JOUR D'UNE CELLULE EN DIRECT (AJAX) +// ================================================================= +if ($action === 'update_single_entry') { + header('Content-Type: application/json'); + $month = $_POST['month_date']; + $cat = $_POST['category']; + $owner = $_POST['owner']; + $amount = (float)$_POST['amount']; + + try { + if ($amount == 0 && $cat !== 'TOTAL_BANQUE') { + // Si on met à 0 une ligne (autre que le total), on supprime l'entrée pour garder la base propre + $stmt = $pdo->prepare("DELETE FROM pf_savings WHERE month_date=? AND owner=? AND category=?"); + $stmt->execute([$month, $owner, $cat]); + } else { + // Sinon on insère ou on met à jour + $stmt = $pdo->prepare("INSERT INTO pf_savings (month_date, owner, category, amount) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE amount = VALUES(amount)"); + $stmt->execute([$month, $owner, $cat, $amount]); + } + echo json_encode(['success' => true]); + } catch (Exception $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); + } + exit; +} + // --- ACTION : SUPPRESSION D'UNE ENTRÉE UNIQUE --- if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'delete_entry') { $owner = $_POST['owner']; diff --git a/modules/budget/views/budget_prev.php b/modules/budget/views/budget_prev.php index 3ff2a5e..55af148 100644 --- a/modules/budget/views/budget_prev.php +++ b/modules/budget/views/budget_prev.php @@ -11,7 +11,6 @@ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $salaryConfig[$row['person']] = $row; } -// Init si vide foreach (['Alex', 'Laia'] as $p) { if (!isset($salaryConfig[$p])) { $salaryConfig[$p] = ['salary'=>0, 'mensualite'=>0, 'frais_func'=>0, 'eco_perso'=>0, 'eco_family'=>0]; @@ -25,16 +24,26 @@ $cats = $pdo->query("SELECT * FROM pf_alloc_categories ORDER BY sort_order ASC, $focusDate = isset($_GET['focus_date']) ? $_GET['focus_date'] : date('Y-m-01'); $focusTs = strtotime($focusDate); -// On affiche 6 mois (Timeline inversée) $months = []; for ($i = 0; $i < 6; $i++) { $months[] = date('Y-m-01', strtotime("-$i months", $focusTs)); } -// Liens navigation $prevMonthLink = date('Y-m-01', strtotime("-1 month", $focusTs)); $nextMonthLink = date('Y-m-01', strtotime("+1 month", $focusTs)); +// NOUVEAU : Récupération des Cycles configurés dans pf_notes +$cycleConfigs = []; +$stmtNotes = $pdo->query("SELECT reference_id, content FROM pf_notes WHERE note_type = 'month_config'"); +while ($row = $stmtNotes->fetch(PDO::FETCH_ASSOC)) { + // Convertit "03-2026" en "2026-03-01" (Notre Tiroir) + $parts = explode('-', $row['reference_id']); + if (count($parts) == 2) { + $mKey = $parts[1] . '-' . $parts[0] . '-01'; + $cycleConfigs[$mKey] = json_decode($row['content'], true); + } +} + // 4. Récupération Valeurs Répartition $inQuery = implode(',', array_fill(0, count($months), '?')); $stmt = $pdo->prepare("SELECT * FROM pf_alloc_values WHERE month_date IN ($inQuery)"); @@ -46,19 +55,16 @@ while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { } // 5. Récupération de l'ID de la catégorie système -// On cherche l'ID de la catégorie 'SYSTEM_VALIDATION' $sysCatId = null; foreach ($cats as $key => $c) { if ($c['name'] === 'SYSTEM_VALIDATION') { $sysCatId = $c['id']; - // IMPORTANT : On retire cette catégorie de la liste affichable ($cats) - // pour qu'elle n'apparaisse pas dans le tableau HTML ! unset($cats[$key]); break; } } -// 6. Lecture des statuts de validation (1 = Validé, 0 = Non) +// 6. Lecture des statuts de validation $focusDate = $months[0]; $isValidatedAlex = false; $isValidatedLaia = false; @@ -73,7 +79,7 @@ $stmtNote = $pdo->prepare("SELECT content FROM pf_notes WHERE note_type = 'budge $stmtNote->execute([$focusDate]); $currentNote = $stmtNote->fetchColumn(); -// 7. Récupération des vacances actives pour les lier au budget +// 7. Récupération des vacances actives $activeHolidays = $pdo->query("SELECT id, title FROM pf_holidays WHERE status IN ('draft', 'planned', 'booked') ORDER BY start_date ASC")->fetchAll(PDO::FETCH_ASSOC); ?> @@ -154,6 +160,13 @@ $activeHolidays = $pdo->query("SELECT id, title FROM pf_holidays WHERE status IN ?> + Dès le $cStart"; + } + ?> @@ -188,10 +201,9 @@ $activeHolidays = $pdo->query("SELECT id, title FROM pf_holidays WHERE status IN @@ -283,16 +295,11 @@ $activeHolidays = $pdo->query("SELECT id, title FROM pf_holidays WHERE status IN query("SELECT id, title FROM pf_holidays WHERE status IN } $allTargets = array_unique($allTargets); - // 3. Calcul des sommes (Logiciel d'affichage) $summaryData = []; foreach($allTargets as $t) $summaryData[$t] = ['Alex' => 0, 'Laia' => 0]; @@ -319,7 +325,6 @@ $activeHolidays = $pdo->query("SELECT id, title FROM pf_holidays WHERE status IN $summaryData[$t]['Laia'] += $val['amount_laia']; } - // Récupération des totaux pour le footer $grandTotalAlex = 0; $grandTotalLaia = 0; $grandTotalGlobal = 0; @@ -371,7 +376,7 @@ $activeHolidays = $pdo->query("SELECT id, title FROM pf_holidays WHERE status IN @@ -475,17 +480,16 @@ $activeHolidays = $pdo->query("SELECT id, title FROM pf_holidays WHERE status IN