@vc-shell/create-vc-app 1.1.99-alpha.1 → 1.2.0
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.
- package/README.md +26 -552
- package/dist/index.js +530 -1900
- package/dist/templates/base/_package.json +5 -5
- package/dist/templates/base/src/main.ts +4 -0
- package/dist/templates/mocks/sample-data/constants.ts +89 -0
- package/dist/templates/mocks/sample-data/index.ts +2 -0
- package/dist/templates/mocks/sample-data/methods.ts +65 -0
- package/dist/templates/modules/classic-module/composables/index.ts +2 -0
- package/dist/templates/modules/classic-module/composables/use{{ModuleNamePascalCase}}Details/index.ts +24 -0
- package/dist/templates/modules/classic-module/composables/use{{ModuleNamePascalCase}}List/index.ts +47 -0
- package/dist/templates/modules/classic-module/index.ts +8 -0
- package/dist/templates/modules/classic-module/locales/en.json +37 -0
- package/dist/templates/modules/classic-module/locales/index.ts +2 -0
- package/dist/templates/modules/classic-module/pages/details.vue +87 -0
- package/dist/templates/modules/classic-module/pages/index.ts +2 -0
- package/dist/templates/modules/classic-module/pages/list.vue +257 -0
- package/dist/templates/sample/classic-module/composables/index.ts +2 -0
- package/dist/templates/sample/classic-module/composables/useDetails/index.ts +54 -0
- package/dist/templates/sample/classic-module/composables/useList/index.ts +62 -0
- package/dist/templates/sample/classic-module/index.ts +8 -0
- package/dist/templates/sample/classic-module/locales/en.json +67 -0
- package/dist/templates/sample/classic-module/locales/index.ts +2 -0
- package/dist/templates/sample/classic-module/pages/details.vue +238 -0
- package/dist/templates/sample/classic-module/pages/index.ts +2 -0
- package/dist/templates/sample/classic-module/pages/list.vue +300 -0
- package/dist/templates/sample/overrides/main.ts +52 -0
- package/package.json +7 -12
- package/dist/cli/argv.d.ts +0 -4
- package/dist/cli/argv.d.ts.map +0 -1
- package/dist/cli/constants.d.ts +0 -4
- package/dist/cli/constants.d.ts.map +0 -1
- package/dist/cli/errors.d.ts +0 -12
- package/dist/cli/errors.d.ts.map +0 -1
- package/dist/cli/help.d.ts +0 -3
- package/dist/cli/help.d.ts.map +0 -1
- package/dist/cli/run.d.ts +0 -2
- package/dist/cli/run.d.ts.map +0 -1
- package/dist/cli/runtime.d.ts +0 -7
- package/dist/cli/runtime.d.ts.map +0 -1
- package/dist/cli/types.d.ts +0 -30
- package/dist/cli/types.d.ts.map +0 -1
- package/dist/cli/utils.d.ts +0 -4
- package/dist/cli/utils.d.ts.map +0 -1
- package/dist/cli/validation.d.ts +0 -5
- package/dist/cli/validation.d.ts.map +0 -1
- package/dist/commands/generate-blade.d.ts +0 -16
- package/dist/commands/generate-blade.d.ts.map +0 -1
- package/dist/templates/base/ai-guides/.cursorrules-vc-shell +0 -529
- package/dist/templates/base/ai-guides/README.md +0 -360
- package/dist/templates/base/ai-guides/guides/AI_GUIDE.md +0 -195
- package/dist/templates/base/ai-guides/guides/blade-patterns.md +0 -384
- package/dist/templates/base/ai-guides/guides/complete-workflow.md +0 -781
- package/dist/templates/base/ai-guides/guides/composables-reference.md +0 -338
- package/dist/templates/base/ai-guides/guides/troubleshooting.md +0 -529
- package/dist/templates/base/ai-guides/guides/ui-components-reference.md +0 -903
- package/dist/templates/base/ai-guides/prompts/adapt-existing-module.md +0 -1026
- package/dist/templates/base/ai-guides/prompts/advanced-scenarios.md +0 -852
- package/dist/templates/base/ai-guides/prompts/api-client-generation.md +0 -877
- package/dist/templates/base/ai-guides/prompts/cli-usage.md +0 -640
- package/dist/templates/base/ai-guides/prompts/quick-start-scenarios.md +0 -773
- package/dist/templates/base/ai-guides/prompts/simple-modifications.md +0 -987
- package/dist/templates/blades/details/blade.vue +0 -175
- package/dist/templates/blades/grid/blade.vue +0 -340
- package/dist/templates/composables/details-composable.ts +0 -101
- package/dist/templates/composables/grid-composable.ts +0 -244
- package/dist/templates/module/components/index.ts +0 -2
- package/dist/templates/module/components/widgets/index.ts +0 -2
- package/dist/templates/module/composables/index.ts +0 -3
- package/dist/templates/module/index.ts +0 -13
- package/dist/templates/module/locales/en.json +0 -65
- package/dist/templates/module/locales/index.ts +0 -4
- package/dist/templates/module/pages/index.ts +0 -3
- package/dist/templates/widgets/widget.vue +0 -113
- package/dist/utils/form-builder.d.ts +0 -69
- package/dist/utils/form-builder.d.ts.map +0 -1
- package/dist/utils/format.d.ts +0 -24
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/naming.d.ts +0 -44
- package/dist/utils/naming.d.ts.map +0 -1
- package/dist/utils/register-module.d.ts +0 -21
- package/dist/utils/register-module.d.ts.map +0 -1
- package/dist/workflows/create-app.d.ts +0 -14
- package/dist/workflows/create-app.d.ts.map +0 -1
|
@@ -1,781 +0,0 @@
|
|
|
1
|
-
# Complete Development Workflow
|
|
2
|
-
|
|
3
|
-
End-to-end guide for creating a VC Shell application from scratch to deployment.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
This guide walks you through the complete process:
|
|
8
|
-
1. Create application
|
|
9
|
-
2. Generate modules
|
|
10
|
-
3. Connect API
|
|
11
|
-
4. Test functionality
|
|
12
|
-
5. Customize and extend
|
|
13
|
-
6. Build for production
|
|
14
|
-
7. Deploy
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## Phase 1: Project Creation (5 minutes)
|
|
19
|
-
|
|
20
|
-
### Step 1.1: Create New Application
|
|
21
|
-
|
|
22
|
-
**Command:**
|
|
23
|
-
```bash
|
|
24
|
-
npx create-vc-app my-shop
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
**Interactive Prompts:**
|
|
28
|
-
```
|
|
29
|
-
✔ Project name: … my-shop
|
|
30
|
-
✔ Base path: … /apps/my-shop/
|
|
31
|
-
|
|
32
|
-
📦 Scaffolding app...
|
|
33
|
-
✅ Created 60 files
|
|
34
|
-
|
|
35
|
-
🏗️ Creating module...
|
|
36
|
-
✔ Module name: … products
|
|
37
|
-
✔ Entity name: … Product
|
|
38
|
-
✔ Create both blades: … yes
|
|
39
|
-
✔ Workspace blade: › Grid blade
|
|
40
|
-
✔ Customize form: … yes
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
**What You Get:**
|
|
44
|
-
```
|
|
45
|
-
my-shop/
|
|
46
|
-
├── src/
|
|
47
|
-
│ ├── main.ts
|
|
48
|
-
│ ├── router/
|
|
49
|
-
│ ├── locales/
|
|
50
|
-
│ ├── modules/
|
|
51
|
-
│ │ └── products/ ← Your first module
|
|
52
|
-
│ ├── pages/
|
|
53
|
-
│ ├── styles/
|
|
54
|
-
│ └── api_client/ ← Placeholder for API
|
|
55
|
-
├── package.json
|
|
56
|
-
├── vite.config.mts
|
|
57
|
-
├── .prettierrc
|
|
58
|
-
├── .eslintrc.js
|
|
59
|
-
└── ai-guides/ ← This documentation
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Step 1.2: Install Dependencies
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
cd my-shop
|
|
66
|
-
yarn install
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
**Time:** ~2 minutes (depending on internet speed)
|
|
70
|
-
|
|
71
|
-
### Step 1.3: Verify Installation
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
yarn serve
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**Expected Output:**
|
|
78
|
-
```
|
|
79
|
-
VITE v6.x.x ready in 1234 ms
|
|
80
|
-
|
|
81
|
-
➜ Local: http://localhost:8080/apps/my-shop/
|
|
82
|
-
➜ Network: use --host to expose
|
|
83
|
-
➜ press h + enter to show help
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
**Open Browser:**
|
|
87
|
-
```
|
|
88
|
-
http://localhost:8080/apps/my-shop/
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**You Should See:**
|
|
92
|
-
- Login screen or dashboard
|
|
93
|
-
- Products module in navigation menu
|
|
94
|
-
- Products list blade (empty, no data yet)
|
|
95
|
-
|
|
96
|
-
✅ **Phase 1 Complete!** You have a working application.
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## Phase 2: Module Generation (10 minutes)
|
|
101
|
-
|
|
102
|
-
### Step 2.1: Add More Modules
|
|
103
|
-
|
|
104
|
-
**Generate Orders Module:**
|
|
105
|
-
```bash
|
|
106
|
-
npx create-vc-app blade
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
**Prompts:**
|
|
110
|
-
```
|
|
111
|
-
? What would you like to generate? › Module (with blades)
|
|
112
|
-
? Module name: › orders
|
|
113
|
-
? Entity name: › Order
|
|
114
|
-
? Create both blades: › yes
|
|
115
|
-
? Workspace blade: › Grid blade
|
|
116
|
-
? Customize form: › yes
|
|
117
|
-
|
|
118
|
-
Add form fields:
|
|
119
|
-
? Field name: › orderNumber
|
|
120
|
-
? Field type: › Text
|
|
121
|
-
? Is required: › yes
|
|
122
|
-
|
|
123
|
-
? Field name: › customer
|
|
124
|
-
? Field type: › Text
|
|
125
|
-
? Is required: › yes
|
|
126
|
-
|
|
127
|
-
? Field name: › total
|
|
128
|
-
? Field type: › Currency
|
|
129
|
-
? Is required: › yes
|
|
130
|
-
|
|
131
|
-
? Field name: › status
|
|
132
|
-
? Field type: › Select (Dropdown)
|
|
133
|
-
? Options: › pending,processing,shipped,delivered
|
|
134
|
-
? Is required: › yes
|
|
135
|
-
|
|
136
|
-
? Field name: › (press Enter to finish)
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
**Result:**
|
|
140
|
-
```
|
|
141
|
-
✅ Module generated successfully!
|
|
142
|
-
|
|
143
|
-
Created:
|
|
144
|
-
- src/modules/orders/
|
|
145
|
-
- Module registered in main.ts
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Step 2.2: Add Categories Module
|
|
149
|
-
|
|
150
|
-
**Non-Interactive Mode (faster):**
|
|
151
|
-
```bash
|
|
152
|
-
npx create-vc-app blade \
|
|
153
|
-
--module categories \
|
|
154
|
-
--type grid \
|
|
155
|
-
--name categories \
|
|
156
|
-
--composable \
|
|
157
|
-
--locales \
|
|
158
|
-
--is-workspace
|
|
159
|
-
|
|
160
|
-
npx create-vc-app blade \
|
|
161
|
-
--module categories \
|
|
162
|
-
--type details \
|
|
163
|
-
--name category-details \
|
|
164
|
-
--composable \
|
|
165
|
-
--locales \
|
|
166
|
-
--form-fields '[
|
|
167
|
-
{"name":"name","label":"Category Name","type":"VcInput","props":"{\"required\":true}"},
|
|
168
|
-
{"name":"description","label":"Description","type":"VcEditor","props":"{}"},
|
|
169
|
-
{"name":"active","label":"Active","type":"VcSwitch","props":"{}"}
|
|
170
|
-
]'
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Step 2.3: Verify Modules
|
|
174
|
-
|
|
175
|
-
**Restart dev server** (Ctrl+C, then `yarn serve`)
|
|
176
|
-
|
|
177
|
-
**Check in Browser:**
|
|
178
|
-
```
|
|
179
|
-
http://localhost:8080/apps/my-shop/
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
**You Should See:**
|
|
183
|
-
- Three modules in menu: Products, Orders, Categories
|
|
184
|
-
- Each module opens its list blade
|
|
185
|
-
- Clicking table rows opens details blade
|
|
186
|
-
|
|
187
|
-
✅ **Phase 2 Complete!** You have multiple modules.
|
|
188
|
-
|
|
189
|
-
---
|
|
190
|
-
|
|
191
|
-
## Phase 3: API Integration (15 minutes)
|
|
192
|
-
|
|
193
|
-
### Step 3.1: Choose API Integration Method
|
|
194
|
-
|
|
195
|
-
**Option A: VirtoCommerce Platform**
|
|
196
|
-
|
|
197
|
-
If you have VirtoCommerce Platform:
|
|
198
|
-
|
|
199
|
-
1. **Create `.env.local`:**
|
|
200
|
-
```env
|
|
201
|
-
APP_PLATFORM_URL=https://your-platform.com
|
|
202
|
-
APP_PLATFORM_MODULES=[Virtocommerce.Catalog, Virtocommerce.Orders]
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
2. **Generate API Client:**
|
|
206
|
-
```bash
|
|
207
|
-
yarn generate-api-client
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
3. **Update Composables:**
|
|
211
|
-
```typescript
|
|
212
|
-
// src/modules/products/composables/useProductsList.ts
|
|
213
|
-
import { useApiClient } from '@vc-shell/framework';
|
|
214
|
-
import { Catalog } from '../../../api_client/virtocommerce.catalog';
|
|
215
|
-
|
|
216
|
-
const { getApiClient } = useApiClient(Catalog);
|
|
217
|
-
|
|
218
|
-
const { action: loadProducts, loading, items } = useAsync(async () => {
|
|
219
|
-
const client = await getApiClient();
|
|
220
|
-
const response = await client.searchProducts({
|
|
221
|
-
skip: (currentPage.value - 1) * pageSize.value,
|
|
222
|
-
take: pageSize.value
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
return {
|
|
226
|
-
results: response.data.results || [],
|
|
227
|
-
totalCount: response.data.totalCount || 0
|
|
228
|
-
};
|
|
229
|
-
});
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
**Option B: Custom REST API**
|
|
233
|
-
|
|
234
|
-
If you have custom REST API:
|
|
235
|
-
|
|
236
|
-
1. **Create `.env.local`:**
|
|
237
|
-
```env
|
|
238
|
-
VITE_API_URL=https://api.myshop.com
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
2. **Create API Client:**
|
|
242
|
-
```typescript
|
|
243
|
-
// src/api_client/custom-api.ts
|
|
244
|
-
const API_URL = import.meta.env.VITE_API_URL;
|
|
245
|
-
|
|
246
|
-
export const api = {
|
|
247
|
-
products: {
|
|
248
|
-
async list(params: { skip: number; take: number; search?: string }) {
|
|
249
|
-
const query = new URLSearchParams({
|
|
250
|
-
skip: params.skip.toString(),
|
|
251
|
-
take: params.take.toString(),
|
|
252
|
-
...(params.search && { search: params.search })
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
const response = await fetch(`${API_URL}/products?${query}`);
|
|
256
|
-
return response.json();
|
|
257
|
-
},
|
|
258
|
-
|
|
259
|
-
async get(id: string) {
|
|
260
|
-
const response = await fetch(`${API_URL}/products/${id}`);
|
|
261
|
-
return response.json();
|
|
262
|
-
},
|
|
263
|
-
|
|
264
|
-
async create(product: any) {
|
|
265
|
-
const response = await fetch(`${API_URL}/products`, {
|
|
266
|
-
method: 'POST',
|
|
267
|
-
headers: { 'Content-Type': 'application/json' },
|
|
268
|
-
body: JSON.stringify(product)
|
|
269
|
-
});
|
|
270
|
-
return response.json();
|
|
271
|
-
},
|
|
272
|
-
|
|
273
|
-
async update(id: string, product: any) {
|
|
274
|
-
const response = await fetch(`${API_URL}/products/${id}`, {
|
|
275
|
-
method: 'PUT',
|
|
276
|
-
headers: { 'Content-Type': 'application/json' },
|
|
277
|
-
body: JSON.stringify(product)
|
|
278
|
-
});
|
|
279
|
-
return response.json();
|
|
280
|
-
},
|
|
281
|
-
|
|
282
|
-
async delete(id: string) {
|
|
283
|
-
await fetch(`${API_URL}/products/${id}`, { method: 'DELETE' });
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
3. **Update Composables:**
|
|
290
|
-
```typescript
|
|
291
|
-
// src/modules/products/composables/useProductsList.ts
|
|
292
|
-
import { api } from '../../../api_client/custom-api';
|
|
293
|
-
|
|
294
|
-
const { action: loadProducts, loading, items } = useAsync(async () => {
|
|
295
|
-
const response = await api.products.list({
|
|
296
|
-
skip: (currentPage.value - 1) * pageSize.value,
|
|
297
|
-
take: pageSize.value,
|
|
298
|
-
search: searchQuery.value
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
return {
|
|
302
|
-
results: response.data || [],
|
|
303
|
-
totalCount: response.total || 0
|
|
304
|
-
};
|
|
305
|
-
});
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
**Option C: Mock Data (for development)**
|
|
309
|
-
|
|
310
|
-
Keep using generated placeholders:
|
|
311
|
-
```typescript
|
|
312
|
-
// src/modules/products/composables/useProductsList.ts
|
|
313
|
-
const { action: loadProducts, loading, items } = useAsync(async () => {
|
|
314
|
-
// Mock data for development
|
|
315
|
-
return {
|
|
316
|
-
results: [
|
|
317
|
-
{ id: '1', name: 'Product 1', price: 100 },
|
|
318
|
-
{ id: '2', name: 'Product 2', price: 200 },
|
|
319
|
-
{ id: '3', name: 'Product 3', price: 300 }
|
|
320
|
-
],
|
|
321
|
-
totalCount: 3
|
|
322
|
-
};
|
|
323
|
-
});
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
### Step 3.2: Test API Integration
|
|
327
|
-
|
|
328
|
-
1. **Restart Server:**
|
|
329
|
-
```bash
|
|
330
|
-
# Ctrl+C, then
|
|
331
|
-
yarn serve
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
2. **Open Application:**
|
|
335
|
-
```
|
|
336
|
-
http://localhost:8080/apps/my-shop/
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
3. **Test Operations:**
|
|
340
|
-
- ✅ List loads with data
|
|
341
|
-
- ✅ Clicking item opens details
|
|
342
|
-
- ✅ Saving works (create/update)
|
|
343
|
-
- ✅ Delete works
|
|
344
|
-
- ✅ Search works
|
|
345
|
-
- ✅ Pagination works
|
|
346
|
-
|
|
347
|
-
4. **Check Console:**
|
|
348
|
-
- No errors in browser console
|
|
349
|
-
- API calls show in Network tab
|
|
350
|
-
- Responses are correct
|
|
351
|
-
|
|
352
|
-
✅ **Phase 3 Complete!** Your modules are connected to API.
|
|
353
|
-
|
|
354
|
-
---
|
|
355
|
-
|
|
356
|
-
## Phase 4: Testing & Validation (10 minutes)
|
|
357
|
-
|
|
358
|
-
### Step 4.1: Manual Testing Checklist
|
|
359
|
-
|
|
360
|
-
**For Each Module:**
|
|
361
|
-
|
|
362
|
-
**List Blade (Grid):**
|
|
363
|
-
- [ ] Table displays data
|
|
364
|
-
- [ ] Columns are correct
|
|
365
|
-
- [ ] Search works
|
|
366
|
-
- [ ] Filters work
|
|
367
|
-
- [ ] Pagination works
|
|
368
|
-
- [ ] Sorting works
|
|
369
|
-
- [ ] Clicking row opens details
|
|
370
|
-
- [ ] Toolbar buttons work (Add, Refresh, Delete)
|
|
371
|
-
- [ ] Empty state shows when no data
|
|
372
|
-
- [ ] Loading state shows during API call
|
|
373
|
-
|
|
374
|
-
**Details Blade (Form):**
|
|
375
|
-
- [ ] Form loads with data (edit mode)
|
|
376
|
-
- [ ] Form is empty (create mode)
|
|
377
|
-
- [ ] All fields display correctly
|
|
378
|
-
- [ ] Required validation works
|
|
379
|
-
- [ ] Save button works
|
|
380
|
-
- [ ] Cancel button closes blade
|
|
381
|
-
- [ ] Delete button works (with confirmation)
|
|
382
|
-
- [ ] Modified indicator shows when changed
|
|
383
|
-
- [ ] Unsaved changes warning works
|
|
384
|
-
- [ ] Success notification on save
|
|
385
|
-
- [ ] Error notification on failure
|
|
386
|
-
|
|
387
|
-
### Step 4.2: Browser DevTools Checks
|
|
388
|
-
|
|
389
|
-
**Console Tab:**
|
|
390
|
-
```
|
|
391
|
-
✅ No errors
|
|
392
|
-
✅ No warnings (except TODO comments)
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
**Network Tab:**
|
|
396
|
-
```
|
|
397
|
-
✅ API calls succeed (status 200)
|
|
398
|
-
✅ Response data is correct
|
|
399
|
-
✅ Request payloads are correct
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
**Vue DevTools:**
|
|
403
|
-
```
|
|
404
|
-
✅ Component tree looks correct
|
|
405
|
-
✅ Props are passed correctly
|
|
406
|
-
✅ Events are emitted
|
|
407
|
-
✅ State updates properly
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
### Step 4.3: Run Linter
|
|
411
|
-
|
|
412
|
-
```bash
|
|
413
|
-
yarn lint
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
**Fix any issues:**
|
|
417
|
-
```bash
|
|
418
|
-
yarn lint --fix
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
### Step 4.4: Type Check
|
|
422
|
-
|
|
423
|
-
```bash
|
|
424
|
-
yarn type-check
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
**Fix TypeScript errors** if any.
|
|
428
|
-
|
|
429
|
-
✅ **Phase 4 Complete!** Application is tested and validated.
|
|
430
|
-
|
|
431
|
-
---
|
|
432
|
-
|
|
433
|
-
## Phase 5: Customization & Extension (variable time)
|
|
434
|
-
|
|
435
|
-
### Step 5.1: Customize Themes and Colors
|
|
436
|
-
|
|
437
|
-
**Add or Modify Color Palette:**
|
|
438
|
-
|
|
439
|
-
VC Shell uses a theme system based on CSS custom properties. You can customize colors by modifying existing themes or creating new ones.
|
|
440
|
-
|
|
441
|
-
**Option 1: Override Existing Theme Colors**
|
|
442
|
-
|
|
443
|
-
Modify the default `light` theme in your `src/styles/custom.scss`:
|
|
444
|
-
|
|
445
|
-
```scss
|
|
446
|
-
// src/styles/custom.scss
|
|
447
|
-
|
|
448
|
-
/* Override specific variables for the 'light' theme */
|
|
449
|
-
:root[data-theme="light"] {
|
|
450
|
-
--primary-500: #D946EF; /* Change primary color to Fuchsia */
|
|
451
|
-
--success-500: #10B981; /* Change success color */
|
|
452
|
-
/* Override any other variables as needed */
|
|
453
|
-
}
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
**Option 2: Create a New Theme Variation**
|
|
457
|
-
|
|
458
|
-
1. **Register the theme in your app:**
|
|
459
|
-
```typescript
|
|
460
|
-
// src/main.ts or App.vue
|
|
461
|
-
import { useTheme, type ThemeDefinition } from '@vc-shell/framework';
|
|
462
|
-
|
|
463
|
-
const { register } = useTheme();
|
|
464
|
-
|
|
465
|
-
const customTheme: ThemeDefinition = {
|
|
466
|
-
key: 'light-customized',
|
|
467
|
-
localizationKey: 'THEMES.LIGHT_CUSTOMIZED'
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
register(customTheme);
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
2. **Define CSS variables for the new theme:**
|
|
474
|
-
```scss
|
|
475
|
-
// src/styles/custom.scss
|
|
476
|
-
|
|
477
|
-
/* Copy all variables from light theme, then override specific ones */
|
|
478
|
-
:root[data-theme="light-customized"] {
|
|
479
|
-
/* Copy all variables from :root[data-theme="light"] */
|
|
480
|
-
--primary-50: #EFF7FC;
|
|
481
|
-
--primary-100: #DAEDF7;
|
|
482
|
-
/* ... all other variables ... */
|
|
483
|
-
|
|
484
|
-
/* Then override only what you want to change */
|
|
485
|
-
--primary-500: #FF6347; /* Tomato Red */
|
|
486
|
-
--accent-500: #4ECDC4; /* Teal */
|
|
487
|
-
}
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
**Option 3: Create a Completely New Theme**
|
|
491
|
-
|
|
492
|
-
1. **Register the theme:**
|
|
493
|
-
```typescript
|
|
494
|
-
const oceanTheme: ThemeDefinition = {
|
|
495
|
-
key: 'ocean-wave',
|
|
496
|
-
localizationKey: 'THEMES.OCEAN_WAVE'
|
|
497
|
-
};
|
|
498
|
-
|
|
499
|
-
register(oceanTheme);
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
2. **Define all CSS variables:**
|
|
503
|
-
```scss
|
|
504
|
-
:root[data-theme="ocean-wave"] {
|
|
505
|
-
--primary-50: #E0F7FA; /* Light cyan */
|
|
506
|
-
--primary-500: #0077B6; /* Main blue */
|
|
507
|
-
--primary-950: #023047; /* Dark blue */
|
|
508
|
-
|
|
509
|
-
/* Define all other necessary variables:
|
|
510
|
-
--secondary-..., --accent-..., --neutrals-...,
|
|
511
|
-
--warning-..., --danger-..., --success-..., --info-...
|
|
512
|
-
*/
|
|
513
|
-
}
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
**Reference:**
|
|
517
|
-
- See [Managing Themes with useTheme](https://docs.virtocommerce.org/platform/developer-guide/custom-apps-development/vc-shell/Essentials/Usage-Guides/managing-themes-with-usetheme) for complete guide
|
|
518
|
-
- Default color palette is available in framework's `colors.scss`
|
|
519
|
-
- Use CSS custom properties (variables) for all theming
|
|
520
|
-
|
|
521
|
-
### Step 5.2: Add Widgets
|
|
522
|
-
|
|
523
|
-
**Generate Widget:**
|
|
524
|
-
```bash
|
|
525
|
-
npx create-vc-app blade --widget
|
|
526
|
-
```
|
|
527
|
-
|
|
528
|
-
**Prompts:**
|
|
529
|
-
```
|
|
530
|
-
? Select module: › products
|
|
531
|
-
? Select blade: › product-details
|
|
532
|
-
? Widget name: › product-stats
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
**Widget Structure:**
|
|
536
|
-
|
|
537
|
-
Widgets use only the `VcWidget` component with its props. No custom content inside:
|
|
538
|
-
|
|
539
|
-
```vue
|
|
540
|
-
<!-- src/modules/products/components/widgets/product-stats/product-stats-widget.vue -->
|
|
541
|
-
<template>
|
|
542
|
-
<VcWidget
|
|
543
|
-
:value="count"
|
|
544
|
-
:title="$t('PRODUCTS.WIDGETS.PRODUCT_STATS.TITLE')"
|
|
545
|
-
icon="material-shoppingmode"
|
|
546
|
-
@click="clickHandler"
|
|
547
|
-
>
|
|
548
|
-
</VcWidget>
|
|
549
|
-
</template>
|
|
550
|
-
|
|
551
|
-
<script setup lang="ts">
|
|
552
|
-
import { VcWidget, useBladeNavigation } from "@vc-shell/framework";
|
|
553
|
-
import { ref } from "vue";
|
|
554
|
-
|
|
555
|
-
const props = defineProps<{
|
|
556
|
-
item: any; // Your entity type
|
|
557
|
-
}>();
|
|
558
|
-
|
|
559
|
-
const { openBlade, resolveBladeByName } = useBladeNavigation();
|
|
560
|
-
const widgetOpened = ref(false);
|
|
561
|
-
const count = ref(0);
|
|
562
|
-
|
|
563
|
-
function clickHandler() {
|
|
564
|
-
if (!widgetOpened.value) {
|
|
565
|
-
openBlade({
|
|
566
|
-
blade: resolveBladeByName("ProductStatsList"),
|
|
567
|
-
options: {
|
|
568
|
-
productId: props.item?.id,
|
|
569
|
-
},
|
|
570
|
-
onOpen() {
|
|
571
|
-
widgetOpened.value = true;
|
|
572
|
-
},
|
|
573
|
-
onClose() {
|
|
574
|
-
widgetOpened.value = false;
|
|
575
|
-
},
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
// Load count data
|
|
581
|
-
// ... your data loading logic
|
|
582
|
-
</script>
|
|
583
|
-
```
|
|
584
|
-
|
|
585
|
-
**Important:** Widgets only use `VcWidget` component props (`value`, `title`, `icon`, `loading`, etc.). Do not add custom HTML content inside `VcWidget`.
|
|
586
|
-
|
|
587
|
-
### Step 5.3: Add Validation Rules
|
|
588
|
-
|
|
589
|
-
**Custom Validators:**
|
|
590
|
-
```typescript
|
|
591
|
-
// src/modules/products/composables/useProductDetails.ts
|
|
592
|
-
import { useForm } from 'vee-validate';
|
|
593
|
-
|
|
594
|
-
const validationSchema = {
|
|
595
|
-
name: { required: true, min: 3, max: 100 },
|
|
596
|
-
sku: { required: true, regex: /^[A-Z0-9-]+$/ },
|
|
597
|
-
price: { required: true, min_value: 0 },
|
|
598
|
-
email: { required: true, email: true }
|
|
599
|
-
};
|
|
600
|
-
|
|
601
|
-
const { validate, errors } = useForm({ validationSchema });
|
|
602
|
-
```
|
|
603
|
-
|
|
604
|
-
### Step 5.4: Add Business Logic
|
|
605
|
-
|
|
606
|
-
**Example: Auto-calculate totals**
|
|
607
|
-
```typescript
|
|
608
|
-
// src/modules/orders/composables/useOrderDetails.ts
|
|
609
|
-
const subtotal = computed(() => {
|
|
610
|
-
return item.value.items?.reduce((sum, i) =>
|
|
611
|
-
sum + (i.quantity * i.price), 0
|
|
612
|
-
) || 0;
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
const tax = computed(() => subtotal.value * 0.1); // 10% tax
|
|
616
|
-
|
|
617
|
-
const total = computed(() =>
|
|
618
|
-
subtotal.value + tax.value + (item.value.shipping || 0)
|
|
619
|
-
);
|
|
620
|
-
|
|
621
|
-
// Update item when totals change
|
|
622
|
-
watch([subtotal, tax], () => {
|
|
623
|
-
item.value.subtotal = subtotal.value;
|
|
624
|
-
item.value.tax = tax.value;
|
|
625
|
-
item.value.total = total.value;
|
|
626
|
-
});
|
|
627
|
-
```
|
|
628
|
-
|
|
629
|
-
### Step 5.5: Add Permissions
|
|
630
|
-
|
|
631
|
-
**Restrict Access:**
|
|
632
|
-
```typescript
|
|
633
|
-
// src/modules/products/pages/products.vue
|
|
634
|
-
import { usePermissions } from '@vc-shell/framework';
|
|
635
|
-
|
|
636
|
-
const { checkPermission } = usePermissions();
|
|
637
|
-
const canEdit = checkPermission('products:edit');
|
|
638
|
-
const canDelete = checkPermission('products:delete');
|
|
639
|
-
|
|
640
|
-
const toolbarItems = computed(() => [
|
|
641
|
-
{
|
|
642
|
-
id: 'add',
|
|
643
|
-
title: 'Add Product',
|
|
644
|
-
icon: 'plus',
|
|
645
|
-
onClick: handleAdd,
|
|
646
|
-
disabled: !canEdit.value
|
|
647
|
-
},
|
|
648
|
-
{
|
|
649
|
-
id: 'delete',
|
|
650
|
-
title: 'Delete',
|
|
651
|
-
icon: 'delete',
|
|
652
|
-
onClick: handleDelete,
|
|
653
|
-
disabled: !canDelete.value || !selectedItems.value.length
|
|
654
|
-
}
|
|
655
|
-
]);
|
|
656
|
-
```
|
|
657
|
-
|
|
658
|
-
✅ **Phase 5 Complete!** Application is customized.
|
|
659
|
-
|
|
660
|
-
---
|
|
661
|
-
|
|
662
|
-
## Phase 6: Build for Production (5 minutes)
|
|
663
|
-
|
|
664
|
-
### Step 6.1: Update Environment
|
|
665
|
-
|
|
666
|
-
**Create `.env.production`:**
|
|
667
|
-
```env
|
|
668
|
-
VITE_API_URL=https://api.production.com
|
|
669
|
-
APP_PLATFORM_URL=https://platform.production.com
|
|
670
|
-
APP_BASE_PATH=/apps/my-shop/
|
|
671
|
-
```
|
|
672
|
-
|
|
673
|
-
### Step 6.2: Build Application
|
|
674
|
-
|
|
675
|
-
```bash
|
|
676
|
-
yarn build
|
|
677
|
-
```
|
|
678
|
-
|
|
679
|
-
**Expected Output:**
|
|
680
|
-
```
|
|
681
|
-
vite v6.x.x building for production...
|
|
682
|
-
✓ 1234 modules transformed.
|
|
683
|
-
dist/index.html 1.23 kB
|
|
684
|
-
dist/assets/index-abc123.js 234.56 kB │ gzip: 78.90 kB
|
|
685
|
-
dist/assets/index-def456.css 12.34 kB │ gzip: 5.67 kB
|
|
686
|
-
✓ built in 12.34s
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
### Step 6.3: Test Production Build
|
|
690
|
-
|
|
691
|
-
```bash
|
|
692
|
-
yarn preview
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
**Or use a simple HTTP server:**
|
|
696
|
-
```bash
|
|
697
|
-
npx serve dist
|
|
698
|
-
```
|
|
699
|
-
|
|
700
|
-
**Open:**
|
|
701
|
-
```
|
|
702
|
-
http://localhost:4173/apps/my-shop/
|
|
703
|
-
```
|
|
704
|
-
|
|
705
|
-
**Verify:**
|
|
706
|
-
- [ ] Application loads
|
|
707
|
-
- [ ] Modules work
|
|
708
|
-
- [ ] API calls work
|
|
709
|
-
- [ ] No console errors
|
|
710
|
-
|
|
711
|
-
✅ **Phase 6 Complete!** Production build is ready.
|
|
712
|
-
|
|
713
|
-
---
|
|
714
|
-
|
|
715
|
-
## Troubleshooting
|
|
716
|
-
|
|
717
|
-
### Issue: Module Not Showing
|
|
718
|
-
|
|
719
|
-
**Problem:** Generated module doesn't appear in navigation
|
|
720
|
-
|
|
721
|
-
**Solution:**
|
|
722
|
-
1. Check `src/main.ts` - module must be registered
|
|
723
|
-
2. Restart dev server
|
|
724
|
-
3. Clear browser cache
|
|
725
|
-
|
|
726
|
-
### Issue: API Calls Fail
|
|
727
|
-
|
|
728
|
-
**Problem:** CORS errors or 404s
|
|
729
|
-
|
|
730
|
-
**Solution:**
|
|
731
|
-
1. Check API URL in `.env.local`
|
|
732
|
-
2. Verify API endpoint exists
|
|
733
|
-
3. Check CORS configuration on backend
|
|
734
|
-
4. Use Vite proxy for development (see `vite.config.mts`)
|
|
735
|
-
|
|
736
|
-
### Issue: Build Fails
|
|
737
|
-
|
|
738
|
-
**Problem:** TypeScript or build errors
|
|
739
|
-
|
|
740
|
-
**Solution:**
|
|
741
|
-
1. Run `yarn type-check` to see all errors
|
|
742
|
-
2. Fix TypeScript errors
|
|
743
|
-
3. Replace `@ts-expect-error` with proper types
|
|
744
|
-
4. Run `yarn lint --fix`
|
|
745
|
-
|
|
746
|
-
---
|
|
747
|
-
|
|
748
|
-
## Next Steps
|
|
749
|
-
|
|
750
|
-
- [Blade Patterns](./blade-patterns.md) - Blade development patterns
|
|
751
|
-
- [Troubleshooting Guide](./troubleshooting.md) - Common issues
|
|
752
|
-
- [API Integration Guide](../prompts/api-client-generation.md) - Advanced API patterns
|
|
753
|
-
- [CLI Usage](../prompts/cli-usage.md) - All CLI commands
|
|
754
|
-
|
|
755
|
-
---
|
|
756
|
-
|
|
757
|
-
## Success Checklist
|
|
758
|
-
|
|
759
|
-
**Development:**
|
|
760
|
-
- [ ] Application created and running
|
|
761
|
-
- [ ] Modules generated
|
|
762
|
-
- [ ] API connected
|
|
763
|
-
- [ ] Manual testing complete
|
|
764
|
-
- [ ] Customizations added
|
|
765
|
-
- [ ] No linter errors
|
|
766
|
-
- [ ] No TypeScript errors
|
|
767
|
-
|
|
768
|
-
**Production:**
|
|
769
|
-
- [ ] Production build successful
|
|
770
|
-
- [ ] Environment variables configured
|
|
771
|
-
- [ ] Application deployed
|
|
772
|
-
- [ ] Production testing complete
|
|
773
|
-
- [ ] Monitoring configured
|
|
774
|
-
- [ ] Backup strategy in place
|
|
775
|
-
|
|
776
|
-
**Documentation:**
|
|
777
|
-
- [ ] README updated
|
|
778
|
-
- [ ] API endpoints documented
|
|
779
|
-
- [ ] Deployment instructions written
|
|
780
|
-
- [ ] Known issues documented
|
|
781
|
-
|