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,112 +1,434 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="ru">
3
- <head>
4
- <meta charset="UTF-8">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
5
  <title>Панель Администратора | MED-CMS</title>
6
- <link rel="stylesheet" href="/med/css/admin.css">
6
+ <link rel="stylesheet" href="/med/css/admin.css" />
7
7
  <style>
8
- .clickable-card { cursor: pointer; transition: transform 0.2s, background 0.2s; }
9
- .clickable-card:hover { transform: translateY(-3px); background: #f1f5f9; }
10
- .data-table-box { background: white; padding: 25px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04); margin-top: 30px; }
11
- table { width: 100%; border-collapse: collapse; margin-top: 15px; font-size: 14px; }
12
- th, td { text-align: left; padding: 12px; border-bottom: 1px solid #cbd5e1; }
13
- th { background-color: #f1f5f9; color: #1e3a8a; }
14
- .uid-badge { background: #f1f5f9; font-family: monospace; padding: 3px 6px; border-radius: 4px; color: #e11d48; font-size: 12px; }
8
+ .clickable-card {
9
+ cursor: pointer;
10
+ transition:
11
+ transform 0.2s,
12
+ background 0.2s;
13
+ }
14
+ .clickable-card:hover {
15
+ transform: translateY(-3px);
16
+ background: #f1f5f9;
17
+ }
18
+ .data-table-box {
19
+ background: white;
20
+ padding: 25px;
21
+ border-radius: 8px;
22
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04);
23
+ margin-top: 30px;
24
+ }
25
+ table {
26
+ width: 100%;
27
+ border-collapse: collapse;
28
+ margin-top: 15px;
29
+ font-size: 14px;
30
+ }
31
+ th,
32
+ td {
33
+ text-align: left;
34
+ padding: 12px;
35
+ border-bottom: 1px solid #cbd5e1;
36
+ }
37
+ th {
38
+ background-color: #f1f5f9;
39
+ color: #1e3a8a;
40
+ }
41
+ .uid-badge {
42
+ background: #f1f5f9;
43
+ font-family: monospace;
44
+ padding: 3px 6px;
45
+ border-radius: 4px;
46
+ color: #e11d48;
47
+ font-size: 12px;
48
+ }
15
49
  </style>
16
- </head>
17
- <body>
50
+ </head>
51
+ <body>
18
52
  <div class="admin-panel">
19
- <header>
20
- <h1>Управление медицинской платформой (Суперадмин)</h1>
21
- <button onclick="logout()" class="btn-logout">Выйти</button>
22
- </header>
23
- <section class="stats-cards">
24
- <div class="card clickable-card" onclick="viewClinicsTable()">Всего клиник: <span id="statClinics">0</span></div>
25
- <div class="card clickable-card" onclick="viewStaffTable()">Врачей в штате: <span id="statStaff">0</span></div>
26
- <div class="card">Пациентов в базе: <span id="statPatients">0</span></div>
27
- </section>
28
- <div id="tableViewerBlock" class="data-table-box hidden">
29
- <h3 id="tableViewerTitle">Название таблицы</h3>
30
- <div id="tableViewerContent"></div>
53
+ <header>
54
+ <h1>Управление медицинской платформой (Суперадмин)</h1>
55
+ <button onclick="logout()" class="btn-logout">Выйти</button>
56
+ </header>
57
+ <section class="stats-cards">
58
+ <div class="card clickable-card" onclick="viewClinicsTable()">
59
+ Всего клиник: <span id="statClinics">0</span>
31
60
  </div>
32
- <div class="grid-forms" style="margin-top: 30px;">
33
- <div class="form-box">
34
- <h3>1. Добавить клинику / поликлинику</h3>
35
- <form id="clinicForm">
36
- <input type="text" id="clinicName" placeholder="Название учреждения" required>
37
- <select id="clinicType" required>
38
- <option value="больница">Больница</option>
39
- <option value="поликлиника">Поликлиника</option>
40
- <option value="станция скорой помощи">Станция скорой помощи</option>
41
- </select>
42
- <input type="text" id="clinicAddress" placeholder="Адрес (Город, улица, дом)" required>
43
- <button type="submit">Создать учреждение</button>
44
- </form>
61
+ <div class="card clickable-card" onclick="viewStaffTable()">
62
+ Врачей в штате: <span id="statStaff">0</span>
63
+ </div>
64
+ <div class="card">
65
+ Пациентов в базе: <span id="statPatients">0</span>
66
+ </div>
67
+ </section>
68
+ <div id="tableViewerBlock" class="data-table-box hidden">
69
+ <h3 id="tableViewerTitle">Название таблицы</h3>
70
+ <div id="tableViewerContent"></div>
71
+ </div>
72
+ <div class="grid-forms" style="margin-top: 30px">
73
+ <div class="form-box">
74
+ <h3>1. Добавить клинику / поликлинику</h3>
75
+ <form id="clinicForm">
76
+ <input
77
+ type="text"
78
+ id="clinicName"
79
+ placeholder="Название учреждения"
80
+ required
81
+ />
82
+ <select id="clinicType" required>
83
+ <option value="больница">Больница</option>
84
+ <option value="поликлиника">Поликлиника</option>
85
+ <option value="станция скорой помощи">
86
+ Станция скорой помощи
87
+ </option>
88
+ </select>
89
+ <input
90
+ type="text"
91
+ id="clinicAddress"
92
+ placeholder="Адрес (Город, улица, дом)"
93
+ required
94
+ />
95
+ <button type="submit">Создать учреждение</button>
96
+ </form>
97
+ </div>
98
+ <div class="form-box">
99
+ <h3>2. Зарегистрировать сотрудника (Выдача аккаунта)</h3>
100
+ <form id="staffForm">
101
+ <input
102
+ type="text"
103
+ id="staffName"
104
+ placeholder="ФИО сотрудника (Иванов И.И.)"
105
+ required
106
+ />
107
+ <input
108
+ type="email"
109
+ id="staffEmail"
110
+ placeholder="Рабочий Email"
111
+ required
112
+ />
113
+ <input
114
+ type="text"
115
+ id="staffPassword"
116
+ placeholder="Временный пароль для входа"
117
+ required
118
+ />
119
+
120
+ <div class="form-group" style="margin-bottom: 15px">
121
+ <label>Должность / Специальность</label>
122
+ <select id="staffMedicalProfile" required>
123
+ <option value="">-- Выберите профиль сотрудника --</option>
124
+ <option value="Главврач">Главврач</option>
125
+ <option value="Медсестра">Медсестра</option>
126
+ <option value="Врач скорой помощи">Врач скорой помощи</option>
127
+ <option value="Фельдшер">Фельдшер</option>
128
+ <option value="Регистратор">Регистратор</option>
129
+ <option value="Терапевт">Терапевт</option>
130
+ <option value="Педиатр">Педиатр</option>
131
+ <option value="Врач общей практики">Врач общей практики</option>
132
+ <option value="Кардиолог">Кардиолог</option>
133
+ <option value="Невролог">Невролог</option>
134
+ <option value="Эндокринолог">Эндокринолог</option>
135
+ <option value="Гастроэнтеролог">Гастроэнтеролог</option>
136
+ <option value="Пульмонолог">Пульмонолог</option>
137
+ <option value="Нефролог">Нефролог</option>
138
+ <option value="Ревматолог">Ревматолог</option>
139
+ <option value="Гематолог">Гематолог</option>
140
+ <option value="Хирург">Хирург</option>
141
+ <option value="Травматолог-ортопед">Травматолог-ортопед</option>
142
+ <option value="Сосудистый хирург">Сосудистый хирург</option>
143
+ <option value="Нейрохирург">Нейрохирург</option>
144
+ <option value="Кардиохирург">Кардиохирург</option>
145
+ <option value="Пластический хирург">Пластический хирург</option>
146
+ <option value="Офтальмолог">Офтальмолог</option>
147
+ <option value="Отоларинголог">Отоларинголог</option>
148
+ <option value="Дерматолог">Дерматолог</option>
149
+ <option value="Стоматолог">Стоматолог</option>
150
+ <option value="Гинеколог">Гинеколог</option>
151
+ <option value="Уролог">Уролог</option>
152
+ <option value="Онколог">Онколог</option>
153
+ <option value="Инфекционист">Инфекционист</option>
154
+ <option value="Аллерголог-иммунолог">
155
+ Аллерголог-иммунолог
156
+ </option>
157
+ <option value="Психиатр">Психиатр</option>
158
+ <option value="Психотерапевт">Психотерапевт</option>
159
+ <option value="Нарколог">Нарколог</option>
160
+ <option value="Анестезиолог-реаниматолог">
161
+ Анестезиолог-реаниматолог
162
+ </option>
163
+ <option value="Рентгенолог">Рентгенолог</option>
164
+ <option value="Врач УЗД">Врач УЗД</option>
165
+ <option value="Эндоскопист">Эндоскопист</option>
166
+ <option value="Патологоанатом">Патологоанатом</option>
167
+ </select>
45
168
  </div>
46
- <div class="form-box">
47
- <h3>2. Зарегистрировать сотрудника (Выдача аккаунта)</h3>
48
- <form id="staffForm">
49
- <input type="text" id="staffName" placeholder="ФИО сотрудника (Иванов И.И.)" required>
50
- <input type="email" id="staffEmail" placeholder="Рабочий Email" required>
51
- <input type="text" id="staffPassword" placeholder="Временный пароль для входа" required>
52
-
53
- <div class="form-group" style="margin-bottom: 15px;">
54
- <label>Должность / Специальность</label>
55
- <select id="staffMedicalProfile" required>
56
- <option value="">-- Выберите профиль сотрудника --</option>
57
- <option value="Главврач">Главврач</option>
58
- <option value="Медсестра">Медсестра</option>
59
- <option value="Врач скорой помощи">Врач скорой помощи</option>
60
- <option value="Фельдшер">Фельдшер</option>
61
- <option value="Регистратор">Регистратор</option>
62
- <option value="Терапевт">Терапевт</option>
63
- <option value="Педиатр">Педиатр</option>
64
- <option value="Врач общей практики">Врач общей практики</option>
65
- <option value="Кардиолог">Кардиолог</option>
66
- <option value="Невролог">Невролог</option>
67
- <option value="Эндокринолог">Эндокринолог</option>
68
- <option value="Гастроэнтеролог">Гастроэнтеролог</option>
69
- <option value="Пульмонолог">Пульмонолог</option>
70
- <option value="Нефролог">Нефролог</option>
71
- <option value="Ревматолог">Ревматолог</option>
72
- <option value="Гематолог">Гематолог</option>
73
- <option value="Хирург">Хирург</option>
74
- <option value="Травматолог-ортопед">Травматолог-ортопед</option>
75
- <option value="Сосудистый хирург">Сосудистый хирург</option>
76
- <option value="Нейрохирург">Нейрохирург</option>
77
- <option value="Кардиохирург">Кардиохирург</option>
78
- <option value="Пластический хирург">Пластический хирург</option>
79
- <option value="Офтальмолог">Офтальмолог</option>
80
- <option value="Отоларинголог">Отоларинголог</option>
81
- <option value="Дерматолог">Дерматолог</option>
82
- <option value="Стоматолог">Стоматолог</option>
83
- <option value="Гинеколог">Гинеколог</option>
84
- <option value="Уролог">Уролог</option>
85
- <option value="Онколог">Онколог</option>
86
- <option value="Инфекционист">Инфекционист</option>
87
- <option value="Аллерголог-иммунолог">Аллерголог-иммунолог</option>
88
- <option value="Психиатр">Психиатр</option>
89
- <option value="Психотерапевт">Психотерапевт</option>
90
- <option value="Нарколог">Нарколог</option>
91
- <option value="Анестезиолог-реаниматолог">Анестезиолог-реаниматолог</option>
92
- <option value="Рентгенолог">Рентгенолог</option>
93
- <option value="Врач УЗД">Врач УЗД</option>
94
- <option value="Эндоскопист">Эндоскопист</option>
95
- <option value="Патологоанатом">Патологоанатом</option>
96
- </select>
97
- </div>
98
-
99
- <div class="form-group" style="margin-bottom: 15px;">
100
- <label>Больница привязки</label>
101
- <select id="staffClinic" required>
102
- <option value="">-- Выберите больницу --</option>
103
- </select>
104
- </div>
105
- <button type="submit">Создать аккаунт сотрудника</button>
106
- </form>
169
+
170
+ <div class="form-group" style="margin-bottom: 15px">
171
+ <label>Больница привязки</label>
172
+ <select id="staffClinic" required>
173
+ <option value="">-- Выберите больницу --</option>
174
+ </select>
107
175
  </div>
176
+ <button type="submit">Создать аккаунт сотрудника</button>
177
+ </form>
178
+ </div>
179
+ </div>
180
+ <div
181
+ class="form-box"
182
+ style="
183
+ margin-top: 30px;
184
+ grid-column: span 2;
185
+ border-top: 4px solid #2563eb;
186
+ "
187
+ >
188
+ <h3>🗺️ 5. Привязка участков и кабинетов к учреждениям и адресам</h3>
189
+
190
+ <form
191
+ id="districtForm"
192
+ style="
193
+ display: grid;
194
+ grid-template-columns: 1fr 1fr;
195
+ gap: 15px;
196
+ margin-bottom: 25px;
197
+ "
198
+ >
199
+ <div>
200
+ <label
201
+ style="
202
+ font-size: 14px;
203
+ color: #475569;
204
+ font-weight: 600;
205
+ display: block;
206
+ margin-bottom: 5px;
207
+ "
208
+ >Выберите медицинское учреждение</label
209
+ >
210
+ <!-- ИСПРАВЛЕНИЕ: Динамический селект вместо текстового ID -->
211
+ <select
212
+ id="distClinicId"
213
+ required
214
+ style="
215
+ width: 100%;
216
+ padding: 12px;
217
+ border: 1px solid #cbd5e1;
218
+ border-radius: 6px;
219
+ font-size: 14px;
220
+ background: #fff;
221
+ "
222
+ >
223
+ <option value="">-- Загрузка списка учреждений... --</option>
224
+ </select>
225
+ </div>
226
+ <div>
227
+ <label
228
+ style="
229
+ font-size: 14px;
230
+ color: #475569;
231
+ font-weight: 600;
232
+ display: block;
233
+ margin-bottom: 5px;
234
+ "
235
+ >Название участка</label
236
+ >
237
+ <input
238
+ type="text"
239
+ id="distName"
240
+ placeholder="Например: Терапевтический участок №3"
241
+ required
242
+ />
243
+ </div>
244
+ <div>
245
+ <label
246
+ style="
247
+ font-size: 14px;
248
+ color: #475569;
249
+ font-weight: 600;
250
+ display: block;
251
+ margin-bottom: 5px;
252
+ "
253
+ >Город</label
254
+ >
255
+ <input
256
+ type="text"
257
+ id="distCity"
258
+ placeholder="Например: Минск"
259
+ required
260
+ />
261
+ </div>
262
+ <div>
263
+ <label
264
+ style="
265
+ font-size: 14px;
266
+ color: #475569;
267
+ font-weight: 600;
268
+ display: block;
269
+ margin-bottom: 5px;
270
+ "
271
+ >Улица привязки</label
272
+ >
273
+ <input
274
+ type="text"
275
+ id="distStreet"
276
+ placeholder="Например: Машерова"
277
+ required
278
+ />
279
+ </div>
280
+ <div>
281
+ <label
282
+ style="
283
+ font-size: 14px;
284
+ color: #475569;
285
+ font-weight: 600;
286
+ display: block;
287
+ margin-bottom: 5px;
288
+ "
289
+ >Номера домов (через дефис или 'все')</label
290
+ >
291
+ <input
292
+ type="text"
293
+ id="distHouses"
294
+ placeholder="Например: 1-20 или все"
295
+ required
296
+ />
297
+ </div>
298
+ <div>
299
+ <label
300
+ style="
301
+ font-size: 14px;
302
+ color: #475569;
303
+ font-weight: 600;
304
+ display: block;
305
+ margin-bottom: 5px;
306
+ "
307
+ >Номер кабинета в этом учреждении</label
308
+ >
309
+ <input
310
+ type="text"
311
+ id="distCabinet"
312
+ placeholder="Например: Кабинет №302"
313
+ required
314
+ />
315
+ </div>
316
+ <!-- Заменяем инпут на динамический селект -->
317
+ <div style="grid-column: span 2">
318
+ <label
319
+ style="
320
+ font-size: 14px;
321
+ color: #475569;
322
+ font-weight: 600;
323
+ display: block;
324
+ margin-bottom: 5px;
325
+ "
326
+ >Закрепить лечащего врача (Сотрудника)</label
327
+ >
328
+ <select
329
+ id="distDoctor"
330
+ required
331
+ style="
332
+ width: 100%;
333
+ padding: 12px;
334
+ border: 1px solid #cbd5e1;
335
+ border-radius: 6px;
336
+ font-size: 14px;
337
+ background: #fff;
338
+ "
339
+ >
340
+ <option value="">-- Загрузка списка сотрудников... --</option>
341
+ </select>
342
+ </div>
343
+
344
+ <button
345
+ type="submit"
346
+ style="grid-column: span 2; background-color: #2563eb"
347
+ >
348
+ Сохранить привязку участка в SQLite
349
+ </button>
350
+ </form>
351
+
352
+ <!-- Проверьте наличие этого блока в dashboard-admin.html ниже формы №5 -->
353
+ <div
354
+ style="
355
+ margin-top: 20px;
356
+ border-top: 1px solid #cbd5e1;
357
+ padding-top: 20px;
358
+ "
359
+ >
360
+ <h4 style="margin: 0 0 10px 0; color: #1e3a8a">
361
+ 📋 Действующая карта медицинских участков и кабинетов
362
+ </h4>
363
+ <div id="liveDistrictsTableBox">
364
+ <!-- Сюда JS вставит таблицу -->
365
+ </div>
108
366
  </div>
367
+ </div>
368
+
369
+ <!-- Форма 4: Публикация новости на Главную страницу сайта -->
370
+ <div class="form-box" style="margin-top: 30px; grid-column: span 2">
371
+ <h3>📰 4. Публикация новости на Главную страницу</h3>
372
+ <form
373
+ id="newsForm"
374
+ style="display: flex; flex-direction: column; gap: 15px"
375
+ >
376
+ <div>
377
+ <label
378
+ style="
379
+ font-size: 14px;
380
+ color: #475569;
381
+ font-weight: 600;
382
+ display: block;
383
+ margin-bottom: 5px;
384
+ "
385
+ >Заголовок публикации</label
386
+ >
387
+ <input
388
+ type="text"
389
+ id="newsTitle"
390
+ placeholder="Например: Изменение графика работы в праздничные дни"
391
+ required
392
+ style="margin-bottom: 0"
393
+ />
394
+ </div>
395
+
396
+ <div>
397
+ <label
398
+ style="
399
+ font-size: 14px;
400
+ color: #475569;
401
+ font-weight: 600;
402
+ display: block;
403
+ margin-bottom: 5px;
404
+ "
405
+ >Текст новости</label
406
+ >
407
+ <textarea
408
+ id="newsContent"
409
+ placeholder="Введите подробный текст объявления или новости клиники..."
410
+ required
411
+ style="
412
+ width: 100%;
413
+ height: 120px;
414
+ padding: 12px;
415
+ border: 1px solid #cbd5e1;
416
+ border-radius: 6px;
417
+ box-sizing: border-box;
418
+ font-family: inherit;
419
+ font-size: 14px;
420
+ background-color: #fff;
421
+ resize: vertical;
422
+ "
423
+ ></textarea>
424
+ </div>
425
+
426
+ <button type="submit" style="background-color: #10b981">
427
+ Опубликовать в ленту новостей
428
+ </button>
429
+ </form>
430
+ </div>
109
431
  </div>
110
432
  <script src="/med/js/admin.js"></script>
111
- </body>
112
- </html>
433
+ </body>
434
+ </html>