nnnn / index.html
Dannylova31's picture
Add 2 files
a9afc21 verified
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gestion RDV - Centre Médico-Radiologique Avicenne</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
medical: {
blue: '#0077B6',
lightblue: '#90E0EF',
darkblue: '#03045E',
teal: '#00B4D8',
white: '#CAF0F8'
}
}
}
}
}
</script>
<style>
.sidebar {
transition: all 0.3s ease;
}
.sidebar-collapsed {
width: 70px;
}
.sidebar-expanded {
width: 250px;
}
.main-content {
transition: margin-left 0.3s ease;
}
.fade-in {
animation: fadeIn 0.5s;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.card-hover:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
</style>
</head>
<body class="bg-gray-100 font-sans">
<div class="flex h-screen overflow-hidden">
<!-- Sidebar -->
<div id="sidebar" class="sidebar sidebar-expanded bg-medical-blue text-white flex flex-col">
<div class="p-4 flex items-center justify-between border-b border-medical-lightblue">
<div class="flex items-center space-x-2">
<div class="flex items-center justify-center w-10 h-10 rounded-full bg-white text-medical-blue">
<i class="fas fa-heartbeat text-2xl"></i>
</div>
<span id="logo-text" class="text-xl font-bold text-white">Avicenne</span>
</div>
<button id="toggle-sidebar" class="text-white hover:text-medical-lightblue">
<i class="fas fa-bars"></i>
</button>
</div>
<div class="p-4 flex items-center space-x-3 border-b border-medical-lightblue">
<div class="w-10 h-10 rounded-full bg-white text-medical-blue flex items-center justify-center">
<i class="fas fa-user-md"></i>
</div>
<div id="user-info">
<p class="font-semibold">Dr. Yassine</p>
<p class="text-xs text-medical-white">Radiologue</p>
</div>
</div>
<nav class="flex-1 overflow-y-auto py-4">
<ul>
<li>
<a href="#" id="dashboard-link" class="flex items-center space-x-3 p-3 hover:bg-medical-darkblue rounded-lg mx-2">
<i class="fas fa-tachometer-alt w-6 text-center"></i>
<span id="dashboard-text">Tableau de bord</span>
</a>
</li>
<li>
<a href="#" id="appointments-link" class="flex items-center space-x-3 p-3 bg-medical-darkblue rounded-lg mx-2">
<i class="fas fa-calendar-check w-6 text-center"></i>
<span id="appointments-text">Rendez-vous</span>
</a>
</li>
<li>
<a href="#" id="patients-link" class="flex items-center space-x-3 p-3 hover:bg-medical-darkblue rounded-lg mx-2">
<i class="fas fa-procedures w-6 text-center"></i>
<span id="patients-text">Patients</span>
</a>
</li>
<li>
<a href="#" id="reports-link" class="flex items-center space-x-3 p-3 hover:bg-medical-darkblue rounded-lg mx-2">
<i class="fas fa-file-medical w-6 text-center"></i>
<span id="reports-text">Rapports</span>
</a>
</li>
<li>
<a href="#" id="logs-link" class="flex items-center space-x-3 p-3 hover:bg-medical-darkblue rounded-lg mx-2">
<i class="fas fa-clipboard-list w-6 text-center"></i>
<span id="logs-text">Journal d'activité</span>
</a>
</li>
<li>
<a href="#" id="settings-link" class="flex items-center space-x-3 p-3 hover:bg-medical-darkblue rounded-lg mx-2">
<i class="fas fa-cog w-6 text-center"></i>
<span id="settings-text">Paramètres</span>
</a>
</li>
</ul>
</nav>
<div class="p-4 border-t border-medical-lightblue">
<button id="logout-btn" class="flex items-center space-x-3 w-full p-2 hover:bg-medical-darkblue rounded-lg">
<i class="fas fa-sign-out-alt w-6 text-center"></i>
<span id="logout-text">Déconnexion</span>
</button>
</div>
</div>
<!-- Main Content -->
<div id="main-content" class="main-content flex-1 overflow-y-auto">
<!-- Header -->
<header class="bg-white shadow-sm p-4 flex justify-between items-center">
<h1 class="text-2xl font-bold text-medical-blue">Gestion des Rendez-vous</h1>
<div class="flex items-center space-x-4">
<div class="relative">
<input type="text" placeholder="Rechercher..." class="pl-10 pr-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue">
<i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
</div>
<div class="relative">
<button id="notifications-btn" class="text-gray-600 hover:text-medical-blue relative">
<i class="fas fa-bell text-xl"></i>
<span class="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full h-5 w-5 flex items-center justify-center">3</span>
</button>
</div>
</div>
</header>
<!-- Content -->
<main class="p-6">
<!-- Stats Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
<div class="bg-white rounded-lg shadow-md p-6 card-hover transition-all duration-300 border-l-4 border-medical-blue">
<div class="flex justify-between items-center">
<div>
<p class="text-gray-500">RDV aujourd'hui</p>
<h3 class="text-2xl font-bold text-medical-blue">12</h3>
</div>
<div class="bg-medical-lightblue text-medical-blue p-3 rounded-full">
<i class="fas fa-calendar-day text-xl"></i>
</div>
</div>
<p class="text-sm text-green-500 mt-2"><i class="fas fa-arrow-up"></i> 2 de plus qu'hier</p>
</div>
<div class="bg-white rounded-lg shadow-md p-6 card-hover transition-all duration-300 border-l-4 border-medical-teal">
<div class="flex justify-between items-center">
<div>
<p class="text-gray-500">RDV cette semaine</p>
<h3 class="text-2xl font-bold text-medical-blue">42</h3>
</div>
<div class="bg-blue-100 text-medical-teal p-3 rounded-full">
<i class="fas fa-calendar-week text-xl"></i>
</div>
</div>
<p class="text-sm text-green-500 mt-2"><i class="fas fa-arrow-up"></i> 5% vs semaine dernière</p>
</div>
<div class="bg-white rounded-lg shadow-md p-6 card-hover transition-all duration-300 border-l-4 border-green-500">
<div class="flex justify-between items-center">
<div>
<p class="text-gray-500">Patients confirmés</p>
<h3 class="text-2xl font-bold text-medical-blue">38</h3>
</div>
<div class="bg-green-100 text-green-500 p-3 rounded-full">
<i class="fas fa-check-circle text-xl"></i>
</div>
</div>
<p class="text-sm text-gray-500 mt-2">4 en attente de confirmation</p>
</div>
<div class="bg-white rounded-lg shadow-md p-6 card-hover transition-all duration-300 border-l-4 border-red-500">
<div class="flex justify-between items-center">
<div>
<p class="text-gray-500">Annulations</p>
<h3 class="text-2xl font-bold text-medical-blue">2</h3>
</div>
<div class="bg-red-100 text-red-500 p-3 rounded-full">
<i class="fas fa-times-circle text-xl"></i>
</div>
</div>
<p class="text-sm text-gray-500 mt-2">1% du total des RDV</p>
</div>
</div>
<!-- Appointments Table -->
<div class="bg-white rounded-lg shadow-md overflow-hidden mb-6">
<div class="p-4 border-b flex justify-between items-center">
<h2 class="text-xl font-semibold text-medical-blue">Liste des Rendez-vous</h2>
<div class="flex space-x-2">
<button id="export-pdf" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg flex items-center space-x-2">
<i class="fas fa-file-pdf"></i>
<span>PDF</span>
</button>
<button id="export-excel" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg flex items-center space-x-2">
<i class="fas fa-file-excel"></i>
<span>Excel</span>
</button>
<button id="add-appointment" class="bg-medical-blue hover:bg-medical-darkblue text-white px-4 py-2 rounded-lg flex items-center space-x-2">
<i class="fas fa-plus"></i>
<span>Nouveau RDV</span>
</button>
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Patient</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date/Heure</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type d'examen</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Statut</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200" id="appointments-table-body">
<!-- Rows will be added dynamically -->
</tbody>
</table>
</div>
<div class="p-4 border-t flex justify-between items-center">
<div class="text-sm text-gray-500">
Affichage de <span id="start-item">1</span> à <span id="end-item">10</span> sur <span id="total-items">24</span> rendez-vous
</div>
<div class="flex space-x-2">
<button class="px-3 py-1 border rounded-md text-gray-700 disabled:opacity-50" id="prev-page" disabled>
<i class="fas fa-chevron-left"></i>
</button>
<button class="px-3 py-1 border rounded-md bg-medical-blue text-white">1</button>
<button class="px-3 py-1 border rounded-md text-gray-700 hover:bg-gray-100">2</button>
<button class="px-3 py-1 border rounded-md text-gray-700 hover:bg-gray-100">3</button>
<button class="px-3 py-1 border rounded-md text-gray-700" id="next-page">
<i class="fas fa-chevron-right"></i>
</button>
</div>
</div>
</div>
<!-- Calendar View -->
<div class="bg-white rounded-lg shadow-md overflow-hidden mb-6">
<div class="p-4 border-b flex justify-between items-center">
<h2 class="text-xl font-semibold text-medical-blue">Vue Calendrier</h2>
<div class="flex items-center space-x-4">
<div class="flex items-center space-x-2">
<button class="px-3 py-1 border rounded-md text-gray-700">
<i class="fas fa-chevron-left"></i>
</button>
<span class="font-medium">Mai 2023</span>
<button class="px-3 py-1 border rounded-md text-gray-700">
<i class="fas fa-chevron-right"></i>
</button>
</div>
<div class="relative">
<select class="appearance-none bg-white border rounded-md pl-3 pr-8 py-1 focus:outline-none focus:ring-2 focus:ring-medical-blue">
<option>Vue semaine</option>
<option selected>Vue mois</option>
<option>Vue jour</option>
</select>
<i class="fas fa-chevron-down absolute right-3 top-2 text-gray-400 pointer-events-none"></i>
</div>
</div>
</div>
<div class="p-4">
<div class="grid grid-cols-7 gap-1 mb-2">
<div class="text-center font-medium text-gray-500 py-2">Lun</div>
<div class="text-center font-medium text-gray-500 py-2">Mar</div>
<div class="text-center font-medium text-gray-500 py-2">Mer</div>
<div class="text-center font-medium text-gray-500 py-2">Jeu</div>
<div class="text-center font-medium text-gray-500 py-2">Ven</div>
<div class="text-center font-medium text-gray-500 py-2">Sam</div>
<div class="text-center font-medium text-gray-500 py-2">Dim</div>
</div>
<div class="grid grid-cols-7 gap-1" id="calendar-grid">
<!-- Calendar cells will be added dynamically -->
</div>
</div>
</div>
</main>
</div>
</div>
<!-- Add Appointment Modal -->
<div id="add-appointment-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-lg shadow-xl w-full max-w-2xl max-h-screen overflow-y-auto">
<div class="p-4 border-b flex justify-between items-center">
<h3 class="text-xl font-semibold text-medical-blue">Nouveau Rendez-vous</h3>
<button id="close-add-modal" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="p-6">
<form id="appointment-form">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<div>
<label class="block text-gray-700 mb-2" for="patient">Patient</label>
<select id="patient" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue">
<option value="">Sélectionner un patient</option>
<option value="1">Jean Martin</option>
<option value="2">Marie Dubois</option>
<option value="3">Pierre Lambert</option>
<option value="4">Sophie Moreau</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-2" for="examen-type">Type d'examen</label>
<select id="examen-type" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue">
<option value="">Sélectionner un type</option>
<option value="radiographie">Radiographie</option>
<option value="irm">IRM</option>
<option value="scanner">Scanner</option>
<option value="echographie">Échographie</option>
<option value="mammographie">Mammographie</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-2" for="appointment-date">Date</label>
<input type="date" id="appointment-date" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue">
</div>
<div>
<label class="block text-gray-700 mb-2" for="appointment-time">Heure</label>
<input type="time" id="appointment-time" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue">
</div>
<div class="md:col-span-2">
<label class="block text-gray-700 mb-2" for="notes">Notes</label>
<textarea id="notes" rows="3" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue"></textarea>
</div>
</div>
<div class="flex justify-end space-x-3">
<button type="button" id="cancel-add-appointment" class="px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-100">
Annuler
</button>
<button type="submit" class="px-4 py-2 bg-medical-blue text-white rounded-lg hover:bg-medical-darkblue">
Enregistrer
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Edit Appointment Modal -->
<div id="edit-appointment-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-lg shadow-xl w-full max-w-2xl max-h-screen overflow-y-auto">
<div class="p-4 border-b flex justify-between items-center">
<h3 class="text-xl font-semibold text-medical-blue">Modifier Rendez-vous</h3>
<button id="close-edit-modal" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="p-6">
<form id="edit-appointment-form">
<input type="hidden" id="edit-appointment-id">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<div>
<label class="block text-gray-700 mb-2" for="edit-patient">Patient</label>
<select id="edit-patient" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue">
<option value="">Sélectionner un patient</option>
<option value="1">Jean Martin</option>
<option value="2">Marie Dubois</option>
<option value="3">Pierre Lambert</option>
<option value="4">Sophie Moreau</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-2" for="edit-examen-type">Type d'examen</label>
<select id="edit-examen-type" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue">
<option value="">Sélectionner un type</option>
<option value="radiographie">Radiographie</option>
<option value="irm">IRM</option>
<option value="scanner">Scanner</option>
<option value="echographie">Échographie</option>
<option value="mammographie">Mammographie</option>
</select>
</div>
<div>
<label class="block text-gray-700 mb-2" for="edit-appointment-date">Date</label>
<input type="date" id="edit-appointment-date" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue">
</div>
<div>
<label class="block text-gray-700 mb-2" for="edit-appointment-time">Heure</label>
<input type="time" id="edit-appointment-time" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue">
</div>
<div class="md:col-span-2">
<label class="block text-gray-700 mb-2" for="edit-status">Statut</label>
<select id="edit-status" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue">
<option value="confirmed">Confirmé</option>
<option value="pending">En attente</option>
<option value="cancelled">Annulé</option>
<option value="completed">Terminé</option>
</select>
</div>
<div class="md:col-span-2">
<label class="block text-gray-700 mb-2" for="edit-notes">Notes</label>
<textarea id="edit-notes" rows="3" class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-medical-blue"></textarea>
</div>
</div>
<div class="flex justify-end space-x-3">
<button type="button" id="cancel-edit-appointment" class="px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-100">
Annuler
</button>
<button type="submit" class="px-4 py-2 bg-medical-blue text-white rounded-lg hover:bg-medical-darkblue">
Enregistrer
</button>
</div>
</form>
</div>
</div>
</div>
<!-- View Appointment Modal -->
<div id="view-appointment-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-lg shadow-xl w-full max-w-2xl max-h-screen overflow-y-auto">
<div class="p-4 border-b flex justify-between items-center">
<h3 class="text-xl font-semibold text-medical-blue">Détails du Rendez-vous</h3>
<button id="close-view-modal" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="p-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<div>
<h4 class="text-lg font-semibold text-medical-blue mb-4">Informations patient</h4>
<div class="space-y-4">
<div>
<p class="text-gray-500">Nom complet</p>
<p id="view-patient-name" class="font-medium">Jean Martin</p>
</div>
<div>
<p class="text-gray-500">Date de naissance</p>
<p id="view-patient-dob" class="font-medium">15/03/1975</p>
</div>
<div>
<p class="text-gray-500">Numéro de sécurité sociale</p>
<p id="view-patient-ssn" class="font-medium">1 85 03 75 123 456 78</p>
</div>
<div>
<p class="text-gray-500">Téléphone</p>
<p id="view-patient-phone" class="font-medium">06 12 34 56 78</p>
</div>
</div>
</div>
<div>
<h4 class="text-lg font-semibold text-medical-blue mb-4">Détails du rendez-vous</h4>
<div class="space-y-4">
<div>
<p class="text-gray-500">Date et heure</p>
<p id="view-appointment-datetime" class="font-medium">15 mai 2023 à 14:30</p>
</div>
<div>
<p class="text-gray-500">Type d'examen</p>
<p id="view-examen-type" class="font-medium">IRM cérébrale</p>
</div>
<div>
<p class="text-gray-500">Statut</p>
<p id="view-status" class="font-medium">
<span class="px-2 py-1 rounded-full bg-green-100 text-green-800">Confirmé</span>
</p>
</div>
<div>
<p class="text-gray-500">Médecin assigné</p>
<p id="view-doctor" class="font-medium">Dr. Dupont</p>
</div>
</div>
</div>
<div class="md:col-span-2">
<h4 class="text-lg font-semibold text-medical-blue mb-4">Notes</h4>
<div class="bg-gray-50 p-4 rounded-lg">
<p id="view-notes">Le patient présente des maux de tête persistants. Une IRM cérébrale a été prescrite pour évaluer d'éventuelles anomalies.</p>
</div>
</div>
<div class="md:col-span-2">
<h4 class="text-lg font-semibold text-medical-blue mb-4">Historique des modifications</h4>
<div class="space-y-3">
<div class="flex items-start space-x-3">
<div class="mt-1">
<div class="w-2 h-2 rounded-full bg-medical-blue"></div>
</div>
<div>
<p class="text-sm font-medium">Modifié par Dr. Dupont</p>
<p class="text-sm text-gray-500">15/05/2023 à 09:15 - Changement d'horaire</p>
</div>
</div>
<div class="flex items-start space-x-3">
<div class="mt-1">
<div class="w-2 h-2 rounded-full bg-medical-blue"></div>
</div>
<div>
<p class="text-sm font-medium">Créé par Sec. Martin</p>
<p class="text-sm text-gray-500">10/05/2023 à 14:30 - Rendez-vous créé</p>
</div>
</div>
</div>
</div>
</div>
<div class="flex justify-end space-x-3">
<button id="print-appointment" class="px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-100 flex items-center space-x-2">
<i class="fas fa-print"></i>
<span>Imprimer</span>
</button>
<button id="edit-from-view" class="px-4 py-2 bg-medical-blue text-white rounded-lg hover:bg-medical-darkblue flex items-center space-x-2">
<i class="fas fa-edit"></i>
<span>Modifier</span>
</button>
</div>
</div>
</div>
</div>
<!-- Notification Panel -->
<div id="notification-panel" class="fixed right-0 top-0 h-full w-80 bg-white shadow-lg transform translate-x-full transition-transform duration-300 z-50">
<div class="p-4 border-b flex justify-between items-center">
<h3 class="text-lg font-semibold">Notifications</h3>
<button id="close-notifications" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="overflow-y-auto h-full">
<div class="p-4 border-b hover:bg-gray-50 cursor-pointer">
<div class="flex items-start space-x-3">
<div class="mt-1">
<div class="w-2 h-2 rounded-full bg-red-500"></div>
</div>
<div>
<p class="font-medium">Nouveau rendez-vous</p>
<p class="text-sm text-gray-500">Sophie Moreau a pris rendez-vous pour une échographie</p>
<p class="text-xs text-gray-400">Il y a 10 minutes</p>
</div>
</div>
</div>
<div class="p-4 border-b hover:bg-gray-50 cursor-pointer">
<div class="flex items-start space-x-3">
<div class="mt-1">
<div class="w-2 h-2 rounded-full bg-blue-500"></div>
</div>
<div>
<p class="font-medium">Rappel de rendez-vous</p>
<p class="text-sm text-gray-500">Jean Martin a un rendez-vous demain à 14h30</p>
<p class="text-xs text-gray-400">Il y a 1 heure</p>
</div>
</div>
</div>
<div class="p-4 border-b hover:bg-gray-50 cursor-pointer">
<div class="flex items-start space-x-3">
<div class="mt-1">
<div class="w-2 h-2 rounded-full bg-yellow-500"></div>
</div>
<div>
<p class="font-medium">Rendez-vous annulé</p>
<p class="text-sm text-gray-500">Pierre Lambert a annulé son scanner</p>
<p class="text-xs text-gray-400">Il y a 3 heures</p>
</div>
</div>
</div>
<div class="p-4 hover:bg-gray-50 cursor-pointer">
<div class="flex items-start space-x-3">
<div class="mt-1">
<div class="w-2 h-2 rounded-full bg-green-500"></div>
</div>
<div>
<p class="font-medium">Nouveau message</p>
<p class="text-sm text-gray-500">Vous avez reçu un message du Dr. Lefèvre</p>
<p class="text-xs text-gray-400">Hier à 16:45</p>
</div>
</div>
</div>
</div>
</div>
<script>
// Sample data for appointments
const appointments = [
{
id: 1,
patient: "Jean Martin",
date: "2023-05-15",
time: "14:30",
type: "IRM cérébrale",
status: "confirmed",
doctor: "Dr. Yassine",
notes: "Le patient présente des maux de tête persistants."
},
{
id: 2,
patient: "Marie Dubois",
date: "2023-05-16",
time: "09:15",
type: "Mammographie",
status: "pending",
doctor: "Dr. Lefèvre",
notes: "Contrôle annuel."
},
{
id: 3,
patient: "Pierre Lambert",
date: "2023-05-16",
time: "11:00",
type: "Radiographie thoracique",
status: "confirmed",
doctor: "Dr. Yassine",
notes: "Douleurs thoraciques persistantes."
},
{
id: 4,
patient: "Sophie Moreau",
date: "2023-05-17",
time: "15:45",
type: "Échographie abdominale",
status: "confirmed",
doctor: "Dr. Lefèvre",
notes: "Douleurs abdominales inexpliquées."
},
{
id: 5,
patient: "Lucie Bernard",
date: "2023-05-17",
time: "16:30",
type: "Scanner",
status: "cancelled",
doctor: "Dr. Yassine",
notes: "Annulé par le patient."
},
{
id: 6,
patient: "Thomas Petit",
date: "2023-05-18",
time: "10:00",
type: "IRM lombaire",
status: "in-progress",
doctor: "Dr. Yassine",
notes: "Lombalgie chronique."
},
{
id: 7,
patient: "Emma Laurent",
date: "2023-05-18",
time: "13:15",
type: "Échographie thyroïdienne",
status: "pending",
doctor: "Dr. Lefèvre",
notes: "Nodule détecté lors de la consultation."
},
{
id: 8,
patient: "Nicolas Roux",
date: "2023-05-19",
time: "08:30",
type: "Radiographie du genou",
status: "confirmed",
doctor: "Dr. Yassine",
notes: "Douleur au genou suite à une chute."
},
{
id: 9,
patient: "Camille Leroy",
date: "2023-05-19",
time: "14:00",
type: "Mammographie",
status: "confirmed",
doctor: "Dr. Lefèvre",
notes: "Dépistage annuel."
},
{
id: 10,
patient: "Antoine Michel",
date: "2023-05-20",
time: "11:45",
type: "Scanner abdominal",
status: "confirmed",
doctor: "Dr. Dupont",
notes: "Suspicion d'appendicite."
}
];
// DOM Elements
const sidebar = document.getElementById('sidebar');
const toggleSidebarBtn = document.getElementById('toggle-sidebar');
const mainContent = document.getElementById('main-content');
const appointmentsTableBody = document.getElementById('appointments-table-body');
const addAppointmentBtn = document.getElementById('add-appointment');
const addAppointmentModal = document.getElementById('add-appointment-modal');
const closeAddModalBtn = document.getElementById('close-add-modal');
const cancelAddAppointmentBtn = document.getElementById('cancel-add-appointment');
const appointmentForm = document.getElementById('appointment-form');
const editAppointmentModal = document.getElementById('edit-appointment-modal');
const closeEditModalBtn = document.getElementById('close-edit-modal');
const cancelEditAppointmentBtn = document.getElementById('cancel-edit-appointment');
const editAppointmentForm = document.getElementById('edit-appointment-form');
const viewAppointmentModal = document.getElementById('view-appointment-modal');
const closeViewModalBtn = document.getElementById('close-view-modal');
const editFromViewBtn = document.getElementById('edit-from-view');
const printAppointmentBtn = document.getElementById('print-appointment');
const exportPdfBtn = document.getElementById('export-pdf');
const exportExcelBtn = document.getElementById('export-excel');
const notificationsBtn = document.getElementById('notifications-btn');
const notificationPanel = document.getElementById('notification-panel');
const closeNotificationsBtn = document.getElementById('close-notifications');
// Initialize the app
document.addEventListener('DOMContentLoaded', function() {
renderAppointments();
renderCalendar();
// Set today's date as default in the add appointment form
const today = new Date().toISOString().split('T')[0];
document.getElementById('appointment-date').value = today;
document.getElementById('appointment-date').min = today;
});
// Toggle sidebar
toggleSidebarBtn.addEventListener('click', function() {
sidebar.classList.toggle('sidebar-collapsed');
sidebar.classList.toggle('sidebar-expanded');
// Toggle text elements in sidebar
const textElements = ['logo-text', 'user-info', 'dashboard-text', 'appointments-text',
'patients-text', 'reports-text', 'logs-text', 'settings-text', 'logout-text'];
textElements.forEach(id => {
const element = document.getElementById(id);
if (element) {
element.classList.toggle('hidden');
}
});
// Adjust main content margin
if (sidebar.classList.contains('sidebar-collapsed')) {
mainContent.classList.add('ml-16');
} else {
mainContent.classList.remove('ml-16');
}
});
// Render appointments table
function renderAppointments() {
appointmentsTableBody.innerHTML = '';
appointments.forEach(appointment => {
const row = document.createElement('tr');
row.className = 'hover:bg-gray-50';
row.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10 bg-medical-lightblue rounded-full flex items-center justify-center">
<i class="fas fa-user text-medical-blue"></i>
</div>
<div class="ml-4">
<div class="text-sm font-medium text-gray-900">${appointment.patient}</div>
<div class="text-sm text-gray-500">${appointment.doctor}</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">${formatDate(appointment.date)}</div>
<div class="text-sm text-gray-500">${appointment.time}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">${appointment.type}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${getStatusClass(appointment.status)}">
${getStatusText(appointment.status)}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button class="text-medical-blue hover:text-medical-darkblue mr-3 view-btn" data-id="${appointment.id}">
<i class="fas fa-eye"></i>
</button>
<button class="text-yellow-600 hover:text-yellow-900 mr-3 edit-btn" data-id="${appointment.id}">
<i class="fas fa-edit"></i>
</button>
<button class="text-red-600 hover:text-red-900 delete-btn" data-id="${appointment.id}">
<i class="fas fa-trash"></i>
</button>
</td>
`;
appointmentsTableBody.appendChild(row);
});
// Add event listeners to buttons
document.querySelectorAll('.view-btn').forEach(btn => {
btn.addEventListener('click', function() {
const appointmentId = parseInt(this.getAttribute('data-id'));
viewAppointment(appointmentId);
});
});
document.querySelectorAll('.edit-btn').forEach(btn => {
btn.addEventListener('click', function() {
const appointmentId = parseInt(this.getAttribute('data-id'));
editAppointment(appointmentId);
});
});
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', function() {
const appointmentId = parseInt(this.getAttribute('data-id'));
deleteAppointment(appointmentId);
});
});
}
// Format date
function formatDate(dateString) {
const options = { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' };
return new Date(dateString).toLocaleDateString('fr-FR', options);
}
// Get status class
function getStatusClass(status) {
switch(status) {
case 'confirmed':
return 'bg-green-100 text-green-800';
case 'pending':
return 'bg-yellow-100 text-yellow-800';
case 'cancelled':
return 'bg-red-100 text-red-800';
case 'completed':
return 'bg-blue-100 text-blue-800';
case 'in-progress':
return 'bg-purple-100 text-purple-800';
default:
return 'bg-gray-100 text-gray-800';
}
}
// Get status text
function getStatusText(status) {
switch(status) {
case 'confirmed':
return 'Confirmé';
case 'pending':
return 'En attente';
case 'cancelled':
return 'Annulé';
case 'completed':
return 'Terminé';
case 'in-progress':
return 'En cours';
default:
return 'Inconnu';
}
}
// Render calendar
function renderCalendar() {
const calendarGrid = document.getElementById('calendar-grid');
calendarGrid.innerHTML = '';
// Get current date
const currentDate = new Date();
const currentMonth = currentDate.getMonth();
const currentYear = currentDate.getFullYear();
// Get first day of month
const firstDay = new Date(currentYear, currentMonth, 1).getDay();
// Adjust for Monday as first day (French calendar)
const firstDayAdjusted = firstDay === 0 ? 6 : firstDay - 1;
// Get days in month
const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
// Get days from previous month to show
const prevMonthDays = new Date(currentYear, currentMonth, 0).getDate();
// Create calendar cells
let dayCount = 0;
let nextMonthDay = 1;
// 6 rows x 7 columns = 42 cells
for (let i = 0; i < 42; i++) {
const cell = document.createElement('div');
cell.className = 'min-h-24 p-1 border border-gray-100';
// Days from previous month
if (i < firstDayAdjusted) {
const prevDay = prevMonthDays - (firstDayAdjusted - i - 1);
cell.innerHTML = `<div class="text-right text-gray-400">${prevDay}</div>`;
cell.classList.add('bg-gray-50');
}
// Days in current month
else if (dayCount < daysInMonth) {
dayCount++;
const dateStr = `${currentYear}-${String(currentMonth + 1).padStart(2, '0')}-${String(dayCount).padStart(2, '0')}`;
cell.innerHTML = `
<div class="text-right font-medium">${dayCount}</div>
<div class="mt-1 space-y-1" id="events-${dateStr}"></div>
`;
// Highlight today
if (dayCount === currentDate.getDate() && currentMonth === new Date().getMonth() && currentYear === new Date().getFullYear()) {
cell.querySelector('div:first-child').classList.add('bg-medical-blue', 'text-white', 'rounded-full', 'w-6', 'h-6', 'flex', 'items-center', 'justify-center', 'mx-auto');
}
// Add appointments to the cell
const eventsContainer = cell.querySelector(`#events-${dateStr}`);
const dayAppointments = appointments.filter(apt => apt.date === dateStr);
dayAppointments.forEach(apt => {
const event = document.createElement('div');
event.className = `text-xs p-1 rounded truncate ${getStatusClass(apt.status)}`;
event.textContent = `${apt.time} - ${apt.patient.split(' ')[0]}`;
eventsContainer.appendChild(event);
});
}
// Days from next month
else {
cell.innerHTML = `<div class="text-right text-gray-400">${nextMonthDay}</div>`;
cell.classList.add('bg-gray-50');
nextMonthDay++;
}
calendarGrid.appendChild(cell);
}
}
// Add new appointment
addAppointmentBtn.addEventListener('click', function() {
addAppointmentModal.classList.remove('hidden');
});
closeAddModalBtn.addEventListener('click', function() {
addAppointmentModal.classList.add('hidden');
});
cancelAddAppointmentBtn.addEventListener('click', function() {
addAppointmentModal.classList.add('hidden');
});
appointmentForm.addEventListener('submit', function(e) {
e.preventDefault();
// Get form values
const patientSelect = document.getElementById('patient');
const patientText = patientSelect.options[patientSelect.selectedIndex].text;
const examenType = document.getElementById('examen-type').value;
const date = document.getElementById('appointment-date').value;
const time = document.getElementById('appointment-time').value;
const notes = document.getElementById('notes').value;
// Create new appointment
const newAppointment = {
id: appointments.length > 0 ? Math.max(...appointments.map(a => a.id)) + 1 : 1,
patient: patientText,
date: date,
time: time,
type: examenType.charAt(0).toUpperCase() + examenType.slice(1),
status: 'pending',
doctor: 'Dr. Dupont',
notes: notes
};
// Add to appointments array
appointments.push(newAppointment);
// Show success message
alert('Rendez-vous créé avec succès!');
// Close modal and reset form
addAppointmentModal.classList.add('hidden');
appointmentForm.reset();
// Refresh appointments list and calendar
renderAppointments();
renderCalendar();
});
// View appointment
function viewAppointment(id) {
const appointment = appointments.find(apt => apt.id === id);
if (!appointment) return;
// Populate view modal
document.getElementById('view-patient-name').textContent = appointment.patient;
document.getElementById('view-patient-dob').textContent = '15/03/1975'; // Sample data
document.getElementById('view-patient-ssn').textContent = '1 85 03 75 123 456 78'; // Sample data
document.getElementById('view-patient-phone').textContent = '06 12 34 56 78'; // Sample data
const formattedDate = new Date(appointment.date).toLocaleDateString('fr-FR', {
weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'
});
document.getElementById('view-appointment-datetime').textContent =
`${formattedDate} à ${appointment.time}`;
document.getElementById('view-examen-type').textContent = appointment.type;
document.getElementById('view-status').innerHTML =
`<span class="px-2 py-1 rounded-full ${getStatusClass(appointment.status)}">${getStatusText(appointment.status)}</span>`;
document.getElementById('view-doctor').textContent = appointment.doctor;
document.getElementById('view-notes').textContent = appointment.notes;
// Store appointment ID in edit button
editFromViewBtn.setAttribute('data-id', appointment.id);
// Show modal
viewAppointmentModal.classList.remove('hidden');
}
closeViewModalBtn.addEventListener('click', function() {
viewAppointmentModal.classList.add('hidden');
});
// Edit from view
editFromViewBtn.addEventListener('click', function() {
const appointmentId = parseInt(this.getAttribute('data-id'));
viewAppointmentModal.classList.add('hidden');
editAppointment(appointmentId);
});
// Print appointment
printAppointmentBtn.addEventListener('click', function() {
window.print();
});
// Edit appointment
function editAppointment(id) {
const appointment = appointments.find(apt => apt.id === id);
if (!appointment) return;
// Populate edit form
document.getElementById('edit-appointment-id').value = appointment.id;
document.getElementById('edit-patient').value = '1'; // Sample data - would be appointment.patientId in real app
document.getElementById('edit-examen-type').value = appointment.type.toLowerCase().split(' ')[0]; // Simplified for demo
document.getElementById('edit-appointment-date').value = appointment.date;
document.getElementById('edit-appointment-time').value = appointment.time;
document.getElementById('edit-status').value = appointment.status;
document.getElementById('edit-notes').value = appointment.notes;
// Show modal
editAppointmentModal.classList.remove('hidden');
}
closeEditModalBtn.addEventListener('click', function() {
editAppointmentModal.classList.add('hidden');
});
cancelEditAppointmentBtn.addEventListener('click', function() {
editAppointmentModal.classList.add('hidden');
});
editAppointmentForm.addEventListener('submit', function(e) {
e.preventDefault();
// Get form values
const id = parseInt(document.getElementById('edit-appointment-id').value);
const patientSelect = document.getElementById('edit-patient');
const patientText = patientSelect.options[patientSelect.selectedIndex].text;
const examenType = document.getElementById('edit-examen-type').value;
const date = document.getElementById('edit-appointment-date').value;
const time = document.getElementById('edit-appointment-time').value;
const status = document.getElementById('edit-status').value;
const notes = document.getElementById('edit-notes').value;
// Find and update appointment
const appointmentIndex = appointments.findIndex(apt => apt.id === id);
if (appointmentIndex !== -1) {
appointments[appointmentIndex] = {
...appointments[appointmentIndex],
patient: patientText,
date: date,
time: time,
type: examenType.charAt(0).toUpperCase() + examenType.slice(1),
status: status,
notes: notes
};
}
// Show success message
alert('Rendez-vous modifié avec succès!');
// Close modal and reset form
editAppointmentModal.classList.add('hidden');
editAppointmentForm.reset();
// Refresh appointments list and calendar
renderAppointments();
renderCalendar();
});
// Delete appointment
function deleteAppointment(id) {
if (confirm('Êtes-vous sûr de vouloir supprimer ce rendez-vous?')) {
// Find and remove appointment
const appointmentIndex = appointments.findIndex(apt => apt.id === id);
if (appointmentIndex !== -1) {
appointments.splice(appointmentIndex, 1);
}
// Show success message
alert('Rendez-vous supprimé avec succès!');
// Refresh appointments list and calendar
renderAppointments();
renderCalendar();
}
}
// Export to PDF
exportPdfBtn.addEventListener('click', function() {
// In a real app, you would use jsPDF to generate a PDF
alert('Export PDF en cours de développement');
});
// Export to Excel
exportExcelBtn.addEventListener('click', function() {
// Create a worksheet
const ws = XLSX.utils.json_to_sheet(appointments.map(apt => ({
'Patient': apt.patient,
'Date': apt.date,
'Heure': apt.time,
'Type d\'examen': apt.type,
'Statut': getStatusText(apt.status),
'Médecin': apt.doctor
})));
// Create a workbook
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Rendez-vous");
// Export the workbook
XLSX.writeFile(wb, "rendez-vous_avicenne.xlsx");
});
// Notifications panel
notificationsBtn.addEventListener('click', function() {
notificationPanel.classList.remove('translate-x-full');
});
closeNotificationsBtn.addEventListener('click', function() {
notificationPanel.classList.add('translate-x-full');
});
</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=Dannylova31/nnnn" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>