undefined / index.html
Esmaeilkiani's picture
Manual changes saved
94fd5d1 verified
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>بهداری دهخدا</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
fontFamily: {
sans: ['Vazir', 'sans-serif'],
}
}
}
</script>
<style>
@font-face {
font-family: 'Vazir';
src: url('https://cdn.jsdelivr.net/gh/rastikerdar/vazir-font@v30.1.0/dist/Vazir.woff2') format('woff2');
}
body {
font-family: 'Vazir', sans-serif;
}
.sidebar {
transition: all 0.3s ease;
}
.fade-in {
animation: fadeIn 0.3s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.rtl-dir {
direction: rtl;
}
</style>
</head>
<body class="bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-gray-200">
<div class="flex h-screen overflow-hidden">
<!-- Sidebar -->
<div id="sidebar" class="sidebar w-64 bg-white dark:bg-gray-800 shadow-lg flex flex-col">
<div class="p-4 border-b border-gray-200 dark:border-gray-700">
<div class="flex items-center justify-between">
<h1 class="text-xl font-bold text-indigo-600 dark:text-indigo-400">SugarCare 🏥</h1>
<button id="darkModeToggle" class="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700">
<i data-feather="moon" class="text-gray-700 dark:text-gray-300"></i>
</button>
</div>
</div>
<nav class="flex-1 overflow-y-auto">
<ul>
<li>
<a href="#" onclick="showDashboard()" class="flex items-center p-3 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300">
<i data-feather="home" class="ml-2"></i>
<span>داشبورد</span>
</a>
</li>
<li>
<a href="#" onclick="showPatients()" class="flex items-center p-3 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300">
<i data-feather="users" class="ml-2"></i>
<span>پرونده بیماران</span>
</a>
</li>
<li>
<a href="#" onclick="showExamination()" class="flex items-center p-3 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300">
<i data-feather="file-plus" class="ml-2"></i>
<span>ثبت معاینه جدید</span>
</a>
</li>
<li>
<a href="#" onclick="showPharmacy()" class="flex items-center p-3 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300">
<i data-feather="package" class="ml-2"></i>
<span>داروخانه</span>
</a>
</li>
<li>
<a href="#" onclick="showVisits()" class="flex items-center p-3 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300">
<i data-feather="list" class="ml-2"></i>
<span>لیست مراجعات</span>
</a>
</li>
<li>
<a href="#" onclick="showReports()" class="flex items-center p-3 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300">
<i data-feather="bar-chart-2" class="ml-2"></i>
<span>گزارش‌ها و آمار</span>
</a>
</li>
</ul>
</nav>
<div class="p-4 border-t border-gray-200 dark:border-gray-700">
<button onclick="exportAllData()" class="w-full flex items-center justify-center p-2 bg-indigo-100 dark:bg-indigo-900 text-indigo-700 dark:text-indigo-300 rounded hover:bg-indigo-200 dark:hover:bg-indigo-800">
<i data-feather="download" class="ml-2"></i>
<span>خروجی تمام داده‌ها</span>
</button>
</div>
</div>
<!-- Main Content -->
<div class="flex-1 overflow-auto">
<header class="bg-white dark:bg-gray-800 shadow-sm p-4 flex items-center justify-between">
<button id="sidebarToggle" class="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 lg:hidden">
<i data-feather="menu"></i>
</button>
<h2 id="pageTitle" class="text-xl font-semibold">داشبورد</h2>
<div class="flex items-center space-x-2 space-x-reverse">
<div class="relative">
<input type="text" placeholder="جستجو..." class="pl-10 pr-4 py-2 border rounded-full text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
<i data-feather="search" class="absolute right-3 top-2.5 text-gray-400"></i>
</div>
<div class="h-8 w-8 rounded-full bg-indigo-100 dark:bg-indigo-900 flex items-center justify-center">
<i data-feather="user" class="text-indigo-600 dark:text-indigo-400"></i>
</div>
</div>
</header>
<main class="p-4">
<!-- Dashboard Content -->
<div id="dashboardContent" class="fade-in">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
<!-- Today's Visits -->
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-4">
<div class="flex items-center">
<div class="p-3 rounded-full bg-indigo-100 dark:bg-indigo-900 text-indigo-600 dark:text-indigo-400">
<i data-feather="calendar"></i>
</div>
<div class="mr-3">
<p class="text-gray-500 dark:text-gray-400 text-sm">مراجعات امروز</p>
<h3 class="font-bold text-xl" id="todayVisits">0</h3>
</div>
</div>
</div>
<!-- Weekly Visits -->
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-4">
<div class="flex items-center">
<div class="p-3 rounded-full bg-green-100 dark:bg-green-900 text-green-600 dark:text-green-400">
<i data-feather="activity"></i>
</div>
<div class="mr-3">
<p class="text-gray-500 dark:text-gray-400 text-sm">مراجعات هفتگی</p>
<h3 class="font-bold text-xl" id="weeklyVisits">0</h3>
</div>
</div>
</div>
<!-- Hospital Transfers -->
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-4">
<div class="flex items-center">
<div class="p-3 rounded-full bg-red-100 dark:bg-red-900 text-red-600 dark:text-red-400">
<i data-feather="truck"></i>
</div>
<div class="mr-3">
<p class="text-gray-500 dark:text-gray-400 text-sm">اعزام به بیمارستان</p>
<h3 class="font-bold text-xl" id="hospitalTransfers">0</h3>
</div>
</div>
</div>
<!-- Ambulance Status -->
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-4">
<div class="flex items-center">
<div class="p-3 rounded-full bg-yellow-100 dark:bg-yellow-900 text-yellow-600 dark:text-yellow-400">
<i data-feather="alert-triangle"></i>
</div>
<div class="mr-3">
<p class="text-gray-500 dark:text-gray-400 text-sm">وضعیت آمبولانس</p>
<h3 class="font-bold text-xl" id="ambulanceStatus">عملیاتی</h3>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Recent Visits -->
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-4 lg:col-span-2">
<div class="flex items-center justify-between mb-4">
<h3 class="font-semibold">آخرین مراجعات</h3>
<button onclick="showVisits()" class="text-sm text-indigo-600 dark:text-indigo-400 hover:underline">مشاهده همه</button>
</div>
<div class="overflow-x-auto">
<table class="min-w-full">
<thead>
<tr class="border-b border-gray-200 dark:border-gray-700">
<th class="text-right py-2 px-4">نام بیمار</th>
<th class="text-right py-2 px-4">کد ملی</th>
<th class="text-right py-2 px-4">واحد کاری</th>
<th class="text-right py-2 px-4">تاریخ</th>
</tr>
</thead>
<tbody id="recentVisits">
<!-- Will be populated by JS -->
</tbody>
</table>
</div>
</div>
<!-- Medicine Stock -->
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-4">
<div class="flex items-center justify-between mb-4">
<h3 class="font-semibold">موجودی داروها</h3>
<button onclick="showPharmacy()" class="text-sm text-indigo-600 dark:text-indigo-400 hover:underline">مشاهده همه</button>
</div>
<div class="space-y-3">
<div>
<div class="flex justify-between text-sm mb-1">
<span>پنی‌سیلین</span>
<span>45 عدد</span>
</div>
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div class="bg-indigo-600 h-2 rounded-full" style="width: 45%"></div>
</div>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span>استامینوفن</span>
<span>32 عدد</span>
</div>
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div class="bg-indigo-600 h-2 rounded-full" style="width: 32%"></div>
</div>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span>ایبوپروفن</span>
<span>18 عدد</span>
</div>
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div class="bg-indigo-600 h-2 rounded-full" style="width: 18%"></div>
</div>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span>آنتی‌هیستامین</span>
<span>56 عدد</span>
</div>
<div class="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div class="bg-indigo-600 h-2 rounded-full" style="width: 56%"></div>
</div>
</div>
</div>
</div>
</div>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-4 mt-6">
<div class="flex items-center justify-between mb-4">
<h3 class="font-semibold">آمار بیماری‌ها در هفته جاری</h3>
</div>
<div class="h-64">
<canvas id="diseasesChart"></canvas>
</div>
</div>
</div>
<!-- Patients Content -->
<div id="patientsContent" class="fade-in hidden">
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-semibold">پرونده بیماران</h2>
<div class="flex space-x-2 space-x-reverse">
<button onclick="showAddPatientModal()" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded flex items-center">
<i data-feather="plus" class="ml-2"></i>
<span>بیمار جدید</span>
</button>
<button onclick="showImportModal()" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded flex items-center">
<i data-feather="upload" class="ml-2"></i>
<span>ورود از اکسل</span>
</button>
</div>
</div>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow overflow-hidden">
<div class="p-4 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center">
<div class="relative max-w-xs">
<input type="text" id="patientSearch" placeholder="جستجوی بیمار..." class="pl-10 pr-4 py-2 border rounded-full text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600 w-full">
<i data-feather="search" class="absolute right-3 top-2.5 text-gray-400"></i>
</div>
<div class="flex items-center space-x-2 space-x-reverse">
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
<i data-feather="filter"></i>
</button>
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
<i data-feather="download"></i>
</button>
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-gray-700">
<tr>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">نام و نام خانوادگی</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">کد ملی</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">کد پرسنلی</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">واحد کاری</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">جنسیت</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">عملیات</th>
</tr>
</thead>
<tbody id="patientsTableBody" class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
<!-- Will be populated by JS -->
</tbody>
</table>
</div>
<div class="p-4 border-t border-gray-200 dark:border-gray-700 flex justify-between items-center">
<div class="text-sm text-gray-500 dark:text-gray-400">
نمایش <span id="patientStart">1</span> تا <span id="patientEnd">10</span> از <span id="patientTotal">0</span> بیمار
</div>
<div class="flex items-center space-x-2 space-x-reverse">
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-50" id="patientPrevBtn" disabled>
<i data-feather="chevron-right"></i>
</button>
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-50" id="patientNextBtn" disabled>
<i data-feather="chevron-left"></i>
</button>
</div>
</div>
</div>
</div>
<!-- Examination Content -->
<div id="examinationContent" class="fade-in hidden">
<h2 class="text-xl font-semibold mb-6">ثبت معاینه جدید</h2>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
<form id="examinationForm">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="patientSelect" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">بیمار</label>
<select id="patientSelect" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
<option value="">انتخاب بیمار...</option>
<!-- Will be populated by JS -->
</select>
</div>
<div>
<label for="examiner" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">معاینه‌کننده</label>
<input type="text" id="examiner" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
<div>
<label for="examinationDate" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">تاریخ و زمان</label>
<input type="datetime-local" id="examinationDate" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
<div>
<label for="disease" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">بیماری/عارضه</label>
<div class="relative">
<input type="text" id="disease" list="diseaseList" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
<datalist id="diseaseList">
<!-- Common diseases will be populated by JS -->
</datalist>
</div>
</div>
<div class="md:col-span-2">
<label for="description" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">شرح حال</label>
<textarea id="description" rows="3" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600"></textarea>
</div>
<div class="md:col-span-2">
<label for="actionsTaken" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">اقدامات انجام شده</label>
<textarea id="actionsTaken" rows="3" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600"></textarea>
</div>
<div class="md:col-span-2">
<div class="flex justify-between items-center mb-2">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">داروهای تجویزی</label>
<button type="button" onclick="addMedicine()" class="text-sm text-indigo-600 dark:text-indigo-400 hover:underline flex items-center">
<i data-feather="plus" class="ml-1 w-4 h-4"></i>
افزودن دارو
</button>
</div>
<div id="medicinesContainer" class="space-y-3">
<!-- Medicine items will be added here -->
</div>
</div>
</div>
<div class="mt-6 flex justify-end space-x-3 space-x-reverse">
<button type="reset" class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700">لغو</button>
<button type="submit" class="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg">ثبت معاینه</button>
</div>
</form>
</div>
</div>
<!-- Pharmacy Content -->
<div id="pharmacyContent" class="fade-in hidden">
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-semibold">داروخانه</h2>
<div class="flex space-x-2 space-x-reverse">
<button onclick="showAddMedicineModal()" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded flex items-center">
<i data-feather="plus" class="ml-2"></i>
<span>داروی جدید</span>
</button>
<button onclick="showImportMedicineModal()" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded flex items-center">
<i data-feather="upload" class="ml-2"></i>
<span>ورود از اکسل</span>
</button>
</div>
</div>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow overflow-hidden">
<div class="p-4 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center">
<div class="relative max-w-xs">
<input type="text" id="medicineSearch" placeholder="جستجوی دارو..." class="pl-10 pr-4 py-2 border rounded-full text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600 w-full">
<i data-feather="search" class="absolute right-3 top-2.5 text-gray-400"></i>
</div>
<div class="flex items-center space-x-2 space-x-reverse">
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
<i data-feather="filter"></i>
</button>
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
<i data-feather="download"></i>
</button>
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-gray-700">
<tr>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">نام دارو</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">نوع دارو</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">واحد</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">دوز</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">موجودی</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">تاریخ انقضا</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">عملیات</th>
</tr>
</thead>
<tbody id="medicineTableBody" class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
<!-- Will be populated by JS -->
</tbody>
</table>
</div>
<div class="p-4 border-t border-gray-200 dark:border-gray-700 flex justify-between items-center">
<div class="text-sm text-gray-500 dark:text-gray-400">
نمایش <span id="medicineStart">1</span> تا <span id="medicineEnd">10</span> از <span id="medicineTotal">0</span> دارو
</div>
<div class="flex items-center space-x-2 space-x-reverse">
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-50" id="medicinePrevBtn" disabled>
<i data-feather="chevron-right"></i>
</button>
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-50" id="medicineNextBtn" disabled>
<i data-feather="chevron-left"></i>
</button>
</div>
</div>
</div>
<div class="mt-6 grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
<h3 class="font-semibold mb-4">توزیع داروها بر اساس نوع</h3>
<div class="h-64">
<canvas id="medicineTypeChart"></canvas>
</div>
</div>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
<h3 class="font-semibold mb-4">داروهای در حال اتمام</h3>
<div class="h-64">
<canvas id="lowStockChart"></canvas>
</div>
</div>
</div>
</div>
<!-- Visits Content -->
<div id="visitsContent" class="fade-in hidden">
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-semibold">لیست مراجعات</h2>
<div class="flex items-center space-x-3 space-x-reverse">
<div class="relative">
<input type="text" placeholder="جستجو..." class="pl-10 pr-4 py-2 border rounded-full text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
<i data-feather="search" class="absolute right-3 top-2.5 text-gray-400"></i>
</div>
<div class="flex items-center space-x-2 space-x-reverse">
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
<i data-feather="filter"></i>
</button>
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
<i data-feather="download"></i>
</button>
</div>
</div>
</div>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-gray-700">
<tr>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">نام بیمار</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">کد ملی</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">کد پرسنلی</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">واحد کاری</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">تاریخ مراجعه</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">بیماری/عارضه</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">داروهای تجویزی</th>
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">عملیات</th>
</tr>
</thead>
<tbody id="visitsTableBody" class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
<!-- Will be populated by JS -->
</tbody>
</table>
</div>
<div class="p-4 border-t border-gray-200 dark:border-gray-700 flex justify-between items-center">
<div class="text-sm text-gray-500 dark:text-gray-400">
نمایش <span id="visitStart">1</span> تا <span id="visitEnd">10</span> از <span id="visitTotal">0</span> مراجعه
</div>
<div class="flex items-center space-x-2 space-x-reverse">
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-50" id="visitPrevBtn" disabled>
<i data-feather="chevron-right"></i>
</button>
<button class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-50" id="visitNextBtn" disabled>
<i data-feather="chevron-left"></i>
</button>
</div>
</div>
</div>
</div>
<!-- Reports Content -->
<div id="reportsContent" class="fade-in hidden">
<h2 class="text-xl font-semibold mb-6">گزارش‌ها و آمار</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
<h3 class="font-semibold mb-4">تعداد مراجعات در یک ماه اخیر</h3>
<div class="h-64">
<canvas id="monthlyVisitsChart"></canvas>
</div>
</div>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
<h3 class="font-semibold mb-4">توزیع مراجعات بر اساس واحد کاری</h3>
<div class="h-64">
<canvas id="departmentVisitsChart"></canvas>
</div>
</div>
</div>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6 mb-6">
<h3 class="font-semibold mb-4">بیماری‌های شایع</h3>
<div class="h-64">
<canvas id="commonDiseasesChart"></canvas>
</div>
</div>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
<h3 class="font-semibold mb-4">وضعیت آمبولانس‌ها</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="bg-green-50 dark:bg-green-900 rounded-lg p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-green-700 dark:text-green-300">آمبولانس 1</p>
<h4 class="text-lg font-semibold text-green-800 dark:text-green-200">عملیاتی</h4>
</div>
<div class="p-2 rounded-full bg-green-100 dark:bg-green-800 text-green-600 dark:text-green-300">
<i data-feather="check-circle"></i>
</div>
</div>
</div>
<div class="bg-yellow-50 dark:bg-yellow-900 rounded-lg p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-yellow-700 dark:text-yellow-300">آمبولانس 2</p>
<h4 class="text-lg font-semibold text-yellow-800 dark:text-yellow-200">در تعمیرات</h4>
</div>
<div class="p-2 rounded-full bg-yellow-100 dark:bg-yellow-800 text-yellow-600 dark:text-yellow-300">
<i data-feather="alert-triangle"></i>
</div>
</div>
</div>
<div class="bg-red-50 dark:bg-red-900 rounded-lg p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm text-red-700 dark:text-red-300">آمبولانس 3</p>
<h4 class="text-lg font-semibold text-red-800 dark:text-red-200">نیاز به سرویس</h4>
</div>
<div class="p-2 rounded-full bg-red-100 dark:bg-red-800 text-red-600 dark:text-red-300">
<i data-feather="x-circle"></i>
</div>
</div>
</div>
</div>
<div class="mt-6">
<button onclick="showAmbulanceReportModal()" class="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg flex items-center">
<i data-feather="plus" class="ml-2"></i>
<span>ثبت گزارش جدید</span>
</button>
</div>
</div>
</div>
</main>
</div>
</div>
<!-- Add Patient Modal -->
<div id="addPatientModal" class="fixed inset-0 z-50 hidden overflow-y-auto">
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div class="absolute inset-0 bg-gray-500 dark:bg-gray-900 opacity-75"></div>
</div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<div class="inline-block align-bottom bg-white dark:bg-gray-800 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
<div class="bg-white dark:bg-gray-800 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-indigo-100 dark:bg-indigo-900 sm:mx-0 sm:h-10 sm:w-10">
<i data-feather="user-plus" class="text-indigo-600 dark:text-indigo-400"></i>
</div>
<div class="mt-3 text-center sm:mt-0 sm:mr-4 sm:text-right w-full">
<h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-gray-100">
ثبت بیمار جدید
</h3>
<div class="mt-4">
<form id="patientForm">
<div class="grid grid-cols-1 gap-4">
<div>
<label for="firstName" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">نام</label>
<input type="text" id="firstName" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
<div>
<label for="lastName" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">نام خانوادگی</label>
<input type="text" id="lastName" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
<div>
<label for="nationalId" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">کد ملی</label>
<input type="text" id="nationalId" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
<div>
<label for="employeeId" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">کد پرسنلی</label>
<input type="text" id="employeeId" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
<div>
<label for="department" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">واحد کاری</label>
<select id="department" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
<option value="">انتخاب واحد...</option>
<!-- Will be populated by JS -->
</select>
</div>
<div>
<label for="workLocation" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">محل کار جزئی (اختیاری)</label>
<input type="text" id="workLocation" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">جنسیت</label>
<div class="flex space-x-4 space-x-reverse mt-1">
<label class="inline-flex items-center">
<input type="radio" name="gender" value="male" class="text-indigo-600 dark:text-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-600">
<span class="mr-2">مرد</span>
</label>
<label class="inline-flex items-center">
<input type="radio" name="gender" value="female" class="text-indigo-600 dark:text-indigo-400 focus:ring-indigo-500 dark:focus:ring-indigo-600">
<span class="mr-2">زن</span>
</label>
</div>
</div>
<div>
<label for="age" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">سن</label>
<input type="number" id="age" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
<div>
<label for="phone" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">شماره تماس</label>
<input type="tel" id="phone" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 dark:bg-gray-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button type="button" onclick="savePatient()" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-indigo-600 text-base font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:ml-3 sm:w-auto sm:text-sm">
ثبت بیمار
</button>
<button type="button" onclick="closeModal('addPatientModal')" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-gray-600 shadow-sm px-4 py-2 bg-white dark:bg-gray-600 text-base font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
انصراف
</button>
</div>
</div>
</div>
</div>
<!-- Import Modal -->
<div id="importModal" class="fixed inset-0 z-50 hidden overflow-y-auto">
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div class="absolute inset-0 bg-gray-500 dark:bg-gray-900 opacity-75"></div>
</div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<div class="inline-block align-bottom bg-white dark:bg-gray-800 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
<div class="bg-white dark:bg-gray-800 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-green-100 dark:bg-green-900 sm:mx-0 sm:h-10 sm:w-10">
<i data-feather="upload" class="text-green-600 dark:text-green-400"></i>
</div>
<div class="mt-3 text-center sm:mt-0 sm:mr-4 sm:text-right w-full">
<h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-gray-100">
ورود اطلاعات از اکسل
</h3>
<div class="mt-4">
<div class="flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 dark:border-gray-600 border-dashed rounded-md">
<div class="space-y-1 text-center">
<div class="flex text-sm text-gray-600 dark:text-gray-300">
<label for="excelFile" class="relative cursor-pointer bg-white dark:bg-gray-800 rounded-md font-medium text-indigo-600 dark:text-indigo-400 hover:text-indigo-500 dark:hover:text-indigo-300 focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-indigo-500">
<span>آپلود فایل اکسل</span>
<input id="excelFile" name="excelFile" type="file" class="sr-only" accept=".xlsx,.xls">
</label>
<p class="mr-1">یا کشیدن و رها کردن</p>
</div>
<p class="text-xs text-gray-500 dark:text-gray-400">
XLS, XLSX تا 10MB
</p>
</div>
</div>
<div id="excelPreview" class="mt-4 hidden">
<h4 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">پیش‌نمایش داده‌ها</h4>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700 border border-gray-200 dark:border-gray-700">
<thead class="bg-gray-50 dark:bg-gray-700">
<tr id="excelHeaders">
<!-- Will be populated by JS -->
</tr>
</thead>
<tbody id="excelRows" class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
<!-- Will be populated by JS -->
</tbody>
</table>
</div>
<div class="mt-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">عملیات</label>
<div class="space-y-2">
<div class="flex items-center">
<input id="addNewPatients" name="importAction" type="radio" value="add" checked class="focus:ring-indigo-500 dark:focus:ring-indigo-600 h-4 w-4 text-indigo-600 dark:text-indigo-400 border-gray-300 dark:border-gray-600">
<label for="addNewPatients" class="mr-2 block text-sm text-gray-700 dark:text-gray-300">
افزودن بیماران جدید
</label>
</div>
<div class="flex items-center">
<input id="updateExisting" name="importAction" type="radio" value="update" class="focus:ring-indigo-500 dark:focus:ring-indigo-600 h-4 w-4 text-indigo-600 dark:text-indigo-400 border-gray-300 dark:border-gray-600">
<label for="updateExisting" class="mr-2 block text-sm text-gray-700 dark:text-gray-300">
به‌روزرسانی بیماران موجود
</label>
</div>
<div class="flex items-center">
<input id="replaceAll" name="importAction" type="radio" value="replace" class="focus:ring-indigo-500 dark:focus:ring-indigo-600 h-4 w-4 text-indigo-600 dark:text-indigo-400 border-gray-300 dark:border-gray-600">
<label for="replaceAll" class="mr-2 block text-sm text-gray-700 dark:text-gray-300">
جایگزینی همه بیماران
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 dark:bg-gray-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button type="button" onclick="importPatients()" id="importBtn" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-600 text-base font-medium text-white hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:ml-3 sm:w-auto sm:text-sm hidden">
وارد کردن داده‌ها
</button>
<button type="button" onclick="closeModal('importModal')" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-gray-600 shadow-sm px-4 py-2 bg-white dark:bg-gray-600 text-base font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
انصراف
</button>
</div>
</div>
</div>
</div>
<!-- Add Medicine Modal -->
<div id="addMedicineModal" class="fixed inset-0 z-50 hidden overflow-y-auto">
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div class="absolute inset-0 bg-gray-500 dark:bg-gray-900 opacity-75"></div>
</div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<div class="inline-block align-bottom bg-white dark:bg-gray-800 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
<div class="bg-white dark:bg-gray-800 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-indigo-100 dark:bg-indigo-900 sm:mx-0 sm:h-10 sm:w-10">
<i data-feather="package" class="text-indigo-600 dark:text-indigo-400"></i>
</div>
<div class="mt-3 text-center sm:mt-0 sm:mr-4 sm:text-right w-full">
<h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-gray-100">
ثبت داروی جدید
</h3>
<div class="mt-4">
<form id="medicineForm">
<div class="grid grid-cols-1 gap-4">
<div>
<label for="medicineName" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">نام دارو</label>
<input type="text" id="medicineName" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
<div>
<label for="medicineType" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">نوع دارو</label>
<select id="medicineType" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
<option value="">انتخاب نوع...</option>
<option value="قرص">قرص</option>
<option value="کپسول">کپسول</option>
<option value="آمپول">آمپول</option>
<option value="شربت">شربت</option>
<option value="پماد">پماد</option>
<option value="قطره">قطره</option>
</select>
</div>
<div>
<label for="medicineUnit" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">واحد شمارش</label>
<select id="medicineUnit" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
<option value="">انتخاب واحد...</option>
<option value="عدد">عدد</option>
<option value="بسته">بسته</option>
<option value="شیشه">شیشه</option>
<option value="تیوب">تیوب</option>
<option value="بطری">بطری</option>
</select>
</div>
<div>
<label for="medicineDose" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">دوز (اختیاری)</label>
<input type="text" id="medicineDose" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
<div>
<label for="medicineQuantity" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">موجودی</label>
<input type="number" id="medicineQuantity" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
<div>
<label for="medicineExpiry" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">تاریخ انقضا</label>
<input type="date" id="medicineExpiry" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 dark:bg-gray-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button type="button" onclick="saveMedicine()" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-indigo-600 text-base font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:ml-3 sm:w-auto sm:text-sm">
ثبت دارو
</button>
<button type="button" onclick="closeModal('addMedicineModal')" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-gray-600 shadow-sm px-4 py-2 bg-white dark:bg-gray-600 text-base font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
انصراف
</button>
</div>
</div>
</div>
</div>
<!-- Ambulance Report Modal -->
<div id="ambulanceReportModal" class="fixed inset-0 z-50 hidden overflow-y-auto">
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div class="absolute inset-0 bg-gray-500 dark:bg-gray-900 opacity-75"></div>
</div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<div class="inline-block align-bottom bg-white dark:bg-gray-800 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
<div class="bg-white dark:bg-gray-800 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 dark:bg-red-900 sm:mx-0 sm:h-10 sm:w-10">
<i data-feather="truck" class="text-red-600 dark:text-red-400"></i>
</div>
<div class="mt-3 text-center sm:mt-0 sm:mr-4 sm:text-right w-full">
<h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-gray-100">
ثبت گزارش آمبولانس
</h3>
<div class="mt-4">
<form id="ambulanceForm">
<div class="grid grid-cols-1 gap-4">
<div>
<label for="ambulanceNumber" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">شماره آمبولانس</label>
<select id="ambulanceNumber" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
<option value="1">آمبولانس 1</option>
<option value="2">آمبولانس 2</option>
<option value="3">آمبولانس 3</option>
</select>
</div>
<div>
<label for="ambulanceStatus" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">وضعیت</label>
<select id="ambulanceStatus" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600">
<option value="operational">عملیاتی</option>
<option value="maintenance">در تعمیرات</option>
<option value="needs_service">نیاز به سرویس</option>
<option value="out_of_service">خارج از سرویس</option>
</select>
</div>
<div>
<label for="ambulanceNotes" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">توضیحات (اختیاری)</label>
<textarea id="ambulanceNotes" rows="3" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600"></textarea>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 dark:bg-gray-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button type="button" onclick="saveAmbulanceReport()" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
ثبت گزارش
</button>
<button type="button" onclick="closeModal('ambulanceReportModal')" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-gray-600 shadow-sm px-4 py-2 bg-white dark:bg-gray-600 text-base font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
انصراف
</button>
</div>
</div>
</div>
</div>
<!-- View Visit Modal -->
<div id="viewVisitModal" class="fixed inset-0 z-50 hidden overflow-y-auto">
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div class="absolute inset-0 bg-gray-500 dark:bg-gray-900 opacity-75"></div>
</div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<div class="inline-block align-bottom bg-white dark:bg-gray-800 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-2xl sm:w-full">
<div class="bg-white dark:bg-gray-800 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mt-3 text-center sm:mt-0 sm:text-right w-full">
<h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-gray-100" id="visitModalTitle">
جزئیات مراجعه
</h3>
<div class="mt-4">
<div class="bg-gray-50 dark:bg-gray-700 rounded-lg p-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<p class="text-sm text-gray-500 dark:text-gray-400">بیمار:</p>
<p class="font-medium" id="visitPatientName">-</p>
</div>
<div>
<p class="text-sm text-gray-500 dark:text-gray-400">کد ملی:</p>
<p class="font-medium" id="visitNationalId">-</p>
</div>
<div>
<p class="text-sm text-gray-500 dark:text-gray-400">کد پرسنلی:</p>
<p class="font-medium" id="visitEmployeeId">-</p>
</div>
<div>
<p class="text-sm text-gray-500 dark:text-gray-400">واحد کاری:</p>
<p class="font-medium" id="visitDepartment">-</p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<p class="text-sm text-gray-500 dark:text-gray-400">تاریخ و زمان:</p>
<p class="font-medium" id="visitDate">-</p>
</div>
<div>
<p class="text-sm text-gray-500 dark:text-gray-400">معاینه‌کننده:</p>
<p class="font-medium" id="visitExaminer">-</p>
</div>
<div>
<p class="text-sm text-gray-500 dark:text-gray-400">بیماری/عارضه:</p>
<p class="font-medium" id="visitDisease">-</p>
</div>
</div>
<div class="mb-4">
<p class="text-sm text-gray-500 dark:text-gray-400">شرح حال:</p>
<p class="font-medium" id="visitDescription">-</p>
</div>
<div class="mb-4">
<p class="text-sm text-gray-500 dark:text-gray-400">اقدامات انجام شده:</p>
<p class="font-medium" id="visitActions">-</p>
</div>
<div>
<p class="text-sm text-gray-500 dark:text-gray-400">داروهای تجویزی:</p>
<ul class="list-disc mr-4 mt-2 space-y-1" id="visitMedicines">
<!-- Will be populated by JS -->
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 dark:bg-gray-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button type="button" onclick="closeModal('viewVisitModal')" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-indigo-600 text-base font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:ml-3 sm:w-auto sm:text-sm">
بستن
</button>
</div>
</div>
</div>
</div>
<script>
// Database setup
let db;
const dbName = "SugarCareDB";
const dbVersion = 1;
// Open or create database
const request = indexedDB.open(dbName, dbVersion);
request.onerror = function(event) {
console.error("Database error:", event.target.error);
};
request.onupgradeneeded = function(event) {
const db = event.target.result;
// Create patients store
const patientsStore = db.createObjectStore("patients", { keyPath: "nationalId" });
patientsStore.createIndex("employeeId", "employeeId", { unique: true });
patientsStore.createIndex("department", "department", { unique: false });
// Create medicines store
const medicinesStore = db.createObjectStore("medicines", { keyPath: "name" });
medicinesStore.createIndex("type", "type", { unique: false });
medicinesStore.createIndex("expiry", "expiry", { unique: false });
// Create visits store
const visitsStore = db.createObjectStore("visits", { keyPath: "id", autoIncrement: true });
visitsStore.createIndex("patientId", "patientId", { unique: false });
visitsStore.createIndex("date", "date", { unique: false });
// Create departments store (for predefined departments)
const departmentsStore = db.createObjectStore("departments", { keyPath: "name" });
// Create common diseases store
const diseasesStore = db.createObjectStore("diseases", { keyPath: "name" });
// Create ambulance reports store
const ambulanceStore = db.createObjectStore("ambulances", { keyPath: "number" });
};
request.onsuccess = function(event) {
db = event.target.result;
console.log("Database opened successfully");
// Initialize data
initializeData();
// Load initial data
loadDashboardData();
loadPatients();
loadMedicines();
loadVisits();
// Set up event listeners
setupEventListeners();
};
function initializeData() {
// Predefined departments
const departments = [
"معاونت کشاورزی", "مطالعات کاربردی", "مهندسی زراعی", "تولید یکم", "تولید دوم",
"اداری", "بازرگانی", "حراست", "انبار", "کارخانه", "یارد", "تجهیزات مکانیکی",
"دفتر فنی", "غیر نیشکری"
];
// Common diseases
const diseases = [
"سرماخوردگی", "آنفلوآنزا", "تب", "سردرد", "درد عضلانی", "درد مفاصل",
"حالت تهوع", "اسهال", "یبوست", "سوزش معده", "سرفه", "گلودرد",
"تنگی نفس", "آلرژی", "خارش پوست", "جوش", "کمردرد", "درد گردن",
"دست یا پا شکسته", "سوختگی", "بریدگی", "خونریزی", "سرگیجه", "ضعف",
"بی‌خوابی", "اضطراب", "استرس", "مشکل بینایی", "مشکل شنوایی", "دندان درد"
];
// Common medicines
const medicines = [
{ name: "استامینوفن", type: "قرص", unit: "بسته", dose: "500mg", quantity: 100, expiry: "2024-12-31" },
{ name: "ایبوپروفن", type: "قرص", unit: "بسته", dose: "400mg", quantity: 80, expiry: "2024-11-30" },
{ name: "آنتی‌هیستامین", type: "قرص", unit: "بسته", dose: "10mg", quantity: 50, expiry: "2024-10-15" },
{ name: "آموکسی‌سیلین", type: "کپسول", unit: "بسته", dose: "500mg", quantity: 30, expiry: "2024-09-30" },
{ name: "پنی‌سیلین", type: "آمپول", unit: "عدد", dose: "1MIU", quantity: 20, expiry: "2024-08-31" },
{ name: "دیفن‌هیدرامین", type: "آمپول", unit: "عدد", dose: "50mg", quantity: 15, expiry: "2024-07-31" },
{ name: "ژلوفن", type: "کپسول", unit: "بسته", dose: "200mg", quantity: 40, expiry: "2024-06-30" },
{ name: "کدئین", type: "قرص", unit: "بسته", dose: "30mg", quantity: 25, expiry: "2024-05-31" },
{ name: "امپرازول", type: "کپسول", unit: "بسته", dose: "20mg", quantity: 35, expiry: "2024-04-30" },
{ name: "متوکاربامول", type: "قرص", unit: "بسته", dose: "500mg", quantity: 45, expiry: "2024-03-31" }
];
// Ambulance initial status
const ambulances = [
{ number: "1", status: "operational", notes: "" },
{ number: "2", status: "operational", notes: "" },
{ number: "3", status: "operational", notes: "" }
];
// Add departments to database if not exists
const tx = db.transaction(["departments", "diseases", "medicines", "ambulances"], "readwrite");
tx.oncomplete = function() {
console.log("Initial data added successfully");
};
tx.onerror = function(event) {
console.error("Error adding initial data:", event.target.error);
};
const departmentsStore = tx.objectStore("departments");
departments.forEach(dept => {
departmentsStore.put({ name: dept });
});
const diseasesStore = tx.objectStore("diseases");
diseases.forEach(disease => {
diseasesStore.put({ name: disease });
});
const medicinesStore = tx.objectStore("medicines");
medicines.forEach(medicine => {
medicinesStore.put(medicine);
});
const ambulanceStore = tx.objectStore("ambulances");
ambulances.forEach(ambulance => {
ambulanceStore.put(ambulance);
});
}
// UI Functions
function setupEventListeners() {
// Sidebar toggle
document.getElementById('sidebarToggle').addEventListener('click', function() {
document.getElementById('sidebar').classList.toggle('hidden');
document.getElementById('sidebar').classList.toggle('lg:flex');
});
// Dark mode toggle
document.getElementById('darkModeToggle').addEventListener('click', function() {
document.documentElement.classList.toggle('dark');
localStorage.setItem('darkMode', document.documentElement.classList.contains('dark'));
});
// Check for saved dark mode preference
if (localStorage.getItem('darkMode') === 'true') {
document.documentElement.classList.add('dark');
}
// Excel file import
document.getElementById('excelFile').addEventListener('change', handleExcelImport);
}
function showDashboard() {
hideAllContent();
document.getElementById('dashboardContent').classList.remove('hidden');
document.getElementById('pageTitle').textContent = 'داشبورد';
loadDashboardData();
}
function showPatients() {
hideAllContent();
document.getElementById('patientsContent').classList.remove('hidden');
document.getElementById('pageTitle').textContent = 'پرونده بیماران';
loadPatients();
}
function showExamination() {
hideAllContent();
document.getElementById('examinationContent').classList.remove('hidden');
document.getElementById('pageTitle').textContent = 'ثبت معاینه جدید';
loadPatientsForExamination();
loadCommonDiseases();
}
function showPharmacy() {
hideAllContent();
document.getElementById('pharmacyContent').classList.remove('hidden');
document.getElementById('pageTitle').textContent = 'داروخانه';
loadMedicines();
loadMedicineCharts();
}
function showVisits() {
hideAllContent();
document.getElementById('visitsContent').classList.remove('hidden');
document.getElementById('pageTitle').textContent = 'لیست مراجعات';
loadVisits();
}
function showReports() {
hideAllContent();
document.getElementById('reportsContent').classList.remove('hidden');
document.getElementById('pageTitle').textContent = 'گزارش‌ها و آمار';
loadReports();
}
function hideAllContent() {
const contents = document.querySelectorAll('[id$="Content"]');
contents.forEach(content => {
content.classList.add('hidden');
});
}
function showAddPatientModal() {
document.getElementById('addPatientModal').classList.remove('hidden');
populateDepartments();
}
function showImportModal() {
document.getElementById('importModal').classList.remove('hidden');
document.getElementById('excelPreview').classList.add('hidden');
document.getElementById('importBtn').classList.add('hidden');
document.getElementById('excelFile').value = '';
}
function showAddMedicineModal() {
document.getElementById('addMedicineModal').classList.remove('hidden');
document.getElementById('medicineForm').reset();
}
function showImportMedicineModal() {
// Similar to showImportModal but for medicines
alert("این ویژگی به زودی اضافه خواهد شد.");
}
function showAmbulanceReportModal() {
document.getElementById('ambulanceReportModal').classList.remove('hidden');
}
function closeModal(modalId) {
document.getElementById(modalId).classList.add('hidden');
}
function populateDepartments() {
const departmentSelect = document.getElementById('department');
departmentSelect.innerHTML = '<option value="">انتخاب واحد...</option>';
const tx = db.transaction("departments", "readonly");
const store = tx.objectStore("departments");
const request = store.getAll();
request.onsuccess = function(event) {
const departments = event.target.result;
departments.forEach(dept => {
const option = document.createElement('option');
option.value = dept.name;
option.textContent = dept.name;
departmentSelect.appendChild(option);
});
};
}
function loadPatientsForExamination() {
const patientSelect = document.getElementById('patientSelect');
patientSelect.innerHTML = '<option value="">انتخاب بیمار...</option>';
const tx = db.transaction("patients", "readonly");
const store = tx.objectStore("patients");
const request = store.getAll();
request.onsuccess = function(event) {
const patients = event.target.result;
patients.forEach(patient => {
const option = document.createElement('option');
option.value = patient.nationalId;
option.textContent = `${patient.firstName} ${patient.lastName} - ${patient.nationalId}`;
patientSelect.appendChild(option);
});
};
}
function loadCommonDiseases() {
const diseaseList = document.getElementById('diseaseList');
diseaseList.innerHTML = '';
const tx = db.transaction("diseases", "readonly");
const store = tx.objectStore("diseases");
const request = store.getAll();
request.onsuccess = function(event) {
const diseases = event.target.result;
diseases.forEach(disease => {
const option = document.createElement('option');
option.value = disease.name;
diseaseList.appendChild(option);
});
};
}
function addMedicine() {
const container = document.getElementById('medicinesContainer');
const medicineId = Date.now();
const medicineDiv = document.createElement('div');
medicineDiv.className = 'flex items-start gap-3';
medicineDiv.innerHTML = `
<div class="flex-1">
<input type="text" placeholder="نام دارو" list="medicineList" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600 medicine-name">
</div>
<div class="w-24">
<input type="number" placeholder="تعداد" class="w-full border rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:border-gray-600 medicine-quantity">
</div>
<button type="button" onclick="this.parentElement.remove()" class="p-2 text-red-500 hover:text-red-700 dark:hover:text-red-400">
<i data-feather="trash-2" class="w-4 h-4"></i>
</button>
`;
container.appendChild(medicineDiv);
feather.replace();
// Populate medicine datalist if not already done
if (!document.getElementById('medicineList')) {
const datalist = document.createElement('datalist');
datalist.id = 'medicineList';
document.body.appendChild(datalist);
const tx = db.transaction("medicines", "readonly");
const store = tx.objectStore("medicines");
const request = store.getAll();
request.onsuccess = function(event) {
const medicines = event.target.result;
datalist.innerHTML = '';
medicines.forEach(medicine => {
const option = document.createElement('option');
option.value = medicine.name;
datalist.appendChild(option);
});
};
}
}
function savePatient() {
const firstName = document.getElementById('firstName').value.trim();
const lastName = document.getElementById('lastName').value.trim();
const nationalId = document.getElementById('nationalId').value.trim();
const employeeId = document.getElementById('employeeId').value.trim();
const department = document.getElementById('department').value;
const workLocation = document.getElementById('workLocation').value.trim();
const gender = document.querySelector('input[name="gender"]:checked')?.value || '';
const age = parseInt(document.getElementById('age').value) || 0;
const phone = document.getElementById('phone').value.trim();
if (!firstName || !lastName || !nationalId || !employeeId || !department || !gender) {
alert("لطفاً تمام فیلدهای ضروری را پر کنید.");
return;
}
const patient = {
firstName,
lastName,
nationalId,
employeeId,
department,
workLocation,
gender,
age,
phone
};
const tx = db.transaction("patients", "readwrite");
const store = tx.objectStore("patients");
const request = store.put(patient);
request.onsuccess = function() {
alert("بیمار با موفقیت ثبت شد.");
closeModal('addPatientModal');
loadPatients();
};
request.onerror = function(event) {
console.error("Error saving patient:", event.target.error);
alert("خطا در ثبت بیمار. لطفاً دوباره امتحان کنید.");
};
}
function saveMedicine() {
const name = document.getElementById('medicineName').value.trim();
const type = document.getElementById('medicineType').value;
const unit = document.getElementById('medicineUnit').value;
const dose = document.getElementById('medicineDose').value.trim();
const quantity = parseInt(document.getElementById('medicineQuantity').value) || 0;
const expiry = document.getElementById('medicineExpiry').value;
if (!name || !type || !unit || !quantity || !expiry) {
alert("لطفاً تمام فیلدهای ضروری را پر کنید.");
return;
}
const medicine = {
name,
type,
unit,
dose,
quantity,
expiry
};
const tx = db.transaction("medicines", "readwrite");
const store = tx.objectStore("medicines");
const request = store.put(medicine);
request.onsuccess = function() {
alert("دارو با موفقیت ثبت شد.");
closeModal('addMedicineModal');
loadMedicines();
loadMedicineCharts();
};
request.onerror = function(event) {
console.error("Error saving medicine:", event.target.error);
alert("خطا در ثبت دارو. لطفاً دوباره امتحان کنید.");
};
}
function saveAmbulanceReport() {
const number = document.getElementById('ambulanceNumber').value;
const status = document.getElementById('ambulanceStatus').value;
const notes = document.getElementById('ambulanceNotes').value.trim();
const report = {
number,
status,
notes,
reportedAt: new Date().toISOString()
};
const tx = db.transaction("ambulances", "readwrite");
const store = tx.objectStore("ambulances");
const request = store.put(report);
request.onsuccess = function() {
alert("گزارش آمبولانس با موفقیت ثبت شد.");
closeModal('ambulanceReportModal');
loadDashboardData();
};
request.onerror = function(event) {
console.error("Error saving ambulance report:", event.target.error);
alert("خطا در ثبت گزارش آمبولانس. لطفاً دوباره امتحان کنید.");
};
}
function handleExcelImport(event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(e) {
const data = new Uint8Array(e.target.result);
const workbook = XLSX.read(data, { type: 'array' });
const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
const jsonData = XLSX.utils.sheet_to_json(firstSheet, { header: 1 });
if (jsonData.length < 2) {
alert("فایل اکسل انتخاب شده حاوی داده‌ای نیست.");
return;
}
// Extract headers and data
const headers = jsonData[0];
const rows = jsonData.slice(1);
// Show preview
const previewDiv = document.getElementById('excelPreview');
const headersRow = document.getElementById('excelHeaders');
const rowsBody = document.getElementById('excelRows');
headersRow.innerHTML = '';
rowsBody.innerHTML = '';
// Add headers
headers.forEach(header => {
const th = document.createElement('th');
th.className = 'px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider';
th.textContent = header || 'بدون عنوان';
headersRow.appendChild(th);
});
// Add first 5 rows as preview
rows.slice(0, 5).forEach(row => {
const tr = document.createElement('tr');
headers.forEach((header, index) => {
const td = document.createElement('td');
td.className = 'px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300';
td.textContent = row[index] || '-';
tr.appendChild(td);
});
rowsBody.appendChild(tr);
});
previewDiv.classList.remove('hidden');
document.getElementById('importBtn').classList.remove('hidden');
// Store the parsed data for later use
document.getElementById('importBtn').dataset.excelData = JSON.stringify({
headers,
rows
});
};
reader.readAsArrayBuffer(file);
}
function importPatients() {
const excelData = JSON.parse(document.getElementById('importBtn').dataset.excelData);
const { headers, rows } = excelData;
const action = document.querySelector('input[name="importAction"]:checked').value;
// Map headers to patient fields (simple heuristic)
const fieldMap = {
'نام': 'firstName',
'نام خانوادگی': 'lastName',
'کد ملی': 'nationalId',
'کد پرسنلی': 'employeeId',
'واحد کاری': 'department',
'محل کار جزئی': 'workLocation',
'جنسیت': 'gender',
'سن': 'age',
'شماره تماس': 'phone'
};
const patients = rows.map(row => {
const patient = {};
headers.forEach((header, index) => {
if (fieldMap[header] && row[index]) {
patient[fieldMap[header]] = row[index];
}
});
return patient;
}).filter(p => p.nationalId); // Only keep patients with national ID
if (patients.length === 0) {
alert("هیچ بیمار معتبری در فایل یافت نشد. لطفاً از تطابق نام ستون‌ها اطمینان حاصل کنید.");
return;
}
const tx = db.transaction("patients", "readwrite");
const store = tx.objectStore("patients");
if (action === 'replace') {
// Clear all patients first
const clearRequest = store.clear();
clearRequest.onsuccess = function() {
addPatients(store, patients);
};
} else {
addPatients(store, patients, action === 'update');
}
function addPatients(store, patients, updateOnly = false) {
let added = 0;
let updated = 0;
patients.forEach(patient => {
const request = store.get(patient.nationalId);
request.onsuccess = function(e) {
const existing = e.target.result;
if (existing) {
if (updateOnly) {
// Update existing patient
const updatedPatient = { ...existing, ...patient };
store.put(updatedPatient);
updated++;
}
} else {
// Add new patient
store.add(patient);
added++;
}
};
});
tx.oncomplete = function() {
alert(`عملیات وارد کردن داده‌ها با موفقیت انجام شد.\n${added} بیمار جدید اضافه شد.\n${updated} بیمار به‌روزرسانی شد.`);
closeModal('importModal');
loadPatients();
};
tx.onerror = function(event) {
console.error("Error during import:", event.target.error);
alert("خطا در وارد کردن داده‌ها. لطفاً دوباره امتحان کنید.");
};
}
}
function loadDashboardData() {
// Today's date for filtering
const today = new Date();
today.setHours(0, 0, 0, 0);
const todayISO = today.toISOString();
const weekAgo = new Date(today);
weekAgo.setDate(weekAgo.getDate() - 7);
const weekAgoISO = weekAgo.toISOString();
// Count today's visits
const visitsTx = db.transaction("visits", "readonly");
const visitsStore = visitsTx.objectStore("visits");
const dateIndex = visitsStore.index("date");
// Today's visits
const todayRange = IDBKeyRange.lowerBound(todayISO);
const todayRequest = dateIndex.count(todayRange);
todayRequest.onsuccess = function() {
document.getElementById('todayVisits').textContent = todayRequest.result;
};
// Weekly visits
const weeklyRange = IDBKeyRange.lowerBound(weekAgoISO);
const weeklyRequest = dateIndex.count(weeklyRange);
weeklyRequest.onsuccess = function() {
document.getElementById('weeklyVisits').textContent = weeklyRequest.result;
};
// Hospital transfers (visits with 'اعزام' in actions)
// This is simplified - you might want a better way to track hospital transfers
const allVisitsRequest = visitsStore.getAll();
allVisitsRequest.onsuccess = function() {
const visits = allVisitsRequest.result;
const hospitalTransfers = visits.filter(v => v.actionsTaken && v.actionsTaken.includes('اعزام')).length;
document.getElementById('hospitalTransfers').textContent = hospitalTransfers;
};
// Ambulance status
const ambulanceTx = db.transaction("ambulances", "readonly");
const ambulanceStore = ambulanceTx.objectStore("ambulances");
const ambulanceRequest = ambulanceStore.getAll();
ambulanceRequest.onsuccess = function() {
const ambulances = ambulanceRequest.result;
const operational = ambulances.filter(a => a.status === 'operational').length;
const total = ambulances.length;
if (operational === total) {
document.getElementById('ambulanceStatus').textContent = 'عملیاتی';
} else {
document.getElementById('ambulanceStatus').textContent = `${operational}/${total} عملیاتی`;
}
};
// Recent visits
const recentVisitsRequest = visitsStore.getAll();
recentVisitsRequest.onsuccess = function() {
const visits = recentVisitsRequest.result
.sort((a, b) => new Date(b.date) - new Date(a.date))
.slice(0, 5);
const recentVisitsBody = document.getElementById('recentVisits');
recentVisitsBody.innerHTML = '';
visits.forEach(visit => {
const tr = document.createElement('tr');
// Get patient details
const patientTx = db.transaction("patients", "readonly");
const patientStore = patientTx.objectStore("patients");
const patientRequest = patientStore.get(visit.patientId);
patientRequest.onsuccess = function() {
const patient = patientRequest.result;
tr.innerHTML = `
<td class="py-2 px-4">${patient ? `${patient.firstName} ${patient.lastName}` : 'نامشخص'}</td>
<td class="py-2 px-4">${patient ? patient.nationalId : 'نامشخص'}</td>
<td class="py-2 px-4">${patient ? patient.department : 'نامشخص'}</td>
<td class="py-2 px-4">${new Date(visit.date).toLocaleString('fa-IR')}</td>
`;
recentVisitsBody.appendChild(tr);
};
});
};
// Diseases chart
loadDiseasesChart();
}
function loadPatients(page = 1, pageSize = 10, search = '') {
const tx = db.transaction("patients", "readonly");
const store = tx.objectStore("patients");
const request = store.getAll();
request.onsuccess = function() {
let patients = request.result;
// Apply search filter
if (search) {
patients = patients.filter(p =>
`${p.firstName} ${p.lastName}`.includes(search) ||
p.nationalId.includes(search) ||
p.employeeId.includes(search)
);
}
// Pagination
const total = patients.length;
const start = (page - 1) * pageSize;
const end = start + pageSize;
const paginatedPatients = patients.slice(start, end);
// Update table
const tbody = document.getElementById('patientsTableBody');
tbody.innerHTML = '';
paginatedPatients.forEach(patient => {
const tr = document.createElement('tr');
tr.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-200">
${patient.firstName} ${patient.lastName}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${patient.nationalId}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${patient.employeeId}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${patient.department}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${patient.gender === 'male' ? 'مرد' : 'زن'}
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button onclick="editPatient('${patient.nationalId}')" class="text-indigo-600 dark:text-indigo-400 hover:text-indigo-900 dark:hover:text-indigo-500 ml-2">
<i data-feather="edit" class="w-4 h-4"></i>
</button>
<button onclick="deletePatient('${patient.nationalId}')" class="text-red-600 dark:text-red-400 hover:text-red-900 dark:hover:text-red-500">
<i data-feather="trash-2" class="w-4 h-4"></i>
</button>
</td>
`;
tbody.appendChild(tr);
});
// Update pagination info
document.getElementById('patientStart').textContent = start + 1;
document.getElementById('patientEnd').textContent = Math.min(end, total);
document.getElementById('patientTotal').textContent = total;
// Update pagination buttons
document.getElementById('patientPrevBtn').disabled = page <= 1;
document.getElementById('patientNextBtn').disabled = end >= total;
// Set up event listeners for pagination buttons
document.getElementById('patientPrevBtn').onclick = () => loadPatients(page - 1, pageSize, search);
document.getElementById('patientNextBtn').onclick = () => loadPatients(page + 1, pageSize, search);
feather.replace();
};
}
function loadMedicines(page = 1, pageSize = 10, search = '') {
const tx = db.transaction("medicines", "readonly");
const store = tx.objectStore("medicines");
const request = store.getAll();
request.onsuccess = function() {
let medicines = request.result;
// Apply search filter
if (search) {
medicines = medicines.filter(m =>
m.name.includes(search) ||
m.type.includes(search)
);
}
// Pagination
const total = medicines.length;
const start = (page - 1) * pageSize;
const end = start + pageSize;
const paginatedMedicines = medicines.slice(start, end);
// Update table
const tbody = document.getElementById('medicineTableBody');
tbody.innerHTML = '';
paginatedMedicines.forEach(medicine => {
const tr = document.createElement('tr');
const expiryDate = new Date(medicine.expiry);
const today = new Date();
today.setHours(0, 0, 0, 0);
// Check if expired or near expiry (within 30 days)
const expiryClass = expiryDate < today ? 'text-red-600 dark:text-red-400' :
(expiryDate <= new Date(today.getTime() + 30 * 24 * 60 * 60 * 1000) ? 'text-yellow-600 dark:text-yellow-400' : '');
// Check for low stock (less than 20%)
const lowStockClass = medicine.quantity < 20 ? 'text-red-600 dark:text-red-400' :
(medicine.quantity < 50 ? 'text-yellow-600 dark:text-yellow-400' : '');
tr.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-200">
${medicine.name}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${medicine.type}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${medicine.unit}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${medicine.dose || '-'}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm ${lowStockClass}">
${medicine.quantity}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm ${expiryClass}">
${new Date(medicine.expiry).toLocaleDateString('fa-IR')}
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button onclick="editMedicine('${medicine.name}')" class="text-indigo-600 dark:text-indigo-400 hover:text-indigo-900 dark:hover:text-indigo-500 ml-2">
<i data-feather="edit" class="w-4 h-4"></i>
</button>
<button onclick="deleteMedicine('${medicine.name}')" class="text-red-600 dark:text-red-400 hover:text-red-900 dark:hover:text-red-500">
<i data-feather="trash-2" class="w-4 h-4"></i>
</button>
</td>
`;
tbody.appendChild(tr);
});
// Update pagination info
document.getElementById('medicineStart').textContent = start + 1;
document.getElementById('medicineEnd').textContent = Math.min(end, total);
document.getElementById('medicineTotal').textContent = total;
// Update pagination buttons
document.getElementById('medicinePrevBtn').disabled = page <= 1;
document.getElementById('medicineNextBtn').disabled = end >= total;
// Set up event listeners for pagination buttons
document.getElementById('medicinePrevBtn').onclick = () => loadMedicines(page - 1, pageSize, search);
document.getElementById('medicineNextBtn').onclick = () => loadMedicines(page + 1, pageSize, search);
feather.replace();
};
}
function loadVisits(page = 1, pageSize = 10) {
const tx = db.transaction("visits", "readonly");
const store = tx.objectStore("visits");
const request = store.getAll();
request.onsuccess = function() {
const visits = request.result.sort((a, b) => new Date(b.date) - new Date(a.date));
// Pagination
const total = visits.length;
const start = (page - 1) * pageSize;
const end = start + pageSize;
const paginatedVisits = visits.slice(start, end);
// Update table
const tbody = document.getElementById('visitsTableBody');
tbody.innerHTML = '';
paginatedVisits.forEach(visit => {
const tr = document.createElement('tr');
// Get patient details
const patientTx = db.transaction("patients", "readonly");
const patientStore = patientTx.objectStore("patients");
const patientRequest = patientStore.get(visit.patientId);
patientRequest.onsuccess = function() {
const patient = patientRequest.result;
tr.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-200">
${patient ? `${patient.firstName} ${patient.lastName}` : 'نامشخص'}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${patient ? patient.nationalId : 'نامشخص'}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${patient ? patient.employeeId : 'نامشخص'}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${patient ? patient.department : 'نامشخص'}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${new Date(visit.date).toLocaleString('fa-IR')}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${visit.disease}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-300">
${visit.medicines ? visit.medicines.map(m => m.name).join(', ') : '-'}
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button onclick="viewVisit(${visit.id})" class="text-indigo-600 dark:text-indigo-400 hover:text-indigo-900 dark:hover:text-indigo-500 ml-2">
<i data-feather="eye" class="w-4 h-4"></i>
</button>
<button onclick="editVisit(${visit.id})" class="text-indigo-600 dark:text-indigo-400 hover:text-indigo-900 dark:hover:text-indigo-500 ml-2">
<i data-feather="edit" class="w-4 h-4"></i>
</button>
<button onclick="deleteVisit(${visit.id})" class="text-red-600 dark:text-red-400 hover:text-red-900 dark:hover:text-red-500">
<i data-feather="trash-2" class="w-4 h-4"></i>
</button>
</td>
`;
tbody.appendChild(tr);
};
});
// Update pagination info
document.getElementById('visitStart').textContent = start + 1;
document.getElementById('visitEnd').textContent = Math.min(end, total);
document.getElementById('visitTotal').textContent = total;
// Update pagination buttons
document.getElementById('visitPrevBtn').disabled = page <= 1;
document.getElementById('visitNextBtn').disabled = end >= total;
// Set up event listeners for pagination buttons
document.getElementById('visitPrevBtn').onclick = () => loadVisits(page - 1, pageSize);
document.getElementById('visitNextBtn').onclick = () => loadVisits(page + 1, pageSize);
feather.replace();
};
}
function loadReports() {
// Monthly visits chart
loadMonthlyVisitsChart();
// Department visits chart
loadDepartmentVisitsChart();
// Common diseases chart
loadCommonDiseasesChart();
}
function viewVisit(visitId) {
const tx = db.transaction("visits", "readonly");
const store = tx.objectStore("visits");
const request = store.get(visitId);
request.onsuccess = function() {
const visit = request.result;
// Get patient details
const patientTx = db.transaction("patients", "readonly");
const patientStore = patientTx.objectStore("patients");
const patientRequest = patientStore.get(visit.patientId);
patientRequest.onsuccess = function() {
const patient = patientRequest.result;
// Populate modal
document.getElementById('visitPatientName').textContent = patient ? `${patient.firstName} ${patient.lastName}` : 'نامشخص';
document.getElementById('visitNationalId').textContent = patient ? patient.nationalId : 'نامشخص';
document.getElementById('visitEmployeeId').textContent = patient ? patient.employeeId : 'نامشخص';
document.getElementById('visitDepartment').textContent = patient ? patient.department : 'نامشخص';
document.getElementById('visitDate').textContent = new Date(visit.date).toLocaleString('fa-IR');
document.getElementById('visitExaminer').textContent = visit.examiner || 'نامشخص';
document.getElementById('visitDisease').textContent = visit.disease || 'نامشخص';
document.getElementById('visitDescription').textContent = visit.description || '-';
document.getElementById('visitActions').textContent = visit.actionsTaken || '-';
// Populate medicines
const medicinesList = document.getElementById('visitMedicines');
medicinesList.innerHTML = '';
if (visit.medicines && visit.medicines.length > 0) {
visit.medicines.forEach(medicine => {
const li = document.createElement('li');
li.textContent = `${medicine.name} (${medicine.quantity} ${medicine.unit})`;
medicinesList.appendChild(li);
});
} else {
const li = document.createElement('li');
li.textContent = '-';
medicinesList.appendChild(li);
}
// Show modal
document.getElementById('viewVisitModal').classList.remove('hidden');
};
};
}
function editPatient(nationalId) {
const tx = db.transaction("patients", "readonly");
const store = tx.objectStore("patients");
const request = store.get(nationalId);
request.onsuccess = function() {
const patient = request.result;
// Populate form
document.getElementById('firstName').value = patient.firstName;
document.getElementById('lastName').value = patient.lastName;
document.getElementById('nationalId').value = patient.nationalId;
document.getElementById('employeeId').value = patient.employeeId;
document.getElementById('department').value = patient.department;
document.getElementById('workLocation').value = patient.workLocation;
document.querySelector(`input[name="gender"][value="${patient.gender}"]`).checked = true;
document.getElementById('age').value = patient.age;
document.getElementById('phone').value = patient.phone;
// Change save function to update
document.querySelector('#addPatientModal button[onclick="savePatient()"]').onclick = function() {
updatePatient(nationalId);
};
// Show modal
document.getElementById('addPatientModal').classList.remove('hidden');
};
}
function updatePatient(nationalId) {
const firstName = document.getElementById('firstName').value.trim();
const lastName = document.getElementById('lastName').value.trim();
const employeeId = document.getElementById('employeeId').value.trim();
const department = document.getElementById('department').value;
const workLocation = document.getElementById('workLocation').value.trim();
const gender = document.querySelector('input[name="gender"]:checked')?.value || '';
const age = parseInt(document.getElementById('age').value) || 0;
const phone = document.getElementById('phone').value.trim();
if (!firstName || !lastName || !employeeId || !department || !gender) {
alert("لطفاً تمام فیلدهای ضروری را پر کنید.");
return;
}
const patient = {
firstName,
lastName,
nationalId,
employeeId,
department,
workLocation,
gender,
age,
phone
};
const tx = db.transaction("patients", "readwrite");
const store = tx.objectStore("patients");
const request = store.put(patient);
request.onsuccess = function() {
alert("اطلاعات بیمار با موفقیت به‌روزرسانی شد.");
closeModal('addPatientModal');
loadPatients();
};
request.onerror = function(event) {
console.error("Error updating patient:", event.target.error);
alert("خطا در به‌روزرسانی بیمار. لطفاً دوباره امتحان کنید.");
};
}
function deletePatient(nationalId) {
if (!confirm("آیا از حذف این بیمار مطمئن هستید؟")) return;
const tx = db.transaction("patients", "readwrite");
const store = tx.objectStore("patients");
const request = store.delete(nationalId);
request.onsuccess = function() {
alert("بیمار با موفقیت حذف شد.");
loadPatients();
};
request.onerror = function(event) {
console.error("Error deleting patient:", event.target.error);
alert("خطا در حذف بیمار. لطفاً دوباره امتحان کنید.");
};
}
function editMedicine(medicineName) {
const tx = db.transaction("medicines", "readonly");
const store = tx.objectStore("medicines");
const request = store.get(medicineName);
request.onsuccess = function() {
const medicine = request.result;
// Populate form
document.getElementById('medicineName').value = medicine.name;
document.getElementById('medicineType').value = medicine.type;
document.getElementById('medicineUnit').value = medicine.unit;
document.getElementById('medicineDose').value = medicine.dose || '';
document.getElementById('medicineQuantity').value = medicine.quantity;
document.getElementById('medicineExpiry').value = medicine.expiry;
// Change save function to update
document.querySelector('#addMedicineModal button[onclick="saveMedicine()"]').onclick = function() {
updateMedicine(medicineName);
};
// Show modal
document.getElementById('addMedicineModal').classList.remove('hidden');
};
}
function updateMedicine(medicineName) {
const name = document.getElementById('medicineName').value.trim();
const type = document.getElementById('medicineType').value;
const unit = document.getElementById('medicineUnit').value;
const dose = document.getElementById('medicineDose').value.trim();
const quantity = parseInt(document.getElementById('medicineQuantity').value) || 0;
const expiry = document.getElementById('medicineExpiry').value;
if (!name || !type || !unit || !quantity || !expiry) {
alert("لطفاً تمام فیلدهای ضروری را پر کنید.");
return;
}
const medicine = {
name,
type,
unit,
dose,
quantity,
expiry
};
const tx = db.transaction("medicines", "readwrite");
const store = tx.objectStore("medicines");
// If name changed, we need to delete old record and add new one
if (name !== medicineName) {
const deleteRequest = store.delete(medicineName);
deleteRequest.onsuccess = function() {
const addRequest = store.add(medicine);
addRequest.onsuccess = function() {
alert("دارو با موفقیت به‌روزرسانی شد.");
closeModal('addMedicineModal');
loadMedicines();
loadMedicineCharts();
};
addRequest.onerror = function(event) {
console.error("Error adding updated medicine:", event.target.error);
alert("خطا در به‌روزرسانی دارو. لطفاً دوباره امتحان کنید.");
};
};
} else {
const request = store.put(medicine);
request.onsuccess = function() {
alert("دارو با موفقیت به‌روزرسانی شد.");
closeModal('addMedicineModal');
loadMedicines();
loadMedicineCharts();
};
request.onerror = function(event) {
console.error("Error updating medicine:", event.target.error);
alert("خطا در به‌روزرسانی دارو. لطفاً دوباره امتحان کنید.");
};
}
}
function deleteMedicine(medicineName) {
if (!confirm("آیا از حذف این دارو مطمئن هستید؟")) return;
const tx = db.transaction("medicines", "readwrite");
const store = tx.objectStore("medicines");
const request = store.delete(medicineName);
request.onsuccess = function() {
alert("دارو با موفقیت حذف شد.");
loadMedicines();
loadMedicineCharts();
};
request.onerror = function(event) {
console.error("Error deleting medicine:", event.target.error);
alert("خطا در حذف دارو. لطفاً دوباره امتحان کنید.");
};
}
function editVisit(visitId) {
// Similar to viewVisit but with editable form
alert("این ویژگی به زودی اضافه خواهد شد.");
}
function deleteVisit(visitId) {
if (!confirm("آیا از حذف این مراجعه مطمئن هستید؟")) return;
const tx = db.transaction("visits", "readwrite");
const store = tx.objectStore("visits");
const request = store.delete(visitId);
request.onsuccess = function() {
alert("مراجعه با موفقیت حذف شد.");
loadVisits();
};
request.onerror = function(event) {
console.error("Error deleting visit:", event.target.error);
alert("خطا در حذف مراجعه. لطفاً دوباره امتحان کنید.");
};
}
// Chart functions
function loadDiseasesChart() {
const ctx = document.getElementById('diseasesChart').getContext('2d');
const tx = db.transaction("visits", "readonly");
const store = tx.objectStore("visits");
const request = store.getAll();
request.onsuccess = function() {
const visits = request.result;
// Count diseases (simple example)
const diseaseCount = {};
visits.forEach(visit => {
if (visit.disease) {
diseaseCount[visit.disease] = (diseaseCount[visit.disease] || 0) + 1;
}
});
// Get top 5 diseases
const topDiseases = Object.entries(diseaseCount)
.sort((a, b) => b[1] - a[1])
.slice(0, 5);
const labels = topDiseases.map(d => d[0]);
const data = topDiseases.map(d => d[1]);
new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'تعداد مراجعات',
data: data,
backgroundColor: '#4f46e5',
borderColor: '#4f46e5',
borderWidth: 1
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
},
plugins: {
legend: {
display: false
}
}
}
});
};
}
function loadMedicineCharts() {
// Medicine type distribution chart
const typeCtx = document.getElementById('medicineTypeChart').getContext('2d');
const tx = db.transaction("medicines", "readonly");
const store = tx.objectStore("medicines");
const request = store.getAll();
request.onsuccess = function() {
const medicines = request.result;
// Count by type
const typeCount = {};
medicines.forEach(medicine => {
typeCount[medicine.type] = (typeCount[medicine.type] || 0) + 1;
});
new Chart(typeCtx, {
type: 'pie',
data: {
labels: Object.keys(typeCount),
datasets: [{
data: Object.values(typeCount),
backgroundColor: [
'#4f46e5',
'#10b981',
'#f59e0b',
'#ef4444',
'#8b5cf6',
'#ec4899'
]
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom'
}
}
}
});
// Low stock chart
const lowStockCtx = document.getElementById('lowStockChart').getContext('2d');
// Sort by quantity ascending and take top 5
const lowStock = medicines
.sort((a, b) => a.quantity - b.quantity)
.slice(0, 5);
new Chart(lowStockCtx, {
type: 'bar',
data: {
labels: lowStock.map(m => m.name),
datasets: [{
label: 'موجودی',
data: lowStock.map(m => m.quantity),
backgroundColor: lowStock.map(m =>
m.quantity < 20 ? '#ef4444' :
m.quantity < 50 ? '#f59e0b' : '#10b981'
)
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
},
plugins: {
legend: {
display: false
}
}
}
});
};
}
function loadMonthlyVisitsChart() {
const ctx = document.getElementById('monthlyVisitsChart').getContext('2d');
const tx = db.transaction("visits", "readonly");
const store = tx.objectStore("visits");
const request = store.getAll();
request.onsuccess = function() {
const visits = request.result;
// Group by day for last 30 days
const now = new Date();
const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
const dailyCount = {};
for (let i = 0; i < 30; i++) {
const date = new Date(thirtyDaysAgo.getTime() + i * 24 * 60 * 60 * 1000);
const dateStr = date.toISOString().split('T')[0];
dailyCount[dateStr] = 0;
}
visits.forEach(visit => {
const visitDate = new Date(visit.date);
if (visitDate >= thirtyDaysAgo) {
const dateStr = visitDate.toISOString().split('T')[0];
if (dailyCount[dateStr] !== undefined) {
dailyCount[dateStr]++;
}
}
});
// Persian date labels
const persianMonths = ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'];
const labels = Object.keys(dailyCount).map(dateStr => {
const date = new Date(dateStr);
return `${date.getDate()} ${persianMonths[date.getMonth()]}`;
});
const data = Object.values(dailyCount);
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'تعداد مراجعات',
data: data,
fill: false,
borderColor: '#4f46e5',
tension: 0.1
}]
},
options: {
responsive: true,
plugins: {
legend: {
display: false
}
},
scales: {
y: {
beginAtZero: true
}
}
}
});
};
}
function loadDepartmentVisitsChart() {
const ctx = document.getElementById('departmentVisitsChart').getContext('2d');
const visitsTx = db.transaction("visits", "readonly");
const visitsStore = visitsTx.objectStore("visits");
const visitsRequest = visitsStore.getAll();
visitsRequest.onsuccess = function() {
const visits = visitsRequest.result;
// Get all departments
const deptTx = db.transaction("departments", "readonly");
const deptStore = deptTx.objectStore("departments");
const deptRequest = deptStore.getAll();
deptRequest.onsuccess = function() {
const departments = deptRequest.result.map(d => d.name);
// Count visits by department
const deptCount = {};
departments.forEach(dept => {
deptCount[dept] = 0;
});
// We need patient details for each visit
let processed = 0;
const total = visits.length;
if (total === 0) {
createChart(departments, Array(departments.length).fill(0));
return;
}
visits.forEach(visit => {
const patientTx = db.transaction("patients", "readonly");
const patientStore = patientTx.objectStore("patients");
const patientRequest = patientStore.get(visit.patientId);
patientRequest.onsuccess = function() {
const patient = patientRequest.result;
if (patient && patient.department) {
deptCount[patient.department] = (deptCount[patient.department] || 0) + 1;
}
processed++;
if (processed === total) {
createChart(departments, departments.map(dept => deptCount[dept] || 0));
}
};
});
};
function createChart(labels, data) {
new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'تعداد مراجعات',
data: data,
backgroundColor: '#4f46e5'
}]
},
options: {
responsive: true,
plugins: {
legend: {
display: false
}
},
scales: {
y: {
beginAtZero: true
}
}
}
});
}
};
}
function loadCommonDiseasesChart() {
const ctx = document.getElementById('commonDiseasesChart').getContext('2d');
const tx = db.transaction("visits", "readonly");
const store = tx.objectStore("visits");
const request = store.getAll();
request.onsuccess = function() {
const visits = request.result;
// Count diseases
const diseaseCount = {};
visits.forEach(visit => {
if (visit.disease) {
diseaseCount[visit.disease] = (diseaseCount[visit.disease] || 0) + 1;
}
});
// Sort by count and take top 10
const sorted = Object.entries(diseaseCount)
.sort((a, b) => b[1] - a[1])
.slice(0, 10);
const labels = sorted.map(d => d[0]);
const data = sorted.map(d => d[1]);
new Chart(ctx, {
type: 'doughnut',
data: {
labels: labels,
datasets: [{
data: data,
backgroundColor: [
'#4f46e5',
'#10b981',
'#f59e0b',
'#ef4444',
'#8b5cf6',
'#ec4899',
'#14b8a6',
'#f97316',
'#84cc16',
'#64748b'
]
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom'
}
}
}
});
};
}
function exportAllData() {
// Export all data as Excel file
alert("این ویژگی به زودی اضافه خواهد شد.");
}
// Initialize when DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
// Set current date and time for examination form
const now = new Date();
const timezoneOffset = now.getTimezoneOffset() * 60000;
const localISOTime = (new Date(now - timezoneOffset)).toISOString().slice(0, 16);
document.getElementById('examinationDate').value = localISOTime;
// Set up form submission for examination
document.getElementById('examinationForm').addEventListener('submit', function(e) {
e.preventDefault();
saveExamination();
});
// Set up search for patients
document.getElementById('patientSearch').addEventListener('input', function(e) {
loadPatients(1, 10, e.target.value);
});
// Set up search for medicines
document.getElementById('medicineSearch').addEventListener('input', function(e) {
loadMedicines(1, 10, e.target.value);
});
// Initialize feather icons
feather.replace();
// Show dashboard by default
showDashboard();
});
function saveExamination() {
const patientId = document.getElementById('patientSelect').value;
const examiner = document.getElementById('examiner').value.trim();
const date = document.getElementById('examinationDate').value;
const disease = document.getElementById('disease').value.trim();
const description = document.getElementById('description').value.trim();
const actionsTaken = document.getElementById('actionsTaken').value.trim();
if (!patientId || !examiner || !date || !disease) {
alert("لطفاً تمام فیلدهای ضروری را پر کنید.");
return;
}
// Collect prescribed medicines
const medicines = [];
const medicineElements = document.querySelectorAll('#medicinesContainer > div');
medicineElements.forEach(div => {
const name = div.querySelector('.medicine-name').value.trim();
const quantity = parseInt(div.querySelector('.medicine-quantity').value) || 0;
if (name && quantity > 0) {
medicines.push({ name, quantity, unit: 'عدد' }); // Default unit, can be enhanced
}
});
const visit = {
patientId,
examiner,
date,
disease,
description,
actionsTaken,
medicines,
createdAt: new Date().toISOString()
};
// Save visit
const tx = db.transaction("visits", "readwrite");
const store = tx.objectStore("visits");
const request = store.add(visit);
request.onsuccess = function() {
// If medicines were prescribed, update their quantities
if (medicines.length > 0) {
updateMedicineQuantities(medicines);
} else {
alert("معاینه با موفقیت ثبت شد.");
document.getElementById('examinationForm').reset();
document.getElementById('medicinesContainer').innerHTML = '';
}
};
request.onerror = function(event) {
console.error("Error saving examination:", event.target.error);
alert("خطا در ثبت معاینه. لطفاً دوباره امتحان کنید.");
};
}
function updateMedicineQuantities(medicines) {
const tx = db.transaction("medicines", "readwrite");
const store = tx.objectStore("medicines");
let processed = 0;
const total = medicines.length;
medicines.forEach(medicine => {
const request = store.get(medicine.name);
request.onsuccess = function() {
const existing = request.result;
if (existing) {
const newQuantity = Math.max(0, existing.quantity - medicine.quantity);
existing.quantity = newQuantity;
const updateRequest = store.put(existing);
updateRequest.onsuccess = function() {
processed++;
if (processed === total) {
alert("معاینه با موفقیت ثبت شد و موجودی داروها به‌روزرسانی شد.");
document.getElementById('examinationForm').reset();
document.getElementById('medicinesContainer').innerHTML = '';
loadMedicines();
loadMedicineCharts();
}
};
} else {
processed++;
if (processed === total) {
alert("معاینه با موفقیت ثبت شد (برخی داروهای تجویز شده در سیستم موجود نیستند).");
document.getElementById('examinationForm').reset();
document.getElementById('medicinesContainer').innerHTML = '';
}
}
};
const now = new persianDate();
document.getElementById('current-date').textContent = now.format('YYYY/MM/DD');
request.onerror = function() {
processed++;
if (processed === total) {
alert("معاینه با موفقیت ثبت شد (خطا در به‌روزرسانی موجودی داروها).");
document.getElementById('examinationForm').reset();
document.getElementById('medicinesContainer').innerHTML = '';
}
};
});
}
</script>
</body>
</html>