wad-lab 1.0.8 → 1.1.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 (62) hide show
  1. package/bin/index.js +15 -8
  2. package/package.json +1 -1
  3. package/templates/springboot-hospital-api/.mvn/wrapper/maven-wrapper.properties +3 -0
  4. package/templates/springboot-hospital-api/mvnw +295 -0
  5. package/templates/springboot-hospital-api/mvnw.cmd +189 -0
  6. package/templates/springboot-hospital-api/pom.xml +41 -0
  7. package/templates/springboot-hospital-api/src/main/java/com/example/hospital/HospitalApplication.java +12 -0
  8. package/templates/springboot-hospital-api/src/main/java/com/example/hospital/controller/HospitalController.java +50 -0
  9. package/templates/springboot-hospital-api/src/main/java/com/example/hospital/model/Appointment.java +95 -0
  10. package/templates/springboot-hospital-api/src/main/java/com/example/hospital/repository/AppointmentRepository.java +15 -0
  11. package/templates/springboot-hospital-api/src/main/java/com/example/hospital/service/HospitalService.java +54 -0
  12. package/templates/springboot-hospital-api/src/main/resources/application.properties +3 -0
  13. package/templates/springboot-hospital-api/src/test/java/com/example/hospital/HospitalApplicationTests.java +12 -0
  14. package/templates/springboot-library-api/.mvn/wrapper/maven-wrapper.properties +3 -0
  15. package/templates/springboot-library-api/mvnw +295 -0
  16. package/templates/springboot-library-api/mvnw.cmd +189 -0
  17. package/templates/springboot-library-api/pom.xml +42 -0
  18. package/templates/springboot-library-api/src/main/java/com/example/library/LibraryApplication.java +12 -0
  19. package/templates/springboot-library-api/src/main/java/com/example/library/controller/LibraryController.java +51 -0
  20. package/templates/springboot-library-api/src/main/java/com/example/library/model/Book.java +76 -0
  21. package/templates/springboot-library-api/src/main/java/com/example/library/model/CategoryAnalytics.java +41 -0
  22. package/templates/springboot-library-api/src/main/java/com/example/library/repository/BookRepository.java +13 -0
  23. package/templates/springboot-library-api/src/main/java/com/example/library/service/LibraryService.java +60 -0
  24. package/templates/springboot-library-api/src/main/resources/application.properties +3 -0
  25. package/templates/vue-game-rps/index.html +12 -0
  26. package/templates/vue-game-rps/package.json +19 -0
  27. package/templates/vue-game-rps/src/App.vue +125 -0
  28. package/templates/vue-game-rps/src/main.js +5 -0
  29. package/templates/vue-game-rps/src/stores/rpsStore.js +43 -0
  30. package/templates/vue-game-rps/vite.config.js +6 -0
  31. package/templates/vue-game-tictactoe/index.html +12 -0
  32. package/templates/vue-game-tictactoe/package.json +19 -0
  33. package/templates/vue-game-tictactoe/src/App.vue +105 -0
  34. package/templates/vue-game-tictactoe/src/main.js +5 -0
  35. package/templates/vue-game-tictactoe/src/stores/tictactoeStore.js +61 -0
  36. package/templates/vue-game-tictactoe/vite.config.js +6 -0
  37. package/templates/vue-game-whackamole/index.html +12 -0
  38. package/templates/vue-game-whackamole/package.json +19 -0
  39. package/templates/vue-game-whackamole/src/App.vue +104 -0
  40. package/templates/vue-game-whackamole/src/main.js +7 -0
  41. package/templates/vue-game-whackamole/src/stores/moleStore.js +71 -0
  42. package/templates/vue-game-whackamole/vite.config.js +6 -0
  43. package/templates/vue-hospital-portal/index.html +12 -0
  44. package/templates/vue-hospital-portal/package.json +20 -0
  45. package/templates/vue-hospital-portal/src/App.vue +107 -0
  46. package/templates/vue-hospital-portal/src/main.js +9 -0
  47. package/templates/vue-hospital-portal/src/router/index.js +17 -0
  48. package/templates/vue-hospital-portal/src/stores/hospitalStore.js +91 -0
  49. package/templates/vue-hospital-portal/src/views/HospitalBillingView.vue +271 -0
  50. package/templates/vue-hospital-portal/src/views/OPDRegistrationView.vue +453 -0
  51. package/templates/vue-hospital-portal/src/views/PatientListView.vue +315 -0
  52. package/templates/vue-hospital-portal/vite.config.js +6 -0
  53. package/templates/vue-library-system/index.html +12 -0
  54. package/templates/vue-library-system/package.json +20 -0
  55. package/templates/vue-library-system/src/App.vue +91 -0
  56. package/templates/vue-library-system/src/main.js +9 -0
  57. package/templates/vue-library-system/src/router/index.js +29 -0
  58. package/templates/vue-library-system/src/stores/libraryStore.js +87 -0
  59. package/templates/vue-library-system/src/views/BookCatalogView.vue +432 -0
  60. package/templates/vue-library-system/src/views/LoanManagerView.vue +296 -0
  61. package/templates/vue-library-system/src/views/MembershipView.vue +269 -0
  62. package/templates/vue-library-system/vite.config.js +6 -0
