med-cms 1.0.0-beta.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/LICENSE.txt +13 -0
  2. package/README.md +117 -0
  3. package/database/config/db-init.js +67 -53
  4. package/database/models/appointments.js +35 -20
  5. package/database/models/clinics.js +25 -13
  6. package/database/models/diseases.js +21 -13
  7. package/database/models/districts.js +55 -0
  8. package/database/models/news.js +25 -0
  9. package/database/models/user-addresses.js +21 -14
  10. package/database/models/users.js +69 -26
  11. package/database/services/admin/create-clinic.js +18 -6
  12. package/database/services/admin/db-analytics.js +42 -16
  13. package/database/services/admin/index.js +6 -6
  14. package/database/services/admin/manage-staff.js +47 -17
  15. package/database/services/doctor/conduct-exam.js +26 -20
  16. package/database/services/doctor/get-schedule.js +26 -18
  17. package/database/services/doctor/index.js +6 -6
  18. package/database/services/doctor/patient-access.js +34 -25
  19. package/database/services/patient/book-appointment.js +37 -17
  20. package/database/services/patient/calc-district.js +70 -21
  21. package/database/services/patient/get-profile.js +49 -21
  22. package/database/services/patient/index.js +5 -5
  23. package/env_init.js +55 -0
  24. package/index.d.ts +38 -24
  25. package/index.js +48 -25
  26. package/migrate-diseases.js +192 -120
  27. package/package.json +3 -3
  28. package/public/css/admin.css +80 -80
  29. package/public/css/auth.css +52 -44
  30. package/public/css/doctor.css +131 -125
  31. package/public/css/home.css +155 -0
  32. package/public/html/dashboard-admin.html +423 -101
  33. package/public/html/dashboard-doctor.html +155 -66
  34. package/public/html/dashboard-patient.html +199 -94
  35. package/public/html/home/about.html +0 -0
  36. package/public/html/home/contact.html +0 -0
  37. package/public/html/home/info.html +0 -0
  38. package/public/html/home.html +159 -0
  39. package/public/html/login.html +73 -43
  40. package/public/js/admin.js +329 -165
  41. package/public/js/auth.js +45 -41
  42. package/public/js/doctor.js +117 -103
  43. package/public/js/home.js +113 -0
  44. package/public/js/patient.js +130 -108
  45. package/server/midleware.js +33 -13
  46. package/server/permissions.js +105 -43
  47. package/server/server.js +517 -176
  48. package/README +0 -161
  49. package/test.js +0 -27
