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
@@ -1,264 +1,255 @@
1
- <script setup>
2
- import { ref, reactive, onMounted } from 'vue'
3
- import ItemService from './services/ItemService'
4
-
5
- const items = ref([])
6
- const loading = ref(false)
7
- const errorMessage = ref('')
8
-
9
- const searchId = ref('')
10
- const selectedItem = ref(null)
11
-
12
- const createForm = reactive({
13
- name: '',
14
- description: '',
15
- price: 0
16
- })
17
-
18
- const editForm = reactive({
19
- id: '',
20
- name: '',
21
- description: '',
22
- price: 0
23
- })
24
-
25
- async function fetchAll() {
26
- loading.value = true
27
- errorMessage.value = ''
28
- try {
29
- const res = await ItemService.getAll()
30
- items.value = res.data
31
- } catch (err) {
32
- errorMessage.value = err.message
33
- } finally {
34
- loading.value = false
35
- }
36
- }
37
-
38
- async function fetchById(id) {
39
- if (!id) return
40
- loading.value = true
41
- errorMessage.value = ''
42
- try {
43
- const res = await ItemService.getOne(id)
44
- selectedItem.value = res.data
45
- } catch (err) {
46
- errorMessage.value = err.message
47
- } finally {
48
- loading.value = false
49
- }
50
- }
51
-
52
- async function createItem() {
53
- if (!createForm.name) return
54
- loading.value = true
55
- errorMessage.value = ''
56
- try {
57
- await ItemService.create({
58
- name: createForm.name,
59
- description: createForm.description,
60
- describtion: createForm.description,
61
- price: Number(createForm.price)
62
- })
63
- createForm.name = ''
64
- createForm.description = ''
65
- createForm.price = 0
66
- await fetchAll()
67
- } catch (err) {
68
- errorMessage.value = err.message
69
- } finally {
70
- loading.value = false
71
- }
72
- }
73
-
74
- async function updateItem() {
75
- if (!editForm.id) return
76
- loading.value = true
77
- errorMessage.value = ''
78
- try {
79
- await ItemService.update(editForm.id, {
80
- id: editForm.id,
81
- name: editForm.name,
82
- description: editForm.description,
83
- describtion: editForm.description,
84
- price: Number(editForm.price)
85
- })
86
- editForm.id = ''
87
- editForm.name = ''
88
- editForm.description = ''
89
- editForm.price = 0
90
- await fetchAll()
91
- } catch (err) {
92
- errorMessage.value = err.message
93
- } finally {
94
- loading.value = false
95
- }
96
- }
97
-
98
- async function deleteItem(id) {
99
- loading.value = true
100
- errorMessage.value = ''
101
- try {
102
- await ItemService.delete(id)
103
- if (selectedItem.value && selectedItem.value.id === id) {
104
- selectedItem.value = null
105
- }
106
- await fetchAll()
107
- } catch (err) {
108
- errorMessage.value = err.message
109
- } finally {
110
- loading.value = false
111
- }
112
- }
113
-
114
- async function patchItem(id, partial) {
115
- loading.value = true
116
- errorMessage.value = ''
117
- try {
118
- await ItemService.patch(id, partial)
119
- await fetchAll()
120
- } catch (err) {
121
- errorMessage.value = err.message
122
- } finally {
123
- loading.value = false
124
- }
125
- }
126
-
127
- function promptPatch(item) {
128
- const newPrice = prompt('Enter new price:')
129
- if (newPrice !== null && newPrice !== '') {
130
- patchItem(item.id, { price: Number(newPrice) })
131
- }
132
- }
133
-
134
- function startEdit(item) {
135
- editForm.id = item.id
136
- editForm.name = item.name
137
- editForm.description = item.description || item.describtion || ''
138
- editForm.price = item.price
139
- }
140
-
141
- function cancelEdit() {
142
- editForm.id = ''
143
- editForm.name = ''
144
- editForm.description = ''
145
- editForm.price = 0
146
- }
147
-
148
- onMounted(() => {
149
- fetchAll()
150
- })
151
- </script>
152
-
153
- <template>
154
- <h2>Vue Axios CRUD</h2>
155
- <br>
156
-
157
- <p v-if="loading">Loading...</p>
158
- <br v-if="loading">
159
-
160
- <p v-if="errorMessage">{{ errorMessage }}</p>
161
- <br v-if="errorMessage">
162
-
163
- <button @click="fetchAll">Refresh All (GET /api/items)</button>
164
- <br><br>
165
- <hr>
166
- <br>
167
-
168
- <h3>Create Item (POST /api/items)</h3>
169
- <br>
170
- <form @submit.prevent="createItem">
171
- <label for="create-name">Name:</label>
172
- <br>
173
- <input id="create-name" v-model="createForm.name" placeholder="Item Name" required>
174
- <br><br>
175
-
176
- <label for="create-desc">Description:</label>
177
- <br>
178
- <input id="create-desc" v-model="createForm.description" placeholder="Item Description" required>
179
- <br><br>
180
-
181
- <label for="create-price">Price:</label>
182
- <br>
183
- <input id="create-price" v-model.number="createForm.price" type="number" placeholder="Item Price" required>
184
- <br><br>
185
-
186
- <button type="submit">Create Item</button>
187
- </form>
188
-
189
- <br>
190
- <hr>
191
- <br>
192
-
193
- <h3>Update Item (PUT /api/items/:id)</h3>
194
- <br>
195
- <form @submit.prevent="updateItem">
196
- <label for="edit-id">Item ID:</label>
197
- <br>
198
- <input id="edit-id" v-model="editForm.id" placeholder="Item ID" required>
199
- <br><br>
200
-
201
- <label for="edit-name">Name:</label>
202
- <br>
203
- <input id="edit-name" v-model="editForm.name" placeholder="Item Name" required>
204
- <br><br>
205
-
206
- <label for="edit-desc">Description:</label>
207
- <br>
208
- <input id="edit-desc" v-model="editForm.description" placeholder="Item Description" required>
209
- <br><br>
210
-
211
- <label for="edit-price">Price:</label>
212
- <br>
213
- <input id="edit-price" v-model.number="editForm.price" type="number" placeholder="Item Price" required>
214
- <br><br>
215
-
216
- <button type="submit">Update Item</button>
217
- <button type="button" @click="cancelEdit">Clear</button>
218
- </form>
219
-
220
- <br>
221
- <hr>
222
- <br>
223
-
224
- <h3>Get Item By ID (GET /api/items/:id)</h3>
225
- <br>
226
- <input v-model="searchId" placeholder="Enter Item ID">
227
- <br><br>
228
- <button @click="fetchById(searchId)">Fetch By ID</button>
229
- <br><br>
230
-
231
- <div v-if="selectedItem">
232
- <h4>Item Details</h4>
233
- <p>ID: {{ selectedItem.id }}</p>
234
- <br>
235
- <p>Name: {{ selectedItem.name }}</p>
236
- <br>
237
- <p>Description: {{ selectedItem.description || selectedItem.describtion }}</p>
238
- <br>
239
- <p>Price: ${{ selectedItem.price }}</p>
240
- <br>
241
- <button @click="selectedItem = null">Close Details</button>
242
- </div>
243
-
244
- <br>
245
- <hr>
246
- <br>
247
-
248
- <h3>Items List (GET /api/items)</h3>
249
- <br>
250
-
251
- <p v-if="items.length === 0">No items loaded.</p>
252
-
253
- <ul v-if="items.length > 0">
254
- <li v-for="item in items" :key="item.id">
255
- <span>{{ item.name }} - {{ item.description || item.describtion }} - ${{ item.price }} (ID: {{ item.id }})</span>
256
- <br><br>
257
- <button @click="fetchById(item.id)">View Details</button>
258
- <button @click="startEdit(item)">Edit</button>
259
- <button @click="deleteItem(item.id)">Delete</button>
260
- <button @click="promptPatch(item)">Patch</button>
261
- <br><br>
262
- </li>
263
- </ul>
264
- </template>
1
+ <script setup>
2
+ import { ref, onMounted } from 'vue'
3
+ import ItemService from './services/ItemService'
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 ItemService.getAll()
25
+ items.value = res.data || []
26
+ } catch (err) {
27
+ errorMessage.value = err.message || 'Failed to load items'
28
+ } finally {
29
+ loading.value = false
30
+ }
31
+ }
32
+
33
+ async function fetchById(id) {
34
+ if (!id) return
35
+ loading.value = true
36
+ errorMessage.value = ''
37
+ try {
38
+ const res = await ItemService.getOne(id)
39
+ selectedItem.value = res.data
40
+ } catch (err) {
41
+ errorMessage.value = err.message || 'Item not found'
42
+ } finally {
43
+ loading.value = false
44
+ }
45
+ }
46
+
47
+ function openCreateModal() {
48
+ isEditMode.value = false
49
+ activeItemData.value = { name: '', description: '', price: 0 }
50
+ isFormModalOpen.value = true
51
+ }
52
+
53
+ function openEditModal(item) {
54
+ isEditMode.value = true
55
+ activeItemData.value = { ...item }
56
+ isFormModalOpen.value = true
57
+ }
58
+
59
+ function openPatchModal(item) {
60
+ activePatchItem.value = item
61
+ isPatchModalOpen.value = true
62
+ }
63
+
64
+ async function handleFormSubmit(payload) {
65
+ loading.value = true
66
+ errorMessage.value = ''
67
+ try {
68
+ if (isEditMode.value) {
69
+ await ItemService.update(payload.id, payload)
70
+ } else {
71
+ await ItemService.create(payload)
72
+ }
73
+ isFormModalOpen.value = false
74
+ await fetchAll()
75
+ } catch (err) {
76
+ errorMessage.value = err.message || 'Failed to save item'
77
+ } finally {
78
+ loading.value = false
79
+ }
80
+ }
81
+
82
+ async function handlePatchSubmit({ id, partial }) {
83
+ loading.value = true
84
+ errorMessage.value = ''
85
+ try {
86
+ await ItemService.patch(id, partial)
87
+ isPatchModalOpen.value = false
88
+ await fetchAll()
89
+ } catch (err) {
90
+ errorMessage.value = err.message || 'Failed to patch item'
91
+ } finally {
92
+ loading.value = false
93
+ }
94
+ }
95
+
96
+ async function handleDelete(id) {
97
+ if (!confirm('Are you sure you want to delete this item?')) return
98
+ loading.value = true
99
+ errorMessage.value = ''
100
+ try {
101
+ await ItemService.delete(id)
102
+ if (selectedItem.value && selectedItem.value.id === id) {
103
+ selectedItem.value = null
104
+ }
105
+ await fetchAll()
106
+ } catch (err) {
107
+ errorMessage.value = err.message || 'Failed to delete item'
108
+ } finally {
109
+ loading.value = false
110
+ }
111
+ }
112
+
113
+ function handleViewDetails(item) {
114
+ selectedItem.value = item
115
+ }
116
+
117
+ onMounted(() => {
118
+ fetchAll()
119
+ })
120
+ </script>
121
+
122
+ <template>
123
+ <div class="app-container">
124
+ <header class="app-header">
125
+ <h1>Vue 3 Axios CRUD with Child Components</h1>
126
+ <p>Modular Architecture: ItemTable, ItemFormModal, ItemPatchModal</p>
127
+ </header>
128
+
129
+ <div v-if="errorMessage" class="error-banner">
130
+ {{ errorMessage }}
131
+ </div>
132
+
133
+ <div v-if="selectedItem" class="detail-card">
134
+ <div class="detail-header">
135
+ <h3>Selected Item Details</h3>
136
+ <button type="button" class="btn-close" @click="selectedItem = null">Close</button>
137
+ </div>
138
+ <div class="detail-body">
139
+ <p><strong>ID:</strong> {{ selectedItem.id }}</p>
140
+ <p><strong>Name:</strong> {{ selectedItem.name }}</p>
141
+ <p><strong>Description:</strong> {{ selectedItem.description || selectedItem.describtion || 'N/A' }}</p>
142
+ <p><strong>Price:</strong> ${{ Number(selectedItem.price).toFixed(2) }}</p>
143
+ </div>
144
+ </div>
145
+
146
+ <ItemTable
147
+ :items="items"
148
+ :loading="loading"
149
+ @open-create="openCreateModal"
150
+ @edit="openEditModal"
151
+ @patch="openPatchModal"
152
+ @delete="handleDelete"
153
+ @view-details="handleViewDetails"
154
+ @refresh="fetchAll"
155
+ />
156
+
157
+ <ItemFormModal
158
+ :show="isFormModalOpen"
159
+ :is-edit="isEditMode"
160
+ :item-data="activeItemData"
161
+ @close="isFormModalOpen = false"
162
+ @submit="handleFormSubmit"
163
+ />
164
+
165
+ <ItemPatchModal
166
+ :show="isPatchModalOpen"
167
+ :item="activePatchItem"
168
+ @close="isPatchModalOpen = false"
169
+ @submit="handlePatchSubmit"
170
+ />
171
+ </div>
172
+ </template>
173
+
174
+ <style>
175
+ * {
176
+ box-sizing: border-box;
177
+ margin: 0;
178
+ padding: 0;
179
+ }
180
+
181
+ body {
182
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
183
+ background-color: #f4f6f8;
184
+ color: #333333;
185
+ }
186
+ </style>
187
+
188
+ <style scoped>
189
+ .app-container {
190
+ max-width: 1000px;
191
+ margin: 0 auto;
192
+ padding: 32px 16px;
193
+ }
194
+
195
+ .app-header {
196
+ margin-bottom: 24px;
197
+ }
198
+
199
+ .app-header h1 {
200
+ font-size: 26px;
201
+ color: #1a1a1a;
202
+ margin-bottom: 4px;
203
+ }
204
+
205
+ .app-header p {
206
+ color: #666666;
207
+ font-size: 14px;
208
+ }
209
+
210
+ .error-banner {
211
+ background-color: #ffebe9;
212
+ color: #cf222e;
213
+ border: 1px solid #ff818266;
214
+ padding: 12px 16px;
215
+ border-radius: 6px;
216
+ margin-bottom: 20px;
217
+ font-size: 14px;
218
+ }
219
+
220
+ .detail-card {
221
+ background: #ffffff;
222
+ border: 1px solid #d0d7de;
223
+ border-radius: 8px;
224
+ padding: 16px;
225
+ margin-bottom: 20px;
226
+ box-shadow: 0 1px 3px rgba(0,0,0,0.05);
227
+ }
228
+
229
+ .detail-header {
230
+ display: flex;
231
+ justify-content: space-between;
232
+ align-items: center;
233
+ border-bottom: 1px solid #eaecef;
234
+ padding-bottom: 8px;
235
+ margin-bottom: 12px;
236
+ }
237
+
238
+ .detail-header h3 {
239
+ font-size: 16px;
240
+ color: #24292f;
241
+ }
242
+
243
+ .btn-close {
244
+ background: none;
245
+ border: none;
246
+ cursor: pointer;
247
+ color: #57606a;
248
+ font-size: 14px;
249
+ }
250
+
251
+ .detail-body p {
252
+ font-size: 14px;
253
+ margin-bottom: 6px;
254
+ }
255
+ </style>