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,61 @@
1
+ import { defineStore } from 'pinia'
2
+
3
+ export const useTicTacToeStore = defineStore('tictactoe', {
4
+ state: () => ({
5
+ board: Array(9).fill(''),
6
+ currentPlayer: 'X',
7
+ winner: null,
8
+ isDraw: false,
9
+ winningConditions: [
10
+ [0, 1, 2],
11
+ [3, 4, 5],
12
+ [6, 7, 8],
13
+ [0, 3, 6],
14
+ [1, 4, 7],
15
+ [2, 5, 8],
16
+ [0, 4, 8],
17
+ [2, 4, 6]
18
+ ]
19
+ }),
20
+ actions: {
21
+ checkWin() {
22
+ for (const [a, b, c] of this.winningConditions) {
23
+ if (this.board[a] && this.board[a] === this.board[b] && this.board[b] === this.board[c]) {
24
+ this.winner = this.currentPlayer
25
+ return true
26
+ }
27
+ }
28
+ return false
29
+ },
30
+ checkDraw() {
31
+ if (!this.board.includes('')) {
32
+ this.isDraw = true
33
+ return true
34
+ }
35
+ return false
36
+ },
37
+ makeMove(index) {
38
+ if (this.board[index] !== '' || this.winner || this.isDraw) {
39
+ return
40
+ }
41
+
42
+ this.board[index] = this.currentPlayer
43
+
44
+ if (this.checkWin()) {
45
+ return
46
+ }
47
+
48
+ if (this.checkDraw()) {
49
+ return
50
+ }
51
+
52
+ this.currentPlayer = this.currentPlayer === 'X' ? 'O' : 'X'
53
+ },
54
+ resetBoard() {
55
+ this.board = Array(9).fill('')
56
+ this.currentPlayer = 'X'
57
+ this.winner = null
58
+ this.isDraw = false
59
+ }
60
+ }
61
+ })
@@ -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>Vue Whack A Mole</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,19 @@
1
+ {
2
+ "name": "vue-game-whackamole",
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
+ },
15
+ "devDependencies": {
16
+ "@vitejs/plugin-vue": "^5.2.1",
17
+ "vite": "^6.0.0"
18
+ }
19
+ }
@@ -0,0 +1,104 @@
1
+ <template>
2
+ <div class="game-container">
3
+ <h1>Vue Whack A Mole</h1>
4
+
5
+ <div class="status-bar">
6
+ <span>Score: {{ store.score }}</span>
7
+ <span>Time Left: {{ store.timeLeft }}s</span>
8
+ </div>
9
+
10
+ <button class="start-btn" :disabled="store.isPlaying" @click="store.startGame()">
11
+ Start Game
12
+ </button>
13
+
14
+ <div class="grid">
15
+ <div
16
+ v-for="i in 9"
17
+ :key="i - 1"
18
+ class="hole"
19
+ @click="store.whackMole(i - 1)"
20
+ >
21
+ <span v-if="store.activeHoleIndex === i - 1" class="mole">🐹</span>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ </template>
26
+
27
+ <script setup>
28
+ import { useMoleStore } from './stores/moleStore'
29
+
30
+ const store = useMoleStore()
31
+ </script>
32
+
33
+ <style>
34
+ body {
35
+ margin: 0;
36
+ font-family: sans-serif;
37
+ display: flex;
38
+ justify-content: center;
39
+ align-items: center;
40
+ min-height: 100vh;
41
+ background-color: #f0f2f5;
42
+ }
43
+
44
+ .game-container {
45
+ text-align: center;
46
+ background: #ffffff;
47
+ padding: 24px;
48
+ border-radius: 12px;
49
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
50
+ width: 320px;
51
+ }
52
+
53
+ h1 {
54
+ margin-top: 0;
55
+ margin-bottom: 16px;
56
+ font-size: 24px;
57
+ }
58
+
59
+ .status-bar {
60
+ display: flex;
61
+ justify-content: space-between;
62
+ margin-bottom: 16px;
63
+ font-size: 16px;
64
+ font-weight: bold;
65
+ }
66
+
67
+ .start-btn {
68
+ padding: 10px 20px;
69
+ font-size: 16px;
70
+ background-color: #42b883;
71
+ color: white;
72
+ border: none;
73
+ border-radius: 6px;
74
+ cursor: pointer;
75
+ margin-bottom: 20px;
76
+ }
77
+
78
+ .start-btn:disabled {
79
+ background-color: #a8d5c2;
80
+ cursor: not-allowed;
81
+ }
82
+
83
+ .grid {
84
+ display: grid;
85
+ grid-template-columns: repeat(3, 1fr);
86
+ gap: 12px;
87
+ }
88
+
89
+ .hole {
90
+ width: 80px;
91
+ height: 80px;
92
+ background-color: #795548;
93
+ border-radius: 50%;
94
+ display: flex;
95
+ justify-content: center;
96
+ align-items: center;
97
+ cursor: pointer;
98
+ user-select: none;
99
+ }
100
+
101
+ .mole {
102
+ font-size: 40px;
103
+ }
104
+ </style>
@@ -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
+ })