Init Git Prod Mars 2026

This commit is contained in:
Oleg Barykin committed 2026-03-05 10:25:39 +01:00
commit d81efe93b1
362 files changed
+86627

No files matched your search

+231
View File
@@ -0,0 +1,231 @@
<?php
// ⚠️ NE PAS inclure contact_admin.php ici (risque d'exécution à l'inclusion)
require_once __DIR__ . '/../contact_admin.php';
$sec_uid = (int)($_SESSION['compte_id'] ?? $_SESSION['user_id'] ?? 0);
// =====================================================
// [CONTEXT UTILISATEUR] — Initiales avatar secrétaire
// =====================================================
$prenomUser = trim((string)($_SESSION['user_prenom'] ?? $_SESSION['prenom'] ?? ''));
$nomUser = trim((string)($_SESSION['user_nom'] ?? $_SESSION['nom'] ?? ''));
if ($prenomUser === '' && $nomUser === '') {
// petit fallback
$prenomUser = 'Secr';
$nomUser = 'Etaire';
}
$initiales = mb_strtoupper(
mb_substr($prenomUser, 0, 1, 'UTF-8') .
mb_substr($nomUser, 0, 1, 'UTF-8'),
'UTF-8'
);
// =====================================================
// [PRATICIEN COURANT] — affichage nom/prénom dans le header
// - on prend ?praticien_id si présent, sinon une valeur de session si dispo
// =====================================================
$currentPraticienId = null;
if (isset($_GET['praticien_id'])) {
$currentPraticienId = (int)$_GET['praticien_id'];
$_SESSION['current_praticien_id'] = $currentPraticienId; // mémorise pour les autres pages
} elseif (!empty($_SESSION['current_praticien_id'])) {
$currentPraticienId = (int)$_SESSION['current_praticien_id'];
}
$currentPraticienName = '';
if ($currentPraticienId) {
$stmt = $pdo->prepare("SELECT id, prenom, nom FROM praticien WHERE id = ? LIMIT 1");
$stmt->execute([$currentPraticienId]);
if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$p = trim((string)($row['prenom'] ?? ''));
$n = trim((string)($row['nom'] ?? ''));
$pid = trim((string)($row['id'] ?? ''));
$currentPraticienName = trim($p.' '.$n);
}
}
// =====================================================
// [Liste Praticien avec autorisations]
// =====================================================
$pid = (int)$currentPraticienId;
$permRow = null;
if ($pid && $sec_uid) {
$q = $pdo->prepare("
SELECT sp.can_manage_rdv, sp.can_edit_slots
FROM secretaire_praticien sp
WHERE sp.secretaire_user_id = :u
AND sp.praticien_id = :pid
AND sp.is_active = 1
LIMIT 1
");
$q->execute(['u' => $sec_uid, 'pid' => $pid]);
$permRow = $q->fetch(PDO::FETCH_ASSOC) ?: null;
}
// =====================================================
// [RETOUR / REFERER SÉCURISÉ]
// =====================================================
$ref = $_SERVER['HTTP_REFERER'] ?? '';
$host = $_SERVER['HTTP_HOST'] ?? '';
$safeRef = '';
if ($ref) {
$u = parse_url($ref);
if (!empty($u['host']) && $u['host'] === $host) $safeRef = $ref;
}
$fallbackBack = $safeRef ?: '/public/cabinet/dashboard.php';
// =====================================================
// [DETECTION MOBILE]
// =====================================================
$is_mobile = preg_match('/Mobile|Android|iPhone|iPad/i', $_SERVER['HTTP_USER_AGENT'] ?? '');
?>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title><?= htmlspecialchars($PAGE_TITLE ?? 'Cabinet', ENT_QUOTES, 'UTF-8') ?></title>
<?= $HEAD_EXTRA ?? '' ?>
<!-- Montserrat -->
<!-- Bootstrap -->
<link href="/css/bootstrap.min.css" rel="stylesheet">
<!-- Styles (chemins corrigés) -->
<link rel="stylesheet" href="<?= asset('/includes/site_style.css') ?>">
<link rel="stylesheet" href="<?= asset('/includes/custom_style.css') ?>"> <!-- ta home -->
<link rel="stylesheet" href="<?= asset('/includes/admin_style.css') ?>">
<link rel="stylesheet" href="<?= asset('/includes/mobil_style.css') ?>">
</head>
<body>
<header class="site-header py-2 border-bottom">
<div class="container d-flex justify-content-between align-items-center">
<!-- Bouton retour + Logo -->
<div class="header-left">
<div class="brand">
<a
href="<?= htmlspecialchars($fallbackBack, ENT_QUOTES, 'UTF-8') ?>"
id="btnBack"
class="btn btn-light btn-circle me-2"
style="border-radius:5px; box-shadow:0 1px 2px rgba(0,0,0,.08);"
aria-label="<?= htmlspecialchars($translations['retour'] ?? 'Retour', ENT_QUOTES, 'UTF-8') ?>"
>
<svg viewBox="0 0 24 24" width="20" height="20" fill="none" aria-hidden="true">
<path d="M15 6l-6 6 6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</a>
<a href="/public/cabinet/dashboard.php">
<img src="/public/uploads/img/logo_u.png"
alt="uslugi.fr"
class="logo-mobile">
<img src="/public/uploads/img/logo.png"
alt="uslugi.fr"
class="logo-desktop">
</a>
</div>
<div class="lang-switch">
<?php require __DIR__ . '/../../includes/menu_langue.php'; ?>
</div>
</div>
<!-- Actions header -->
<nav class="header-actions d-flex align-items-center gap-3 position-relative">
<!-- ⚡ A LA PLACE DE L’ICÔNE MESSAGES : le praticien courant -->
<div class="text-nowrap" style="font-weight:600;">
<?php if ($currentPraticienName): ?>
<?= htmlspecialchars($currentPraticienName, ENT_QUOTES, 'UTF-8') ?>
<?php else: ?>
<span class="text-muted"><?= htmlspecialchars($translations['aucun_praticien_selectionne'] ?? 'Praticien non sélectionné', ENT_QUOTES, 'UTF-8') ?></span>
<?php endif; ?>
</div>
<!-- Menu utilisateur (avatar) -->
<div class="menu-wrap">
<button type="button" id="btnMenu" class="btn p-0 border-0 bg-transparent">
<div class="avatar d-flex align-items-center justify-content-center">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 12a5 5 0 1 0-5-5 5 5 0 0 0 5 5m0 2c-5.33 0-8 2.67-8 4v2h16v-2c0-1.33-2.67-4-8-4"/>
</svg>
</div>
</button>
<ul class="dropdown-menu-custom menu-panel" id="menu" style="display:none; min-width: 220px;">
<?php if (($_SESSION['role'] ?? '') === 'secretaire'): ?>
<li onclick="location.href='/public/cabinet/dashboard.php'">
<?= htmlspecialchars($translations['home'] ?? 'Accueil') ?>
</li>
<?php if ($pid && $permRow): ?>
<?php if (!empty($permRow['can_manage_rdv'])): ?>
<li onclick="location.href='/public/cabinet/agenda.php?praticien_id=<?= $pid ?>'">
<?= htmlspecialchars($translations['sec_btn_agenda'] ?? 'Agenda') ?>
</li>
<li onclick="location.href='/public/cabinet/rendez_vous_du_jour.php?praticien_id=<?= $pid ?>'">
<?= htmlspecialchars($translations['sec_btn_rdv'] ?? 'Rendez-vous') ?>
</li>
<li onclick="location.href='/public/cabinet/rendez_vous.php?praticien_id=<?= $pid ?>'">
<?= htmlspecialchars($translations['sec_btn_rdv_jour'] ?? 'Les rendez-vous') ?>
</li>
<li onclick="location.href='/public/cabinet/reserver_rdv.php?praticien_id=<?= $pid ?>'">
<?= htmlspecialchars($translations['sec_btn_prendre'] ?? 'Prendre un RDV') ?>
</li>
<?php endif; ?>
<?php if (!empty($permRow['can_edit_slots'])): ?>
<li onclick="location.href='/public/cabinet/disponibilites.php?praticien_id=<?= $pid ?>'">
<?= htmlspecialchars($translations['sec_btn_dispos'] ?? 'Disponibilités') ?>
</li>
<?php endif; ?>
<?php endif; ?>
<li onclick="closeMenu(); openContactAdmin()">
<?= htmlspecialchars($translations['contact_admin'] ?? 'Contact Admin') ?>
</li>
<li onclick="location.href='/public/deconnexion.php'">
<?= htmlspecialchars($translations['menu_deconnexion'] ?? 'Déconnexion') ?>
</li>
<?php endif; ?>
</ul>
</div>
</nav>
</div>
</header>
<script>
// --- Menu principal
function toggleMenu() {
const menu = document.getElementById('menu');
if (!menu) return;
menu.style.display = (menu.style.display === 'block') ? 'none' : 'block';
}
function closeMenu() {
const menu = document.getElementById('menu');
if (menu) menu.style.display = 'none';
}
document.getElementById('btnMenu')?.addEventListener('click', function(e){
e.stopPropagation();
toggleMenu();
});
document.addEventListener('click', function(e){
const menu = document.getElementById('menu');
const btn = document.getElementById('btnMenu');
if (!menu || !btn) return;
if (!btn.contains(e.target) && !menu.contains(e.target)) closeMenu();
});
document.addEventListener('keydown', function(e){ if (e.key === 'Escape') closeMenu(); });
</script>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>