create-steve-rogers 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 (34) hide show
  1. package/apps/HMSR/backend/.env.example +6 -0
  2. package/apps/HMSR/backend/config/db.js +14 -0
  3. package/apps/HMSR/backend/database/schema.sql +55 -0
  4. package/apps/HMSR/backend/database/seed.js +53 -0
  5. package/apps/HMSR/backend/middleware/auth.js +26 -0
  6. package/apps/HMSR/backend/package-lock.json +1130 -0
  7. package/apps/HMSR/backend/package.json +19 -0
  8. package/apps/HMSR/backend/routes/appointments.js +157 -0
  9. package/apps/HMSR/backend/routes/auth.js +115 -0
  10. package/apps/HMSR/backend/routes/medicalReports.js +126 -0
  11. package/apps/HMSR/backend/routes/patients.js +103 -0
  12. package/apps/HMSR/backend/routes/reports.js +60 -0
  13. package/apps/HMSR/backend/server.js +38 -0
  14. package/apps/HMSR/frontend/package-lock.json +17217 -0
  15. package/apps/HMSR/frontend/package.json +23 -0
  16. package/apps/HMSR/frontend/public/index.html +17 -0
  17. package/apps/HMSR/frontend/src/App.js +91 -0
  18. package/apps/HMSR/frontend/src/components/Layout.js +58 -0
  19. package/apps/HMSR/frontend/src/components/PrivateRoute.js +25 -0
  20. package/apps/HMSR/frontend/src/context/AuthContext.js +54 -0
  21. package/apps/HMSR/frontend/src/index.css +581 -0
  22. package/apps/HMSR/frontend/src/index.js +17 -0
  23. package/apps/HMSR/frontend/src/pages/Appointments.js +250 -0
  24. package/apps/HMSR/frontend/src/pages/Dashboard.js +116 -0
  25. package/apps/HMSR/frontend/src/pages/Login.js +73 -0
  26. package/apps/HMSR/frontend/src/pages/MedicalReports.js +217 -0
  27. package/apps/HMSR/frontend/src/pages/Patients.js +196 -0
  28. package/apps/HMSR/frontend/src/pages/Register.js +98 -0
  29. package/apps/HMSR/frontend/src/pages/Reports.js +170 -0
  30. package/apps/HMSR/frontend/src/services/api.js +15 -0
  31. package/apps/config.js +8 -0
  32. package/exclude.txt +1 -0
  33. package/index.js +55 -0
  34. package/package.json +14 -0
