wad-lab 1.0.9 → 1.1.1

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 (70) hide show
  1. package/bin/index.js +13 -5
  2. package/package.json +1 -1
  3. package/templates/servlet-session-tracking/WEB-INF/LoginServlet.java +46 -0
  4. package/templates/servlet-session-tracking/WEB-INF/LogoutServlet.java +39 -0
  5. package/templates/servlet-session-tracking/WEB-INF/ProfileServlet.java +83 -0
  6. package/templates/servlet-session-tracking/WEB-INF/classes/LoginServlet.class +0 -0
  7. package/templates/servlet-session-tracking/WEB-INF/classes/LogoutServlet.class +0 -0
  8. package/templates/servlet-session-tracking/WEB-INF/classes/ProfileServlet.class +0 -0
  9. package/templates/servlet-session-tracking/WEB-INF/web.xml +38 -0
  10. package/templates/servlet-session-tracking/index.html +36 -0
  11. package/templates/springboot-hospital-api/.mvn/wrapper/maven-wrapper.properties +3 -0
  12. package/templates/springboot-hospital-api/mvnw +295 -0
  13. package/templates/springboot-hospital-api/mvnw.cmd +189 -0
  14. package/templates/springboot-hospital-api/pom.xml +41 -0
  15. package/templates/springboot-hospital-api/src/main/java/com/example/hospital/HospitalApplication.java +12 -0
  16. package/templates/springboot-hospital-api/src/main/java/com/example/hospital/controller/HospitalController.java +50 -0
  17. package/templates/springboot-hospital-api/src/main/java/com/example/hospital/model/Appointment.java +95 -0
  18. package/templates/springboot-hospital-api/src/main/java/com/example/hospital/repository/AppointmentRepository.java +15 -0
  19. package/templates/springboot-hospital-api/src/main/java/com/example/hospital/service/HospitalService.java +54 -0
  20. package/templates/springboot-hospital-api/src/main/resources/application.properties +3 -0
  21. package/templates/springboot-hospital-api/src/test/java/com/example/hospital/HospitalApplicationTests.java +12 -0
  22. package/templates/springboot-library-api/.mvn/wrapper/maven-wrapper.properties +3 -0
  23. package/templates/springboot-library-api/mvnw +295 -0
  24. package/templates/springboot-library-api/mvnw.cmd +189 -0
  25. package/templates/springboot-library-api/pom.xml +42 -0
  26. package/templates/springboot-library-api/src/main/java/com/example/library/LibraryApplication.java +12 -0
  27. package/templates/springboot-library-api/src/main/java/com/example/library/controller/LibraryController.java +51 -0
  28. package/templates/springboot-library-api/src/main/java/com/example/library/model/Book.java +76 -0
  29. package/templates/springboot-library-api/src/main/java/com/example/library/model/CategoryAnalytics.java +41 -0
  30. package/templates/springboot-library-api/src/main/java/com/example/library/repository/BookRepository.java +13 -0
  31. package/templates/springboot-library-api/src/main/java/com/example/library/service/LibraryService.java +60 -0
  32. package/templates/springboot-library-api/src/main/resources/application.properties +3 -0
  33. package/templates/vue-game-rps/index.html +12 -0
  34. package/templates/vue-game-rps/package.json +19 -0
  35. package/templates/vue-game-rps/src/App.vue +125 -0
  36. package/templates/vue-game-rps/src/main.js +5 -0
  37. package/templates/vue-game-rps/src/stores/rpsStore.js +43 -0
  38. package/templates/vue-game-rps/vite.config.js +6 -0
  39. package/templates/vue-game-tictactoe/index.html +12 -0
  40. package/templates/vue-game-tictactoe/package.json +19 -0
  41. package/templates/vue-game-tictactoe/src/App.vue +105 -0
  42. package/templates/vue-game-tictactoe/src/main.js +5 -0
  43. package/templates/vue-game-tictactoe/src/stores/tictactoeStore.js +61 -0
  44. package/templates/vue-game-tictactoe/vite.config.js +6 -0
  45. package/templates/vue-game-whackamole/index.html +12 -0
  46. package/templates/vue-game-whackamole/package.json +19 -0
  47. package/templates/vue-game-whackamole/src/App.vue +104 -0
  48. package/templates/vue-game-whackamole/src/main.js +7 -0
  49. package/templates/vue-game-whackamole/src/stores/moleStore.js +71 -0
  50. package/templates/vue-game-whackamole/vite.config.js +6 -0
  51. package/templates/vue-hospital-portal/index.html +12 -0
  52. package/templates/vue-hospital-portal/package.json +20 -0
  53. package/templates/vue-hospital-portal/src/App.vue +107 -0
  54. package/templates/vue-hospital-portal/src/main.js +9 -0
  55. package/templates/vue-hospital-portal/src/router/index.js +17 -0
  56. package/templates/vue-hospital-portal/src/stores/hospitalStore.js +91 -0
  57. package/templates/vue-hospital-portal/src/views/HospitalBillingView.vue +271 -0
  58. package/templates/vue-hospital-portal/src/views/OPDRegistrationView.vue +453 -0
  59. package/templates/vue-hospital-portal/src/views/PatientListView.vue +315 -0
  60. package/templates/vue-hospital-portal/vite.config.js +6 -0
  61. package/templates/vue-library-system/index.html +12 -0
  62. package/templates/vue-library-system/package.json +20 -0
  63. package/templates/vue-library-system/src/App.vue +91 -0
  64. package/templates/vue-library-system/src/main.js +9 -0
  65. package/templates/vue-library-system/src/router/index.js +29 -0
  66. package/templates/vue-library-system/src/stores/libraryStore.js +87 -0
  67. package/templates/vue-library-system/src/views/BookCatalogView.vue +432 -0
  68. package/templates/vue-library-system/src/views/LoanManagerView.vue +296 -0
  69. package/templates/vue-library-system/src/views/MembershipView.vue +269 -0
  70. package/templates/vue-library-system/vite.config.js +6 -0
