wad-lab 1.0.4 → 1.0.6

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 (49) hide show
  1. package/bin/index.js +9 -1
  2. package/package.json +1 -1
  3. package/templates/game-memory-cards/index.html +24 -0
  4. package/templates/game-memory-cards/script.js +90 -0
  5. package/templates/game-memory-cards/style.css +74 -0
  6. package/templates/game-rock-paper-scissors/index.html +35 -0
  7. package/templates/game-rock-paper-scissors/script.js +49 -0
  8. package/templates/game-rock-paper-scissors/style.css +67 -0
  9. package/templates/game-tic-tac-toe/index.html +30 -0
  10. package/templates/game-tic-tac-toe/script.js +82 -0
  11. package/templates/game-tic-tac-toe/style.css +66 -0
  12. package/templates/game-whack-a-mole/index.html +34 -0
  13. package/templates/game-whack-a-mole/script.js +83 -0
  14. package/templates/game-whack-a-mole/style.css +75 -0
  15. package/templates/html-css-js/index.html +224 -27
  16. package/templates/html-css-js/script.js +358 -25
  17. package/templates/html-css-js/style.css +452 -11
  18. package/templates/vue-cart-router-pinia/index.html +12 -0
  19. package/templates/vue-cart-router-pinia/package.json +20 -0
  20. package/templates/vue-cart-router-pinia/src/App.vue +78 -0
  21. package/templates/vue-cart-router-pinia/src/main.js +9 -0
  22. package/templates/vue-cart-router-pinia/src/router/index.js +17 -0
  23. package/templates/vue-cart-router-pinia/src/stores/cartStore.js +58 -0
  24. package/templates/vue-cart-router-pinia/src/views/CartView.vue +139 -0
  25. package/templates/vue-cart-router-pinia/src/views/CheckoutView.vue +144 -0
  26. package/templates/vue-cart-router-pinia/src/views/ProductCatalogView.vue +73 -0
  27. package/templates/vue-cart-router-pinia/vite.config.js +6 -0
  28. package/templates/vue-memory-game/index.html +12 -0
  29. package/templates/vue-memory-game/package.json +19 -0
  30. package/templates/vue-memory-game/src/App.vue +106 -0
  31. package/templates/vue-memory-game/src/main.js +7 -0
  32. package/templates/vue-memory-game/src/stores/memoryStore.js +64 -0
  33. package/templates/vue-memory-game/vite.config.js +6 -0
  34. package/templates/vue-todo-pinia/index.html +12 -0
  35. package/templates/vue-todo-pinia/package.json +19 -0
  36. package/templates/vue-todo-pinia/src/App.vue +179 -0
  37. package/templates/vue-todo-pinia/src/main.js +7 -0
  38. package/templates/vue-todo-pinia/src/stores/todoStore.js +50 -0
  39. package/templates/vue-todo-pinia/vite.config.js +6 -0
  40. package/templates/vue-todo-router/index.html +12 -0
  41. package/templates/vue-todo-router/package.json +19 -0
  42. package/templates/vue-todo-router/src/App.vue +55 -0
  43. package/templates/vue-todo-router/src/data/todoState.js +38 -0
  44. package/templates/vue-todo-router/src/main.js +7 -0
  45. package/templates/vue-todo-router/src/router/index.js +17 -0
  46. package/templates/vue-todo-router/src/views/AddTodoView.vue +85 -0
  47. package/templates/vue-todo-router/src/views/TodoDetailView.vue +89 -0
  48. package/templates/vue-todo-router/src/views/TodoListView.vue +77 -0
  49. package/templates/vue-todo-router/vite.config.js +6 -0
@@ -1,22 +1,463 @@
1
+ * {
2
+ box-sizing: border-box;
3
+ margin: 0;
4
+ padding: 0;
5
+ }
6
+
1
7
  body {
2
- font-family: sans-serif;
3
- margin: 20px;
8
+ font-family: Arial, Helvetica, sans-serif;
9
+ background-color: #f4f6f9;
10
+ color: #333333;
11
+ line-height: 1.6;
4
12
  }
5
13
 
