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
@@ -0,0 +1,139 @@
1
+ <script setup>
2
+ import { useCartStore } from '../stores/cartStore'
3
+
4
+ const cartStore = useCartStore()
5
+ </script>
6
+
7
+ <template>
8
+ <div>
9
+ <h2>Your Shopping Cart</h2>
10
+
11
+ <div v-if="cartStore.items.length === 0" class="empty-cart">
12
+ <p>Your cart is empty.</p>
13
+ <router-link to="/">Browse Products</router-link>
14
+ </div>
15
+
16
+ <div v-else>
17
+ <table class="cart-table">
18
+ <thead>
19
+ <tr>
20
+ <th>Product</th>
21
+ <th>Price</th>
22
+ <th>Quantity</th>
23
+ <th>Subtotal</th>
24
+ <th>Action</th>
25
+ </tr>
26
+ </thead>
27
+ <tbody>
28
+ <tr v-for="item in cartStore.items" :key="item.id">
29
+ <td>{{ item.name }}</td>
30
+ <td>${{ item.price }}</td>
31
+ <td class="qty-cell">
32
+ <button type="button" class="btn-qty" @click="cartStore.decrementQuantity(item.id)">-</button>
33
+ <span>{{ item.quantity }}</span>
34
+ <button type="button" class="btn-qty" @click="cartStore.incrementQuantity(item.id)">+</button>
35
+ </td>
36
+ <td>${{ item.price * item.quantity }}</td>
37
+ <td>
38
+ <button type="button" class="btn-remove" @click="cartStore.removeFromCart(item.id)">Remove</button>
39
+ </td>
40
+ </tr>
41
+ </tbody>
42
+ <tfoot>
43
+ <tr>
44
+ <td colspan="3" class="total-label">Grand Total:</td>
45
+ <td colspan="2" class="total-value">${{ cartStore.cartTotal }}</td>
46
+ </tr>
47
+ </tfoot>
48
+ </table>
49
+
50
+ <div class="cart-actions">
51
+ <button type="button" class="btn btn-clear" @click="cartStore.clearCart()">Clear Cart</button>
52
+ <router-link to="/checkout" class="btn btn-checkout">Proceed to Checkout</router-link>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </template>
57
+
58
+ <style scoped>
59
+ .empty-cart {
60
+ padding: 30px;
61
+ text-align: center;
62
+ color: #777;
63
+ }
64
+
65
+ .cart-table {
66
+ width: 100%;
67
+ border-collapse: collapse;
68
+ margin: 15px 0;
69
+ }
70
+
71
+ .cart-table th, .cart-table td {
72
+ border: 1px solid #ddd;
73
+ padding: 10px;
74
+ text-align: left;
75
+ }
76
+
77
+ .cart-table th {
78
+ background-color: #f2f2f2;
79
+ }
80
+
81
+ .qty-cell {
82
+ display: flex;
83
+ align-items: center;
84
+ gap: 8px;
85
+ }
86
+
87
+ .btn-qty {
88
+ width: 24px;
89
+ height: 24px;
90
+ background-color: #eee;
91
+ border: 1px solid #ccc;
92
+ cursor: pointer;
93
+ }
94
+
95
+ .btn-remove {
96
+ background-color: #e74c3c;
97
+ color: white;
98
+ border: none;
99
+ padding: 4px 8px;
100
+ border-radius: 3px;
101
+ cursor: pointer;
102
+ }
103
+
104
+ .total-label {
105
+ text-align: right;
106
+ font-weight: bold;
107
+ }
108
+
109
+ .total-value {
110
+ font-weight: bold;
111
+ color: #27ae60;
112
+ font-size: 16px;
113
+ }
114
+
115
+ .cart-actions {
116
+ display: flex;
117
+ justify-content: space-between;
118
+ margin-top: 15px;
119
+ }
120
+
121
+ .btn {
122
+ padding: 10px 18px;
123
+ border-radius: 4px;
124
+ text-decoration: none;
125
+ font-size: 14px;
126
+ cursor: pointer;
127
+ border: none;
128
+ }
129
+
130
+ .btn-clear {
131
+ background-color: #95a5a6;
132
+ color: white;
133
+ }
134
+
135
+ .btn-checkout {
136
+ background-color: #27ae60;
137
+ color: white;
138
+ }
139
+ </style>
@@ -0,0 +1,144 @@
1
+ <script setup>
2
+ import { ref } from 'vue'
3
+ import { useRouter } from 'vue-router'
4
+ import { useCartStore } from '../stores/cartStore'
5
+
6
+ const cartStore = useCartStore()
7
+ const router = useRouter()
8
+
9
+ const name = ref('')
10
+ const address = ref('')
11
+ const orderPlaced = ref(false)
12
+
13
+ function handleCheckout() {
14
+ orderPlaced.value = true
15
+ cartStore.clearCart()
16
+ }
17
+ </script>
18
+
19
+ <template>
20
+ <div class="checkout-wrapper">
21
+ <h2>Checkout & Order Summary</h2>
22
+
23
+ <div v-if="orderPlaced" class="success-banner">
24
+ <h3>Thank you for your order! 🎉</h3>
25
+ <p>Your order has been placed successfully.</p>
26
+ <router-link to="/" class="btn btn-shop">Continue Shopping</router-link>
27
+ </div>
28
+
29
+ <div v-else-if="cartStore.items.length === 0" class="empty-state">
30
+ <p>No items in cart to checkout.</p>
31
+ <router-link to="/">Browse Catalog</router-link>
32
+ </div>
33
+
34
+ <div v-else class="checkout-content">
35
+ <div class="order-summary">
36
+ <h3>Order Items:</h3>
37
+ <ul>
38
+ <li v-for="item in cartStore.items" :key="item.id">
39
+ {{ item.name }} x {{ item.quantity }} — ${{ item.price * item.quantity }}
40
+ </li>
41
+ </ul>
42
+ <p class="summary-total">Total Amount: <strong>${{ cartStore.cartTotal }}</strong></p>
43
+ </div>
44
+
45
+ <form @submit.prevent="handleCheckout" class="checkout-form">
46
+ <h3>Shipping Information</h3>
47
+ <div class="form-group">
48
+ <label for="custName">Full Name:</label>
49
+ <input id="custName" type="text" v-model="name" required placeholder="John Doe" />
50
+ </div>
51
+
52
+ <div class="form-group">
53
+ <label for="custAddr">Delivery Address:</label>
54
+ <textarea id="custAddr" v-model="address" rows="3" required placeholder="123 Main St, City"></textarea>
55
+ </div>
56
+
57
+ <button type="submit" class="btn btn-place">Confirm and Place Order</button>
58
+ </form>
59
+ </div>
60
+ </div>
61
+ </template>
62
+
63
+ <style scoped>
64
+ .checkout-wrapper {
65
+ max-width: 500px;
66
+ }
67
+
68
+ .checkout-content {
69
+ display: flex;
70
+ flex-direction: column;
71
+ gap: 20px;
72
+ }
73
+
74
+ .order-summary {
75
+ background-color: #f8f9fa;
76
+ padding: 15px;
77
+ border-radius: 6px;
78
+ border: 1px solid #ddd;
79
+ }
80
+
81
+ .order-summary ul {
82
+ padding-left: 20px;
83
+ margin: 10px 0;
84
+ }
85
+
86
+ .summary-total {
87
+ font-size: 16px;
88
+ margin-top: 10px;
89
+ }
90
+
91
+ .checkout-form {
92
+ display: flex;
93
+ flex-direction: column;
94
+ gap: 12px;
95
+ }
96
+
97
+ .form-group {
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 4px;
101
+ }
102
+
103
+ input, textarea {
104
+ padding: 8px;
105
+ border: 1px solid #ccc;
106
+ border-radius: 4px;
107
+ }
108
+
109
+ .btn {
110
+ padding: 10px 16px;
111
+ border: none;
112
+ border-radius: 4px;
113
+ cursor: pointer;
114
+ text-decoration: none;
115
+ font-size: 14px;
116
+ text-align: center;
117
+ }
118
+
119
+ .btn-place {
120
+ background-color: #27ae60;
121
+ color: white;
122
+ margin-top: 10px;
123
+ }
124
+
125
+ .btn-shop {
126
+ background-color: #2980b9;
127
+ color: white;
128
+ display: inline-block;
129
+ margin-top: 10px;
130
+ }
131
+
132
+ .success-banner {
133
+ background-color: #d4edda;
134
+ color: #155724;
135
+ padding: 20px;
136
+ border-radius: 6px;
137
+ text-align: center;
138
+ }
139
+
140
+ .empty-state {
141
+ padding: 20px 0;
142
+ text-align: center;
143
+ }
144
+ </style>
@@ -0,0 +1,73 @@
1
+ <script setup>
2
+ import { useCartStore } from '../stores/cartStore'
3
+
4
+ const cartStore = useCartStore()
5
+ </script>
6
+
7
+ <template>
8
+ <div>
9
+ <h2>Available Products</h2>
10
+ <div class="product-grid">
11
+ <div v-for="product in cartStore.products" :key="product.id" class="product-card">
12
+ <h3>{{ product.name }}</h3>
13
+ <p class="category">{{ product.category }}</p>
14
+ <p class="price">${{ product.price }}</p>
15
+ <button
16
+ type="button"
17
+ class="btn btn-add"
18
+ @click="cartStore.addToCart(product)"
19
+ >
20
+ Add to Cart
21
+ </button>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ </template>
26
+
27
+ <style scoped>
28
+ .product-grid {
29
+ display: grid;
30
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
31
+ gap: 15px;
32
+ margin-top: 15px;
33
+ }
34
+
35
+ .product-card {
36
+ border: 1px solid #ddd;
37
+ border-radius: 6px;
38
+ padding: 15px;
39
+ text-align: center;
40
+ background-color: #fafafa;
41
+ }
42
+
43
+ .product-card h3 {
44
+ font-size: 16px;
45
+ margin: 5px 0;
46
+ }
47
+
48
+ .category {
49
+ color: #777;
50
+ font-size: 12px;
51
+ margin-bottom: 8px;
52
+ }
53
+
54
+ .price {
55
+ font-size: 18px;
56
+ font-weight: bold;
57
+ color: #27ae60;
58
+ margin-bottom: 12px;
59
+ }
60
+
61
+ .btn-add {
62
+ background-color: #2980b9;
63
+ color: white;
64
+ border: none;
65
+ padding: 8px 12px;
66
+ border-radius: 4px;
67
+ cursor: pointer;
68
+ }
69
+
70
+ .btn-add:hover {
71
+ background-color: #1f618d;
72
+ }
73
+ </style>
@@ -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 Pinia Memory Game</title>
7
+ </head>
8
+ <body>
9
+ <div id="app"></div>
10
+ <script type="module" src="/src/main.js"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "vue-memory-game",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "pinia": "^4.1.0",
13
+ "vue": "^3.5.44"
14
+ },
15
+ "devDependencies": {
16
+ "@vitejs/plugin-vue": "^6.0.10",
17
+ "vite": "^8.3.4"
18
+ }
19
+ }
@@ -0,0 +1,106 @@
1
+ <script setup>
2
+ import { onMounted } from 'vue'
3
+ import { useMemoryStore } from './stores/memoryStore'
4
+
5
+ const store = useMemoryStore()
6
+
7
+ onMounted(() => {
8
+ store.initGame()
9
+ })
10
+ </script>
11
+
12
+ <template>
13
+ <div class="game-wrapper">
14
+ <h1>Vue Pinia Memory Game</h1>
15
+
16
+ <div class="stats">
17
+ <span>Moves: {{ store.moves }}</span>
18
+ <span>Matches: {{ store.matches }} / {{ store.symbols.length }}</span>
19
+ </div>
20
+
21
+ <button type="button" class="btn" @click="store.initGame()">Restart Game</button>
22
+
23
+ <div v-if="store.isGameOver" class="win-banner">
24
+ 🎉 You won in {{ store.moves }} moves!
25
+ </div>
26
+
27
+ <div class="grid">
28
+ <div
29
+ v-for="card in store.cards"
30
+ :key="card.id"
31
+ class="card"
32
+ :class="{ flipped: card.isFlipped, matched: card.isMatched }"
33
+ @click="store.flipCard(card)"
34
+ >
35
+ {{ card.isFlipped || card.isMatched ? card.symbol : '?' }}
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </template>
40
+
41
+ <style scoped>
42
+ .game-wrapper {
43
+ max-width: 360px;
44
+ margin: 30px auto;
45
+ text-align: center;
46
+ font-family: Arial, sans-serif;
47
+ }
48
+
49
+ .stats {
50
+ display: flex;
51
+ justify-content: space-around;
52
+ font-size: 18px;
53
+ font-weight: bold;
54
+ margin: 15px 0;
55
+ }
56
+
57
+ .btn {
58
+ padding: 8px 16px;
59
+ background-color: #2980b9;
60
+ color: white;
61
+ border: none;
62
+ border-radius: 4px;
63
+ cursor: pointer;
64
+ margin-bottom: 20px;
65
+ }
66
+
67
+ .win-banner {
68
+ padding: 10px;
69
+ background-color: #d4edda;
70
+ color: #155724;
71
+ margin-bottom: 15px;
72
+ border-radius: 4px;
73
+ font-weight: bold;
74
+ }
75
+
76
+ .grid {
77
+ display: grid;
78
+ grid-template-columns: repeat(4, 75px);
79
+ gap: 10px;
80
+ justify-content: center;
81
+ }
82
+
83
+ .card {
84
+ width: 75px;
85
+ height: 75px;
86
+ background-color: #34495e;
87
+ color: white;
88
+ font-size: 32px;
89
+ display: flex;
90
+ justify-content: center;
91
+ align-items: center;
92
+ border-radius: 6px;
93
+ cursor: pointer;
94
+ user-select: none;
95
+ }
96
+
97
+ .card.flipped {
98
+ background-color: #ecf0f1;
99
+ color: #2c3e50;
100
+ }
101
+
102
+ .card.matched {
103
+ background-color: #2ecc71;
104
+ color: white;
105
+ }
106
+ </style>
@@ -0,0 +1,7 @@
1
+ import { createApp } from 'vue'
2
+ import { createPinia } from 'pinia'
3
+ import App from './App.vue'
4
+
5
+ const app = createApp(App)
6
+ app.use(createPinia())
7
+ app.mount('#app')
@@ -0,0 +1,64 @@
1
+ import { defineStore } from 'pinia'
2
+
3
+ export const useMemoryStore = defineStore('memory', {
4
+ state: () => ({
5
+ symbols: ['🐶', '🐱', '🐭', '🐹', '🐰', '🦊'],
6
+ cards: [],
7
+ flippedCards: [],
8
+ moves: 0,
9
+ matches: 0,
10
+ isLocked: false
11
+ }),
12
+ getters: {
13
+ isGameOver: (state) => state.matches === state.symbols.length
14
+ },
15
+ actions: {
16
+ initGame() {
17
+ const duplicated = [...this.symbols, ...this.symbols]
18
+ duplicated.sort(() => 0.5 - Math.random())
19
+
20
+ this.cards = duplicated.map((symbol, idx) => ({
21
+ id: idx,
22
+ symbol: symbol,
23
+ isFlipped: false,
24
+ isMatched: false
25
+ }))
26
+
27
+ this.flippedCards = []
28
+ this.moves = 0
29
+ this.matches = 0
30
+ this.isLocked = false
31
+ },
32
+
33
+ flipCard(card) {
34
+ if (this.isLocked || card.isFlipped || card.isMatched) return
35
+
36
+ card.isFlipped = true
37
+ this.flippedCards.push(card)
38
+
39
+ if (this.flippedCards.length === 2) {
40
+ this.moves++
41
+ this.checkMatch()
42
+ }
43
+ },
44
+
45
+ checkMatch() {
46
+ const [card1, card2] = this.flippedCards
47
+
48
+ if (card1.symbol === card2.symbol) {
49
+ card1.isMatched = true
50
+ card2.isMatched = true
51
+ this.matches++
52
+ this.flippedCards = []
53
+ } else {
54
+ this.isLocked = true
55
+ setTimeout(() => {
56
+ card1.isFlipped = false
57
+ card2.isFlipped = false
58
+ this.flippedCards = []
59
+ this.isLocked = false
60
+ }, 800)
61
+ }
62
+ }
63
+ }
64
+ })
@@ -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 Pinia Todo List</title>
7
+ </head>
8
+ <body>
9
+ <div id="app"></div>
10
+ <script type="module" src="/src/main.js"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "vue-todo-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
+ },
15
+ "devDependencies": {
16
+ "@vitejs/plugin-vue": "^6.0.10",
17
+ "vite": "^8.3.4"
18
+ }
19
+ }