Spaces:
Running
Running
crrez un tb web permettant de voir tous le personnel de ce syndicat sous forme de donnes crud pour permettre de saisir et ajouter et sup et mettre ajour les donnes du personnel du syndicat de la sante par wilaya suivant le fichier word joint بناء علي اجتماع رؤساء النقابات المهنية والكتب التنفيذي للاتحاد العام للعمل و الصحة في موريتانيا المنعقد في مقره المركزي يوم السبت الموافق 11 أكتوبر 2025 تم إقرار هذا الدليل الانتخابي الشامل و الذي سنيشر بالطرق الادارية ويعمل به بعد ان تم اقراره:
413b1b9 verified | <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Gestion du Personnel - Syndicat de la Santé</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/animejs/lib/anime.iife.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> | |
| <style> | |
| .fade-in { | |
| animation: fadeIn 0.5s ease-in; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .table-row:hover { | |
| background-color: #f8fafc; | |
| transform: translateY(-1px); | |
| transition: all 0.2s ease; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50"> | |
| <!-- Navigation --> | |
| <nav class="bg-blue-800 text-white shadow-lg"> | |
| <div class="container mx-auto px-4 py-3"> | |
| <div class="flex justify-between items-center"> | |
| <div class="flex items-center space-x-2"> | |
| <i data-feather="users" class="w-6 h-6"></i> | |
| <span class="text-xl font-bold">Syndicat de la Santé - Mauritanie</span> | |
| </div> | |
| <div class="space-x-4"> | |
| <a href="index.html" class="hover:text-blue-200 transition-colors">Accueil</a> | |
| <a href="personnel.html" class="bg-blue-700 px-3 py-1 rounded-lg">Personnel</a> | |
| </div> | |
| </div> | |
| </div> | |
| </nav> | |
| <!-- Header --> | |
| <div class="bg-white shadow-sm"> | |
| <div class="container mx-auto px-4 py-6"> | |
| <h1 class="text-3xl font-bold text-gray-800 mb-2">Gestion du Personnel par Wilaya</h1> | |
| <p class="text-gray-600">Système CRUD pour la gestion des données du personnel du syndicat</p> | |
| </div> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="container mx-auto px-4 py-8"> | |
| <!-- Filters and Actions --> | |
| <div class="mb-6 flex flex-col lg:flex-row gap-4 justify-between items-start lg:items-center"> | |
| <div class="flex flex-col sm:flex-row gap-3"> | |
| <select id="wilayaFilter" class="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"> | |
| <option value="">Toutes les wilayas</option> | |
| <option value="nouakchott">Nouakchott</option> | |
| <option value="hodh_chargui">Hodh Chargui</option> | |
| <option value="hodh_gharbi">Hodh Gharbi</option> | |
| <option value="assaba">Assaba</option> | |
| <option value="gorgol">Gorgol</option> | |
| <option value="guidimakha">Guidimakha</option> | |
| <option value="tagant">Tagant</option> | |
| <option value="brakna">Brakna</option> | |
| <option value="trarza">Trarza</option> | |
| <option value="adrar">Adrar</option> | |
| <option value="dakhlet_nouadhibou">Dakhlet Nouadhibou</option> | |
| <option value="inchiri">Inchiri</option> | |
| </select> | |
| <input type="text" id="searchInput" placeholder="Rechercher par nom, poste..." class="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 w-full sm:w-64"> | |
| </div> | |
| <button onclick="openAddModal()" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg flex items-center gap-2 transition-colors"> | |
| <i data-feather="plus" class="w-4 h-4"></i> | |
| Ajouter un membre | |
| </button> | |
| </div> | |
| <!-- Personnel Table --> | |
| <div class="bg-white rounded-lg shadow overflow-hidden fade-in"> | |
| <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"> | |
| Nom & Prénom | |
| </th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| Poste/Rôle | |
| </th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| Wilaya | |
| </th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| Téléphone | |
| </th> | |
| <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| Actions | |
| </th> | |
| </tr> | |
| </thead> | |
| <tbody id="personnelTable" class="bg-white divide-y divide-gray-200"> | |
| <!-- Data will be populated by JavaScript --> | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| <!-- Empty State --> | |
| <div id="emptyState" class="hidden text-center py-12"> | |
| <i data-feather="users" class="w-16 h-16 text-gray-400 mx-auto mb-4"></i> | |
| <h3 class="text-lg font-medium text-gray-900 mb-2">Aucun membre trouvé</h3> | |
| <p class="text-gray-500 mb-4">Aucun membre ne correspond à vos critères de recherche.</p> | |
| <button onclick="openAddModal()" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg inline-flex items-center gap-2"> | |
| <i data-feather="plus" class="w-4 h-4"></i> | |
| Ajouter le premier membre | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Add/Edit Modal --> | |
| <div id="personnelModal" class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50 hidden"> | |
| <div class="relative top-20 mx-auto p-5 border w-full max-w-2xl shadow-lg rounded-lg bg-white"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 id="modalTitle" class="text-xl font-bold text-gray-800">Ajouter un membre</h3> | |
| <button onclick="closeModal()" class="text-gray-400 hover:text-gray-600"> | |
| <i data-feather="x" class="w-6 h-6"></i> | |
| </button> | |
| </div> | |
| <form id="personnelForm" class="space-y-4"> | |
| <input type="hidden" id="editId"> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <div> | |
| <label for="nom" class="block text-sm font-medium text-gray-700 mb-1">Nom complet *</label> | |
| <input type="text" id="nom" required class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"> | |
| </div> | |
| <div> | |
| <label for="poste" class="block text-sm font-medium text-gray-700 mb-1">Poste/Rôle *</label> | |
| <input type="text" id="poste" required class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"> | |
| </div> | |
| <div> | |
| <label for="wilaya" class="block text-sm font-medium text-gray-700 mb-1">Wilaya *</label> | |
| <select id="wilaya" required class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"> | |
| <option value="">Sélectionner une wilaya</option> | |
| <option value="nouakchott">Nouakchott</option> | |
| <option value="hodh_chargui">Hodh Chargui</option> | |
| <option value="hodh_gharbi">Hodh Gharbi</option> | |
| <option value="assaba">Assaba</option> | |
| <option value="gorgol">Gorgol</option> | |
| <option value="guidimakha">Guidimakha</option> | |
| <option value="tagant">Tagant</option> | |
| <option value="brakna">Brakna</option> | |
| <option value="trarza">Trarza</option> | |
| <option value="adrar">Adrar</option> | |
| <option value="dakhlet_nouadhibou">Dakhlet Nouadhibou</option> | |
| <option value="inchiri">Inchiri</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label for="telephone" class="block text-sm font-medium text-gray-700 mb-1">Téléphone</label> | |
| <input type="tel" id="telephone" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"> | |
| </div> | |
| <div class="md:col-span-2"> | |
| <label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email</label> | |
| <input type="email" id="email" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"> | |
| </div> | |
| </div> | |
| <div class="flex justify-end space-x-3 pt-4"> | |
| <button type="button" onclick="closeModal()" class="px-4 py-2 text-gray-700 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"> | |
| Annuler | |
| </button> | |
| <button type="submit" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors"> | |
| Enregistrer | |
| </button> | |
| </div> | |
| </form> | |
| </div> | |
| </div> | |
| <script> | |
| // Sample data from the provided document | |
| let personnelData = [ | |
| { id: 1, nom: "الدكتور محمد المصطفى ولد إبراهيم", poste: "الأمين العام للاتحاد", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 2, nom: "دكتور محمد اميه", poste: "نقابة الأطباء الأخصائيين الموريتانيين", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 3, nom: "محمد الحسن الدوا", poste: "النقابة الوطنية لعمال قطاع العمل الاجتماعي", wilaya: "nouakchott", telephone: "42047024", email: "" }, | |
| { id: 4, nom: "البي محمد الأمين البراكة", poste: "نقابة مهنيي العمل الاجتماعي", wilaya: "nouakchott", telephone: "43439164", email: "" }, | |
| { id: 5, nom: "محمد محمد السالك اغربط", poste: "النقابة العامة لاسلاك إدارة الشغل", wilaya: "nouakchott", telephone: "46889697", email: "" }, | |
| { id: 6, nom: "احمد بوسالف", poste: "النقابة الوطنية لعمال مؤسسات التامين و الضمان الصحي بموريتانيا", wilaya: "nouakchott", telephone: "42246060", email: "" }, | |
| { id: 7, nom: "عبد الرحمن ولد حمود", poste: "نقابة مهنيي الممرضين والقابلات في موريتانيا", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 8, nom: "د.سيديا ولد أحمدوا", poste: "النقابة الوطنية لصيادلة موريتانيا", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 9, nom: "سيدي عالي محمد مدان", poste: "نقابة فنيّي التخدير والإنعاش بموريتانيا", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 10, nom: "د.محمد الأمين ولد محمد محمود", poste: "نقابة الأطباء العاميين الموريتانيين", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 11, nom: "د.محمد ولد أبات", poste: "نقابة الأطباء والصيادلة واطباء الأسنان الموريتانيين", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 12, nom: "أحمد ولد منان", poste: "النقابة الوطنية لفنيي تكنولوجيا صناعة الأسنان", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 13, nom: "يسلم ولد محمد ولد الداه", poste: "النقابة الوطنية لفنيي المختبر الطبي", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 14, nom: "د.أحمد ولد العالم", poste: "النقابة الوطنية لأطباء الأسنان في موريتانيا", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 15, nom: "المهندس اسحاق محمد سيديا", poste: "نقابة المهندسين والتقنيين لبيوطبيين الموريتانيين", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 16, nom: "محمد سالم محمد باب اليدالي", poste: "نقابة لبيولوجيين الطبيين الموريتانيين", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 17, nom: "ليلى محمد سالم أحميدات", poste: "النقابة الموريتانية للموظفين والوكلاء العقدويين في قطاع الصحة", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 18, nom: "حمزة محمدن ماماه", poste: "نقابة الفنيين العاليين في الصحة", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 19, nom: "الدكتور يحي محمد الأمين الطالب دحمان", poste: "نقابة المقيمين الطبيين", wilaya: "nouakchott", telephone: "", email: "" }, | |
| { id: 20, nom: "عالين ولد العيد", poste: "الكونفدرالية الموريتانية للشغيلة", wilaya: "nouakchott", telephone: "44305631", email: "" }, | |
| { id: 21, nom: "اندوم مامادو", poste: "المدير العام للحملة", wilaya: "nouakchott", telephone: "44149462", email: "" }, | |
| { id: 22, nom: "خدي همت با", poste: "المركز الصحي بالسبخة", wilaya: "nouakchott", telephone: "47772814", email: "" }, | |
| { id: 23, nom: "عاشورا جاكانا", poste: "المركز الصحي بالسبخة", wilaya: "nouakchott", telephone: "46563263", email: "" }, | |
| { id: 24, nom: "ماء العينين تكدي", poste: "المركز الصحي بالسبخة", wilaya: "nouakchott", telephone: "22739526", email: "" } | |
| ]; | |
| // Load data from localStorage or use sample data | |
| function loadPersonnelData() { | |
| const saved = localStorage.getItem('personnelData'); | |
| if (saved) { | |
| personnelData = JSON.parse(saved); | |
| } | |
| renderTable(); | |
| } | |
| // Save data to localStorage | |
| function savePersonnelData() { | |
| localStorage.setItem('personnelData', JSON.stringify(personnelData)); | |
| } | |
| // Render table with data | |
| function renderTable() { | |
| const tableBody = document.getElementById('personnelTable'); | |
| const emptyState = document.getElementById('emptyState'); | |
| const wilayaFilter = document.getElementById('wilayaFilter').value; | |
| const searchTerm = document.getElementById('searchInput').value.toLowerCase(); | |
| const filteredData = personnelData.filter(person => { | |
| const matchesWilaya = !wilayaFilter || person.wilaya === wilayaFilter; | |
| const matchesSearch = !searchTerm || | |
| person.nom.toLowerCase().includes(searchTerm) || | |
| person.poste.toLowerCase().includes(searchTerm) || | |
| (person.telephone && person.telephone.includes(searchTerm)); | |
| return matchesWilaya && matchesSearch; | |
| }); | |
| if (filteredData.length === 0) { | |
| tableBody.innerHTML = ''; | |
| emptyState.classList.remove('hidden'); | |
| return; | |
| } | |
| emptyState.classList.add('hidden'); | |
| tableBody.innerHTML = filteredData.map(person => ` | |
| <tr class="table-row fade-in"> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${person.nom}</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${person.poste}</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"> | |
| ${getWilayaName(person.wilaya)} | |
| </td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${person.telephone || 'Non renseigné'}</td> | |
| <td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
| <div class="flex space-x-2"> | |
| <button onclick="editPersonnel(${person.id})" class="text-blue-600 hover:text-blue-900 flex items-center gap-1"> | |
| <i data-feather="edit" class="w-4 h-4"></i> | |
| Modifier | |
| </button> | |
| <button onclick="deletePersonnel(${person.id})" class="text-red-600 hover:text-red-900 flex items-center gap-1"> | |
| <i data-feather="trash-2" class="w-4 h-4"></i> | |
| Supprimer | |
| </button> | |
| </div> | |
| </td> | |
| </tr> | |
| `).join(''); | |
| feather.replace(); | |
| } | |
| // Get wilaya name | |
| function getWilayaName(code) { | |
| const wilayas = { | |
| 'nouakchott': 'نواكشوط', | |
| 'hodh_chargui': 'الحوض الشرقي', | |
| 'hodh_gharbi': 'الحوض الغربي', | |
| 'assaba': 'لعصابة', | |
| 'gorgol': 'غورغول', | |
| 'guidimakha': 'غيدي ماغا', | |
| 'tagant': 'تكانت', | |
| 'brakna': 'لبراكنة', | |
| 'trarza': 'اترارزة', | |
| 'adrar': 'آدرار', | |
| 'dakhlet_nouadhibou': 'داخلت انواذيبو', | |
| 'inchiri': 'انشيري' | |
| }; | |
| return wilayas[code] || code; | |
| } | |
| // Open add modal | |
| function openAddModal() { | |
| document.getElementById('modalTitle').textContent = 'Ajouter un membre'; | |
| document.getElementById('personnelForm').reset(); | |
| document.getElementById('editId').value = ''; | |
| document.getElementById('personnelModal').classList.remove('hidden'); | |
| } | |
| // Close modal | |
| function closeModal() { | |
| document.getElementById('personnelModal').classList.add('hidden'); | |
| } | |
| // Edit personnel | |
| function editPersonnel(id) { | |
| const person = personnelData.find(p => p.id === id); | |
| if (person) { | |
| document.getElementById('modalTitle').textContent = 'Modifier un membre'; | |
| document.getElementById('nom').value = person.nom; | |
| document.getElementById('poste').value = person.poste; | |
| document.getElementById('wilaya').value = person.wilaya; | |
| document.getElementById('telephone').value = person.telephone || ''; | |
| document.getElementById('email').value = person.email || ''; | |
| document.getElementById('editId').value = person.id; | |
| document.getElementById('personnelModal').classList.remove('hidden'); | |
| } | |
| } | |
| // Delete personnel | |
| function deletePersonnel(id) { | |
| Swal.fire({ | |
| title: 'Êtes-vous sûr?', | |
| text: "Cette action ne peut pas être annulée!", | |
| icon: 'warning', | |
| showCancelButton: true, | |
| confirmButtonColor: '#d33', | |
| cancelButtonColor: '#3085d6', | |
| confirmButtonText: 'Oui, supprimer!', | |
| cancelButtonText: 'Annuler' | |
| }).then((result) => { | |
| if (result.isConfirmed) { | |
| personnelData = personnelData.filter(p => p.id !== id); | |
| savePersonnelData(); | |
| renderTable(); | |
| Swal.fire( | |
| 'Supprimé!', | |
| 'Le membre a été supprimé.', | |
| 'success' | |
| ); | |
| } | |
| }); | |
| } | |
| // Form submission | |
| document.getElementById('personnelForm').addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| const id = document.getElementById('editId').value; | |
| const nom = document.getElementById('nom').value; | |
| const poste = document.getElementById('poste').value; | |
| const wilaya = document.getElementById('wilaya').value; | |
| const telephone = document.getElementById('telephone').value; | |
| const email = document.getElementById('email').value; | |
| if (id) { | |
| // Edit existing | |
| const index = personnelData.findIndex(p => p.id == id); | |
| personnelData[index] = { ...personnelData[index], nom, poste, wilaya, telephone, email }; | |
| } else { | |
| // Add new | |
| const newId = personnelData.length > 0 ? Math.max(...personnelData.map(p => p.id)) + 1 : 1; | |
| personnelData.push({ id: newId, nom, poste, wilaya, telephone, email }; | |
| } | |
| savePersonnelData(); | |
| renderTable(); | |
| closeModal(); | |
| Swal.fire({ | |
| icon: 'success', | |
| title: id ? 'Membre modifié!' : 'Membre ajouté!', | |
| showConfirmButton: false, | |
| timer: 1500 | |
| }); | |
| }); | |
| // Event listeners for filters | |
| document.getElementById('wilayaFilter').addEventListener('change', renderTable); | |
| document.getElementById('searchInput').addEventListener('input', renderTable); | |
| // Initialize | |
| document.addEventListener('DOMContentLoaded', function() { | |
| loadPersonnelData(); | |
| feather.replace(); | |
| }); | |
| </script> | |
| </body> | |
| </html> |