wad-lab 1.1.2 → 1.1.3

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 (145) hide show
  1. package/bin/index.js +12 -1
  2. package/package.json +1 -1
  3. package/templates/springboot-2model-1controller-api/pom.xml +42 -0
  4. package/templates/springboot-2model-1controller-api/src/main/java/com/example/company/CompanyApplication.java +11 -0
  5. package/templates/springboot-2model-1controller-api/src/main/java/com/example/company/controller/CompanyController.java +74 -0
  6. package/templates/springboot-2model-1controller-api/src/main/java/com/example/company/model/Department.java +51 -0
  7. package/templates/springboot-2model-1controller-api/src/main/java/com/example/company/model/Employee.java +73 -0
  8. package/templates/springboot-2model-1controller-api/src/main/java/com/example/company/repository/DepartmentRepository.java +12 -0
  9. package/templates/springboot-2model-1controller-api/src/main/java/com/example/company/repository/EmployeeRepository.java +12 -0
  10. package/templates/springboot-2model-1controller-api/src/main/java/com/example/company/service/CompanyService.java +60 -0
  11. package/templates/springboot-2model-1controller-api/src/main/resources/application.properties +4 -0
  12. package/templates/vue-axios-basic/index.html +12 -0
  13. package/templates/{frontend → vue-axios-basic}/package.json +6 -9
  14. package/templates/vue-axios-basic/src/App.vue +405 -0
  15. package/templates/{frontend → vue-axios-basic}/src/main.js +0 -2
  16. package/templates/vue-axios-basic/src/services/api.js +7 -0
  17. package/templates/vue-axios-basic/vite.config.js +9 -0
  18. package/templates/{frontend → vue-axios-interceptor}/index.html +2 -3
  19. package/templates/vue-axios-interceptor/package.json +20 -0
  20. package/templates/vue-axios-interceptor/src/App.vue +159 -0
  21. package/templates/vue-axios-interceptor/src/components/ToastNotification.vue +47 -0
  22. package/templates/vue-axios-interceptor/src/main.js +7 -0
  23. package/templates/vue-axios-interceptor/src/services/api.js +32 -0
  24. package/templates/vue-axios-interceptor/src/stores/toastStore.js +23 -0
  25. package/templates/vue-axios-interceptor/vite.config.js +6 -0
  26. package/templates/vue-axios-pinia/index.html +12 -0
  27. package/templates/vue-axios-pinia/package.json +20 -0
  28. package/templates/vue-axios-pinia/src/App.vue +427 -0
  29. package/templates/vue-axios-pinia/src/main.js +5 -0
  30. package/templates/vue-axios-pinia/src/services/api.js +7 -0
  31. package/templates/vue-axios-pinia/src/stores/companyStore.js +96 -0
  32. package/templates/vue-axios-pinia/vite.config.js +9 -0
  33. package/templates/vue-axios-pinia-props/index.html +12 -0
  34. package/templates/vue-axios-pinia-props/package.json +20 -0
  35. package/templates/vue-axios-pinia-props/src/App.vue +69 -0
  36. package/templates/vue-axios-pinia-props/src/components/DepartmentSection.vue +152 -0
  37. package/templates/vue-axios-pinia-props/src/components/EmployeeSection.vue +181 -0
  38. package/templates/vue-axios-pinia-props/src/main.js +5 -0
  39. package/templates/vue-axios-pinia-props/src/services/api.js +7 -0
  40. package/templates/vue-axios-pinia-props/src/stores/companyStore.js +35 -0
  41. package/templates/vue-axios-pinia-props/vite.config.js +6 -0
  42. package/templates/vue-axios-props-emits/index.html +12 -0
  43. package/templates/vue-axios-props-emits/package.json +19 -0
  44. package/templates/vue-axios-props-emits/src/App.vue +167 -0
  45. package/templates/vue-axios-props-emits/src/components/DepartmentForm.vue +98 -0
  46. package/templates/vue-axios-props-emits/src/components/DepartmentList.vue +91 -0
  47. package/templates/vue-axios-props-emits/src/components/EmployeeForm.vue +128 -0
  48. package/templates/vue-axios-props-emits/src/components/EmployeeList.vue +94 -0
  49. package/templates/vue-axios-props-emits/src/main.js +4 -0
  50. package/templates/vue-axios-props-emits/src/services/api.js +7 -0
  51. package/templates/vue-axios-props-emits/vite.config.js +9 -0
  52. package/templates/vue-axios-router/index.html +12 -0
  53. package/templates/vue-axios-router/package.json +20 -0
  54. package/templates/vue-axios-router/src/App.vue +90 -0
  55. package/templates/vue-axios-router/src/main.js +5 -0
  56. package/templates/vue-axios-router/src/router/index.js +19 -0
  57. package/templates/vue-axios-router/src/services/api.js +7 -0
  58. package/templates/vue-axios-router/src/views/AddEmployeeView.vue +247 -0
  59. package/templates/vue-axios-router/src/views/DepartmentView.vue +273 -0
  60. package/templates/vue-axios-router/src/views/EmployeeView.vue +196 -0
  61. package/templates/vue-axios-router/src/views/HomeDashboardView.vue +263 -0
  62. package/templates/vue-axios-router/vite.config.js +6 -0
  63. package/templates/vue-axios-router-children/index.html +12 -0
  64. package/templates/vue-axios-router-children/package.json +20 -0
  65. package/templates/vue-axios-router-children/src/App.vue +20 -0
  66. package/templates/vue-axios-router-children/src/main.js +5 -0
  67. package/templates/vue-axios-router-children/src/router/index.js +42 -0
  68. package/templates/vue-axios-router-children/src/services/api.js +7 -0
  69. package/templates/vue-axios-router-children/src/views/CompanyLayout.vue +75 -0
  70. package/templates/vue-axios-router-children/src/views/CompanyOverview.vue +109 -0
  71. package/templates/vue-axios-router-children/src/views/DepartmentListView.vue +231 -0
  72. package/templates/vue-axios-router-children/src/views/EmployeeDetailView.vue +159 -0
  73. package/templates/vue-axios-router-children/src/views/EmployeeListView.vue +295 -0
  74. package/templates/vue-axios-router-children/vite.config.js +6 -0
  75. package/templates/vue-axios-router-pinia/index.html +12 -0
  76. package/templates/vue-axios-router-pinia/package.json +21 -0
  77. package/templates/vue-axios-router-pinia/src/App.vue +92 -0
  78. package/templates/vue-axios-router-pinia/src/main.js +9 -0
  79. package/templates/vue-axios-router-pinia/src/router/index.js +17 -0
  80. package/templates/vue-axios-router-pinia/src/services/api.js +7 -0
  81. package/templates/vue-axios-router-pinia/src/stores/companyStore.js +70 -0
  82. package/templates/vue-axios-router-pinia/src/views/DashboardView.vue +77 -0
  83. package/templates/vue-axios-router-pinia/src/views/DepartmentView.vue +209 -0
  84. package/templates/vue-axios-router-pinia/src/views/EmployeeView.vue +237 -0
  85. package/templates/vue-axios-router-pinia/vite.config.js +6 -0
  86. package/templates/vue-axios-router-pinia-props/index.html +12 -0
  87. package/templates/vue-axios-router-pinia-props/package.json +21 -0
  88. package/templates/vue-axios-router-pinia-props/src/App.vue +67 -0
  89. package/templates/vue-axios-router-pinia-props/src/components/EntityForm.vue +101 -0
  90. package/templates/vue-axios-router-pinia-props/src/components/EntityTable.vue +92 -0
  91. package/templates/vue-axios-router-pinia-props/src/components/SummaryBadge.vue +43 -0
  92. package/templates/vue-axios-router-pinia-props/src/main.js +9 -0
  93. package/templates/vue-axios-router-pinia-props/src/router/index.js +29 -0
  94. package/templates/vue-axios-router-pinia-props/src/services/api.js +29 -0
  95. package/templates/vue-axios-router-pinia-props/src/stores/companyStore.js +84 -0
  96. package/templates/vue-axios-router-pinia-props/src/views/ManageDepartmentsView.vue +64 -0
  97. package/templates/vue-axios-router-pinia-props/src/views/ManageEmployeesView.vue +67 -0
  98. package/templates/vue-axios-router-pinia-props/src/views/OverviewView.vue +38 -0
  99. package/templates/vue-axios-router-pinia-props/vite.config.js +6 -0
  100. package/templates/vue-axios-router-props/index.html +12 -0
  101. package/templates/vue-axios-router-props/package.json +20 -0
  102. package/templates/vue-axios-router-props/src/App.vue +59 -0
  103. package/templates/vue-axios-router-props/src/components/DataCard.vue +53 -0
  104. package/templates/vue-axios-router-props/src/components/EntryForm.vue +117 -0
  105. package/templates/vue-axios-router-props/src/main.js +7 -0
  106. package/templates/vue-axios-router-props/src/router/index.js +23 -0
  107. package/templates/vue-axios-router-props/src/services/api.js +7 -0
  108. package/templates/vue-axios-router-props/src/views/DepartmentPage.vue +77 -0
  109. package/templates/vue-axios-router-props/src/views/EmployeePage.vue +116 -0
  110. package/templates/vue-axios-router-props/vite.config.js +6 -0
  111. package/templates/backend/.gitattributes +0 -2
  112. package/templates/backend/.idea/compiler.xml +0 -21
  113. package/templates/backend/.idea/encodings.xml +0 -6
  114. package/templates/backend/.idea/jarRepositories.xml +0 -20
  115. package/templates/backend/.idea/misc.xml +0 -12
  116. package/templates/backend/.idea/vcs.xml +0 -6
  117. package/templates/backend/pom.xml +0 -104
  118. package/templates/backend/src/main/java/com/example/crud/CrudApplication.java +0 -13
  119. package/templates/backend/src/main/java/com/example/crud/controller/ItemController.java +0 -42
  120. package/templates/backend/src/main/java/com/example/crud/model/Item.java +0 -20
  121. package/templates/backend/src/main/java/com/example/crud/repository/ItemRepository.java +0 -9
  122. package/templates/backend/src/main/java/com/example/crud/service/ItemService.java +0 -37
  123. package/templates/backend/src/main/resources/application.properties +0 -4
  124. package/templates/backend/src/test/java/com/example/crud/CrudApplicationTests.java +0 -13
  125. package/templates/frontend/.vscode/extensions.json +0 -3
  126. package/templates/frontend/README.md +0 -38
  127. package/templates/frontend/jsconfig.json +0 -8
  128. package/templates/frontend/public/favicon.ico +0 -0
  129. package/templates/frontend/src/App.vue +0 -50
  130. package/templates/frontend/src/assets/base.css +0 -86
  131. package/templates/frontend/src/assets/logo.svg +0 -1
  132. package/templates/frontend/src/assets/main.css +0 -35
  133. package/templates/frontend/src/components/HelloWorld.vue +0 -44
  134. package/templates/frontend/src/components/TheWelcome.vue +0 -95
  135. package/templates/frontend/src/components/WelcomeItem.vue +0 -87
  136. package/templates/frontend/src/components/icons/IconCommunity.vue +0 -7
  137. package/templates/frontend/src/components/icons/IconDocumentation.vue +0 -7
  138. package/templates/frontend/src/components/icons/IconEcosystem.vue +0 -7
  139. package/templates/frontend/src/components/icons/IconSupport.vue +0 -7
  140. package/templates/frontend/src/components/icons/IconTooling.vue +0 -19
  141. package/templates/frontend/src/services/ItemService.js +0 -21
  142. package/templates/frontend/vite.config.js +0 -18
  143. /package/templates/{backend → springboot-2model-1controller-api}/.mvn/wrapper/maven-wrapper.properties +0 -0
  144. /package/templates/{backend → springboot-2model-1controller-api}/mvnw +0 -0
  145. /package/templates/{backend → springboot-2model-1controller-api}/mvnw.cmd +0 -0