@@ -0,0 +1,271 @@
1
+ <script setup>
2
+ import { computed } from 'vue'
3
+ import { useHospitalStore } from '../stores/hospitalStore'
4
+
5
+ const hospital = useHospitalStore()
6
+
7
+ const paidTotal = computed(() => {
8
+ return hospital.patients
9
+ .filter((p) => p.paymentStatus === 'Paid')
10
+ .reduce((sum, p) => sum + (Number(p.bill) || 0), 0)
11
+ })
12
+
13
+ const pendingTotal = computed(() => {
14
+ return hospital.patients
15
+ .filter((p) => p.paymentStatus !== 'Paid')
16
+ .reduce((sum, p) => sum + (Number(p.bill) || 0), 0)
17
+ })
18
+
19
+ function handleSettle(id) {
20
+ hospital.settlePayment(id)
21
+ }
22
+ </script>
23
+
24
+ <template>
25
+ <div class="billing-page">
26
+ <h2>Hospital Financial & Critical Care Overview</h2>
27
+
28
+ <div class="metrics-grid">
29
+ <div class="metric-card">
30
+ <span class="metric-label">Total Revenue</span>
31
+ <span class="metric-value font-blue">${{ hospital.totalRevenue }}</span>
32
+ <span class="metric-sub">Across all admissions</span>
33
+ </div>
34
+
35
+ <div class="metric-card">
36
+ <span class="metric-label">Paid Revenue</span>
37
+ <span class="metric-value font-green">${{ paidTotal }}</span>
38
+ <span class="metric-sub">Cleared payments</span>
39
+ </div>
40
+
41
+ <div class="metric-card">
42
+ <span class="metric-label">Pending Dues</span>
43
+ <span class="metric-value font-amber">${{ pendingTotal }}</span>
44
+ <span class="metric-sub">Awaiting settlement</span>
45
+ </div>
46
+
47
+ <div class="metric-card">
48
+ <span class="metric-label">Critical / ICU Cases</span>
49
+ <span class="metric-value font-red">{{ hospital.criticalCount }}</span>
50
+ <span class="metric-sub">Requiring priority monitoring</span>
51
+ </div>
52
+ </div>
53
+
54
+ <div class="table-card">
55
+ <h3>Patient Invoices & Payment Ledger</h3>
56
+ <div v-if="hospital.patients.length === 0" class="empty-state">
57
+ No active patient billing records.
58
+ </div>
59
+ <div v-else class="table-container">
60
+ <table class="billing-table">
61
+ <thead>
62
+ <tr>
63
+ <th>Patient</th>
64
+ <th>Assigned Doctor</th>
65
+ <th>Bed Type</th>
66
+ <th>Risk</th>
67
+ <th>Total Bill</th>
68
+ <th>Status</th>
69
+ <th>Action</th>
70
+ </tr>
71
+ </thead>
72
+ <tbody>
73
+ <tr v-for="patient in hospital.patients" :key="patient.id">
74
+ <td class="font-bold">{{ patient.name }}</td>
75
+ <td>{{ patient.doctor }}</td>
76
+ <td>{{ patient.bedType }}</td>
77
+ <td>
78
+ <span :class="['badge-risk', 'badge-' + (patient.risk ? patient.risk.toLowerCase() : 'normal')]">
79
+ {{ patient.risk || 'Normal' }}
80
+ </span>
81
+ </td>
82
+ <td class="font-bold">${{ patient.bill }}</td>
83
+ <td>
84
+ <span :class="['status-badge', patient.paymentStatus === 'Paid' ? 'status-paid' : 'status-pending']">
85
+ {{ patient.paymentStatus || 'Pending' }}
86
+ </span>
87
+ </td>
88
+ <td>
89
+ <button
90
+ v-if="patient.paymentStatus !== 'Paid'"
91
+ class="btn-settle"
92
+ @click="handleSettle(patient.id)"
93
+ >
94
+ Mark Paid
95
+ </button>
96
+ <span v-else class="settled-text">Settled</span>
97
+ </td>
98
+ </tr>
99
+ </tbody>
100
+ </table>
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </template>
105
+
106
+ <style scoped>
107
+ .billing-page {
108
+ display: flex;
109
+ flex-direction: column;
110
+ gap: 20px;
111
+ }
112
+
113
+ h2 {
114
+ margin: 0;
115
+ font-size: 20px;
116
+ color: #1a202c;
117
+ }
118
+
119
+ h3 {
120
+ margin: 0 0 14px 0;
121
+ font-size: 16px;
122
+ color: #2d3748;
123
+ }
124
+
125
+ .metrics-grid {
126
+ display: grid;
127
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
128
+ gap: 15px;
129
+ }
130
+
131
+ .metric-card {
132
+ background-color: #ffffff;
133
+ border: 1px solid #e2e8f0;
134
+ border-radius: 8px;
135
+ padding: 16px;
136
+ display: flex;
137
+ flex-direction: column;
138
+ gap: 6px;
139
+ }
140
+
141
+ .metric-label {
142
+ font-size: 13px;
143
+ color: #718096;
144
+ font-weight: 500;
145
+ }
146
+
147
+ .metric-value {
148
+ font-size: 26px;
149
+ font-weight: 700;
150
+ }
151
+
152
+ .metric-sub {
153
+ font-size: 11px;
154
+ color: #a0aec0;
155
+ }
156
+
157
+ .font-blue {
158
+ color: #2b6cb0;
159
+ }
160
+
161
+ .font-green {
162
+ color: #2f855a;
163
+ }
164
+
165
+ .font-amber {
166
+ color: #c05621;
167
+ }
168
+
169
+ .font-red {
170
+ color: #c53030;
171
+ }
172
+
173
+ .table-card {
174
+ background-color: #ffffff;
175
+ border: 1px solid #e2e8f0;
176
+ border-radius: 8px;
177
+ padding: 18px;
178
+ }
179
+
180
+ .empty-state {
181
+ color: #718096;
182
+ padding: 20px 0;
183
+ text-align: center;
184
+ }
185
+
186
+ .table-container {
187
+ overflow-x: auto;
188
+ }
189
+
190
+ .billing-table {
191
+ width: 100%;
192
+ border-collapse: collapse;
193
+ font-size: 13px;
194
+ text-align: left;
195
+ }
196
+
197
+ .billing-table th {
198
+ background-color: #f7fafc;
199
+ color: #4a5568;
200
+ padding: 10px 12px;
201
+ border-bottom: 2px solid #e2e8f0;
202
+ }
203
+
204
+ .billing-table td {
205
+ padding: 10px 12px;
206
+ border-bottom: 1px solid #edf2f7;
207
+ }
208
+
209
+ .font-bold {
210
+ font-weight: 600;
211
+ }
212
+
213
+ .badge-risk {
214
+ font-size: 11px;
215
+ padding: 2px 7px;
216
+ border-radius: 10px;
217
+ font-weight: 600;
218
+ }
219
+
220
+ .badge-high {
221
+ background-color: #fed7d7;
222
+ color: #9b2c2c;
223
+ }
224
+
225
+ .badge-moderate {
226
+ background-color: #feebc8;
227
+ color: #c05621;
228
+ }
229
+
230
+ .badge-normal {
231
+ background-color: #c6f6d5;
232
+ color: #22543d;
233
+ }
234
+
235
+ .status-badge {
236
+ font-size: 11px;
237
+ font-weight: 700;
238
+ padding: 3px 8px;
239
+ border-radius: 12px;
240
+ }
241
+
242
+ .status-paid {
243
+ background-color: #c6f6d5;
244
+ color: #22543d;
245
+ }
246
+
247
+ .status-pending {
248
+ background-color: #feebc8;
249
+ color: #9c4221;
250
+ }
251
+
252
+ .btn-settle {
253
+ background-color: #3182ce;
254
+ color: #ffffff;
255
+ border: none;
256
+ padding: 5px 10px;
257
+ border-radius: 4px;
258
+ font-size: 12px;
259
+ cursor: pointer;
260
+ font-weight: 600;
261
+ }
262
+
263
+ .btn-settle:hover {
264
+ background-color: #2b6cb0;
265
+ }
266
+
267
+ .settled-text {
268
+ font-size: 12px;
269
+ color: #718096;
270
+ }
271
+ </style>
@@ -0,0 +1,453 @@
1
+ <script setup>
2
+ import { ref, computed } from 'vue'
3
+ import { useRouter } from 'vue-router'
4
+ import { useHospitalStore } from '../stores/hospitalStore'
5
+
6
+ const hospital = useHospitalStore()
7
+ const router = useRouter()
8
+
9
+ const opdMessage = ref('')
10
+ const admissionMessage = ref('')
11
+
12
+ const form = ref({
13
+ name: '',
14
+ age: '',
15
+ doctor: hospital.doctors[0]?.name || 'Dr. Sarah Connor',
16
+ bedType: 'General Ward',
17
+ vitals: {
18
+ bp: '120/80',
19
+ hr: 75,
20
+ temp: 98.6
21
+ },
22
+ bill: 350
23
+ })
24
+
25
+ function updateBedType(type) {
26
+ form.value.bedType = type
27
+ if (type === 'ICU') {
28
+ form.value.bill = 1200
29
+ } else {
30
+ form.value.bill = 350
31
+ }
32
+ }
33
+
34
+ const predictedRisk = computed(() => {
35
+ return hospital.calculateRisk(form.value.vitals)
36
+ })
37
+
38
+ function handleBookOpd(doctorId) {
39
+ const result = hospital.bookAppointment(doctorId)
40
+ opdMessage.value = result.message
41
+ setTimeout(() => {
42
+ opdMessage.value = ''
43
+ }, 3500)
44
+ }
45
+
46
+ function handleAdmitPatient() {
47
+ if (!form.value.name.trim() || !form.value.age) {
48
+ return
49
+ }
50
+ hospital.admitPatient({
51
+ name: form.value.name,
52
+ age: form.value.age,
53
+ doctor: form.value.doctor,
54
+ bedType: form.value.bedType,
55
+ vitals: {
56
+ bp: form.value.vitals.bp,
57
+ hr: form.value.vitals.hr,
58
+ temp: form.value.vitals.temp
59
+ },
60
+ bill: form.value.bill,
61
+ paymentStatus: 'Pending'
62
+ })
63
+
64
+ admissionMessage.value = `Patient ${form.value.name} successfully admitted to ${form.value.bedType}!`
65
+ form.value.name = ''
66
+ form.value.age = ''
67
+ form.value.vitals = { bp: '120/80', hr: 75, temp: 98.6 }
68
+ form.value.bedType = 'General Ward'
69
+ form.value.bill = 350
70
+
71
+ setTimeout(() => {
72
+ admissionMessage.value = ''
73
+ router.push('/patients')
74
+ }, 1200)
75
+ }
76
+ </script>
77
+
78
+ <template>
79
+ <div class="registration-page">
80
+ <section class="card opd-section">
81
+ <h2>OPD Doctor Appointments</h2>
82
+ <div v-if="opdMessage" class="alert alert-info">
83
+ {{ opdMessage }}
84
+ </div>
85
+ <div class="doctor-grid">
86
+ <div v-for="doc in hospital.doctors" :key="doc.id" class="doctor-card">
87
+ <div class="doctor-header">
88
+ <h3>{{ doc.name }}</h3>
89
+ <span class="specialty-badge">{{ doc.specialty }}</span>
90
+ </div>
91
+ <p class="fee-text">Consultation Fee: <strong>${{ doc.fee }}</strong></p>
92
+ <p class="slot-text">
93
+ Available Slots:
94
+ <span :class="['slot-count', doc.availableSlots > 0 ? 'slot-open' : 'slot-full']">
95
+ {{ doc.availableSlots }}
96
+ </span>
97
+ </p>
98
+ <button
99
+ class="btn btn-opd"
100
+ :disabled="doc.availableSlots === 0"
101
+ @click="handleBookOpd(doc.id)"
102
+ >
103
+ {{ doc.availableSlots > 0 ? 'Book Appointment' : 'Fully Booked' }}
104
+ </button>
105
+ </div>
106
+ </div>
107
+ </section>
108
+
109
+ <section class="card admission-section">
110
+ <h2>Patient Bed & ICU Admission Form</h2>
111
+ <div v-if="admissionMessage" class="alert alert-success">
112
+ {{ admissionMessage }}
113
+ </div>
114
+ <form @submit.prevent="handleAdmitPatient" class="admission-form">
115
+ <div class="form-row">
116
+ <div class="form-group flex-1">
117
+ <label for="pName">Patient Name</label>
118
+ <input id="pName" v-model="form.name" type="text" placeholder="e.g. Eleanor Vance" required />
119
+ </div>
120
+ <div class="form-group width-small">
121
+ <label for="pAge">Age</label>
122
+ <input id="pAge" v-model="form.age" type="number" min="1" max="130" placeholder="e.g. 34" required />
123
+ </div>
124
+ </div>
125
+
126
+ <div class="form-row">
127
+ <div class="form-group flex-1">
128
+ <label for="pDoc">Assigned Doctor</label>
129
+ <select id="pDoc" v-model="form.doctor">
130
+ <option v-for="doc in hospital.doctors" :key="doc.id" :value="doc.name">
131
+ {{ doc.name }} ({{ doc.specialty }})
132
+ </option>
133
+ </select>
134
+ </div>
135
+ <div class="form-group flex-1">
136
+ <label>Bed Allocation</label>
137
+ <div class="bed-options">
138
+ <button
139
+ type="button"
140
+ :class="['bed-btn', form.bedType === 'General Ward' ? 'bed-btn-active' : '']"
141
+ @click="updateBedType('General Ward')"
142
+ >
143
+ General Ward ($350)
144
+ </button>
145
+ <button
146
+ type="button"
147
+ :class="['bed-btn', form.bedType === 'ICU' ? 'bed-btn-active bed-btn-icu' : '']"
148
+ @click="updateBedType('ICU')"
149
+ >
150
+ ICU ($1,200)
151
+ </button>
152
+ </div>
153
+ </div>
154
+ </div>
155
+
156
+ <fieldset class="vitals-fieldset">
157
+ <legend>Patient Vitals</legend>
158
+ <div class="vitals-row">
159
+ <div class="form-group flex-1">
160
+ <label for="vBp">Blood Pressure (mmHg)</label>
161
+ <input id="vBp" v-model="form.vitals.bp" type="text" placeholder="120/80" required />
162
+ </div>
163
+ <div class="form-group flex-1">
164
+ <label for="vHr">Heart Rate (bpm)</label>
165
+ <input id="vHr" v-model.number="form.vitals.hr" type="number" min="30" max="250" required />
166
+ </div>
167
+ <div class="form-group flex-1">
168
+ <label for="vTemp">Temperature (°F)</label>
169
+ <input id="vTemp" v-model.number="form.vitals.temp" type="number" step="0.1" min="90" max="110" required />
170
+ </div>
171
+ </div>
172
+
173
+ <div class="risk-preview">
174
+ <span>Evaluated Risk Level: </span>
175
+ <span :class="['risk-tag', 'risk-' + predictedRisk.toLowerCase()]">
176
+ {{ predictedRisk }} Risk
177
+ </span>
178
+ </div>
179
+ </fieldset>
180
+
181
+ <div class="form-row">
182
+ <div class="form-group flex-1">
183
+ <label for="pBill">Estimated Billing ($)</label>
184
+ <input id="pBill" v-model.number="form.bill" type="number" min="0" required />
185
+ </div>
186
+ </div>
187
+
188
+ <button type="submit" class="btn btn-submit">
189
+ Admit Patient & Allocate Bed
190
+ </button>
191
+ </form>
192
+ </section>
193
+ </div>
194
+ </template>
195
+
196
+ <style scoped>
197
+ .registration-page {
198
+ display: flex;
199
+ flex-direction: column;
200
+ gap: 25px;
201
+ }
202
+
203
+ .card {
204
+ background-color: #ffffff;
205
+ border: 1px solid #e1e8ed;
206
+ border-radius: 8px;
207
+ padding: 20px 24px;
208
+ }
209
+
210
+ h2 {
211
+ margin-top: 0;
212
+ margin-bottom: 16px;
213
+ font-size: 19px;
214
+ color: #1a202c;
215
+ border-bottom: 2px solid #edf2f7;
216
+ padding-bottom: 8px;
217
+ }
218
+
219
+ .alert {
220
+ padding: 10px 14px;
221
+ border-radius: 4px;
222
+ margin-bottom: 16px;
223
+ font-size: 14px;
224
+ }
225
+
226
+ .alert-info {
227
+ background-color: #ebf8ff;
228
+ color: #2b6cb0;
229
+ border: 1px solid #bee3f8;
230
+ }
231
+
232
+ .alert-success {
233
+ background-color: #f0fff4;
234
+ color: #276749;
235
+ border: 1px solid #c6f6d5;
236
+ }
237
+
238
+ .doctor-grid {
239
+ display: grid;
240
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
241
+ gap: 15px;
242
+ }
243
+
244
+ .doctor-card {
245
+ border: 1px solid #e2e8f0;
246
+ border-radius: 6px;
247
+ padding: 14px;
248
+ background-color: #fafbfc;
249
+ display: flex;
250
+ flex-direction: column;
251
+ justify-content: space-between;
252
+ }
253
+
254
+ .doctor-header h3 {
255
+ margin: 0 0 6px 0;
256
+ font-size: 16px;
257
+ color: #2d3748;
258
+ }
259
+
260
+ .specialty-badge {
261
+ display: inline-block;
262
+ background-color: #e2e8f0;
263
+ color: #4a5568;
264
+ font-size: 12px;
265
+ padding: 2px 8px;
266
+ border-radius: 12px;
267
+ }
268
+
269
+ .fee-text,
270
+ .slot-text {
271
+ margin: 8px 0;
272
+ font-size: 14px;
273
+ color: #4a5568;
274
+ }
275
+
276
+ .slot-count {
277
+ font-weight: bold;
278
+ padding: 2px 6px;
279
+ border-radius: 4px;
280
+ }
281
+
282
+ .slot-open {
283
+ background-color: #c6f6d5;
284
+ color: #22543d;
285
+ }
286
+
287
+ .slot-full {
288
+ background-color: #fed7d7;
289
+ color: #742a2a;
290
+ }
291
+
292
+ .admission-form {
293
+ display: flex;
294
+ flex-direction: column;
295
+ gap: 16px;
296
+ }
297
+
298
+ .form-row {
299
+ display: flex;
300
+ gap: 15px;
301
+ flex-wrap: wrap;
302
+ }
303
+
304
+ .flex-1 {
305
+ flex: 1;
306
+ min-width: 200px;
307
+ }
308
+
309
+ .width-small {
310
+ width: 110px;
311
+ }
312
+
313
+ .form-group {
314
+ display: flex;
315
+ flex-direction: column;
316
+ gap: 5px;
317
+ }
318
+
319
+ label {
320
+ font-size: 13px;
321
+ font-weight: 600;
322
+ color: #4a5568;
323
+ }
324
+
325
+ input,
326
+ select {
327
+ padding: 8px 10px;
328
+ border: 1px solid #cbd5e0;
329
+ border-radius: 5px;
330
+ font-size: 14px;
331
+ background-color: #ffffff;
332
+ }
333
+
334
+ input:focus,
335
+ select:focus {
336
+ outline: none;
337
+ border-color: #3182ce;
338
+ }
339
+
340
+ .bed-options {
341
+ display: flex;
342
+ gap: 10px;
343
+ }
344
+
345
+ .bed-btn {
346
+ flex: 1;
347
+ padding: 8px 12px;
348
+ border: 1px solid #cbd5e0;
349
+ background-color: #f7fafc;
350
+ color: #4a5568;
351
+ border-radius: 5px;
352
+ cursor: pointer;
353
+ font-size: 13px;
354
+ font-weight: 500;
355
+ }
356
+
357
+ .bed-btn-active {
358
+ background-color: #3182ce;
359
+ color: #ffffff;
360
+ border-color: #3182ce;
361
+ }
362
+
363
+ .bed-btn-active.bed-btn-icu {
364
+ background-color: #dd6b20;
365
+ border-color: #dd6b20;
366
+ }
367
+
368
+ .vitals-fieldset {
369
+ border: 1px solid #e2e8f0;
370
+ border-radius: 6px;
371
+ padding: 12px 16px;
372
+ background-color: #f7fafc;
373
+ }
374
+
375
+ legend {
376
+ font-size: 13px;
377
+ font-weight: bold;
378
+ color: #2b6cb0;
379
+ padding: 0 6px;
380
+ }
381
+
382
+ .vitals-row {
383
+ display: flex;
384
+ gap: 12px;
385
+ flex-wrap: wrap;
386
+ }
387
+
388
+ .risk-preview {
389
+ margin-top: 10px;
390
+ font-size: 13px;
391
+ display: flex;
392
+ align-items: center;
393
+ gap: 8px;
394
+ }
395
+
396
+ .risk-tag {
397
+ font-weight: 700;
398
+ padding: 3px 10px;
399
+ border-radius: 12px;
400
+ font-size: 12px;
401
+ text-transform: uppercase;
402
+ }
403
+
404
+ .risk-high {
405
+ background-color: #fed7d7;
406
+ color: #9b2c2c;
407
+ }
408
+
409
+ .risk-moderate {
410
+ background-color: #feebc8;
411
+ color: #c05621;
412
+ }
413
+
414
+ .risk-normal {
415
+ background-color: #c6f6d5;
416
+ color: #22543d;
417
+ }
418
+
419
+ .btn {
420
+ padding: 9px 16px;
421
+ border: none;
422
+ border-radius: 5px;
423
+ font-weight: 600;
424
+ font-size: 14px;
425
+ cursor: pointer;
426
+ }
427
+
428
+ .btn-opd {
429
+ background-color: #2b6cb0;
430
+ color: #ffffff;
431
+ margin-top: 8px;
432
+ }
433
+
434
+ .btn-opd:hover:not(:disabled) {
435
+ background-color: #2c5282;
436
+ }
437
+
438
+ .btn-opd:disabled {
439
+ background-color: #cbd5e0;
440
+ cursor: not-allowed;
441
+ color: #718096;
442
+ }
443
+
444
+ .btn-submit {
445
+ background-color: #2f855a;
446
+ color: #ffffff;
447
+ padding: 12px;
448
+ }
449
+
450
+ .btn-submit:hover {
451
+ background-color: #276749;
452
+ }
453
+ </style>