@@ -0,0 +1,581 @@
1
+ :root {
2
+ --primary: #0d6e6e;
3
+ --primary-dark: #095555;
4
+ --primary-light: #e8f5f5;
5
+ --accent: #c45c26;
6
+ --bg: #f4f7f7;
7
+ --surface: #ffffff;
8
+ --text: #1a2e2e;
9
+ --text-muted: #5a7373;
10
+ --border: #d4e4e4;
11
+ --danger: #c0392b;
12
+ --warning: #d68910;
13
+ --success: #1e8449;
14
+ --shadow: 0 4px 20px rgba(13, 110, 110, 0.08);
15
+ --radius: 10px;
16
+ --font: 'DM Sans', system-ui, sans-serif;
17
+ }
18
+
19
+ * {
20
+ box-sizing: border-box;
21
+ margin: 0;
22
+ padding: 0;
23
+ }
24
+
25
+ body {
26
+ font-family: var(--font);
27
+ background: var(--bg);
28
+ color: var(--text);
29
+ line-height: 1.5;
30
+ -webkit-font-smoothing: antialiased;
31
+ }
32
+
33
+ a {
34
+ color: var(--primary);
35
+ text-decoration: none;
36
+ }
37
+
38
+ a:hover {
39
+ text-decoration: underline;
40
+ }
41
+
42
+ /* Layout */
43
+ .app-layout {
44
+ display: flex;
45
+ min-height: 100vh;
46
+ }
47
+
48
+ .sidebar {
49
+ width: 260px;
50
+ background: linear-gradient(180deg, var(--primary) 0%, var(--primary-dark) 100%);
51
+ color: white;
52
+ display: flex;
53
+ flex-direction: column;
54
+ flex-shrink: 0;
55
+ }
56
+
57
+ .sidebar-brand {
58
+ padding: 1.5rem;
59
+ display: flex;
60
+ gap: 0.75rem;
61
+ align-items: center;
62
+ border-bottom: 1px solid rgba(255, 255, 255, 0.15);
63
+ }
64
+
65
+ .sidebar-brand h1 {
66
+ font-size: 1.1rem;
67
+ font-weight: 700;
68
+ }
69
+
70
+ .sidebar-brand p {
71
+ font-size: 0.75rem;
72
+ opacity: 0.8;
73
+ }
74
+
75
+ .brand-icon {
76
+ width: 40px;
77
+ height: 40px;
78
+ background: white;
79
+ color: var(--primary);
80
+ border-radius: 10px;
81
+ display: flex;
82
+ align-items: center;
83
+ justify-content: center;
84
+ font-size: 1.5rem;
85
+ font-weight: 700;
86
+ }
87
+
88
+ .brand-icon.large {
89
+ width: 56px;
90
+ height: 56px;
91
+ font-size: 2rem;
92
+ margin: 0 auto 1rem;
93
+ }
94
+
95
+ .sidebar-nav {
96
+ flex: 1;
97
+ padding: 1rem 0.75rem;
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 0.25rem;
101
+ }
102
+
103
+ .sidebar-nav a {
104
+ color: rgba(255, 255, 255, 0.85);
105
+ padding: 0.75rem 1rem;
106
+ border-radius: 8px;
107
+ text-decoration: none;
108
+ font-weight: 500;
109
+ transition: background 0.2s;
110
+ }
111
+
112
+ .sidebar-nav a:hover,
113
+ .sidebar-nav a.active {
114
+ background: rgba(255, 255, 255, 0.15);
115
+ color: white;
116
+ text-decoration: none;
117
+ }
118
+
119
+ .sidebar-footer {
120
+ padding: 1rem 1.25rem 1.5rem;
121
+ border-top: 1px solid rgba(255, 255, 255, 0.15);
122
+ }
123
+
124
+ .user-info {
125
+ margin-bottom: 0.75rem;
126
+ }
127
+
128
+ .user-info strong {
129
+ display: block;
130
+ font-size: 0.9rem;
131
+ }
132
+
133
+ .role-badge {
134
+ display: inline-block;
135
+ font-size: 0.7rem;
136
+ text-transform: capitalize;
137
+ padding: 0.15rem 0.5rem;
138
+ border-radius: 4px;
139
+ margin-top: 0.25rem;
140
+ background: rgba(255, 255, 255, 0.2);
141
+ }
142
+
143
+ .main-content {
144
+ flex: 1;
145
+ padding: 2rem;
146
+ overflow-x: hidden;
147
+ }
148
+
149
+ /* Auth */
150
+ .auth-page {
151
+ min-height: 100vh;
152
+ display: flex;
153
+ align-items: center;
154
+ justify-content: center;
155
+ padding: 2rem;
156
+ background: linear-gradient(135deg, var(--primary-light) 0%, var(--bg) 50%, #fff 100%);
157
+ }
158
+
159
+ .auth-card {
160
+ background: var(--surface);
161
+ padding: 2.5rem;
162
+ border-radius: 16px;
163
+ box-shadow: var(--shadow);
164
+ width: 100%;
165
+ max-width: 420px;
166
+ }
167
+
168
+ .auth-header {
169
+ text-align: center;
170
+ margin-bottom: 2rem;
171
+ }
172
+
173
+ .auth-header h1 {
174
+ font-size: 1.35rem;
175
+ color: var(--primary);
176
+ }
177
+
178
+ .auth-header p {
179
+ color: var(--text-muted);
180
+ font-size: 0.9rem;
181
+ margin-top: 0.25rem;
182
+ }
183
+
184
+ .auth-footer {
185
+ text-align: center;
186
+ margin-top: 1.5rem;
187
+ font-size: 0.9rem;
188
+ color: var(--text-muted);
189
+ }
190
+
191
+ .demo-credentials {
192
+ margin-top: 1.5rem;
193
+ padding: 1rem;
194
+ background: var(--primary-light);
195
+ border-radius: 8px;
196
+ font-size: 0.8rem;
197
+ color: var(--text-muted);
198
+ }
199
+
200
+ .demo-credentials p {
201
+ margin: 0.2rem 0;
202
+ }
203
+
204
+ /* Page */
205
+ .page-header {
206
+ display: flex;
207
+ justify-content: space-between;
208
+ align-items: flex-start;
209
+ margin-bottom: 1.5rem;
210
+ flex-wrap: wrap;
211
+ gap: 1rem;
212
+ }
213
+
214
+ .page-header h1 {
215
+ font-size: 1.75rem;
216
+ color: var(--primary-dark);
217
+ }
218
+
219
+ .page-header p {
220
+ color: var(--text-muted);
221
+ margin-top: 0.25rem;
222
+ }
223
+
224
+ /* Cards & Stats */
225
+ .card {
226
+ background: var(--surface);
227
+ border-radius: var(--radius);
228
+ padding: 1.5rem;
229
+ box-shadow: var(--shadow);
230
+ margin-bottom: 1.5rem;
231
+ }
232
+
233
+ .card h2 {
234
+ font-size: 1.1rem;
235
+ margin-bottom: 1rem;
236
+ color: var(--primary-dark);
237
+ }
238
+
239
+ .form-card {
240
+ border: 1px solid var(--border);
241
+ }
242
+
243
+ .stats-grid {
244
+ display: grid;
245
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
246
+ gap: 1rem;
247
+ margin-bottom: 1.5rem;
248
+ }
249
+
250
+ .stat-card {
251
+ background: var(--surface);
252
+ padding: 1.25rem 1.5rem;
253
+ border-radius: var(--radius);
254
+ box-shadow: var(--shadow);
255
+ border-left: 4px solid var(--primary);
256
+ }
257
+
258
+ .stat-card.highlight {
259
+ border-left-color: var(--accent);
260
+ }
261
+
262
+ .stat-label {
263
+ display: block;
264
+ font-size: 0.85rem;
265
+ color: var(--text-muted);
266
+ margin-bottom: 0.35rem;
267
+ }
268
+
269
+ .stat-value {
270
+ font-size: 2rem;
271
+ font-weight: 700;
272
+ color: var(--primary-dark);
273
+ }
274
+
275
+ .quick-actions h2 {
276
+ margin-bottom: 1rem;
277
+ font-size: 1.2rem;
278
+ }
279
+
280
+ .action-grid {
281
+ display: grid;
282
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
283
+ gap: 1rem;
284
+ }
285
+
286
+ .action-card {
287
+ background: var(--surface);
288
+ padding: 1.25rem;
289
+ border-radius: var(--radius);
290
+ box-shadow: var(--shadow);
291
+ text-decoration: none;
292
+ color: inherit;
293
+ border: 1px solid transparent;
294
+ transition: border-color 0.2s, transform 0.2s;
295
+ }
296
+
297
+ .action-card:hover {
298
+ border-color: var(--primary);
299
+ transform: translateY(-2px);
300
+ text-decoration: none;
301
+ }
302
+
303
+ .action-card h3 {
304
+ color: var(--primary);
305
+ margin-bottom: 0.35rem;
306
+ }
307
+
308
+ .action-card p {
309
+ font-size: 0.85rem;
310
+ color: var(--text-muted);
311
+ }
312
+
313
+ /* Forms */
314
+ .form-group {
315
+ margin-bottom: 1rem;
316
+ }
317
+
318
+ .form-group label {
319
+ display: block;
320
+ font-size: 0.85rem;
321
+ font-weight: 600;
322
+ margin-bottom: 0.35rem;
323
+ color: var(--text);
324
+ }
325
+
326
+ .form-group input,
327
+ .form-group select,
328
+ .form-group textarea {
329
+ width: 100%;
330
+ padding: 0.65rem 0.85rem;
331
+ border: 1px solid var(--border);
332
+ border-radius: 8px;
333
+ font-family: inherit;
334
+ font-size: 0.95rem;
335
+ transition: border-color 0.2s;
336
+ }
337
+
338
+ .form-group input:focus,
339
+ .form-group select:focus,
340
+ .form-group textarea:focus {
341
+ outline: none;
342
+ border-color: var(--primary);
343
+ box-shadow: 0 0 0 3px var(--primary-light);
344
+ }
345
+
346
+ .form-grid {
347
+ display: grid;
348
+ grid-template-columns: repeat(2, 1fr);
349
+ gap: 0 1rem;
350
+ }
351
+
352
+ .form-grid .full-width {
353
+ grid-column: 1 / -1;
354
+ }
355
+
356
+ .form-actions {
357
+ display: flex;
358
+ gap: 0.75rem;
359
+ margin-top: 0.5rem;
360
+ }
361
+
362
+ .report-filter-form {
363
+ display: flex;
364
+ flex-wrap: wrap;
365
+ gap: 1rem;
366
+ align-items: flex-end;
367
+ }
368
+
369
+ .report-filter-form .form-group {
370
+ margin-bottom: 0;
371
+ min-width: 180px;
372
+ }
373
+
374
+ /* Buttons */
375
+ .btn {
376
+ display: inline-flex;
377
+ align-items: center;
378
+ justify-content: center;
379
+ padding: 0.6rem 1.25rem;
380
+ border: none;
381
+ border-radius: 8px;
382
+ font-family: inherit;
383
+ font-size: 0.9rem;
384
+ font-weight: 600;
385
+ cursor: pointer;
386
+ transition: background 0.2s, opacity 0.2s;
387
+ }
388
+
389
+ .btn:disabled {
390
+ opacity: 0.6;
391
+ cursor: not-allowed;
392
+ }
393
+
394
+ .btn-primary {
395
+ background: var(--primary);
396
+ color: white;
397
+ }
398
+
399
+ .btn-primary:hover:not(:disabled) {
400
+ background: var(--primary-dark);
401
+ }
402
+
403
+ .btn-outline {
404
+ background: transparent;
405
+ color: var(--primary);
406
+ border: 1px solid var(--primary);
407
+ }
408
+
409
+ .btn-outline:hover {
410
+ background: var(--primary-light);
411
+ }
412
+
413
+ .btn-danger {
414
+ background: var(--danger);
415
+ color: white;
416
+ }
417
+
418
+ .btn-warning {
419
+ background: var(--warning);
420
+ color: white;
421
+ }
422
+
423
+ .btn-sm {
424
+ padding: 0.35rem 0.75rem;
425
+ font-size: 0.8rem;
426
+ }
427
+
428
+ .btn-block {
429
+ width: 100%;
430
+ }
431
+
432
+ /* Table */
433
+ .table-responsive {
434
+ overflow-x: auto;
435
+ }
436
+
437
+ table {
438
+ width: 100%;
439
+ border-collapse: collapse;
440
+ font-size: 0.9rem;
441
+ }
442
+
443
+ th,
444
+ td {
445
+ padding: 0.75rem 1rem;
446
+ text-align: left;
447
+ border-bottom: 1px solid var(--border);
448
+ }
449
+
450
+ th {
451
+ font-weight: 600;
452
+ color: var(--text-muted);
453
+ font-size: 0.8rem;
454
+ text-transform: uppercase;
455
+ letter-spacing: 0.03em;
456
+ }
457
+
458
+ tr:hover td {
459
+ background: var(--primary-light);
460
+ }
461
+
462
+ .actions {
463
+ display: flex;
464
+ gap: 0.5rem;
465
+ flex-wrap: wrap;
466
+ }
467
+
468
+ .text-wrap {
469
+ max-width: 200px;
470
+ white-space: pre-wrap;
471
+ word-break: break-word;
472
+ }
473
+
474
+ .text-muted {
475
+ color: var(--text-muted);
476
+ }
477
+
478
+ /* Status badges */
479
+ .status-badge {
480
+ display: inline-block;
481
+ padding: 0.2rem 0.6rem;
482
+ border-radius: 20px;
483
+ font-size: 0.75rem;
484
+ font-weight: 600;
485
+ text-transform: capitalize;
486
+ }
487
+
488
+ .status-scheduled {
489
+ background: #d4efdf;
490
+ color: #1e8449;
491
+ }
492
+
493
+ .status-completed {
494
+ background: #d6eaf8;
495
+ color: #1a5276;
496
+ }
497
+
498
+ .status-cancelled {
499
+ background: #fadbd8;
500
+ color: #922b21;
501
+ }
502
+
503
+ /* Alerts */
504
+ .alert {
505
+ padding: 0.85rem 1rem;
506
+ border-radius: 8px;
507
+ margin-bottom: 1rem;
508
+ font-size: 0.9rem;
509
+ }
510
+
511
+ .alert-error {
512
+ background: #fadbd8;
513
+ color: #922b21;
514
+ border: 1px solid #f5b7b1;
515
+ }
516
+
517
+ .alert-success {
518
+ background: #d4efdf;
519
+ color: #1e5631;
520
+ border: 1px solid #a9dfbf;
521
+ }
522
+
523
+ /* Loading */
524
+ .loading-screen {
525
+ min-height: 100vh;
526
+ display: flex;
527
+ flex-direction: column;
528
+ align-items: center;
529
+ justify-content: center;
530
+ gap: 1rem;
531
+ color: var(--text-muted);
532
+ }
533
+
534
+ .spinner {
535
+ width: 40px;
536
+ height: 40px;
537
+ border: 3px solid var(--border);
538
+ border-top-color: var(--primary);
539
+ border-radius: 50%;
540
+ animation: spin 0.8s linear infinite;
541
+ }
542
+
543
+ @keyframes spin {
544
+ to {
545
+ transform: rotate(360deg);
546
+ }
547
+ }
548
+
549
+ /* Responsive */
550
+ @media (max-width: 768px) {
551
+ .app-layout {
552
+ flex-direction: column;
553
+ }
554
+
555
+ .sidebar {
556
+ width: 100%;
557
+ }
558
+
559
+ .sidebar-nav {
560
+ flex-direction: row;
561
+ flex-wrap: wrap;
562
+ padding: 0.5rem;
563
+ }
564
+
565
+ .sidebar-nav a {
566
+ padding: 0.5rem 0.75rem;
567
+ font-size: 0.85rem;
568
+ }
569
+
570
+ .main-content {
571
+ padding: 1rem;
572
+ }
573
+
574
+ .form-grid {
575
+ grid-template-columns: 1fr;
576
+ }
577
+
578
+ .page-header {
579
+ flex-direction: column;
580
+ }
581
+ }
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import { BrowserRouter } from 'react-router-dom';
4
+ import App from './App';
5
+ import { AuthProvider } from './context/AuthContext';
6
+ import './index.css';
7
+
8
+ const root = ReactDOM.createRoot(document.getElementById('root'));
9
+ root.render(
10
+ <React.StrictMode>
11
+ <BrowserRouter>
12
+ <AuthProvider>
13
+ <App />
14
+ </AuthProvider>
15
+ </BrowserRouter>
16
+ </React.StrictMode>
17
+ );