@@ -0,0 +1,23 @@
1
+ import { defineStore } from 'pinia'
2
+
3
+ export const useToastStore = defineStore('toast', {
4
+ state: () => ({
5
+ message: '',
6
+ type: 'success',
7
+ visible: false
8
+ }),
9
+ actions: {
10
+ show(message, type = 'success') {
11
+ this.message = message
12
+ this.type = type
13
+ this.visible = true
14
+ setTimeout(() => {
15
+ this.hide()
16
+ }, 3000)
17
+ },
18
+ hide() {
19
+ this.visible = false
20
+ this.message = ''
21
+ }
22
+ }
23
+ })
@@ -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 Axios Pinia</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-axios-pinia",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "axios": "^1.7.7",
13
+ "pinia": "^4.1.0",
14
+ "vue": "^3.5.44"
15
+ },
16
+ "devDependencies": {
17
+ "@vitejs/plugin-vue": "^6.0.10",
18
+ "vite": "^8.3.4"
19
+ }
20
+ }
@@ -0,0 +1,427 @@
1
+ <template>
2
+ <div class="container">
3
+ <header class="header">
4
+ <h1>Company Management</h1>
5
+ <p>Vue 3 + Axios + Pinia</p>
6
+ </header>
7
+
8
+ <div class="stats-grid">
9
+ <div class="stat-card">
10
+ <h3>Total Departments</h3>
11
+ <p class="stat-value">{{ companyStore.totalDepartments }}</p>
12
+ </div>
13
+ <div class="stat-card">
14
+ <h3>Total Employees</h3>
15
+ <p class="stat-value">{{ companyStore.totalEmployees }}</p>
16
+ </div>
17
+ <div class="stat-card">
18
+ <h3>Total Payroll</h3>
19
+ <p class="stat-value">${{ companyStore.totalPayroll.toLocaleString() }}</p>
20
+ </div>
21
+ </div>
22
+
23
+ <div v-if="companyStore.loading" class="status-msg info">Loading data...</div>
24
+ <div v-if="companyStore.error" class="status-msg error">{{ companyStore.error }}</div>
25
+
26
+ <div class="main-grid">
27
+ <section class="card">
28
+ <h2>Departments</h2>
29
+
30
+ <form @submit.prevent="handleCreateDepartment" class="form">
31
+ <div class="form-group">
32
+ <label for="dept-name">Department Name</label>
33
+ <input
34
+ id="dept-name"
35
+ v-model="deptForm.name"
36
+ type="text"
37
+ required
38
+ placeholder="e.g. Engineering"
39
+ />
40
+ </div>
41
+ <div class="form-group">
42
+ <label for="dept-code">Department Code</label>
43
+ <input
44
+ id="dept-code"
45
+ v-model="deptForm.code"
46
+ type="text"
47
+ required
48
+ placeholder="e.g. ENG"
49
+ />
50
+ </div>
51
+ <button type="submit" class="btn btn-primary">Add Department</button>
52
+ </form>
53
+
54
+ <div class="table-wrapper">
55
+ <table>
56
+ <thead>
57
+ <tr>
58
+ <th>ID</th>
59
+ <th>Name</th>
60
+ <th>Code</th>
61
+ <th>Action</th>
62
+ </tr>
63
+ </thead>
64
+ <tbody>
65
+ <tr v-if="companyStore.departments.length === 0">
66
+ <td colspan="4" class="empty">No departments found</td>
67
+ </tr>
68
+ <tr v-for="dept in companyStore.departments" :key="dept.id">
69
+ <td>{{ dept.id }}</td>
70
+ <td>{{ dept.name }}</td>
71
+ <td><code>{{ dept.code }}</code></td>
72
+ <td>
73
+ <button @click="companyStore.deleteDepartment(dept.id)" class="btn btn-danger">Delete</button>
74
+ </td>
75
+ </tr>
76
+ </tbody>
77
+ </table>
78
+ </div>
79
+ </section>
80
+
81
+ <section class="card">
82
+ <h2>Employees</h2>
83
+
84
+ <form @submit.prevent="handleCreateEmployee" class="form">
85
+ <div class="form-group">
86
+ <label for="emp-name">Full Name</label>
87
+ <input
88
+ id="emp-name"
89
+ v-model="empForm.name"
90
+ type="text"
91
+ required
92
+ placeholder="e.g. Jane Doe"
93
+ />
94
+ </div>
95
+ <div class="form-group">
96
+ <label for="emp-email">Email Address</label>
97
+ <input
98
+ id="emp-email"
99
+ v-model="empForm.email"
100
+ type="email"
101
+ required
102
+ placeholder="e.g. jane@example.com"
103
+ />
104
+ </div>
105
+ <div class="form-group">
106
+ <label for="emp-dept">Department</label>
107
+ <select id="emp-dept" v-model="empForm.departmentId" required>
108
+ <option value="" disabled>Select Department</option>
109
+ <option v-for="dept in companyStore.departments" :key="dept.id" :value="dept.id">
110
+ {{ dept.name }} ({{ dept.code }})
111
+ </option>
112
+ </select>
113
+ </div>
114
+ <div class="form-group">
115
+ <label for="emp-salary">Salary</label>
116
+ <input
117
+ id="emp-salary"
118
+ v-model.number="empForm.salary"
119
+ type="number"
120
+ min="0"
121
+ step="any"
122
+ required
123
+ placeholder="e.g. 75000"
124
+ />
125
+ </div>
126
+ <button type="submit" class="btn btn-primary">Add Employee</button>
127
+ </form>
128
+
129
+ <div class="table-wrapper">
130
+ <table>
131
+ <thead>
132
+ <tr>
133
+ <th>ID</th>
134
+ <th>Name</th>
135
+ <th>Email</th>
136
+ <th>Department</th>
137
+ <th>Salary</th>
138
+ <th>Action</th>
139
+ </tr>
140
+ </thead>
141
+ <tbody>
142
+ <tr v-if="companyStore.employees.length === 0">
143
+ <td colspan="6" class="empty">No employees found</td>
144
+ </tr>
145
+ <tr v-for="emp in companyStore.employees" :key="emp.id">
146
+ <td>{{ emp.id }}</td>
147
+ <td>{{ emp.name }}</td>
148
+ <td>{{ emp.email }}</td>
149
+ <td>{{ getDepartmentName(emp.departmentId) }}</td>
150
+ <td>${{ Number(emp.salary).toLocaleString() }}</td>
151
+ <td>
152
+ <button @click="companyStore.deleteEmployee(emp.id)" class="btn btn-danger">Delete</button>
153
+ </td>
154
+ </tr>
155
+ </tbody>
156
+ </table>
157
+ </div>
158
+ </section>
159
+ </div>
160
+ </div>
161
+ </template>
162
+
163
+ <script setup>
164
+ import { reactive, onMounted } from 'vue'
165
+ import { useCompanyStore } from './stores/companyStore'
166
+
167
+ const companyStore = useCompanyStore()
168
+
169
+ const deptForm = reactive({
170
+ name: '',
171
+ code: ''
172
+ })
173
+
174
+ const empForm = reactive({
175
+ name: '',
176
+ email: '',
177
+ departmentId: '',
178
+ salary: ''
179
+ })
180
+
181
+ const handleCreateDepartment = async () => {
182
+ if (!deptForm.name || !deptForm.code) return
183
+ await companyStore.createDepartment({
184
+ name: deptForm.name,
185
+ code: deptForm.code
186
+ })
187
+ deptForm.name = ''
188
+ deptForm.code = ''
189
+ }
190
+
191
+ const handleCreateEmployee = async () => {
192
+ if (!empForm.name || !empForm.email || !empForm.departmentId) return
193
+ await companyStore.createEmployee({
194
+ name: empForm.name,
195
+ email: empForm.email,
196
+ departmentId: empForm.departmentId,
197
+ salary: Number(empForm.salary) || 0
198
+ })
199
+ empForm.name = ''
200
+ empForm.email = ''
201
+ empForm.departmentId = ''
202
+ empForm.salary = ''
203
+ }
204
+
205
+ const getDepartmentName = (deptId) => {
206
+ const dept = companyStore.departments.find(d => d.id === deptId)
207
+ return dept ? dept.name : (deptId || 'N/A')
208
+ }
209
+
210
+ onMounted(() => {
211
+ companyStore.fetchDepartments()
212
+ companyStore.fetchEmployees()
213
+ })
214
+ </script>
215
+
216
+ <style>
217
+ * {
218
+ box-sizing: border-box;
219
+ margin: 0;
220
+ padding: 0;
221
+ }
222
+
223
+ body {
224
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
225
+ background-color: #f4f5f7;
226
+ color: #333333;
227
+ line-height: 1.5;
228
+ }
229
+
230
+ .container {
231
+ max-width: 1200px;
232
+ margin: 0 auto;
233
+ padding: 32px 16px;
234
+ }
235
+
236
+ .header {
237
+ margin-bottom: 24px;
238
+ }
239
+
240
+ .header h1 {
241
+ font-size: 28px;
242
+ color: #1a1a1a;
243
+ }
244
+
245
+ .header p {
246
+ color: #666666;
247
+ font-size: 14px;
248
+ }
249
+
250
+ .stats-grid {
251
+ display: grid;
252
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
253
+ gap: 16px;
254
+ margin-bottom: 24px;
255
+ }
256
+
257
+ .stat-card {
258
+ background: #ffffff;
259
+ border: 1px solid #e1e4e8;
260
+ border-radius: 8px;
261
+ padding: 16px;
262
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
263
+ }
264
+
265
+ .stat-card h3 {
266
+ font-size: 13px;
267
+ text-transform: uppercase;
268
+ color: #666666;
269
+ margin-bottom: 6px;
270
+ }
271
+
272
+ .stat-value {
273
+ font-size: 24px;
274
+ font-weight: 700;
275
+ color: #0969da;
276
+ }
277
+
278
+ .status-msg {
279
+ padding: 10px 14px;
280
+ border-radius: 6px;
281
+ font-size: 14px;
282
+ margin-bottom: 20px;
283
+ }
284
+
285
+ .status-msg.info {
286
+ background-color: #ddf4ff;
287
+ color: #0969da;
288
+ border: 1px solid #54aeff66;
289
+ }
290
+
291
+ .status-msg.error {
292
+ background-color: #ffebe9;
293
+ color: #cf222e;
294
+ border: 1px solid #ff818266;
295
+ }
296
+
297
+ .main-grid {
298
+ display: grid;
299
+ grid-template-columns: 1fr;
300
+ gap: 24px;
301
+ }
302
+
303
+ @media (min-width: 900px) {
304
+ .main-grid {
305
+ grid-template-columns: 1fr 1fr;
306
+ }
307
+ }
308
+
309
+ .card {
310
+ background: #ffffff;
311
+ border: 1px solid #e1e4e8;
312
+ border-radius: 8px;
313
+ padding: 20px;
314
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
315
+ }
316
+
317
+ .card h2 {
318
+ font-size: 20px;
319
+ margin-bottom: 16px;
320
+ color: #24292f;
321
+ border-bottom: 1px solid #eaecef;
322
+ padding-bottom: 8px;
323
+ }
324
+
325
+ .form {
326
+ display: flex;
327
+ flex-direction: column;
328
+ gap: 12px;
329
+ margin-bottom: 24px;
330
+ }
331
+
332
+ .form-group {
333
+ display: flex;
334
+ flex-direction: column;
335
+ gap: 4px;
336
+ }
337
+
338
+ .form-group label {
339
+ font-size: 13px;
340
+ font-weight: 600;
341
+ color: #444444;
342
+ }
343
+
344
+ .form-group input,
345
+ .form-group select {
346
+ padding: 8px 12px;
347
+ border: 1px solid #d0d7de;
348
+ border-radius: 6px;
349
+ font-size: 14px;
350
+ background-color: #ffffff;
351
+ color: #24292f;
352
+ outline: none;
353
+ }
354
+
355
+ .form-group input:focus,
356
+ .form-group select:focus {
357
+ border-color: #0969da;
358
+ box-shadow: 0 0 0 3px rgba(9, 105, 218, 0.15);
359
+ }
360
+
361
+ .btn {
362
+ display: inline-block;
363
+ padding: 8px 16px;
364
+ font-size: 14px;
365
+ font-weight: 500;
366
+ border-radius: 6px;
367
+ border: 1px solid transparent;
368
+ cursor: pointer;
369
+ text-align: center;
370
+ transition: background-color 0.15s ease-in-out;
371
+ }
372
+
373
+ .btn-primary {
374
+ background-color: #1f883d;
375
+ color: #ffffff;
376
+ }
377
+
378
+ .btn-primary:hover {
379
+ background-color: #1a7f37;
380
+ }
381
+
382
+ .btn-danger {
383
+ background-color: #cf222e;
384
+ color: #ffffff;
385
+ padding: 4px 10px;
386
+ font-size: 12px;
387
+ }
388
+
389
+ .btn-danger:hover {
390
+ background-color: #a40e26;
391
+ }
392
+
393
+ .table-wrapper {
394
+ overflow-x: auto;
395
+ }
396
+
397
+ table {
398
+ width: 100%;
399
+ border-collapse: collapse;
400
+ font-size: 14px;
401
+ text-align: left;
402
+ }
403
+
404
+ th, td {
405
+ padding: 10px 12px;
406
+ border-bottom: 1px solid #e1e4e8;
407
+ }
408
+
409
+ th {
410
+ background-color: #f6f8fa;
411
+ font-weight: 600;
412
+ color: #57606a;
413
+ }
414
+
415
+ td code {
416
+ background-color: #eff1f3;
417
+ padding: 2px 6px;
418
+ border-radius: 4px;
419
+ font-size: 12px;
420
+ }
421
+
422
+ .empty {
423
+ text-align: center;
424
+ color: #8c959f;
425
+ padding: 24px;
426
+ }
427
+ </style>
@@ -0,0 +1,5 @@
1
+ import { createApp } from 'vue'
2
+ import { createPinia } from 'pinia'
3
+ import App from './App.vue'
4
+
5
+ createApp(App).use(createPinia()).mount('#app')
@@ -0,0 +1,7 @@
1
+ import axios from 'axios'
2
+
3
+ const api = axios.create({
4
+ baseURL: 'http://localhost:8080/api'
5
+ })
6
+
7
+ export default api
@@ -0,0 +1,96 @@
1
+ import { defineStore } from 'pinia'
2
+ import api from '../services/api'
3
+
4
+ export const useCompanyStore = defineStore('company', {
5
+ state: () => ({
6
+ departments: [],
7
+ employees: [],
8
+ loading: false,
9
+ error: null
10
+ }),
11
+ getters: {
12
+ totalDepartments: (state) => state.departments.length,
13
+ totalEmployees: (state) => state.employees.length,
14
+ totalPayroll: (state) => state.employees.reduce((sum, emp) => sum + (Number(emp.salary) || 0), 0)
15
+ },
16
+ actions: {
17
+ async fetchDepartments() {
18
+ this.loading = true
19
+ this.error = null
20
+ try {
21
+ const response = await api.get('/departments')
22
+ this.departments = response.data
23
+ } catch (err) {
24
+ this.error = err.response?.data?.message || err.message
25
+ } finally {
26
+ this.loading = false
27
+ }
28
+ },
29
+ async createDepartment(data) {
30
+ this.loading = true
31
+ this.error = null
32
+ try {
33
+ const response = await api.post('/departments', data)
34
+ this.departments.push(response.data)
35
+ return response.data
36
+ } catch (err) {
37
+ this.error = err.response?.data?.message || err.message
38
+ throw err
39
+ } finally {
40
+ this.loading = false
41
+ }
42
+ },
43
+ async deleteDepartment(id) {
44
+ this.loading = true
45
+ this.error = null
46
+ try {
47
+ await api.delete(`/departments/${id}`)
48
+ this.departments = this.departments.filter(dept => dept.id !== id)
49
+ } catch (err) {
50
+ this.error = err.response?.data?.message || err.message
51
+ throw err
52
+ } finally {
53
+ this.loading = false
54
+ }
55
+ },
56
+ async fetchEmployees() {
57
+ this.loading = true
58
+ this.error = null
59
+ try {
60
+ const response = await api.get('/employees')
61
+ this.employees = response.data
62
+ } catch (err) {
63
+ this.error = err.response?.data?.message || err.message
64
+ } finally {
65
+ this.loading = false
66
+ }
67
+ },
68
+ async createEmployee(data) {
69
+ this.loading = true
70
+ this.error = null
71
+ try {
72
+ const response = await api.post('/employees', data)
73
+ this.employees.push(response.data)
74
+ return response.data
75
+ } catch (err) {
76
+ this.error = err.response?.data?.message || err.message
77
+ throw err
78
+ } finally {
79
+ this.loading = false
80
+ }
81
+ },
82
+ async deleteEmployee(id) {
83
+ this.loading = true
84
+ this.error = null
85
+ try {
86
+ await api.delete(`/employees/${id}`)
87
+ this.employees = this.employees.filter(emp => emp.id !== id)
88
+ } catch (err) {
89
+ this.error = err.response?.data?.message || err.message
90
+ throw err
91
+ } finally {
92
+ this.loading = false
93
+ }
94
+ }
95
+ }
96
+ })
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+
4
+ export default defineConfig({
5
+ plugins: [vue()],
6
+ server: {
7
+ port: 5173
8
+ }
9
+ })
@@ -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>Company Management</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-axios-pinia-props",
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
+ "axios": "^1.7.7",
13
+ "pinia": "^4.1.0",
14
+ "vue": "^3.5.44"
15
+ },
16
+ "devDependencies": {
17
+ "@vitejs/plugin-vue": "^6.0.10",
18
+ "vite": "^8.3.4"
19
+ }
20
+ }