6
- input:focus {
7
- outline: 2px solid black;
14
+ .app-header {
15
+ background-color: #2c3e50;
16
+ color: #ffffff;
17
+ padding: 20px;
18
+ text-align: center;
8
19
  }
9
20
 
10
- input:invalid {
11
- border: 1px solid gray;
21
+ .app-header h1 {
22
+ margin-bottom: 10px;
23
+ font-size: 24px;
12
24
  }
13
25
 
14
- p::before {
15
- content: "• ";
26
+ .nav-bar {
27
+ display: flex;
28
+ justify-content: center;
29
+ gap: 15px;
30
+ flex-wrap: wrap;
16
31
  }
17
32
 
18
- table, th, td {
19
- border: 1px solid black;
33
+ .nav-bar a {
34
+ color: #ecf0f1;
35
+ text-decoration: none;
36
+ font-weight: bold;
37
+ padding: 6px 12px;
38
+ border-radius: 4px;
39
+ transition: background-color 0.3s ease, transform 0.2s ease;
40
+ }
41
+
42
+ .nav-bar a:hover {
43
+ background-color: #34495e;
44
+ transform: translateY(-2px);
45
+ }
46
+
47
+ .container {
48
+ max-width: 1000px;
49
+ margin: 25px auto;
50
+ padding: 0 15px;
51
+ }
52
+
53
+ .card {
54
+ background-color: #ffffff;
55
+ border-radius: 8px;
56
+ padding: 25px;
57
+ margin-bottom: 25px;
58
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.08);
59
+ position: relative;
60
+ }
61
+
62
+ .card h2 {
63
+ color: #2c3e50;
64
+ border-bottom: 2px solid #3498db;
65
+ padding-bottom: 8px;
66
+ margin-bottom: 20px;
67
+ }
68
+
69
+ fieldset {
70
+ border: 1px solid #bdc3c7;
71
+ border-radius: 6px;
72
+ padding: 20px;
73
+ }
74
+
75
+ legend {
76
+ padding: 0 10px;
77
+ font-weight: bold;
78
+ color: #2c3e50;
79
+ }
80
+
81
+ .form-grid {
82
+ display: grid;
83
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
84
+ gap: 15px;
85
+ margin-top: 10px;
86
+ }
87
+
88
+ .form-group {
89
+ display: flex;
90
+ flex-direction: column;
91
+ }
92
+
93
+ .form-group.full-width {
94
+ grid-column: 1 / -1;
95
+ }
96
+
97
+ label {
98
+ font-size: 14px;
99
+ font-weight: bold;
100
+ margin-bottom: 5px;
101
+ color: #34495e;
102
+ }
103
+
104
+ input[type="text"],
105
+ input[type="password"],
106
+ input[type="email"],
107
+ input[type="tel"],
108
+ input[type="number"],
109
+ input[type="date"],
110
+ input[type="time"],
111
+ input[type="month"],
112
+ input[type="color"],
113
+ input[type="file"],
114
+ select,
115
+ textarea {
116
+ width: 100%;
117
+ padding: 10px;
118
+ border: 1px solid #ccc;
119
+ border-radius: 4px;
120
+ font-size: 14px;
121
+ transition: border-color 0.3s ease, box-shadow 0.3s ease;
122
+ }
123
+
124
+ input::placeholder,
125
+ textarea::placeholder {
126
+ color: #95a5a6;
127
+ font-style: italic;
128
+ }
129
+
130
+ input:focus,
131
+ select:focus,
132
+ textarea:focus {
133
+ outline: none;
134
+ border-color: #3498db;
135
+ box-shadow: 0 0 5px rgba(52, 152, 219, 0.5);
136
+ }
137
+
138
+ input:invalid:not(:placeholder-shown):not(:focus) {
139
+ border-color: #e74c3c;
140
+ }
141
+
142
+ input:valid:not(:placeholder-shown):not([type="color"]):not([type="range"]) {
143
+ border-color: #2ecc71;
144
+ }
145
+
146
+ .radio-group,
147
+ .checkbox-group {
148
+ display: flex;
149
+ gap: 15px;
150
+ align-items: center;
151
+ flex-wrap: wrap;
152
+ padding-top: 5px;
153
+ }
154
+
155
+ .radio-group label,
156
+ .checkbox-group label {
157
+ font-weight: normal;
158
+ cursor: pointer;
159
+ display: inline-flex;
160
+ align-items: center;
161
+ gap: 5px;
162
+ }
163
+
164
+ input[type="range"] {
165
+ width: 100%;
166
+ cursor: pointer;
167
+ }
168
+
169
+ .button-group {
170
+ display: flex;
171
+ gap: 10px;
172
+ margin-top: 20px;
173
+ }
174
+
175
+ .btn {
176
+ padding: 10px 20px;
177
+ border: none;
178
+ border-radius: 4px;
179
+ font-size: 14px;
180
+ font-weight: bold;
181
+ cursor: pointer;
182
+ transition: background-color 0.3s ease, transform 0.1s ease;
183
+ }
184
+
185
+ .btn:active {
186
+ transform: scale(0.98);
187
+ }
188
+
189
+ .btn-primary {
190
+ background-color: #3498db;
191
+ color: #ffffff;
192
+ }
193
+
194
+ .btn-primary:hover {
195
+ background-color: #2980b9;
196
+ }
197
+
198
+ .btn-secondary {
199
+ background-color: #95a5a6;
200
+ color: #ffffff;
201
+ }
202
+
203
+ .btn-secondary:hover {
204
+ background-color: #7f8c8d;
205
+ }
206
+
207
+ .btn-danger {
208
+ background-color: #e74c3c;
209
+ color: #ffffff;
210
+ padding: 5px 10px;
211
+ font-size: 12px;
212
+ }
213
+
214
+ .btn-danger:hover {
215
+ background-color: #c0392b;
216
+ }
217
+
218
+ .btn-sm {
219
+ padding: 6px 12px;
220
+ background-color: #34495e;
221
+ color: #ffffff;
222
+ font-size: 12px;
223
+ }
224
+
225
+ .btn-sm:hover {
226
+ background-color: #2c3e50;
227
+ }
228
+
229
+ .alert-box {
230
+ margin-top: 15px;
231
+ padding: 12px;
232
+ border-radius: 4px;
233
+ display: none;
234
+ }
235
+
236
+ .alert-box.success {
237
+ display: block;
238
+ background-color: #d4edda;
239
+ color: #155724;
240
+ border: 1px solid #c3e6cb;
241
+ }
242
+
243
+ .alert-box.error {
244
+ display: block;
245
+ background-color: #f8d7da;
246
+ color: #721c24;
247
+ border: 1px solid #f5c6cb;
248
+ }
249
+
250
+ .table-container {
251
+ overflow-x: auto;
252
+ }
253
+
254
+ table {
255
+ width: 100%;
20
256
  border-collapse: collapse;
21
- padding: 4px 8px;
257
+ margin-top: 10px;
258
+ }
259
+
260
+ caption {
261
+ font-weight: bold;
262
+ margin-bottom: 8px;
263
+ text-align: left;
264
+ }
265
+
266
+ table, th, td {
267
+ border: 1px solid #dddddd;
268
+ }
269
+
270
+ th, td {
271
+ padding: 10px;
272
+ text-align: left;
273
+ font-size: 14px;
274
+ }
275
+
276
+ th {
277
+ background-color: #2c3e50;
278
+ color: #ffffff;
279
+ }
280
+
281
+ tbody tr:nth-child(even) {
282
+ background-color: #f9f9f9;
283
+ }
284
+
285
+ tbody tr:hover {
286
+ background-color: #f1f1f1;
287
+ }
288
+
289
+ tfoot {
290
+ font-weight: bold;
291
+ background-color: #ecf0f1;
292
+ }
293
+
294
+ .dom-grid {
295
+ display: grid;
296
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
297
+ gap: 20px;
298
+ }
299
+
300
+ .dom-box {
301
+ border: 1px solid #e0e0e0;
302
+ border-radius: 6px;
303
+ padding: 15px;
304
+ background-color: #fafafa;
305
+ display: flex;
306
+ flex-direction: column;
307
+ align-items: center;
308
+ text-align: center;
309
+ gap: 10px;
310
+ }
311
+
312
+ .dom-box h3 {
313
+ font-size: 16px;
314
+ color: #2c3e50;
315
+ }
316
+
317
+ .dom-box img {
318
+ cursor: pointer;
319
+ transition: transform 0.3s ease;
320
+ }
321
+
322
+ .dom-box img:hover {
323
+ transform: scale(1.1);
324
+ }
325
+
326
+ .counter-display {
327
+ font-size: 36px;
328
+ font-weight: bold;
329
+ color: #e74c3c;
330
+ min-height: 50px;
331
+ }
332
+
333
+ .btn-cluster {
334
+ display: flex;
335
+ gap: 8px;
336
+ flex-wrap: wrap;
337
+ justify-content: center;
338
+ }
339
+
340
+ ol#orderList {
341
+ text-align: left;
342
+ width: 100%;
343
+ padding-left: 20px;
344
+ }
345
+
346
+ ol#orderList li {
347
+ padding: 6px;
348
+ cursor: pointer;
349
+ user-select: none;
350
+ border-radius: 4px;
351
+ transition: background-color 0.2s ease;
352
+ }
353
+
354
+ ol#orderList li:hover {
355
+ background-color: #e8f4fd;
356
+ }
357
+
358
+ .collapse-panel {
359
+ display: block;
360
+ width: 100%;
361
+ padding: 10px;
362
+ background-color: #eaf2f8;
363
+ border: 1px dashed #3498db;
364
+ border-radius: 4px;
365
+ }
366
+
367
+ .styled-list {
368
+ list-style-type: none;
369
+ width: 100%;
370
+ text-align: left;
371
+ }
372
+
373
+ .styled-list li {
374
+ padding: 8px;
375
+ border-bottom: 1px solid #eee;
376
+ cursor: pointer;
377
+ position: relative;
378
+ transition: transform 0.2s ease, color 0.2s ease;
379
+ }
380
+
381
+ .styled-list li::before {
382
+ content: "➔ ";
383
+ color: #3498db;
384
+ }
385
+
386
+ .styled-list li:hover {
387
+ color: #2980b9;
388
+ transform: translateX(5px);
389
+ }
390
+
391
+ .console-box {
392
+ background-color: #2c3e50;
393
+ color: #2ecc71;
394
+ padding: 15px;
395
+ border-radius: 6px;
396
+ font-family: 'Courier New', Courier, monospace;
397
+ font-size: 13px;
398
+ white-space: pre-wrap;
399
+ max-height: 350px;
400
+ overflow-y: auto;
401
+ margin-top: 15px;
402
+ }
403
+
404
+ .fixed-badge {
405
+ position: fixed;
406
+ bottom: 20px;
407
+ right: 20px;
408
+ background-color: #e67e22;
409
+ color: #ffffff;
410
+ padding: 8px 16px;
411
+ border-radius: 20px;
412
+ font-size: 12px;
413
+ font-weight: bold;
414
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
415
+ z-index: 1000;
416
+ }
417
+
418
+ .animated-badge {
419
+ animation-name: badgePulse;
420
+ animation-duration: 2s;
421
+ animation-iteration-count: infinite;
422
+ animation-direction: alternate;
423
+ animation-timing-function: ease-in-out;
424
+ }
425
+
426
+ @keyframes badgePulse {
427
+ from {
428
+ transform: scale(1);
429
+ }
430
+ to {
431
+ transform: scale(1.08);
432
+ }
433
+ }
434
+
435
+ .mouse-trail-particle {
436
+ position: absolute;
437
+ width: 12px;
438
+ height: 12px;
439
+ background-color: #e74c3c;
440
+ border-radius: 50%;
441
+ pointer-events: none;
442
+ transform: translate(-50%, -50%);
443
+ animation: fadeParticle 0.8s forwards;
444
+ z-index: 9999;
445
+ }
446
+
447
+ @keyframes fadeParticle {
448
+ 0% {
449
+ opacity: 1;
450
+ transform: translate(-50%, -50%) scale(1);
451
+ }
452
+ 100% {
453
+ opacity: 0;
454
+ transform: translate(-50%, -50%) scale(2.5);
455
+ }
456
+ }
457
+
458
+ .app-footer {
459
+ text-align: center;
460
+ padding: 15px;
461
+ color: #7f8c8d;
462
+ font-size: 13px;
22
463
  }