@@ -1,199 +1,363 @@
1
- document.addEventListener('DOMContentLoaded', () => {
2
- loadDashboardStats();
1
+ // Инициализация дашборда: строго один слушатель, который запускает всё по очереди
2
+ document.addEventListener("DOMContentLoaded", async () => {
3
+ console.log("🚀 [Admin] Запуск инициализации панелей...");
4
+ await loadDashboardStats();
5
+ await loadClinicsDropdown();
6
+ await loadClinicsForDistrictsSelect();
7
+ await loadStaffForDistrictsSelect();
8
+ await renderLiveDistrictsTable();
3
9
  });
10
+
11
+ // Базовая статистика верхних карточек
4
12
  async function loadDashboardStats() {
5
- try {
6
- const response = await fetch('/med/api/admin/stats');
7
- const result = await response.json();
8
- if (!result.success) {
9
- alert('Ошибка доступа к админ-панели: ' + result.message);
10
- window.location.href = '/med/html/login.html';
11
- return;
12
- }
13
- document.getElementById('statClinics').textContent = result.stats.summary.totalClinics;
14
- document.getElementById('statPatients').textContent = result.stats.summary.totalPatients;
15
- document.getElementById('statStaff').textContent = result.stats.summary.totalStaff;
16
- await loadClinicsDropdown();
17
- } catch (err) {
18
- console.error('Ошибка загрузки статистики:', err);
13
+ try {
14
+ const response = await fetch("/med/api/admin/stats");
15
+ const result = await response.json();
16
+ if (!result.success) {
17
+ alert("Ошибка доступа к админ-панели: " + result.message);
18
+ window.location.href = "/med/med-login";
19
+ return;
19
20
  }
21
+ document.getElementById("statClinics").textContent =
22
+ result.stats.summary.totalClinics;
23
+ document.getElementById("statPatients").textContent =
24
+ result.stats.summary.totalPatients;
25
+ document.getElementById("statStaff").textContent =
26
+ result.stats.summary.totalStaff;
27
+ } catch (err) {
28
+ console.error("Ошибка загрузки статистики:", err);
29
+ }
20
30
  }
31
+
32
+ // Загрузка клиник в форму №2 (Создание сотрудника)
21
33
  async function loadClinicsDropdown() {
22
- try {
23
- const response = await fetch('/med/api/admin/list-clinics');
24
- const result = await response.json();
25
-
26
- const select = document.getElementById('staffClinic');
27
- select.innerHTML = '<option value="">-- Выберите больницу --</option>';
34
+ try {
35
+ const response = await fetch("/med/api/admin/list-clinics");
36
+ const result = await response.json();
37
+ const select = document.getElementById("staffClinic");
38
+ if (!select) return;
28
39
 
29
- if (result.success && result.data.length > 0) {
30
- result.data.forEach(clinic => {
31
- const opt = document.createElement('option');
32
- opt.value = clinic.id; opt.textContent = `[ID: ${clinic.id}] ${clinic.name}`;
33
- select.appendChild(opt);
34
- });
35
- }
36
- } catch (err) {
37
- console.error('Ошибка наполнения списка клиник:', err);
40
+ select.innerHTML = '<option value="">-- Выберите больницу --</option>';
41
+ if (result.success && result.data.length > 0) {
42
+ result.data.forEach((clinic) => {
43
+ const opt = document.createElement("option");
44
+ opt.value = clinic.id;
45
+ opt.textContent = `[ID: ${clinic.id}] ${clinic.name}`;
46
+ select.appendChild(opt);
47
+ });
38
48
  }
49
+ } catch (err) {
50
+ console.error("Ошибка наполнения списка клиник:", err);
51
+ }
39
52
  }
40
53
 
41
- async function viewClinicsTable() {
42
- const block = document.getElementById('tableViewerBlock');
43
- const title = document.getElementById('tableViewerTitle');
44
- const content = document.getElementById('tableViewerContent');
45
-
46
- block.classList.remove('hidden');
47
- title.textContent = ' 🏥 Реестр медицинских учреждений системы';
48
- content.innerHTML = '<p>Загрузка таблицы...</p>';
54
+ // Загрузка клиник в форму №5 (Конфигуратор участков)
55
+ async function loadClinicsForDistrictsSelect() {
56
+ const select = document.getElementById("distClinicId");
57
+ if (!select) return;
58
+ try {
59
+ const response = await fetch("/med/api/admin/list-clinics");
60
+ const result = await response.json();
61
+ select.innerHTML =
62
+ '<option value="">-- Выберите медицинское учреждение --</option>';
63
+ if (result.success && result.data && result.data.length > 0) {
64
+ result.data.forEach((clinic) => {
65
+ const opt = document.createElement("option");
66
+ opt.value = clinic.id;
67
+ opt.textContent = `[ID: ${clinic.id}] ${clinic.name}`;
68
+ select.appendChild(opt);
69
+ });
70
+ } else {
71
+ select.innerHTML =
72
+ '<option value="">Клиники не найдены. Создайте их в форме №1</option>';
73
+ }
74
+ } catch (err) {
75
+ console.error("Ошибка заполнения селекта клиник:", err);
76
+ }
77
+ }
49
78
 
50
- try {
51
- const res = await fetch('/med/api/admin/list-clinics');
52
- const result = await res.json();
79
+ // Загрузка существующих сотрудников в селект формы №5 (Конфигуратор участков)
80
+ async function loadStaffForDistrictsSelect() {
81
+ const select = document.getElementById("distDoctor");
82
+ if (!select) return;
83
+ try {
84
+ const response = await fetch("/med/api/admin/list-staff");
85
+ const result = await response.json();
86
+ select.innerHTML =
87
+ '<option value="">-- Выберите сотрудника из базы данных --</option>';
88
+ if (result.success && result.data && result.data.length > 0) {
89
+ result.data.forEach((staff) => {
90
+ const opt = document.createElement("option");
91
+ opt.value = staff.fullName;
92
+ const clinicName = staff.Clinic ? staff.Clinic.name : "Без привязки";
93
+ opt.textContent = `${staff.fullName} (${staff.position || "Врач"} — ${clinicName})`;
94
+ select.appendChild(opt);
95
+ });
96
+ console.log(
97
+ `✅ Селект сотрудников успешно обновлен: ${result.data.length} шт.`,
98
+ );
99
+ } else {
100
+ select.innerHTML =
101
+ '<option value="">Нет зарегистрированных сотрудников. Создайте их в форме №2</option>';
102
+ }
103
+ } catch (err) {
104
+ console.error("Ошибка заполнения селекта сотрудников:", err);
105
+ }
106
+ }
53
107
 
54
- if (result.success && result.data.length > 0) {
55
- let html = `
56
- <table>
108
+ // Отрисовка интерактивной таблицы участков из SQLite
109
+ async function renderLiveDistrictsTable() {
110
+ const container = document.getElementById("liveDistrictsTableBox");
111
+ if (!container) return;
112
+ try {
113
+ const res = await fetch("/med/api/admin/list-districts");
114
+ const result = await res.json();
115
+ if (result.success && result.data && result.data.length > 0) {
116
+ let html = `
117
+ <table style="width:100%; border-collapse:collapse; font-size:13px; margin-top:15px; text-align:left;">
57
118
  <thead>
58
- <tr>
59
- <th>ID Клиники</th>
60
- <th>Название</th>
61
- <th>Тип</th>
62
- <th>Адрес</th>
119
+ <tr style="background:#f1f5f9; color:#1e3a8a; border-bottom:2px solid #cbd5e1;">
120
+ <th style="padding:10px;">Медицинское учреждение</th>
121
+ <th style="padding:10px;">Название участка</th>
122
+ <th style="padding:10px;">Кабинет</th>
123
+ <th style="padding:10px;">Адрес покрытия</th>
124
+ <th style="padding:10px;">Дома</th>
125
+ <th style="padding:10px;">Закрепленный сотрудник</th>
63
126
  </tr>
64
127
  </thead>
65
128
  <tbody>
66
129
  `;
67
- result.data.forEach(c => {
68
- html += `
69
- <tr>
70
- <td><span class="uid-badge">${c.id}</span></td>
71
- <td><b>${c.name}</b></td>
72
- <td>${c.type}</td>
73
- <td>${c.address}</td>
130
+ result.data.forEach((d) => {
131
+ const clinicName = d.Clinic
132
+ ? d.Clinic.name
133
+ : '<span style="color:red;">Не привязано</span>';
134
+ html += `
135
+ <tr style="border-bottom:1px solid #cbd5e1;">
136
+ <td style="padding:10px;"><b>${clinicName}</b></td>
137
+ <td style="padding:10px;"><span class="uid-badge" style="background:#e0f2fe; color:#0369a1; padding:3px 6px; border-radius:4px; font-weight:bold;">${d.name}</span></td>
138
+ <td style="padding:10px;"><span class="uid-badge" style="background:#dcfce7; color:#15803d; padding:3px 6px; border-radius:4px; font-weight:bold;">${d.cabinet}</span></td>
139
+ <td style="padding:10px;">г. ${d.city}, ул. ${d.street}</td>
140
+ <td style="padding:10px;">д. ${d.houses}</td>
141
+ <td style="padding:10px; color:#475569;">👤 ${d.doctorName || "Не назначен"}</td>
74
142
  </tr>
75
143
  `;
76
- });
77
- html += '</tbody></table>';
78
- content.innerHTML = html;
79
- } else {
80
- content.innerHTML = '<p>В базе данных пока нет созданных учреждений.</p>';
81
- }
82
- } catch (err) {
83
- content.innerHTML = '<p style="color:red;">Ошибка загрузки данных клиник</p>';
144
+ });
145
+ html += "</tbody></table>";
146
+ container.innerHTML = html;
147
+ } else {
148
+ container.innerHTML =
149
+ '<p style="color:#64748b; font-style:italic; margin:15px 0 0 0;">В системе пока нет настроенных участков покрытия клиник.</p>';
84
150
  }
151
+ } catch (err) {
152
+ console.error("Ошибка рендеринга таблицы участков:", err);
153
+ container.innerHTML =
154
+ '<p style="color:red; margin:15px 0 0 0;">Ошибка автоматического обновления таблицы участков</p>';
155
+ }
85
156
  }
86
157
 
87
- async function viewStaffTable() {
88
- const block = document.getElementById('tableViewerBlock');
89
- const title = document.getElementById('tableViewerTitle');
90
- const content = document.getElementById('tableViewerContent');
158
+ // Форма 1: Создание клиники
159
+ document.getElementById("clinicForm").addEventListener("submit", async (e) => {
160
+ e.preventDefault();
161
+ const payload = {
162
+ name: document.getElementById("clinicName").value,
163
+ type: document.getElementById("clinicType").value,
164
+ address: document.getElementById("clinicAddress").value,
165
+ };
166
+ try {
167
+ const response = await fetch("/med/api/admin/clinics", {
168
+ method: "POST",
169
+ headers: {
170
+ "Content-Type": "application/json",
171
+ },
172
+ body: JSON.stringify(payload),
173
+ });
174
+ const result = await response.json();
175
+ if (result.success) {
176
+ alert(`Учреждение успешно добавлено в SQLite под ID №${result.data.id}!`);
177
+ document.getElementById("clinicForm").reset();
91
178
 
92
- block.classList.remove('hidden');
93
- title.textContent = '👨‍⚕️ Зарегистрированный медицинский персонал';
94
- content.innerHTML = '<p>Загрузка таблицы...</p>';
179
+ // АВТОМАТИКА: Обновляем карточки и выпадающие списки клиник во всех формах
180
+ await loadDashboardStats();
181
+ await loadClinicsDropdown();
182
+ await loadClinicsForDistrictsSelect();
183
+ } else {
184
+ alert("Ошибка: " + result.error);
185
+ }
186
+ } catch (err) {
187
+ alert("Ошибка сети при создании клиники");
188
+ console.error(err);
189
+ }
190
+ });
95
191
 
96
- try {
97
- const res = await fetch('/med/api/admin/list-staff');
98
- const result = await res.json();
192
+ // Форма 2: Создание сотрудника
193
+ document.getElementById("staffForm").addEventListener("submit", async (e) => {
194
+ e.preventDefault();
195
+ const clinicSelect = document.getElementById("staffClinic");
196
+ const selectedClinicId = clinicSelect.value;
197
+ const selectedProfile = document.getElementById("staffMedicalProfile").value;
198
+ if (!selectedClinicId) {
199
+ alert("Пожалуйста, выберите больницу из списка!");
200
+ return;
201
+ }
202
+ const payload = {
203
+ fullName: document.getElementById("staffName").value,
204
+ email: document.getElementById("staffEmail").value,
205
+ rawPassword: document.getElementById("staffPassword").value,
206
+ medicalProfile: selectedProfile,
207
+ clinicId: parseInt(selectedClinicId, 10),
208
+ };
209
+ try {
210
+ const response = await fetch("/med/api/admin/staff", {
211
+ method: "POST",
212
+ headers: { "Content-Type": "application/json" },
213
+ body: JSON.stringify(payload),
214
+ });
215
+ const result = await response.json();
216
+ if (result.success) {
217
+ alert(`Сотрудник успешно создан!\nПрофиль: ${selectedProfile}`);
218
+ document.getElementById("staffForm").reset();
99
219
 
100
- if (result.success && result.data.length > 0) {
101
- let html = `
102
- <table>
103
- <thead>
104
- <tr>
105
- <th>ID Сотрудника</th>
106
- <th>ФИО</th>
107
- <th>Email</th>
108
- <th>Должность</th> <!-- Новая колонка -->
109
- <th>Специализация</th>
110
- <th>Место работы</th>
111
- </tr>
112
- </thead>
113
- <tbody>
114
- `;
115
- result.data.forEach(s => {
116
- const clinicName = s.Clinic ? s.Clinic.name : '<span style="color:red;">Не привязан</span>';
117
- html += `
118
- <tr>
119
- <td><span class="uid-badge">${s.id}</span></td>
120
- <td><b>${s.fullName}</b></td>
121
- <td>${s.email}</td>
122
- <td><span class="badge" style="background:#f1f5f9; color:#475569;">${s.position || 'Врач'}</span></td> <!-- Выводим должность -->
123
- <td>${s.specialty || 'Нет'}</td>
124
- <td>${clinicName}</td>
125
- </tr>
126
- `;
127
- });
128
- html += '</tbody></table>';
129
- content.innerHTML = html;
130
- } else {
131
- content.innerHTML = '<p>В штате системы пока нет зарегистрированных сотрудников.</p>';
132
- }
133
- } catch (err) {
134
- content.innerHTML = '<p style="color:red;">Ошибка загрузки данных персонала</p>';
220
+ // АВТОМАТИКА: Мгновенно обновляем статистику и селект сотрудников в форме участков!
221
+ await loadDashboardStats();
222
+ await loadStaffForDistrictsSelect();
223
+ } else {
224
+ alert("Ошибка creation: " + result.error);
135
225
  }
136
- }
137
- document.getElementById('clinicForm').addEventListener('submit', async (e) => {
138
- e.preventDefault();
139
- const payload = {
140
- name: document.getElementById('clinicName').value,
141
- type: document.getElementById('clinicType').value,
142
- address: document.getElementById('clinicAddress').value
143
- };
144
- try {
145
- const response = await fetch('/med/api/admin/clinics', {
146
- method: 'POST',
147
- headers: { 'Content-Type': 'application/json' },
148
- body: JSON.stringify(payload)
149
- });
150
- const result = await response.json();
151
- if (result.success) {
152
- alert(`Учреждение успешно добавлено в SQLite под ID №${result.data.id}!`);
153
- document.getElementById('clinicForm').reset();
154
- await loadDashboardStats();
155
- } else {
156
- alert('Ошибка: ' + result.error);
157
- }
158
- } catch (err) {
159
- alert('Ошибка сети при создании клиники');
226
+ } catch (err) {
227
+ alert("Ошибка сети при создании сотрудника");
228
+ }
229
+ });
230
+
231
+ // Форма 4: Новости
232
+ document.getElementById("newsForm").addEventListener("submit", async (e) => {
233
+ e.preventDefault();
234
+ const payload = {
235
+ title: document.getElementById("newsTitle").value,
236
+ content: document.getElementById("newsContent").value,
237
+ };
238
+ try {
239
+ const response = await fetch("/med/api/admin/news", {
240
+ method: "POST",
241
+ headers: { "Content-Type": "application/json" },
242
+ body: JSON.stringify(payload),
243
+ });
244
+ const result = await response.json();
245
+ if (result.success) {
246
+ alert(
247
+ `Новость "${result.data.title}" успешно опубликована в ленту главной страницы!`,
248
+ );
249
+ document.getElementById("newsForm").reset();
250
+ await loadDashboardStats();
251
+ } else {
252
+ alert("Ошибка публикации новости: " + result.error);
160
253
  }
254
+ } catch (err) {
255
+ alert("Ошибка сети при попытке опубликовать новость");
256
+ }
161
257
  });
162
- document.getElementById('staffForm').addEventListener('submit', async (e) => {
258
+
259
+ // Форма 5: Отправка участка
260
+ document
261
+ .getElementById("districtForm")
262
+ .addEventListener("submit", async (e) => {
163
263
  e.preventDefault();
164
- const clinicSelect = document.getElementById('staffClinic');
165
- const selectedClinicId = clinicSelect.value;
166
- const selectedProfile = document.getElementById('staffMedicalProfile').value;
167
- if (!selectedClinicId) {
168
- alert('Пожалуйста, выберите больницу из списка!');
169
- return;
170
- }
171
264
  const payload = {
172
- fullName: document.getElementById('staffName').value,
173
- email: document.getElementById('staffEmail').value,
174
- rawPassword: document.getElementById('staffPassword').value,
175
- medicalProfile: selectedProfile,
176
- clinicId: parseInt(selectedClinicId, 10)
265
+ clinicId: document.getElementById("distClinicId").value,
266
+ name: document.getElementById("distName").value,
267
+ city: document.getElementById("distCity").value,
268
+ street: document.getElementById("distStreet").value,
269
+ houses: document.getElementById("distHouses").value,
270
+ cabinet: document.getElementById("distCabinet").value,
271
+ doctorName: document.getElementById("distDoctor").value,
177
272
  };
178
273
  try {
179
- const response = await fetch('/med/api/admin/staff', {
180
- method: 'POST',
181
- headers: { 'Content-Type': 'application/json' },
182
- body: JSON.stringify(payload)
183
- });
184
- const result = await response.json();
185
- if (result.success) {
186
- alert(`Сотрудник успешно создан!\nПрофиль: ${selectedProfile}`);
187
- document.getElementById('staffForm').reset();
188
- await loadDashboardStats();
189
- } else {
190
- alert('Ошибка создания: ' + result.error);
191
- }
274
+ const response = await fetch("/med/api/admin/districts", {
275
+ method: "POST",
276
+ headers: { "Content-Type": "application/json" },
277
+ body: JSON.stringify(payload),
278
+ });
279
+ const result = await response.json();
280
+ if (result.success) {
281
+ alert(`Привязка для ${result.data.name} успешно зафиксирована!`);
282
+ document.getElementById("districtForm").reset();
283
+ await renderLiveDistrictsTable();
284
+ } else {
285
+ alert("Ошибка привязки участка: " + result.error);
286
+ }
192
287
  } catch (err) {
193
- alert('Ошибка сети при создании сотрудника');
288
+ alert("Ошибка сети при отправке данных участка");
194
289
  }
195
- });
290
+ });
291
+ // Просмотр реестров в таблице
292
+ async function viewClinicsTable() {
293
+ const block = document.getElementById("tableViewerBlock");
294
+ const title = document.getElementById("tableViewerTitle");
295
+ const content = document.getElementById("tableViewerContent");
296
+ block.classList.remove("hidden");
297
+ title.textContent = " 🏥 Реестр медицинских учреждений системы";
298
+ content.innerHTML = "Загрузка таблицы...";
299
+ try {
300
+ const res = await fetch("/med/api/admin/list-clinics");
301
+ const result = await res.json();
302
+ if (result.success && result.data.length > 0) {
303
+ let html =
304
+ "<table><thead><tr><th>ID Клиники</th><th>Название</th><th>Тип</th><th>Адрес</th></tr></thead><tbody>";
305
+ result.data.forEach((c) => {
306
+ html += `<tr><td><span class="uid-badge">${c.id}</span></td><td><b>${c.name}</b></td><td>${c.type}</td><td>${c.address}</td></tr>`;
307
+ });
308
+ html += "";
309
+ content.innerHTML = html;
310
+ } else {
311
+ content.innerHTML = "В базе данных пока нет созданных учреждений.";
312
+ }
313
+ } catch (err) {
314
+ content.innerHTML = "Ошибка загрузки данных клиник";
315
+ }
316
+ }
317
+ async function viewStaffTable() {
318
+ const block = document.getElementById("tableViewerBlock");
319
+ const title = document.getElementById("tableViewerTitle");
320
+ const content = document.getElementById("tableViewerContent");
321
+ block.classList.remove("hidden");
322
+ title.textContent = "👨‍⚕️ Зарегистрированный медицинский персонал";
323
+ content.innerHTML = "Загрузка таблицы...";
324
+ try {
325
+ const res = await fetch("/med/api/admin/list-staff");
326
+ const result = await res.json();
327
+ if (result.success && result.data.length > 0) {
328
+ let html = `<table><thead><tr><th>ID Сотрудника</th><th>ФИО</th><th>Email</th><th>Должность</th><th>Специализация</th><th>Место работы</th></tr></thead><tbody>`;
329
+ result.data.forEach((s) => {
330
+ const clinicName = s.Clinic ? s.Clinic.name : "Не привязан";
331
+ html += `
332
+ <tr>
333
+ <td>
334
+ <span class="uid-badge">${s.id}</span>
335
+ </td>
336
+ <td>
337
+ <b>${s.fullName}</b>
338
+ </td>
339
+ <td>${s.email}</td>
340
+ <td>
341
+ <span class="badge" style="background:#f1f5f9; color:#475569;">
342
+ ${s.position || "Врач"}
343
+ </span>
344
+ </td>
345
+ <td>${s.specialty || "Нет"}</td>
346
+ <td>${clinicName}</td>
347
+ </tr>
348
+ `;
349
+ });
350
+ html += "";
351
+ content.innerHTML = html;
352
+ } else {
353
+ content.innerHTML =
354
+ "В штате системы пока нет зарегистрированных сотрудников.";
355
+ }
356
+ } catch (err) {
357
+ content.innerHTML = "Ошибка загрузки данных персонала";
358
+ }
359
+ }
196
360
  async function logout() {
197
- await fetch('/med/api/auth/logout', { method: 'POST' });
198
- window.location.href = '/med/med-login';
199
- }
361
+ await fetch("/med/api/auth/logout", { method: "POST" });
362
+ window.location.href = "/med/med-login";
363
+ }
package/public/js/auth.js CHANGED
@@ -1,55 +1,59 @@
1
1
  function toggleAuth() {
2
- document.getElementById('loginBox').classList.toggle('hidden');
3
- document.getElementById('registerBox').classList.toggle('hidden');
2
+ document.getElementById("loginBox").classList.toggle("hidden");
3
+ document.getElementById("registerBox").classList.toggle("hidden");
4
4
  }
5
5
 
6
- document.getElementById('loginForm').addEventListener('submit', async (e) => {
7
- e.preventDefault();
8
- const email = document.getElementById('loginEmail').value;
9
- const password = document.getElementById('loginPassword').value;
6
+ document.getElementById("loginForm").addEventListener("submit", async (e) => {
7
+ e.preventDefault();
8
+ const email = document.getElementById("loginEmail").value;
9
+ const password = document.getElementById("loginPassword").value;
10
10
 
11
- try {
12
- const response = await fetch('/med/api/auth/login', {
13
- method: 'POST',
14
- headers: { 'Content-Type': 'application/json' },
15
- body: JSON.stringify({ email, password })
16
- });
11
+ try {
12
+ const response = await fetch("/med/api/auth/login", {
13
+ method: "POST",
14
+ headers: { "Content-Type": "application/json" },
15
+ body: JSON.stringify({ email, password }),
16
+ });
17
17
 
18
- const result = await response.json();
19
-
20
- if (result.success) {
21
- if (result.user.role === 'admin') window.location.href = '/med/html/dashboard-admin.html';
22
- else if (result.user.role === 'doctor') window.location.href = '/med/html/dashboard-doctor.html';
23
- else window.location.href = '/med/html/dashboard-patient.html';
24
- } else {
25
- alert('Ошибка: ' + result.message);
26
- }
27
- } catch (err) {
28
- alert('Не удалось связаться с сервером');
18
+ const result = await response.json();
19
+
20
+ if (result.success) {
21
+ if (result.user.role === "admin")
22
+ window.location.href = "/med/html/dashboard-admin.html";
23
+ else if (result.user.role === "doctor")
24
+ window.location.href = "/med/html/dashboard-doctor.html";
25
+ else window.location.href = "/med/html/dashboard-patient.html";
26
+ } else {
27
+ alert("Ошибка: " + result.message);
29
28
  }
29
+ } catch (err) {
30
+ alert("Не удалось связаться с сервером");
31
+ }
30
32
  });
31
33
 
32
- document.getElementById('registerForm').addEventListener('submit', async (e) => {
34
+ document
35
+ .getElementById("registerForm")
36
+ .addEventListener("submit", async (e) => {
33
37
  e.preventDefault();
34
- const fullName = document.getElementById('regName').value;
35
- const email = document.getElementById('regEmail').value;
36
- const password = document.getElementById('regPassword').value;
38
+ const fullName = document.getElementById("regName").value;
39
+ const email = document.getElementById("regEmail").value;
40
+ const password = document.getElementById("regPassword").value;
37
41
 
38
42
  try {
39
- const response = await fetch('/med/api/auth/register', {
40
- method: 'POST',
41
- headers: { 'Content-Type': 'application/json' },
42
- body: JSON.stringify({ email, password, fullName })
43
- });
43
+ const response = await fetch("/med/api/auth/register", {
44
+ method: "POST",
45
+ headers: { "Content-Type": "application/json" },
46
+ body: JSON.stringify({ email, password, fullName }),
47
+ });
44
48
 
45
- const result = await response.json();
46
- if (result.success) {
47
- alert('Регистрация прошла успешно! Теперь вы можете войти.');
48
- toggleAuth();
49
- } else {
50
- alert('Ошибка регистрации: ' + result.message);
51
- }
49
+ const result = await response.json();
50
+ if (result.success) {
51
+ alert("Регистрация прошла успешно! Теперь вы можете войти.");
52
+ toggleAuth();
53
+ } else {
54
+ alert("Ошибка регистрации: " + result.message);
55
+ }
52
56
  } catch (err) {
53
- alert('Ошибка сети');
57
+ alert("Ошибка сети");
54
58
  }
55
- });
59
+ });