fix holidays

This commit is contained in:
2026-05-05 08:57:15 +02:00
parent 2cb62d7ead
commit 5b050a7c24
5 changed files with 92 additions and 31 deletions
+38
View File
@@ -323,6 +323,23 @@ body.no-scroll {
margin-top: auto; margin-top: auto;
} }
.modal-footer {
display: flex;
justify-content: flex-end;
gap: 12px;
margin-top: 24px;
padding-top: 20px;
border-top: 1px solid var(--border-light);
width: 100%; /* Empêche le débordement */
box-sizing: border-box;
}
/* On s'assure que les boutons ne sont pas géants par défaut */
.modal-footer .pf-btn {
width: auto;
min-width: 100px;
}
/* Notifications Toasts */ /* Notifications Toasts */
.pf-toast { .pf-toast {
position: fixed; position: fixed;
@@ -395,6 +412,8 @@ body.no-scroll {
.pf-modal { .pf-modal {
align-items: flex-end; /* Aligne la modale en bas */ align-items: flex-end; /* Aligne la modale en bas */
padding: 0; padding: 0;
z-index: 1000 !important;
background: rgba(15, 23, 42, 0.75);
} }
.pf-modal-content { .pf-modal-content {
@@ -409,6 +428,18 @@ body.no-scroll {
transform: translateY(100%); transform: translateY(100%);
animation: slideUpSheet 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards; animation: slideUpSheet 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
max-height: 92vh; /* Laisse un petit espace en haut */ max-height: 92vh; /* Laisse un petit espace en haut */
z-index: 1001;
overflow: hidden;
}
.prev-section-header,
.view-header {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap; /* Important pour le mobile */
gap: 15px;
margin-bottom: 20px;
width: 100%;
} }
/* Barre de drag visuelle en haut de la modale */ /* Barre de drag visuelle en haut de la modale */
@@ -422,6 +453,13 @@ body.no-scroll {
margin: -10px auto 20px auto; margin: -10px auto 20px auto;
} }
.modal-footer {
flex-direction: column-reverse; /* Empilement propre sur mobile */
}
.modal-footer .pf-btn {
width: 100%; /* Largeur totale uniquement sur mobile */
}
@keyframes slideUpSheet { @keyframes slideUpSheet {
to { to {
transform: translateY(0); transform: translateY(0);
+23
View File
@@ -599,6 +599,11 @@ input[type="number"] {
overflow-x: auto; overflow-x: auto;
white-space: nowrap; white-space: nowrap;
} }
.pf-btn {
position: relative !important;
right: auto !important;
top: auto !important;
}
.form-row { .form-row {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
@@ -664,6 +669,19 @@ input[type="number"] {
font-weight: 700; font-weight: 700;
} }
.prev-section-header,
.view-header,
.budget-view > div[style*="justify-content: space-between"] {
display: flex !important;
flex-direction: row !important;
justify-content: space-between !important;
align-items: center !important;
float: none !important; /* On annule tout float résiduel */
position: relative !important; /* On s'assure qu'il n'est pas en absolute */
width: 100% !important;
gap: 15px !important;
}
.prev-salary-table { .prev-salary-table {
width: 100%; width: 100%;
max-width: 900px; max-width: 900px;
@@ -1009,6 +1027,11 @@ th.col-laia {
.budget-view > div[style*="display:grid"] > div { .budget-view > div[style*="display:grid"] > div {
padding: 12px 10px !important; padding: 12px 10px !important;
} }
.budget-view
> div[style*="justify-content: space-between"]:not(.view-header) {
flex-direction: column !important;
align-items: stretch !important;
}
/* 4. EN-TÊTES EPARGNE (Titre isolé, boutons 50/50 en dessous) */ /* 4. EN-TÊTES EPARGNE (Titre isolé, boutons 50/50 en dessous) */
.budget-view .budget-view
+6 -6
View File
@@ -139,24 +139,24 @@ function getTranslatedMonthName($dateString) {
</div> </div>
<div> <div>
<div class="prev-section-header"> <div class="prev-section-header" style="background: #f8fafc; padding: 15px; border-radius: 12px; border: 1px solid #e2e8f0; margin-bottom: 20px;">
<div style="display:flex; gap:10px; align-items:center;"> <div style="display:flex; gap:10px; align-items:center;">
<h2><?= tr('bud_prev_budget_alloc') ?></h2> <h2 style="margin:0; font-size:1.3rem;"><?= tr('bud_prev_budget_alloc') ?></h2>
<div class="nav-group"> <div class="nav-group" style="display:flex; gap:5px;">
<a href="?tab=budget_prev&focus_date=<?= $prevMonthLink ?>" class="btn-nav">◀</a> <a href="?tab=budget_prev&focus_date=<?= $prevMonthLink ?>" class="btn-nav">◀</a>
<a href="?tab=budget_prev&focus_date=<?= date('Y-m-01') ?>" class="btn-nav"><?= tr('bud_prev_today') ?></a> <a href="?tab=budget_prev&focus_date=<?= date('Y-m-01') ?>" class="btn-nav"><?= tr('bud_prev_today') ?></a>
<a href="?tab=budget_prev&focus_date=<?= $nextMonthLink ?>" class="btn-nav">▶</a> <a href="?tab=budget_prev&focus_date=<?= $nextMonthLink ?>" class="btn-nav">▶</a>
</div> </div>
</div> </div>
<div style="display:flex; gap:10px;"> <div style="display:flex; gap:10px;">
<button class="pf-btn btn-secondary" onclick="duplicateMonth()"> <button type="button" class="pf-btn btn-secondary" onclick="duplicateMonth()">
🔁 <?= tr('bud_sav_add_one_month') ?> 🔁 <?= tr('bud_sav_add_one_month') ?>
</button> </button>
<button class="pf-btn" onclick="document.getElementById('addCatModal').style.display='flex'; document.body.classList.add('no-scroll');"> <button type="button" class="pf-btn" onclick="document.getElementById('addCatModal').style.display='flex'; document.body.classList.add('no-scroll');">
<?= tr('bud_prev_new_line') ?> <?= tr('bud_prev_new_line') ?>
</button> </button>
</div> </div>
</div> </div>
<div class="prev-timeline-wrapper"> <div class="prev-timeline-wrapper">
<table class="prev-alloc-table"> <table class="prev-alloc-table">
+11 -12
View File
@@ -578,7 +578,7 @@ $monthName = $monthNames[(int)$viewM] . ' ' . $viewY;
<div class="form-group" id="blockInputFrais" style="margin-bottom:15px; display:none;"> <div class="form-group" id="blockInputFrais" style="margin-bottom:15px; display:none;">
<label class="pf-label"><?= tr('bud_fixed_charge') ?></label> <label class="pf-label"><?= tr('bud_fixed_charge') ?></label>
<select name="budget_item_id" id="fraisSelect" class="pf-input" disabled> <select name="budget_item_id" id="fraisSelect" class="pf-input" disabled>
<option value=""><?= tr('hdl_select_beneficiary') ?></option> <option value=""><?= tr('bud_select_beneficiary') ?></option>
<?php foreach ($fixedChargesList as $fc): ?><option value="<?= $fc['id'] ?>"><?= htmlspecialchars($fc['name']) ?></option><?php endforeach; ?> <?php foreach ($fixedChargesList as $fc): ?><option value="<?= $fc['id'] ?>"><?= htmlspecialchars($fc['name']) ?></option><?php endforeach; ?>
</select> </select>
</div> </div>
@@ -586,7 +586,7 @@ $monthName = $monthNames[(int)$viewM] . ' ' . $viewY;
<div class="form-group" id="blockInputIncome" style="margin-bottom:15px; display:none;"> <div class="form-group" id="blockInputIncome" style="margin-bottom:15px; display:none;">
<label class="pf-label"><?= tr('bud_expected_income') ?></label> <label class="pf-label"><?= tr('bud_expected_income') ?></label>
<select name="budget_item_id" id="incomeSelect" class="pf-input" disabled> <select name="budget_item_id" id="incomeSelect" class="pf-input" disabled>
<option value=""><?= tr('hdl_select_beneficiary') ?> </option> <option value=""><?= tr('bud_select_beneficiary') ?> </option>
<?php foreach ($incomeList as $inc): ?><option value="<?= $inc['id'] ?>"><?= htmlspecialchars($inc['name']) ?></option><?php endforeach; ?> <?php foreach ($incomeList as $inc): ?><option value="<?= $inc['id'] ?>"><?= htmlspecialchars($inc['name']) ?></option><?php endforeach; ?>
</select> </select>
</div> </div>
@@ -622,23 +622,22 @@ $monthName = $monthNames[(int)$viewM] . ' ' . $viewY;
<div id="importCsvModal" class="pf-modal" style="display: <?= $showPreview ? 'flex' : 'none' ?>;"> <div id="importCsvModal" class="pf-modal" style="display: <?= $showPreview ? 'flex' : 'none' ?>;">
<div class="pf-modal-content <?= $showPreview ? 'modal-large' : '' ?>"> <div class="pf-modal-content <?= $showPreview ? 'modal-large' : '' ?>">
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;"> <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;">
<h3 class="pf-modal-title" style="margin:0; border:none; padding:0;"><?= tr('bud_import_csv') ?? 'Importer un fichier CSV' ?></h3> <h3 class="pf-modal-title" style="margin:0; border:none; padding:0;"><?= tr('bud_import_csv') ?></h3>
<button type="button" onclick="<?= $showPreview ? "window.location.href='?tab=suivi&m=$viewM&y=$viewY';" : "closeSuiviModal('importCsvModal');" ?>" class="pf-modal-close" style="font-size:1.8rem; background:none; border:none; cursor:pointer; color:#64748b; padding:0; line-height:1;">&times;</button> <button type="button" onclick="closeSuiviModal('importCsvModal')" class="pf-modal-close" style="background:none; border:none; font-size:1.5rem; cursor:pointer;">&times;</button>
</div> </div>
<?php if (!$showPreview): ?> <?php if (!$showPreview): ?>
<form method="POST" enctype="multipart/form-data" style="display:flex; flex-direction:column; gap:20px;"> <form method="POST" enctype="multipart/form-data">
<div class="import-dropzone"> <div class="import-dropzone">
<div style="font-size: 2.5rem; margin-bottom: 10px;">📄</div> <div style="font-size: 2.5rem; margin-bottom: 10px;">📄</div>
<label class="pf-label" style="font-size: 1rem; color: #1e293b; margin-bottom: 10px;"><?= tr('bud_csv_file') ?? 'Sélectionnez le fichier de votre banque' ?></label> <label class="pf-label"><?= tr('bud_csv_file') ?></label>
<input type="file" name="csv_file" accept=".csv" class="pf-input" style="max-width: 300px; margin: 0 auto; display: block;" required> <input type="file" name="csv_file" accept=".csv" class="pf-input" style="max-width: 300px; margin: 10px auto; display: block;" required>
</div> </div>
<div class="modal-footer" style="margin-top:0; border-top:none;"> <div class="modal-footer">
<button type="button" onclick="closeSuiviModal('importCsvModal')" class="pf-btn btn-secondary"><?= tr('btn_cancel') ?></button> <button type="button" onclick="closeSuiviModal('importCsvModal')" class="pf-btn btn-secondary"><?= tr('btn_cancel') ?></button>
<button type="submit" class="pf-btn"><?= tr('bud_preview') ?? 'Prévisualiser' ?></button> <button type="submit" class="pf-btn"><?= tr('bud_preview') ?></button>
</div> </div>
</form> </form>
<?php else: ?> <?php else: ?>
<form method="POST" id="formMapping"> <form method="POST" id="formMapping">
<input type="hidden" name="action" value="save_import"> <input type="hidden" name="action" value="save_import">
@@ -828,10 +827,10 @@ async function deleteExpense(id) {
try { try {
await pachaFetch("budget.php?tab=suivi", { method: "POST", body: formData }); await pachaFetch("budget.php?tab=suivi", { method: "POST", body: formData });
showToast("Dépense supprimée !"); // showToast(tr('bud_toast_deleted')); //
setTimeout(() => window.location.reload(), 800); setTimeout(() => window.location.reload(), 800);
} catch (err) { } catch (err) {
showToast("Erreur lors de la suppression", "error"); showToast(tr('error_occured'), "error");
} }
} }
+3 -2
View File
@@ -22,8 +22,9 @@ if ($selectedYear !== 'all') {
$sql = " $sql = "
SELECT h.*, SELECT h.*,
(COALESCE(h.budget_food, 0) + COALESCE(h.budget_extra, 0) + COALESCE(SUM(hi.amount), 0)) as total_cost, (COALESCE(h.budget_food, 0) + COALESCE(h.budget_extra, 0) + COALESCE(SUM(hi.amount), 0)) as total_cost,
(SELECT COALESCE(SUM(ABS(amount)), 0) FROM pf_expenses WHERE holiday_id = h.id) as real_expenses_sum, ((SELECT COALESCE(SUM(ABS(amount)), 0) FROM pf_expenses WHERE holiday_id = h.id) +
SUM(CASE WHEN hi.is_paid = 1 THEN hi.amount ELSE 0 END) as items_paid_sum (SELECT COALESCE(SUM(amount), 0) FROM pf_holidays_items WHERE holiday_id = h.id AND is_paid = 1)) as total_paid,
(SELECT COALESCE(SUM(amount), 0) FROM pf_savings WHERE holiday_id = h.id) as total_saved
FROM pf_holidays h FROM pf_holidays h
LEFT JOIN pf_holidays_items hi ON h.id = hi.holiday_id LEFT JOIN pf_holidays_items hi ON h.id = hi.holiday_id
$whereSQL $whereSQL