login
This commit is contained in:
+63
@@ -512,3 +512,66 @@ p {
|
|||||||
.btn-icon-action.delete:hover {
|
.btn-icon-action.delete:hover {
|
||||||
background: #fef2f2; /* Fond rouge très clair au survol */
|
background: #fef2f2; /* Fond rouge très clair au survol */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* === 13. PAGE DE CONNEXION (LOGIN) === */
|
||||||
|
.pf-login-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: calc(100vh - 200px);
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-login-card {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
padding: 32px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: var(--shadow-lg);
|
||||||
|
border: 1px solid var(--border-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-login-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-login-header .pf-login-icon {
|
||||||
|
width: 60px; /* Tu peux ajuster cette valeur selon le rendu voulu */
|
||||||
|
height: auto;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
border-radius: 12px; /* Optionnel : ajoute un léger arrondi si ton favicon est carré */
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-login-header h1 {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
margin: 0;
|
||||||
|
color: var(--text-main);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-login-header p {
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-login-error {
|
||||||
|
background: #fef2f2;
|
||||||
|
color: #ef4444;
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #fca5a5;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pf-btn-block {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ return [
|
|||||||
'tests_copy_report' => 'Copiar l\'informe',
|
'tests_copy_report' => 'Copiar l\'informe',
|
||||||
'tests_waiting' => 'Esperant l\'inici...',
|
'tests_waiting' => 'Esperant l\'inici...',
|
||||||
'tests_report_copied' => 'Informe copiat al porta-retalls!',
|
'tests_report_copied' => 'Informe copiat al porta-retalls!',
|
||||||
|
'tests_live_preview' => 'Previsualització en viu',
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// GLOBAL & NAVIGATION
|
// GLOBAL & NAVIGATION
|
||||||
// ==========================================
|
// ==========================================
|
||||||
@@ -70,6 +70,7 @@ return [
|
|||||||
'btn_logout' => 'Tancar sessió',
|
'btn_logout' => 'Tancar sessió',
|
||||||
'error_missing_fields' => 'Camps obligatoris.',
|
'error_missing_fields' => 'Camps obligatoris.',
|
||||||
'error_invalid_credentials' => 'Identificadors incorrectes.',
|
'error_invalid_credentials' => 'Identificadors incorrectes.',
|
||||||
|
'login_subtitle' => 'Si us plau, identifiqueu-vos per continuar',
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// ACCUEIL / INDEX
|
// ACCUEIL / INDEX
|
||||||
@@ -129,6 +130,11 @@ return [
|
|||||||
'fc_menu_carole' => 'Permisos Carole',
|
'fc_menu_carole' => 'Permisos Carole',
|
||||||
'fc_clear' => 'Esborrar',
|
'fc_clear' => 'Esborrar',
|
||||||
'fc_menu_kids_leaves' => 'Permisos nens',
|
'fc_menu_kids_leaves' => 'Permisos nens',
|
||||||
|
'fc_err_save_snap' => 'Error en desar el correctiu.',
|
||||||
|
'fc_err_fetch_gov' => 'Error en la connexió amb l’API governamental.',
|
||||||
|
'fc_err_no_data_gov' => 'No s’han trobat dades a l’API del govern per a aquest any.',
|
||||||
|
'fc_err_action' => 'Error en l’acció: ',
|
||||||
|
'leg_presence_pep' => 'Presència Pep',
|
||||||
|
|
||||||
'leg_school_holidays' => 'Vacances Escolars',
|
'leg_school_holidays' => 'Vacances Escolars',
|
||||||
'leg_public_holiday' => 'Festiu',
|
'leg_public_holiday' => 'Festiu',
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ return [
|
|||||||
'tests_copy_report' => 'Copier le rapport',
|
'tests_copy_report' => 'Copier le rapport',
|
||||||
'tests_waiting' => 'En attente du lancement...',
|
'tests_waiting' => 'En attente du lancement...',
|
||||||
'tests_report_copied' => 'Rapport copié dans le presse-papier !',
|
'tests_report_copied' => 'Rapport copié dans le presse-papier !',
|
||||||
|
'tests_live_preview' => 'Aperçu en direct',
|
||||||
|
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
@@ -72,6 +73,7 @@ return [
|
|||||||
'btn_logout' => 'Déconnexion',
|
'btn_logout' => 'Déconnexion',
|
||||||
'error_missing_fields' => 'Champs obligatoires.',
|
'error_missing_fields' => 'Champs obligatoires.',
|
||||||
'error_invalid_credentials' => 'Identifiants incorrects.',
|
'error_invalid_credentials' => 'Identifiants incorrects.',
|
||||||
|
'login_subtitle' => 'Veuillez vous identifier pour continuer',
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// ACCUEIL / INDEX
|
// ACCUEIL / INDEX
|
||||||
@@ -131,6 +133,11 @@ return [
|
|||||||
'fc_menu_carole' => 'Congés Carole',
|
'fc_menu_carole' => 'Congés Carole',
|
||||||
'fc_clear' => 'Effacer',
|
'fc_clear' => 'Effacer',
|
||||||
'fc_menu_kids_leaves' => 'Congés Enfants',
|
'fc_menu_kids_leaves' => 'Congés Enfants',
|
||||||
|
'fc_err_save_snap' => 'Erreur lors de la sauvegarde du correctif.',
|
||||||
|
'fc_err_fetch_gov' => 'Erreur lors de la connexion à l’API gouvernementale.',
|
||||||
|
'fc_err_no_data_gov' => 'Aucune donnée trouvée sur l’API du gouvernement pour cette année.',
|
||||||
|
'fc_err_action' => 'Erreur lors de l’action : ',
|
||||||
|
'leg_presence_pep' => 'Présence Pep',
|
||||||
|
|
||||||
'leg_school_holidays' => 'Vacances Scolaires',
|
'leg_school_holidays' => 'Vacances Scolaires',
|
||||||
'leg_public_holiday' => 'Férié',
|
'leg_public_holiday' => 'Férié',
|
||||||
|
|||||||
@@ -42,26 +42,42 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
require __DIR__ . '/header.php';
|
require __DIR__ . '/header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="pf-login-container">
|
<div class="pf-container pf-login-wrapper">
|
||||||
<h1 style="text-align:center; font-size:1.8rem;"><?= tr('login_header') ?></h1>
|
<div class="pf-login-card">
|
||||||
|
|
||||||
<?php if ($error): ?>
|
<div class="pf-login-header">
|
||||||
<div class="pf-error"><?= htmlspecialchars($error) ?></div>
|
<img src="/favicon.png" alt="PachaFamily Logo" class="pf-login-icon">
|
||||||
<?php endif; ?>
|
<h1><?= tr('login_header') ?></h1>
|
||||||
|
<p><?= tr('login_subtitle') ?></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ($error): ?>
|
||||||
|
<div class="pf-login-error">
|
||||||
|
<?= htmlspecialchars($error) ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<form method="post" action="/login.php<?= isset($_GET['redirect']) ? '?redirect=' . urlencode($_GET['redirect']) : '' ?>">
|
<form method="post" action="/login.php<?= isset($_GET['redirect']) ? '?redirect=' . urlencode($_GET['redirect']) : '' ?>">
|
||||||
<div class="pf-form-group">
|
<div class="pf-form-group">
|
||||||
<label for="username"><?= tr('label_username') ?></label>
|
<label class="pf-label" for="username"><?= tr('label_username') ?></label>
|
||||||
<input type="text" id="username" name="username" required autofocus placeholder="<?= tr('placeholder_username') ?>">
|
<input type="text" id="username" name="username" class="pf-input" required autofocus placeholder="<?= tr('placeholder_username') ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pf-form-group">
|
||||||
|
<label class="pf-label" for="password"><?= tr('label_password') ?></label>
|
||||||
|
<input type="password" id="password" name="password" class="pf-input" required placeholder="••••••">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="pf-btn pf-btn-block">
|
||||||
|
<?= tr('btn_login_submit') ?>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pf-form-group">
|
|
||||||
<label for="password"><?= tr('label_password') ?></label>
|
|
||||||
<input type="password" id="password" name="password" required placeholder="••••••">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="pf-btn"><?= tr('btn_login_submit') ?></button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<?php require __DIR__ . '/footer.php'; ?>
|
||||||
|
|
||||||
|
<?php require __DIR__ . '/footer.php'; ?>
|
||||||
|
|
||||||
<?php require __DIR__ . '/footer.php'; ?>
|
<?php require __DIR__ . '/footer.php'; ?>
|
||||||
@@ -99,6 +99,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
this.setupModalUI(); // Prépare le selecteur d'année dans la modale
|
this.setupModalUI(); // Prépare le selecteur d'année dans la modale
|
||||||
await this.refreshAllData();
|
await this.refreshAllData();
|
||||||
this.updateSchoolYearLabel();
|
this.updateSchoolYearLabel();
|
||||||
|
|
||||||
|
setTimeout(() => this.scrollToCurrentMonth(), 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modifie dynamiquement le titre de la modale pour y insérer le selecteur d'année
|
// Modifie dynamiquement le titre de la modale pour y insérer le selecteur d'année
|
||||||
@@ -590,6 +592,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
this.weeks.forEach((w, idx) => {
|
this.weeks.forEach((w, idx) => {
|
||||||
const tr = document.createElement("tr");
|
const tr = document.createElement("tr");
|
||||||
|
tr.setAttribute("data-month", w.monthKey);
|
||||||
if (idx === 0 || this.weeks[idx - 1].monthKey !== w.monthKey)
|
if (idx === 0 || this.weeks[idx - 1].monthKey !== w.monthKey)
|
||||||
tr.classList.add("fc-month-first-week-row");
|
tr.classList.add("fc-month-first-week-row");
|
||||||
if (
|
if (
|
||||||
@@ -688,6 +691,33 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Auto-scroll vers le mois en cours ---
|
||||||
|
scrollToCurrentMonth() {
|
||||||
|
const wrapper = document.getElementById("planningTable-wrapper");
|
||||||
|
const thead = document.querySelector("#planningTable thead");
|
||||||
|
if (!wrapper || !thead) return;
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
// Construit la clé au format "YYYY-MM"
|
||||||
|
const currentYm = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
|
||||||
|
|
||||||
|
// Cherche la TOUTE PREMIÈRE ligne qui correspond à ce mois
|
||||||
|
const targetRow = document.querySelector(
|
||||||
|
`#planningTable tbody tr[data-month="${currentYm}"]`,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (targetRow) {
|
||||||
|
// On donne 50ms au navigateur pour finir son rendu graphique avant de calculer les hauteurs
|
||||||
|
setTimeout(() => {
|
||||||
|
const scrollPos = targetRow.offsetTop - thead.offsetHeight;
|
||||||
|
wrapper.scrollTo({
|
||||||
|
top: scrollPos > 0 ? scrollPos : 0,
|
||||||
|
behavior: "smooth",
|
||||||
|
});
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderMonthCalendar() {
|
renderMonthCalendar() {
|
||||||
if (!this.monthCalendar) return;
|
if (!this.monthCalendar) return;
|
||||||
this.monthCalendar.innerHTML = "";
|
this.monthCalendar.innerHTML = "";
|
||||||
|
|||||||
Reference in New Issue
Block a user