@@ -0,0 +1,7 @@
1
+ import { createApp } from 'vue'
2
+ import { createPinia } from 'pinia'
3
+ import App from './App.vue'
4
+
5
+ const app = createApp(App)
6
+ app.use(createPinia())
7
+ app.mount('#app')
@@ -0,0 +1,71 @@
1
+ import { defineStore } from 'pinia'
2
+
3
+ export const useMoleStore = defineStore('mole', {
4
+ state: () => ({
5
+ score: 0,
6
+ timeLeft: 30,
7
+ isPlaying: false,
8
+ activeHoleIndex: -1,
9
+ timerInterval: null,
10
+ moleTimeout: null
11
+ }),
12
+ actions: {
13
+ startGame() {
14
+ if (this.isPlaying) return
15
+ this.stopGame()
16
+ this.score = 0
17
+ this.timeLeft = 30
18
+ this.isPlaying = true
19
+ this.peepMole()
20
+
21
+ this.timerInterval = setInterval(() => {
22
+ this.timeLeft--
23
+ if (this.timeLeft <= 0) {
24
+ this.stopGame()
25
+ }
26
+ }, 1000)
27
+ },
28
+ peepMole() {
29
+ if (!this.isPlaying) return
30
+
31
+ let nextHole
32
+ do {
33
+ nextHole = Math.floor(Math.random() * 9)
34
+ } while (nextHole === this.activeHoleIndex)
35
+
36
+ this.activeHoleIndex = nextHole
37
+ const stayTime = Math.floor(Math.random() * 400) + 700
38
+
39
+ clearTimeout(this.moleTimeout)
40
+ this.moleTimeout = setTimeout(() => {
41
+ if (!this.isPlaying) return
42
+ this.activeHoleIndex = -1
43
+ this.peepMole()
44
+ }, stayTime)
45
+ },
46
+ whackMole(index) {
47
+ if (this.isPlaying && index === this.activeHoleIndex) {
48
+ this.score++
49
+ this.activeHoleIndex = -1
50
+ clearTimeout(this.moleTimeout)
51
+ this.moleTimeout = setTimeout(() => {
52
+ if (this.isPlaying) {
53
+ this.peepMole()
54
+ }
55
+ }, 200)
56
+ }
57
+ },
58
+ stopGame() {
59
+ if (this.timerInterval) {
60
+ clearInterval(this.timerInterval)
61
+ this.timerInterval = null
62
+ }
63
+ if (this.moleTimeout) {
64
+ clearTimeout(this.moleTimeout)
65
+ this.moleTimeout = null
66
+ }
67
+ this.isPlaying = false
68
+ this.activeHoleIndex = -1
69
+ }
70
+ }
71
+ })
@@ -0,0 +1,6 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+
4
+ export default defineConfig({
5
+ plugins: [vue()]
6
+ })
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Hospital Care Portal</title>
7
+ </head>
8
+ <body>
9
+ <div id="app"></div>
10
+ <script type="module" src="/src/main.js"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "vue-hospital-portal",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "pinia": "^4.1.0",
13
+ "vue": "^3.5.44",
14
+ "vue-router": "^5.4.0"
15
+ },
16
+ "devDependencies": {
17
+ "@vitejs/plugin-vue": "^6.0.10",
18
+ "vite": "^8.3.4"
19
+ }
20
+ }
@@ -0,0 +1,107 @@
1
+ <script setup>
2
+ </script>
3
+
4
+ <template>
5
+ <div class="app-layout">
6
+ <header class="app-header">
7
+ <div class="brand">
8
+ <span class="cross-icon">+</span>
9
+ <h1 class="portal-title">Hospital Care Portal</h1>
10
+ </div>
11
+ <nav class="nav-links">
12
+ <router-link to="/">Book OPD / Admit</router-link>
13
+ <router-link to="/patients">Patients List</router-link>
14
+ <router-link to="/billing">Billing / Stats</router-link>
15
+ </nav>
16
+ </header>
17
+
18
+ <main class="content-container">
19
+ <router-view />
20
+ </main>
21
+ </div>
22
+ </template>
23
+
24
+ <style>
25
+ * {
26
+ box-sizing: border-box;
27
+ }
28
+
29
+ body {
30
+ margin: 0;
31
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
32
+ color: #2d3748;
33
+ background-color: #f7fafc;
34
+ }
35
+ </style>
36
+
37
+ <style scoped>
38
+ .app-layout {
39
+ min-height: 100vh;
40
+ display: flex;
41
+ flex-direction: column;
42
+ }
43
+
44
+ .app-header {
45
+ background-color: #1a365d;
46
+ color: #ffffff;
47
+ padding: 14px 28px;
48
+ display: flex;
49
+ justify-content: space-between;
50
+ align-items: center;
51
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
52
+ }
53
+
54
+ .brand {
55
+ display: flex;
56
+ align-items: center;
57
+ gap: 10px;
58
+ }
59
+
60
+ .cross-icon {
61
+ background-color: #e53e3e;
62
+ color: #ffffff;
63
+ font-weight: bold;
64
+ font-size: 16px;
65
+ width: 24px;
66
+ height: 24px;
67
+ border-radius: 4px;
68
+ display: inline-flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ }
72
+
73
+ .portal-title {
74
+ margin: 0;
75
+ font-size: 18px;
76
+ font-weight: 700;
77
+ letter-spacing: 0.5px;
78
+ }
79
+
80
+ .nav-links {
81
+ display: flex;
82
+ gap: 12px;
83
+ }
84
+
85
+ .nav-links a {
86
+ color: #e2e8f0;
87
+ text-decoration: none;
88
+ font-size: 14px;
89
+ font-weight: 500;
90
+ padding: 6px 14px;
91
+ border-radius: 4px;
92
+ transition: background-color 0.2s, color 0.2s;
93
+ }
94
+
95
+ .nav-links a:hover,
96
+ .nav-links a.router-link-active {
97
+ background-color: #2b6cb0;
98
+ color: #ffffff;
99
+ }
100
+
101
+ .content-container {
102
+ max-width: 960px;
103
+ width: 100%;
104
+ margin: 28px auto;
105
+ padding: 0 20px;
106
+ }
107
+ </style>
@@ -0,0 +1,9 @@
1
+ import { createApp } from 'vue'
2
+ import { createPinia } from 'pinia'
3
+ import App from './App.vue'
4
+ import router from './router'
5
+
6
+ const app = createApp(App)
7
+ app.use(createPinia())
8
+ app.use(router)
9
+ app.mount('#app')
@@ -0,0 +1,17 @@
1
+ import { createRouter, createWebHistory } from 'vue-router'
2
+ import OPDRegistrationView from '../views/OPDRegistrationView.vue'
3
+ import PatientListView from '../views/PatientListView.vue'
4
+ import HospitalBillingView from '../views/HospitalBillingView.vue'
5
+
6
+ const routes = [
7
+ { path: '/', name: 'OPDRegistration', component: OPDRegistrationView },
8
+ { path: '/patients', name: 'PatientList', component: PatientListView },
9
+ { path: '/billing', name: 'HospitalBilling', component: HospitalBillingView }
10
+ ]
11
+
12
+ const router = createRouter({
13
+ history: createWebHistory(),
14
+ routes
15
+ })
16
+
17
+ export default router
@@ -0,0 +1,91 @@
1
+ import { defineStore } from 'pinia'
2
+
3
+ export const useHospitalStore = defineStore('hospital', {
4
+ state: () => ({
5
+ doctors: [
6
+ { id: 1, name: 'Dr. Sarah Connor', specialty: 'Cardiology', fee: 150, availableSlots: 5 },
7
+ { id: 2, name: 'Dr. Gregory House', specialty: 'Diagnostics & ICU', fee: 250, availableSlots: 3 },
8
+ { id: 3, name: 'Dr. John Watson', specialty: 'General Medicine', fee: 90, availableSlots: 6 }
9
+ ],
10
+ patients: [
11
+ {
12
+ id: 1,
13
+ name: 'Robert Paulson',
14
+ age: 45,
15
+ vitals: { bp: '130/85', hr: 78, temp: 98.6 },
16
+ doctor: 'Dr. Sarah Connor',
17
+ bedType: 'General Ward',
18
+ bill: 350,
19
+ risk: 'Moderate',
20
+ paymentStatus: 'Pending'
21
+ }
22
+ ]
23
+ }),
24
+ getters: {
25
+ totalPatients: (state) => state.patients.length,
26
+ criticalCount: (state) => state.patients.filter((p) => p.risk === 'High' || p.bedType === 'ICU').length,
27
+ totalRevenue: (state) => state.patients.reduce((sum, p) => sum + (Number(p.bill) || 0), 0)
28
+ },
29
+ actions: {
30
+ calculateRisk(vitals) {
31
+ if (!vitals) return 'Normal'
32
+ const bpStr = vitals.bp || vitals.bloodPressure || '120/80'
33
+ const hrVal = Number(vitals.hr || vitals.heartRate || 75)
34
+ const tempVal = Number(vitals.temp || vitals.temperature || 98.6)
35
+
36
+ let systolic = 120
37
+ let diastolic = 80
38
+ if (typeof bpStr === 'string' && bpStr.includes('/')) {
39
+ const parts = bpStr.split('/').map((s) => parseInt(s.trim(), 10))
40
+ if (!isNaN(parts[0])) systolic = parts[0]
41
+ if (!isNaN(parts[1])) diastolic = parts[1]
42
+ }
43
+
44
+ if (systolic >= 140 || systolic < 90 || diastolic >= 90 || hrVal > 100 || hrVal < 50 || tempVal >= 102) {
45
+ return 'High'
46
+ }
47
+ if (systolic >= 125 || diastolic >= 83 || hrVal > 85 || hrVal < 60 || tempVal >= 100.4) {
48
+ return 'Moderate'
49
+ }
50
+ return 'Normal'
51
+ },
52
+ admitPatient(patientData) {
53
+ const risk = this.calculateRisk(patientData.vitals)
54
+ const autoBill = patientData.bedType === 'ICU' ? 1200 : 350
55
+ const newPatient = {
56
+ id: Date.now(),
57
+ name: patientData.name,
58
+ age: Number(patientData.age),
59
+ doctor: patientData.doctor || 'Dr. Sarah Connor',
60
+ bedType: patientData.bedType || 'General Ward',
61
+ bill: Number(patientData.bill) || autoBill,
62
+ vitals: {
63
+ bp: (patientData.vitals && (patientData.vitals.bp || patientData.vitals.bloodPressure)) || '120/80',
64
+ hr: Number(patientData.vitals && (patientData.vitals.hr || patientData.vitals.heartRate)) || 72,
65
+ temp: Number(patientData.vitals && (patientData.vitals.temp || patientData.vitals.temperature)) || 98.6
66
+ },
67
+ risk: risk,
68
+ paymentStatus: patientData.paymentStatus || 'Pending'
69
+ }
70
+ this.patients.unshift(newPatient)
71
+ return newPatient
72
+ },
73
+ dischargePatient(id) {
74
+ this.patients = this.patients.filter((p) => p.id !== id)
75
+ },
76
+ bookAppointment(doctorId) {
77
+ const doc = this.doctors.find((d) => d.id === doctorId)
78
+ if (doc && doc.availableSlots > 0) {
79
+ doc.availableSlots -= 1
80
+ return { success: true, message: `Appointment confirmed with ${doc.name}` }
81
+ }
82
+ return { success: false, message: 'No appointment slots available for this doctor' }
83
+ },
84
+ settlePayment(id) {
85
+ const p = this.patients.find((item) => item.id === id)
86
+ if (p) {
87
+ p.paymentStatus = 'Paid'
88
+ }
89
+ }
90
+ }
91
+ })
@@ -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>