wad-lab 1.2.2 → 1.2.4

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 (207) hide show
  1. package/bin/index.js +477 -627
  2. package/package.json +1 -1
  3. package/templates/fullstack-springboot-vue/frontend/vue-axios-basic/src/App.vue +241 -429
  4. package/templates/fullstack-springboot-vue/frontend/vue-axios-basic/src/components/ItemFormModal.vue +183 -0
  5. package/templates/fullstack-springboot-vue/frontend/vue-axios-basic/src/components/ItemPatchModal.vue +193 -0
  6. package/templates/fullstack-springboot-vue/frontend/vue-axios-basic/src/components/ItemTable.vue +177 -0
  7. package/templates/fullstack-springboot-vue/frontend/vue-axios-pinia/src/App.vue +150 -441
  8. package/templates/fullstack-springboot-vue/frontend/vue-axios-pinia/src/components/ItemFormModal.vue +207 -0
  9. package/templates/fullstack-springboot-vue/frontend/vue-axios-pinia/src/components/ItemStats.vue +64 -0
  10. package/templates/fullstack-springboot-vue/frontend/vue-axios-pinia/src/components/ItemTable.vue +195 -0
  11. package/templates/fullstack-springboot-vue/frontend/vue-axios-router/src/App.vue +41 -90
  12. package/templates/fullstack-springboot-vue/frontend/vue-axios-router/src/components/ItemFormModal.vue +173 -0
  13. package/templates/fullstack-springboot-vue/frontend/vue-axios-router/src/components/ItemTable.vue +102 -0
  14. package/templates/fullstack-springboot-vue/frontend/vue-axios-router/src/components/NavBar.vue +57 -0
  15. package/templates/fullstack-springboot-vue/frontend/vue-axios-router/src/views/DepartmentView.vue +132 -296
  16. package/templates/fullstack-springboot-vue/frontend/vue-axios-router/src/views/EmployeeView.vue +126 -219
  17. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-children/src/components/ItemDetail.vue +115 -0
  18. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-children/src/components/ItemTable.vue +104 -0
  19. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-children/src/components/SideBar.vue +59 -0
  20. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-children/src/views/CompanyLayout.vue +2 -51
  21. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-children/src/views/DepartmentListView.vue +92 -250
  22. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-children/src/views/EmployeeDetailView.vue +59 -181
  23. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-children/src/views/EmployeeListView.vue +67 -315
  24. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-pinia/src/App.vue +19 -70
  25. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-pinia/src/components/ItemFormModal.vue +173 -0
  26. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-pinia/src/components/ItemPatchModal.vue +144 -0
  27. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-pinia/src/components/ItemTable.vue +102 -0
  28. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-pinia/src/components/NavBar.vue +53 -0
  29. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-pinia/src/views/DepartmentView.vue +107 -229
  30. package/templates/fullstack-springboot-vue/frontend/vue-axios-router-pinia/src/views/EmployeeView.vue +143 -257
  31. package/templates/game-bingo/script.js +1 -1
  32. package/templates/game-memory-cards/script.js +2 -2
  33. package/templates/game-rock-paper-scissors/index.html +3 -3
  34. package/templates/game-rock-paper-scissors/script.js +2 -2
  35. package/templates/game-tic-tac-toe/script.js +2 -2
  36. package/templates/game-whack-a-mole/index.html +9 -9
  37. package/templates/servlet-basic/WEB-INF/ItemServlet.java +13 -0
  38. package/templates/servlet-basic/WEB-INF/classes/ItemServlet.class +0 -0
  39. package/templates/servlet-flow/WEB-INF/HelloServlet.java +34 -25
  40. package/templates/servlet-flow/WEB-INF/classes/HelloServlet.class +0 -0
  41. package/templates/servlet-jdbc/WEB-INF/JdbcItemServlet.java +13 -0
  42. package/templates/servlet-jdbc/WEB-INF/classes/JdbcItemServlet.class +0 -0
  43. package/templates/snippets/mongo-queries-cheatsheet.txt +105 -0
  44. package/templates/springboot-2model-aggregation-join/.mvn/wrapper/maven-wrapper.properties +3 -0
  45. package/templates/springboot-2model-aggregation-join/mvnw +295 -0
  46. package/templates/springboot-2model-aggregation-join/mvnw.cmd +189 -0
  47. package/templates/springboot-2model-aggregation-join/pom.xml +54 -0
  48. package/templates/springboot-2model-aggregation-join/src/main/java/com/example/aggregation/AggregationApplication.java +11 -0
  49. package/templates/springboot-2model-aggregation-join/src/main/java/com/example/aggregation/controller/DepartmentController.java +65 -0
  50. package/templates/springboot-2model-aggregation-join/src/main/java/com/example/aggregation/controller/EmployeeController.java +65 -0
  51. package/templates/springboot-2model-aggregation-join/src/main/java/com/example/aggregation/dto/DepartmentStatsDTO.java +15 -0
  52. package/templates/springboot-2model-aggregation-join/src/main/java/com/example/aggregation/dto/EmployeeJoinDTO.java +19 -0
  53. package/templates/springboot-2model-aggregation-join/src/main/java/com/example/aggregation/model/Department.java +20 -0
  54. package/templates/springboot-2model-aggregation-join/src/main/java/com/example/aggregation/model/Employee.java +21 -0
  55. package/templates/springboot-2model-aggregation-join/src/main/java/com/example/aggregation/repository/DepartmentRepository.java +9 -0
  56. package/templates/springboot-2model-aggregation-join/src/main/java/com/example/aggregation/repository/EmployeeRepository.java +9 -0
  57. package/templates/springboot-2model-aggregation-join/src/main/java/com/example/aggregation/service/DepartmentService.java +81 -0
  58. package/templates/springboot-2model-aggregation-join/src/main/java/com/example/aggregation/service/EmployeeService.java +80 -0
  59. package/templates/springboot-2model-aggregation-join/src/main/resources/application.properties +2 -0
  60. package/templates/springboot-2model-aggregation-join/src/test/java/com/example/aggregation/AggregationApplicationTests.java +13 -0
  61. package/templates/vue-2model-crud-patch/README.md +64 -0
  62. package/templates/vue-2model-crud-patch/index.html +12 -0
  63. package/templates/vue-2model-crud-patch/package-lock.json +1785 -0
  64. package/templates/vue-2model-crud-patch/package.json +21 -0
  65. package/templates/vue-2model-crud-patch/src/App.vue +63 -0
  66. package/templates/vue-2model-crud-patch/src/components/AnalyticsBoard.vue +291 -0
  67. package/templates/vue-2model-crud-patch/src/components/DepartmentFormModal.vue +138 -0
  68. package/templates/vue-2model-crud-patch/src/components/DepartmentPatchModal.vue +210 -0
  69. package/templates/vue-2model-crud-patch/src/components/DepartmentTable.vue +133 -0
  70. package/templates/vue-2model-crud-patch/src/components/EmployeeFormModal.vue +177 -0
  71. package/templates/vue-2model-crud-patch/src/components/EmployeePatchModal.vue +221 -0
  72. package/templates/vue-2model-crud-patch/src/components/EmployeeTable.vue +171 -0
  73. package/templates/vue-2model-crud-patch/src/components/NavBar.vue +156 -0
  74. package/templates/vue-2model-crud-patch/src/main.js +12 -0
  75. package/templates/vue-2model-crud-patch/src/router/index.js +33 -0
  76. package/templates/vue-2model-crud-patch/src/services/api.js +64 -0
  77. package/templates/vue-2model-crud-patch/src/stores/departmentStore.js +149 -0
  78. package/templates/vue-2model-crud-patch/src/stores/employeeStore.js +143 -0
  79. package/templates/vue-2model-crud-patch/src/style.css +415 -0
  80. package/templates/vue-2model-crud-patch/src/views/AnalyticsView.vue +59 -0
  81. package/templates/vue-2model-crud-patch/src/views/DepartmentsView.vue +135 -0
  82. package/templates/vue-2model-crud-patch/src/views/EmployeesView.vue +143 -0
  83. package/templates/vue-2model-crud-patch/vite.config.js +9 -0
  84. package/templates/vue-axios/src/App.vue +255 -264
  85. package/templates/vue-axios/src/components/ItemFormModal.vue +183 -0
  86. package/templates/vue-axios/src/components/ItemPatchModal.vue +193 -0
  87. package/templates/vue-axios/src/components/ItemTable.vue +177 -0
  88. package/templates/vue-axios-basic/src/App.vue +241 -429
  89. package/templates/vue-axios-basic/src/components/ItemFormModal.vue +183 -0
  90. package/templates/vue-axios-basic/src/components/ItemPatchModal.vue +193 -0
  91. package/templates/vue-axios-basic/src/components/ItemTable.vue +177 -0
  92. package/templates/vue-axios-pinia/src/App.vue +150 -441
  93. package/templates/vue-axios-pinia/src/components/ItemFormModal.vue +207 -0
  94. package/templates/vue-axios-pinia/src/components/ItemStats.vue +64 -0
  95. package/templates/vue-axios-pinia/src/components/ItemTable.vue +195 -0
  96. package/templates/vue-axios-router/src/App.vue +41 -90
  97. package/templates/vue-axios-router/src/components/ItemFormModal.vue +173 -0
  98. package/templates/vue-axios-router/src/components/ItemTable.vue +102 -0
  99. package/templates/vue-axios-router/src/components/NavBar.vue +57 -0
  100. package/templates/vue-axios-router/src/views/DepartmentView.vue +132 -296
  101. package/templates/vue-axios-router/src/views/EmployeeView.vue +126 -219
  102. package/templates/vue-axios-router-children/src/components/ItemDetail.vue +115 -0
  103. package/templates/vue-axios-router-children/src/components/ItemTable.vue +104 -0
  104. package/templates/vue-axios-router-children/src/components/SideBar.vue +59 -0
  105. package/templates/vue-axios-router-children/src/views/CompanyLayout.vue +2 -51
  106. package/templates/vue-axios-router-children/src/views/DepartmentListView.vue +92 -250
  107. package/templates/vue-axios-router-children/src/views/EmployeeDetailView.vue +59 -181
  108. package/templates/vue-axios-router-children/src/views/EmployeeListView.vue +67 -315
  109. package/templates/vue-axios-router-pinia/src/App.vue +19 -70
  110. package/templates/vue-axios-router-pinia/src/components/ItemFormModal.vue +173 -0
  111. package/templates/vue-axios-router-pinia/src/components/ItemPatchModal.vue +144 -0
  112. package/templates/vue-axios-router-pinia/src/components/ItemTable.vue +102 -0
  113. package/templates/vue-axios-router-pinia/src/components/NavBar.vue +53 -0
  114. package/templates/vue-axios-router-pinia/src/views/DepartmentView.vue +107 -229
  115. package/templates/vue-axios-router-pinia/src/views/EmployeeView.vue +143 -257
  116. package/templates/vue-banking-app/src/components/AccountOverview.vue +75 -0
  117. package/templates/vue-banking-app/src/components/TransactionForm.vue +89 -0
  118. package/templates/vue-banking-app/src/components/TransactionTable.vue +113 -0
  119. package/templates/vue-banking-app/src/stores/bankStore.js +16 -3
  120. package/templates/vue-banking-app/src/views/DashboardView.vue +23 -71
  121. package/templates/vue-banking-app/src/views/StatementView.vue +11 -158
  122. package/templates/vue-banking-app/src/views/TransactionFormView.vue +23 -121
  123. package/templates/vue-basics/src/App.vue +105 -76
  124. package/templates/vue-basics/src/components/CounterCard.vue +107 -0
  125. package/templates/vue-basics/src/components/ItemList.vue +99 -0
  126. package/templates/vue-basics/src/components/UserForm.vue +138 -0
  127. package/templates/vue-cart-router-pinia/src/components/CartSummary.vue +139 -0
  128. package/templates/vue-cart-router-pinia/src/components/CheckoutModal.vue +149 -0
  129. package/templates/vue-cart-router-pinia/src/components/ProductCard.vue +63 -0
  130. package/templates/vue-cart-router-pinia/src/stores/cartStore.js +11 -0
  131. package/templates/vue-cart-router-pinia/src/views/CartView.vue +52 -118
  132. package/templates/vue-cart-router-pinia/src/views/CheckoutView.vue +2 -5
  133. package/templates/vue-cart-router-pinia/src/views/ProductCatalogView.vue +20 -56
  134. package/templates/vue-employee-system/src/App.vue +75 -344
  135. package/templates/vue-employee-system/src/components/DepartmentFilter.vue +108 -0
  136. package/templates/vue-employee-system/src/components/EmployeeModal.vue +183 -0
  137. package/templates/vue-employee-system/src/components/EmployeeTable.vue +91 -0
  138. package/templates/vue-employee-system/src/stores/employeeStore.js +12 -0
  139. package/templates/vue-fetch/src/App.vue +261 -285
  140. package/templates/vue-fetch/src/components/FetchFormModal.vue +183 -0
  141. package/templates/vue-fetch/src/components/FetchPatchModal.vue +193 -0
  142. package/templates/vue-fetch/src/components/FetchTable.vue +177 -0
  143. package/templates/vue-food-ordering/src/components/CartSummary.vue +134 -0
  144. package/templates/vue-food-ordering/src/components/FoodMenu.vue +126 -0
  145. package/templates/vue-food-ordering/src/components/OrderModal.vue +150 -0
  146. package/templates/vue-food-ordering/src/views/MenuView.vue +11 -132
  147. package/templates/vue-food-ordering/src/views/OrderCartView.vue +31 -164
  148. package/templates/vue-game-rps/src/App.vue +29 -88
  149. package/templates/vue-game-tictactoe/src/App.vue +23 -53
  150. package/templates/vue-game-whackamole/src/App.vue +44 -63
  151. package/templates/vue-hospital-portal/src/components/AppointmentForm.vue +144 -0
  152. package/templates/vue-hospital-portal/src/components/DoctorCard.vue +73 -0
  153. package/templates/vue-hospital-portal/src/components/PatientTable.vue +123 -0
  154. package/templates/vue-hospital-portal/src/stores/hospitalStore.js +10 -1
  155. package/templates/vue-hospital-portal/src/views/OPDRegistrationView.vue +40 -416
  156. package/templates/vue-hospital-portal/src/views/PatientListView.vue +11 -301
  157. package/templates/vue-library-system/src/components/BookForm.vue +125 -0
  158. package/templates/vue-library-system/src/components/BookTable.vue +112 -0
  159. package/templates/vue-library-system/src/components/BorrowModal.vue +131 -0
  160. package/templates/vue-library-system/src/stores/libraryStore.js +26 -1
  161. package/templates/vue-library-system/src/views/BookCatalogView.vue +34 -415
  162. package/templates/vue-memory-game/src/App.vue +36 -40
  163. package/templates/vue-memory-game/src/stores/memoryStore.js +32 -37
  164. package/templates/vue-router/src/App.vue +24 -14
  165. package/templates/vue-router/src/components/AboutCard.vue +38 -0
  166. package/templates/vue-router/src/components/HomeHero.vue +75 -0
  167. package/templates/vue-router/src/components/NavBar.vue +54 -0
  168. package/templates/vue-router/src/views/ItemsLayout.vue +17 -9
  169. package/templates/vue-router/src/views/ListView.vue +106 -18
  170. package/templates/vue-router-pinia/src/App.vue +24 -14
  171. package/templates/vue-router-pinia/src/components/ItemFormModal.vue +163 -0
  172. package/templates/vue-router-pinia/src/components/ItemTable.vue +90 -0
  173. package/templates/vue-router-pinia/src/components/NavBar.vue +54 -0
  174. package/templates/vue-router-pinia/src/stores/itemStore.js +8 -1
  175. package/templates/vue-router-pinia/src/views/ListView.vue +78 -14
  176. package/templates/vue-router-pinia-springboot/frontend/src/App.vue +25 -8
  177. package/templates/vue-router-pinia-springboot/frontend/src/components/ItemFormModal.vue +183 -0
  178. package/templates/vue-router-pinia-springboot/frontend/src/components/ItemPatchModal.vue +193 -0
  179. package/templates/vue-router-pinia-springboot/frontend/src/components/ItemTable.vue +177 -0
  180. package/templates/vue-router-pinia-springboot/frontend/src/components/NavBar.vue +54 -0
  181. package/templates/vue-router-pinia-springboot/frontend/src/views/ListView.vue +92 -76
  182. package/templates/vue-springboot-mongo-aggregation/frontend/src/App.vue +184 -193
  183. package/templates/vue-springboot-mongo-aggregation/frontend/src/components/AnalyticsCards.vue +56 -0
  184. package/templates/vue-springboot-mongo-aggregation/frontend/src/components/CategorySummaryTable.vue +71 -0
  185. package/templates/vue-springboot-mongo-aggregation/frontend/src/components/ItemTable.vue +114 -0
  186. package/templates/vue-springboot-mongo-crud/frontend/src/App.vue +228 -158
  187. package/templates/vue-springboot-mongo-crud/frontend/src/components/ItemFormModal.vue +183 -0
  188. package/templates/vue-springboot-mongo-crud/frontend/src/components/ItemPatchModal.vue +193 -0
  189. package/templates/vue-springboot-mongo-crud/frontend/src/components/ItemTable.vue +177 -0
  190. package/templates/vue-symposium-system/src/App.vue +41 -256
  191. package/templates/vue-symposium-system/src/components/AttendeeTable.vue +100 -0
  192. package/templates/vue-symposium-system/src/components/EventCard.vue +67 -0
  193. package/templates/vue-symposium-system/src/components/RegistrationForm.vue +118 -0
  194. package/templates/vue-symposium-system/src/stores/symposiumStore.js +10 -0
  195. package/templates/vue-todo-pinia/src/App.vue +40 -138
  196. package/templates/vue-todo-pinia/src/components/TodoFilter.vue +74 -0
  197. package/templates/vue-todo-pinia/src/components/TodoInput.vue +53 -0
  198. package/templates/vue-todo-pinia/src/components/TodoList.vue +101 -0
  199. package/templates/vue-todo-pinia/src/stores/todoStore.js +6 -0
  200. package/templates/vue-todo-router/src/App.vue +5 -36
  201. package/templates/vue-todo-router/src/components/TodoForm.vue +78 -0
  202. package/templates/vue-todo-router/src/components/TodoList.vue +84 -0
  203. package/templates/vue-todo-router/src/components/TodoNavBar.vue +47 -0
  204. package/templates/vue-todo-router/src/data/todoState.js +7 -0
  205. package/templates/vue-todo-router/src/views/AddTodoView.vue +7 -66
  206. package/templates/vue-todo-router/src/views/TodoDetailView.vue +15 -1
  207. package/templates/vue-todo-router/src/views/TodoListView.vue +22 -64
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wad-lab",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "Interactive CLI for WAD Lab starter templates compatible with Node 12+",
5
5
  "bin": {
6
6
  "wad-lab": "bin/index.js"
@@ -1,429 +1,241 @@
1
- <template>
2
- <div class="container">
3
- <header class="header">
4
- <h1>Company Directory</h1>
5
- <p>Vue 3 + Axios Direct CRUD</p>
6
- </header>
7
-
8
- <div class="grid">
9
- <section class="card">
10
- <h2>Departments</h2>
11
-
12
- <form @submit.prevent="createDepartment" class="form">
13
- <div class="form-group">
14
- <label for="dept-name">Department Name</label>
15
- <input
16
- id="dept-name"
17
- v-model="deptForm.name"
18
- type="text"
19
- required
20
- placeholder="e.g. Engineering"
21
- />
22
- </div>
23
- <div class="form-group">
24
- <label for="dept-code">Department Code</label>
25
- <input
26
- id="dept-code"
27
- v-model="deptForm.code"
28
- type="text"
29
- required
30
- placeholder="e.g. ENG"
31
- />
32
- </div>
33
- <button type="submit" class="btn btn-primary">Add Department</button>
34
- </form>
35
-
36
- <div class="table-wrapper">
37
- <table>
38
- <thead>
39
- <tr>
40
- <th>ID</th>
41
- <th>Name</th>
42
- <th>Code</th>
43
- <th>Action</th>
44
- </tr>
45
- </thead>
46
- <tbody>
47
- <tr v-if="departments.length === 0">
48
- <td colspan="4" class="empty">No departments found</td>
49
- </tr>
50
- <tr v-for="dept in departments" :key="dept.id">
51
- <td>{{ dept.id }}</td>
52
- <td>{{ dept.name }}</td>
53
- <td><code>{{ dept.code }}</code></td>
54
- <td>
55
- <button @click="patchDepartment(dept.id, dept.code)" class="btn">Patch</button>
56
- <button @click="deleteDepartment(dept.id)" class="btn btn-danger">Delete</button>
57
- </td>
58
- </tr>
59
- </tbody>
60
- </table>
61
- </div>
62
- </section>
63
-
64
- <section class="card">
65
- <h2>Employees</h2>
66
-
67
- <form @submit.prevent="createEmployee" class="form">
68
- <div class="form-group">
69
- <label for="emp-name">Full Name</label>
70
- <input
71
- id="emp-name"
72
- v-model="empForm.name"
73
- type="text"
74
- required
75
- placeholder="e.g. Jane Doe"
76
- />
77
- </div>
78
- <div class="form-group">
79
- <label for="emp-email">Email Address</label>
80
- <input
81
- id="emp-email"
82
- v-model="empForm.email"
83
- type="email"
84
- required
85
- placeholder="e.g. jane@example.com"
86
- />
87
- </div>
88
- <div class="form-group">
89
- <label for="emp-dept">Department</label>
90
- <select id="emp-dept" v-model="empForm.departmentId" required>
91
- <option value="" disabled>Select Department</option>
92
- <option v-for="dept in departments" :key="dept.id" :value="dept.id">
93
- {{ dept.name }} ({{ dept.code }})
94
- </option>
95
- </select>
96
- </div>
97
- <div class="form-group">
98
- <label for="emp-salary">Salary</label>
99
- <input
100
- id="emp-salary"
101
- v-model.number="empForm.salary"
102
- type="number"
103
- min="0"
104
- step="any"
105
- required
106
- placeholder="e.g. 75000"
107
- />
108
- </div>
109
- <button type="submit" class="btn btn-primary">Add Employee</button>
110
- </form>
111
-
112
- <div class="table-wrapper">
113
- <table>
114
- <thead>
115
- <tr>
116
- <th>ID</th>
117
- <th>Name</th>
118
- <th>Email</th>
119
- <th>Department</th>
120
- <th>Salary</th>
121
- <th>Action</th>
122
- </tr>
123
- </thead>
124
- <tbody>
125
- <tr v-if="employees.length === 0">
126
- <td colspan="6" class="empty">No employees found</td>
127
- </tr>
128
- <tr v-for="emp in employees" :key="emp.id">
129
- <td>{{ emp.id }}</td>
130
- <td>{{ emp.name }}</td>
131
- <td>{{ emp.email }}</td>
132
- <td>{{ getDepartmentName(emp.departmentId) }}</td>
133
- <td>${{ Number(emp.salary).toLocaleString() }}</td>
134
- <td>
135
- <button @click="patchEmployeeSalary(emp.id, emp.salary)" class="btn">Patch</button>
136
- <button @click="deleteEmployee(emp.id)" class="btn btn-danger">Delete</button>
137
- </td>
138
- </tr>
139
- </tbody>
140
- </table>
141
- </div>
142
- </section>
143
- </div>
144
- </div>
145
- </template>
146
-
147
- <script setup>
148
- import { ref, reactive, onMounted } from 'vue'
149
- import api from './services/api'
150
-
151
- const departments = ref([])
152
- const employees = ref([])
153
-
154
- const deptForm = reactive({
155
- name: '',
156
- code: ''
157
- })
158
-
159
- const empForm = reactive({
160
- name: '',
161
- email: '',
162
- departmentId: '',
163
- salary: ''
164
- })
165
-
166
- const fetchDepartments = async () => {
167
- try {
168
- const response = await api.get('/departments')
169
- departments.value = response.data
170
- } catch (error) {
171
- console.error(error)
172
- }
173
- }
174
-
175
- const fetchEmployees = async () => {
176
- try {
177
- const response = await api.get('/employees')
178
- employees.value = response.data
179
- } catch (error) {
180
- console.error(error)
181
- }
182
- }
183
-
184
- const createDepartment = async () => {
185
- try {
186
- await api.post('/departments', {
187
- name: deptForm.name,
188
- code: deptForm.code
189
- })
190
- deptForm.name = ''
191
- deptForm.code = ''
192
- await fetchDepartments()
193
- } catch (error) {
194
- console.error(error)
195
- }
196
- }
197
-
198
- const deleteDepartment = async (id) => {
199
- try {
200
- await api.delete(`/departments/${id}`)
201
- await fetchDepartments()
202
- await fetchEmployees()
203
- } catch (error) {
204
- console.error(error)
205
- }
206
- }
207
-
208
- const createEmployee = async () => {
209
- try {
210
- await api.post('/employees', {
211
- name: empForm.name,
212
- email: empForm.email,
213
- departmentId: Number(empForm.departmentId),
214
- salary: Number(empForm.salary)
215
- })
216
- empForm.name = ''
217
- empForm.email = ''
218
- empForm.departmentId = ''
219
- empForm.salary = ''
220
- await fetchEmployees()
221
- } catch (error) {
222
- console.error(error)
223
- }
224
- }
225
-
226
- const deleteEmployee = async (id) => {
227
- try {
228
- await api.delete(`/employees/${id}`)
229
- await fetchEmployees()
230
- } catch (error) {
231
- console.error(error)
232
- }
233
- }
234
-
235
- const patchDepartment = async (id, currentCode) => {
236
- const code = prompt('Enter new department code:', currentCode)
237
- if (!code || code === currentCode) return
238
- try {
239
- await api.patch(`/departments/${id}`, { code })
240
- await fetchDepartments()
241
- } catch (error) {
242
- console.error(error)
243
- }
244
- }
245
-
246
- const patchEmployeeSalary = async (id, currentSalary) => {
247
- const salary = prompt('Enter new salary:', currentSalary)
248
- if (!salary || Number(salary) === Number(currentSalary)) return
249
- try {
250
- await api.patch(`/employees/${id}`, { salary: Number(salary) })
251
- await fetchEmployees()
252
- } catch (error) {
253
- console.error(error)
254
- }
255
- }
256
-
257
- const getDepartmentName = (deptId) => {
258
- const dept = departments.value.find((d) => d.id === deptId)
259
- return dept ? dept.name : `Dept #${deptId}`
260
- }
261
-
262
- onMounted(() => {
263
- fetchDepartments()
264
- fetchEmployees()
265
- })
266
- </script>
267
-
268
- <style>
269
- * {
270
- box-sizing: border-box;
271
- margin: 0;
272
- padding: 0;
273
- }
274
-
275
- body {
276
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
277
- background-color: #f4f5f7;
278
- color: #333333;
279
- line-height: 1.5;
280
- }
281
-
282
- .container {
283
- max-width: 1200px;
284
- margin: 0 auto;
285
- padding: 32px 16px;
286
- }
287
-
288
- .header {
289
- margin-bottom: 24px;
290
- }
291
-
292
- .header h1 {
293
- font-size: 28px;
294
- color: #1a1a1a;
295
- }
296
-
297
- .header p {
298
- color: #666666;
299
- font-size: 14px;
300
- }
301
-
302
- .grid {
303
- display: grid;
304
- grid-template-columns: 1fr;
305
- gap: 24px;
306
- }
307
-
308
- @media (min-width: 900px) {
309
- .grid {
310
- grid-template-columns: 1fr 1fr;
311
- }
312
- }
313
-
314
- .card {
315
- background: #ffffff;
316
- border: 1px solid #e1e4e8;
317
- border-radius: 8px;
318
- padding: 20px;
319
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
320
- }
321
-
322
- .card h2 {
323
- font-size: 20px;
324
- margin-bottom: 16px;
325
- color: #222222;
326
- border-bottom: 1px solid #edf0f2;
327
- padding-bottom: 8px;
328
- }
329
-
330
- .form {
331
- display: flex;
332
- flex-direction: column;
333
- gap: 12px;
334
- margin-bottom: 20px;
335
- }
336
-
337
- .form-group {
338
- display: flex;
339
- flex-direction: column;
340
- gap: 4px;
341
- }
342
-
343
- .form-group label {
344
- font-size: 13px;
345
- font-weight: 600;
346
- color: #444444;
347
- }
348
-
349
- .form-group input,
350
- .form-group select {
351
- padding: 8px 10px;
352
- border: 1px solid #cccccc;
353
- border-radius: 4px;
354
- font-size: 14px;
355
- background-color: #ffffff;
356
- }
357
-
358
- .form-group input:focus,
359
- .form-group select:focus {
360
- outline: none;
361
- border-color: #0066cc;
362
- }
363
-
364
- .btn {
365
- padding: 8px 14px;
366
- border: none;
367
- border-radius: 4px;
368
- cursor: pointer;
369
- font-size: 13px;
370
- font-weight: 600;
371
- transition: background-color 0.15s ease;
372
- }
373
-
374
- .btn-primary {
375
- background-color: #0066cc;
376
- color: #ffffff;
377
- }
378
-
379
- .btn-primary:hover {
380
- background-color: #0052a3;
381
- }
382
-
383
- .btn-danger {
384
- background-color: #d9383a;
385
- color: #ffffff;
386
- padding: 4px 8px;
387
- font-size: 12px;
388
- }
389
-
390
- .btn-danger:hover {
391
- background-color: #b8282a;
392
- }
393
-
394
- .table-wrapper {
395
- overflow-x: auto;
396
- }
397
-
398
- table {
399
- width: 100%;
400
- border-collapse: collapse;
401
- font-size: 13px;
402
- margin-top: 8px;
403
- }
404
-
405
- th, td {
406
- text-align: left;
407
- padding: 8px 10px;
408
- border-bottom: 1px solid #eeeeee;
409
- }
410
-
411
- th {
412
- background-color: #fafbfc;
413
- color: #555555;
414
- font-weight: 600;
415
- }
416
-
417
- code {
418
- background: #f0f0f0;
419
- padding: 2px 4px;
420
- border-radius: 3px;
421
- font-size: 12px;
422
- }
423
-
424
- .empty {
425
- text-align: center;
426
- color: #888888;
427
- padding: 16px;
428
- }
429
- </style>
1
+ <script setup>
2
+ import { ref, onMounted } from 'vue'
3
+ import api from './services/api'
4
+ import ItemTable from './components/ItemTable.vue'
5
+ import ItemFormModal from './components/ItemFormModal.vue'
6
+ import ItemPatchModal from './components/ItemPatchModal.vue'
7
+
8
+ const items = ref([])
9
+ const loading = ref(false)
10
+ const errorMessage = ref('')
11
+ const selectedItem = ref(null)
12
+
13
+ const isFormModalOpen = ref(false)
14
+ const isEditMode = ref(false)
15
+ const activeItemData = ref(null)
16
+
17
+ const isPatchModalOpen = ref(false)
18
+ const activePatchItem = ref(null)
19
+
20
+ async function fetchAll() {
21
+ loading.value = true
22
+ errorMessage.value = ''
23
+ try {
24
+ const res = await api.get('/items')
25
+ items.value = res.data || []
26
+ } catch (err) {
27
+ errorMessage.value = err.message || 'Failed to fetch items'
28
+ } finally {
29
+ loading.value = false
30
+ }
31
+ }
32
+
33
+ function openCreateModal() {
34
+ isEditMode.value = false
35
+ activeItemData.value = { name: '', description: '', price: 0 }
36
+ isFormModalOpen.value = true
37
+ }
38
+
39
+ function openEditModal(item) {
40
+ isEditMode.value = true
41
+ activeItemData.value = { ...item }
42
+ isFormModalOpen.value = true
43
+ }
44
+
45
+ function openPatchModal(item) {
46
+ activePatchItem.value = item
47
+ isPatchModalOpen.value = true
48
+ }
49
+
50
+ async function handleFormSubmit(payload) {
51
+ loading.value = true
52
+ errorMessage.value = ''
53
+ try {
54
+ if (isEditMode.value) {
55
+ await api.put('/items/' + payload.id, payload)
56
+ } else {
57
+ await api.post('/items', payload)
58
+ }
59
+ isFormModalOpen.value = false
60
+ await fetchAll()
61
+ } catch (err) {
62
+ errorMessage.value = err.message || 'Failed to save item'
63
+ } finally {
64
+ loading.value = false
65
+ }
66
+ }
67
+
68
+ async function handlePatchSubmit({ id, partial }) {
69
+ loading.value = true
70
+ errorMessage.value = ''
71
+ try {
72
+ await api.patch('/items/' + id, partial)
73
+ isPatchModalOpen.value = false
74
+ await fetchAll()
75
+ } catch (err) {
76
+ errorMessage.value = err.message || 'Failed to patch item'
77
+ } finally {
78
+ loading.value = false
79
+ }
80
+ }
81
+
82
+ async function handleDelete(id) {
83
+ if (!confirm('Are you sure you want to delete this item?')) return
84
+ loading.value = true
85
+ errorMessage.value = ''
86
+ try {
87
+ await api.delete('/items/' + id)
88
+ if (selectedItem.value && selectedItem.value.id === id) {
89
+ selectedItem.value = null
90
+ }
91
+ await fetchAll()
92
+ } catch (err) {
93
+ errorMessage.value = err.message || 'Failed to delete item'
94
+ } finally {
95
+ loading.value = false
96
+ }
97
+ }
98
+
99
+ function handleViewDetails(item) {
100
+ selectedItem.value = item
101
+ }
102
+
103
+ onMounted(() => {
104
+ fetchAll()
105
+ })
106
+ </script>
107
+
108
+ <template>
109
+ <div class="app-container">
110
+ <header class="app-header">
111
+ <h1>Vue 3 Axios Basic CRUD</h1>
112
+ <p>Direct Axios with ItemTable, ItemFormModal, ItemPatchModal</p>
113
+ </header>
114
+
115
+ <div v-if="errorMessage" class="error-banner">
116
+ {{ errorMessage }}
117
+ </div>
118
+
119
+ <div v-if="selectedItem" class="detail-card">
120
+ <div class="detail-header">
121
+ <h3>Selected Item</h3>
122
+ <button type="button" class="btn-close" @click="selectedItem = null">Close</button>
123
+ </div>
124
+ <div class="detail-body">
125
+ <p><strong>ID:</strong> {{ selectedItem.id }}</p>
126
+ <p><strong>Name:</strong> {{ selectedItem.name }}</p>
127
+ <p><strong>Description:</strong> {{ selectedItem.description || selectedItem.describtion || 'N/A' }}</p>
128
+ <p><strong>Price:</strong> ${{ Number(selectedItem.price).toFixed(2) }}</p>
129
+ </div>
130
+ </div>
131
+
132
+ <ItemTable
133
+ :items="items"
134
+ :loading="loading"
135
+ @open-create="openCreateModal"
136
+ @edit="openEditModal"
137
+ @patch="openPatchModal"
138
+ @delete="handleDelete"
139
+ @view-details="handleViewDetails"
140
+ @refresh="fetchAll"
141
+ />
142
+
143
+ <ItemFormModal
144
+ :show="isFormModalOpen"
145
+ :is-edit="isEditMode"
146
+ :item-data="activeItemData"
147
+ @close="isFormModalOpen = false"
148
+ @submit="handleFormSubmit"
149
+ />
150
+
151
+ <ItemPatchModal
152
+ :show="isPatchModalOpen"
153
+ :item="activePatchItem"
154
+ @close="isPatchModalOpen = false"
155
+ @submit="handlePatchSubmit"
156
+ />
157
+ </div>
158
+ </template>
159
+
160
+ <style>
161
+ * {
162
+ box-sizing: border-box;
163
+ margin: 0;
164
+ padding: 0;
165
+ }
166
+
167
+ body {
168
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
169
+ background-color: #f4f6f8;
170
+ color: #333333;
171
+ }
172
+ </style>
173
+
174
+ <style scoped>
175
+ .app-container {
176
+ max-width: 1000px;
177
+ margin: 0 auto;
178
+ padding: 32px 16px;
179
+ }
180
+
181
+ .app-header {
182
+ margin-bottom: 24px;
183
+ }
184
+
185
+ .app-header h1 {
186
+ font-size: 26px;
187
+ color: #1a1a1a;
188
+ margin-bottom: 4px;
189
+ }
190
+
191
+ .app-header p {
192
+ color: #666666;
193
+ font-size: 14px;
194
+ }
195
+
196
+ .error-banner {
197
+ background-color: #ffebe9;
198
+ color: #cf222e;
199
+ border: 1px solid #ff818266;
200
+ padding: 12px 16px;
201
+ border-radius: 6px;
202
+ margin-bottom: 20px;
203
+ font-size: 14px;
204
+ }
205
+
206
+ .detail-card {
207
+ background: #ffffff;
208
+ border: 1px solid #d0d7de;
209
+ border-radius: 8px;
210
+ padding: 16px;
211
+ margin-bottom: 20px;
212
+ box-shadow: 0 1px 3px rgba(0,0,0,0.05);
213
+ }
214
+
215
+ .detail-header {
216
+ display: flex;
217
+ justify-content: space-between;
218
+ align-items: center;
219
+ border-bottom: 1px solid #eaecef;
220
+ padding-bottom: 8px;
221
+ margin-bottom: 12px;
222
+ }
223
+
224
+ .detail-header h3 {
225
+ font-size: 16px;
226
+ color: #24292f;
227
+ }
228
+
229
+ .btn-close {
230
+ background: none;
231
+ border: none;
232
+ cursor: pointer;
233
+ color: #57606a;
234
+ font-size: 14px;
235
+ }
236
+
237
+ .detail-body p {
238
+ font-size: 14px;
239
+ margin-bottom: 6px;
240
+ }
241
+ </style>