@@ -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 Shopping Cart</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-cart-router-pinia",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "pinia": "^4.1.0",
13
+ "vue": "^3.5.44",
14
+ "vue-router": "^5.4.0"
15
+ },
16
+ "devDependencies": {
17
+ "@vitejs/plugin-vue": "^6.0.10",
18
+ "vite": "^8.3.4"
19
+ }
20
+ }
@@ -0,0 +1,78 @@
1
+ <script setup>
2
+ import { useCartStore } from './stores/cartStore'
3
+
4
+ const cartStore = useCartStore()
5
+ </script>
6
+
7
+ <template>
8
+ <div class="store-app">
9
+ <header class="store-header">
10
+ <h1>Vue Pinia Shopping Cart</h1>
11
+ <nav class="nav">
12
+ <router-link to="/" class="nav-link">Products</router-link>
13
+ <span class="divider">|</span>
14
+ <router-link to="/cart" class="nav-link cart-link">
15
+ Cart ({{ cartStore.cartCount }})
16
+ </router-link>
17
+ </nav>
18
+ </header>
19
+
20
+ <main class="store-main">
21
+ <router-view />
22
+ </main>
23
+ </div>
24
+ </template>
25
+
26
+ <style scoped>
27
+ .store-app {
28
+ max-width: 650px;
29
+ margin: 30px auto;
30
+ font-family: Arial, sans-serif;
31
+ padding: 0 15px;
32
+ }
33
+
34
+ .store-header {
35
+ display: flex;
36
+ justify-content: space-between;
37
+ align-items: center;
38
+ border-bottom: 2px solid #333;
39
+ padding-bottom: 15px;
40
+ margin-bottom: 20px;
41
+ }
42
+
43
+ .store-header h1 {
44
+ font-size: 20px;
45
+ margin: 0;
46
+ }
47
+
48
+ .nav {
49
+ display: flex;
50
+ gap: 10px;
51
+ align-items: center;
52
+ }
53
+
54
+ .nav-link {
55
+ text-decoration: none;
56
+ color: #2980b9;
57
+ font-weight: bold;
58
+ }
59
+
60
+ .nav-link.router-link-exact-active {
61
+ color: #27ae60;
62
+ text-decoration: underline;
63
+ }
64
+
65
+ .cart-link {
66
+ background-color: #f1f2f6;
67
+ padding: 6px 12px;
68
+ border-radius: 20px;
69
+ }
70
+
71
+ .divider {
72
+ color: #ccc;
73
+ }
74
+
75
+ .store-main {
76
+ padding: 10px 0;
77
+ }
78
+ </style>
@@ -0,0 +1,9 @@
1
+ import { createApp } from 'vue'
2
+ import { createPinia } from 'pinia'
3
+ import App from './App.vue'
4
+ import router from './router'
5
+
6
+ const app = createApp(App)
7
+ app.use(createPinia())
8
+ app.use(router)
9
+ app.mount('#app')
@@ -0,0 +1,17 @@
1
+ import { createRouter, createWebHistory } from 'vue-router'
2
+ import ProductCatalogView from '../views/ProductCatalogView.vue'
3
+ import CartView from '../views/CartView.vue'
4
+ import CheckoutView from '../views/CheckoutView.vue'
5
+
6
+ const routes = [
7
+ { path: '/', name: 'Catalog', component: ProductCatalogView },
8
+ { path: '/cart', name: 'Cart', component: CartView },
9
+ { path: '/checkout', name: 'Checkout', component: CheckoutView }
10
+ ]
11
+
12
+ const router = createRouter({
13
+ history: createWebHistory(),
14
+ routes
15
+ })
16
+
17
+ export default router
@@ -0,0 +1,58 @@
1
+ import { defineStore } from 'pinia'
2
+
3
+ export const useCartStore = defineStore('cart', {
4
+ state: () => ({
5
+ products: [
6
+ { id: 1, name: 'Wireless Laptop', price: 999, category: 'Electronics' },
7
+ { id: 2, name: 'Noise-Canceling Headphones', price: 149, category: 'Audio' },
8
+ { id: 3, name: 'Mechanical Keyboard', price: 79, category: 'Accessories' },
9
+ { id: 4, name: 'Optical Gaming Mouse', price: 39, category: 'Accessories' },
10
+ { id: 5, name: 'USB-C Docking Hub', price: 49, category: 'Electronics' }
11
+ ],
12
+ items: []
13
+ }),
14
+ getters: {
15
+ cartCount: (state) => {
16
+ return state.items.reduce((total, item) => total + item.quantity, 0)
17
+ },
18
+ cartTotal: (state) => {
19
+ return state.items.reduce((total, item) => total + item.price * item.quantity, 0)
20
+ }
21
+ },
22
+ actions: {
23
+ addToCart(product) {
24
+ const existing = this.items.find((item) => item.id === product.id)
25
+ if (existing) {
26
+ existing.quantity++
27
+ } else {
28
+ this.items.push({
29
+ id: product.id,
30
+ name: product.name,
31
+ price: product.price,
32
+ quantity: 1
33
+ })
34
+ }
35
+ },
36
+ incrementQuantity(id) {
37
+ const item = this.items.find((i) => i.id === id)
38
+ if (item) {
39
+ item.quantity++
40
+ }
41
+ },
42
+ decrementQuantity(id) {
43
+ const item = this.items.find((i) => i.id === id)
44
+ if (item) {
45
+ item.quantity--
46
+ if (item.quantity <= 0) {
47
+ this.removeFromCart(id)
48
+ }
49
+ }
50
+ },
51
+ removeFromCart(id) {
52
+ this.items = this.items.filter((item) => item.id !== id)
53
+ },
54
+ clearCart() {
55
+ this.items = []
56
+ }
57
+ }
58
+ })