@awes-io/ui 2.142.0 → 2.143.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/CHANGELOG.md +58 -0
- package/assets/css/components/_index.css +7 -1
- package/assets/css/components/animation.css +38 -32
- package/assets/css/components/content-placeholder.css +103 -0
- package/assets/css/components/empty-container.css +69 -1
- package/assets/css/components/filter-chosen.css +6 -0
- package/assets/css/components/filter-date-range.css +17 -1
- package/assets/css/components/filter-month.css +23 -17
- package/assets/css/components/filter-select.css +11 -0
- package/assets/css/components/layout.css +1 -32
- package/assets/css/components/modal.css +1 -1
- package/assets/css/components/number.css +12 -0
- package/assets/css/components/page-aside.css +54 -0
- package/assets/js/css.js +1 -1
- package/assets/js/icons/mono.js +59 -91
- package/assets/js/icons/multicolor.js +1 -31
- package/components/1_atoms/AwContentPlaceholder.vue +60 -0
- package/components/1_atoms/AwFlow.vue +21 -48
- package/components/1_atoms/AwLabel.vue +1 -1
- package/components/2_molecules/AwButton.vue +1 -1
- package/components/2_molecules/AwEmptyContainer.vue +74 -72
- package/components/2_molecules/AwNumber.vue +180 -0
- package/components/2_molecules/AwSelect.vue +11 -4
- package/components/3_organisms/AwFilterChosen.vue +73 -0
- package/components/3_organisms/AwFilterDateRange.vue +177 -0
- package/components/3_organisms/AwFilterMonth.vue +37 -40
- package/components/3_organisms/AwFilterSelect.vue +368 -0
- package/components/3_organisms/AwImageUpload.vue +1 -1
- package/components/3_organisms/AwMarkdownEditor.vue +0 -0
- package/components/3_organisms/AwMultiBlockBuilder.vue +1 -1
- package/components/3_organisms/AwTable/AwTableBuilder.vue +12 -60
- package/components/4_pages/AwPageAside.vue +108 -0
- package/components/5_layouts/AwLayoutCenter.vue +3 -8
- package/components/5_layouts/_AwUserMenu.vue +1 -1
- package/dist/css/aw-icons.css +26 -0
- package/dist/fonts/aw-icons.svg +18 -0
- package/dist/fonts/aw-icons.ttf +0 -0
- package/dist/fonts/aw-icons.woff +0 -0
- package/dist/fonts/aw-icons.woff2 +0 -0
- package/docs/_template.md +80 -0
- package/docs/components/atoms/aw-accordion-fold.md +91 -0
- package/docs/components/atoms/aw-action-card-body.md +67 -0
- package/docs/components/atoms/aw-action-card.md +94 -0
- package/docs/components/atoms/aw-action-icon.md +88 -0
- package/docs/components/atoms/aw-avatar.md +106 -0
- package/docs/components/atoms/aw-card.md +112 -0
- package/docs/components/atoms/aw-checkbox.md +112 -0
- package/docs/components/atoms/aw-content-placeholder.md +116 -0
- package/docs/components/atoms/aw-description.md +83 -0
- package/docs/components/atoms/aw-dock.md +84 -0
- package/docs/components/atoms/aw-dropdown-button.md +94 -0
- package/docs/components/atoms/aw-dropdown.md +128 -0
- package/docs/components/atoms/aw-file.md +73 -0
- package/docs/components/atoms/aw-flow.md +92 -0
- package/docs/components/atoms/aw-grid.md +91 -0
- package/docs/components/atoms/aw-headline.md +71 -0
- package/docs/components/atoms/aw-icon-system-color.md +121 -0
- package/docs/components/atoms/aw-icon-system-mono.md +205 -0
- package/docs/components/atoms/aw-icon.md +235 -0
- package/docs/components/atoms/aw-info.md +85 -0
- package/docs/components/atoms/aw-input.md +120 -0
- package/docs/components/atoms/aw-label.md +83 -0
- package/docs/components/atoms/aw-link.md +99 -0
- package/docs/components/atoms/aw-list.md +88 -0
- package/docs/components/atoms/aw-progress.md +70 -0
- package/docs/components/atoms/aw-radio.md +109 -0
- package/docs/components/atoms/aw-refresh-wrapper.md +81 -0
- package/docs/components/atoms/aw-select-native.md +106 -0
- package/docs/components/atoms/aw-slider.md +82 -0
- package/docs/components/atoms/aw-sub-headline.md +73 -0
- package/docs/components/atoms/aw-switcher.md +115 -0
- package/docs/components/atoms/aw-tag.md +80 -0
- package/docs/components/atoms/aw-title.md +70 -0
- package/docs/components/atoms/aw-toggler.md +69 -0
- package/docs/components/layouts/aw-layout-center.md +168 -0
- package/docs/components/layouts/aw-layout-error.md +153 -0
- package/docs/components/layouts/aw-layout-provider.md +238 -0
- package/docs/components/layouts/aw-layout.md +88 -0
- package/docs/components/molecules/aw-action-button.md +91 -0
- package/docs/components/molecules/aw-alert.md +96 -0
- package/docs/components/molecules/aw-badge.md +108 -0
- package/docs/components/molecules/aw-banner-text.md +90 -0
- package/docs/components/molecules/aw-button-nav.md +46 -0
- package/docs/components/molecules/aw-button.md +123 -0
- package/docs/components/molecules/aw-description-input.md +67 -0
- package/docs/components/molecules/aw-empty-container.md +86 -0
- package/docs/components/molecules/aw-island.md +234 -0
- package/docs/components/molecules/aw-number.md +138 -0
- package/docs/components/molecules/aw-select-object.md +401 -0
- package/docs/components/molecules/aw-select.md +215 -0
- package/docs/components/molecules/aw-tab-nav.md +108 -0
- package/docs/components/molecules/aw-tel.md +129 -0
- package/docs/components/molecules/aw-textarea.md +83 -0
- package/docs/components/molecules/aw-userpic.md +115 -0
- package/docs/components/organisms/aw-address-block.md +64 -0
- package/docs/components/organisms/aw-address.md +132 -0
- package/docs/components/organisms/aw-birthday-picker.md +73 -0
- package/docs/components/organisms/aw-bottom-bar.md +66 -0
- package/docs/components/organisms/aw-calendar-days.md +115 -0
- package/docs/components/organisms/aw-calendar-nav.md +98 -0
- package/docs/components/organisms/aw-calendar-view.md +98 -0
- package/docs/components/organisms/aw-calendar.md +166 -0
- package/docs/components/organisms/aw-chart.md +154 -0
- package/docs/components/organisms/aw-chip-select.md +164 -0
- package/docs/components/organisms/aw-chip.md +126 -0
- package/docs/components/organisms/aw-code-snippet.md +94 -0
- package/docs/components/organisms/aw-code.md +132 -0
- package/docs/components/organisms/aw-context-menu.md +117 -0
- package/docs/components/organisms/aw-cropper.md +151 -0
- package/docs/components/organisms/aw-date.md +161 -0
- package/docs/components/organisms/aw-display-date.md +33 -0
- package/docs/components/organisms/aw-download-link.md +46 -0
- package/docs/components/organisms/aw-fetch-data.md +161 -0
- package/docs/components/organisms/aw-filter-chosen.md +226 -0
- package/docs/components/organisms/aw-filter-date-range.md +205 -0
- package/docs/components/organisms/aw-filter-month.md +43 -0
- package/docs/components/organisms/aw-filter-select.md +225 -0
- package/docs/components/organisms/aw-form.md +174 -0
- package/docs/components/organisms/aw-gmap-marker.md +86 -0
- package/docs/components/organisms/aw-gmap.md +90 -0
- package/docs/components/organisms/aw-image-upload.md +56 -0
- package/docs/components/organisms/aw-island-avatar.md +87 -0
- package/docs/components/organisms/aw-markdown-editor.md +104 -0
- package/docs/components/organisms/aw-modal-buttons.md +57 -0
- package/docs/components/organisms/aw-modal.md +246 -0
- package/docs/components/organisms/aw-model-edit.md +74 -0
- package/docs/components/organisms/aw-money.md +53 -0
- package/docs/components/organisms/aw-multi-block-builder.md +165 -0
- package/docs/components/organisms/aw-pagination.md +121 -0
- package/docs/components/organisms/aw-password.md +103 -0
- package/docs/components/organisms/aw-preview-card.md +45 -0
- package/docs/components/organisms/aw-search.md +116 -0
- package/docs/components/organisms/aw-subnav.md +122 -0
- package/docs/components/organisms/aw-table-builder.md +165 -0
- package/docs/components/organisms/aw-table-col.md +123 -0
- package/docs/components/organisms/aw-table-head.md +92 -0
- package/docs/components/organisms/aw-table-row.md +91 -0
- package/docs/components/organisms/aw-table.md +172 -0
- package/docs/components/organisms/aw-tags.md +54 -0
- package/docs/components/organisms/aw-toggle-show-aside.md +43 -0
- package/docs/components/organisms/aw-uploader-files.md +125 -0
- package/docs/components/organisms/aw-uploader.md +163 -0
- package/docs/components/organisms/aw-user-menu.md +87 -0
- package/docs/components/pages/aw-page-aside.md +296 -0
- package/docs/components/pages/aw-page-menu-buttons.md +172 -0
- package/docs/components/pages/aw-page-modal.md +198 -0
- package/docs/components/pages/aw-page-single.md +253 -0
- package/docs/components/pages/aw-page.md +194 -0
- package/docs/configuration.md +493 -0
- package/docs/cookbook/advanced-patterns.md +1388 -0
- package/docs/cookbook/common-patterns.md +965 -0
- package/docs/cookbook/index.md +786 -0
- package/docs/getting-started.md +596 -0
- package/docs/guides/best-practices.md +1106 -0
- package/docs/guides/data-fetching.md +852 -0
- package/docs/guides/error-handling.md +1172 -0
- package/docs/guides/forms-guide.md +1329 -0
- package/docs/guides/mobile-subnavigation.md +359 -0
- package/docs/guides/page-patterns/aside-pages.md +1418 -0
- package/docs/guides/page-patterns/dashboard-pages.md +990 -0
- package/docs/guides/page-patterns/detail-pages.md +1493 -0
- package/docs/guides/page-patterns/list-pages.md +1094 -0
- package/docs/index.md +263 -1
- package/docs/integrations.md +870 -0
- package/docs/reference/menu.md +462 -0
- package/docs/reference/plugins.md +970 -0
- package/docs/reference/troubleshooting.md +945 -0
- package/nuxt/awes.config.js +9 -8
- package/nuxt/icons.css +26 -0
- package/nuxt/index.js +2 -2
- package/nuxt/pages/more.vue +1 -1
- package/package.json +5 -3
- package/readme.md +171 -1
- package/docs/aw-accordion-fold.md +0 -46
- package/docs/aw-address.md +0 -44
- package/docs/aw-avatar.md +0 -51
- package/docs/aw-badge.md +0 -32
- package/docs/aw-button-nav.md +0 -44
- package/docs/aw-button.md +0 -50
- package/docs/aw-calendar-days.md +0 -46
- package/docs/aw-calendar-nav.md +0 -25
- package/docs/aw-calendar-view.md +0 -12
- package/docs/aw-calendar.md +0 -59
- package/docs/aw-card.md +0 -48
- package/docs/aw-chart.md +0 -51
- package/docs/aw-checkbox.md +0 -56
- package/docs/aw-chip-select.md +0 -46
- package/docs/aw-chip.md +0 -53
- package/docs/aw-code-snippet.md +0 -18
- package/docs/aw-code.md +0 -56
- package/docs/aw-content-wrapper.md +0 -40
- package/docs/aw-context-menu.md +0 -31
- package/docs/aw-cropper.md +0 -60
- package/docs/aw-dashboard-card.md +0 -37
- package/docs/aw-dashboard-donut.md +0 -30
- package/docs/aw-dashboard-line.md +0 -20
- package/docs/aw-dashboard-progress.md +0 -33
- package/docs/aw-dashboard-section.md +0 -32
- package/docs/aw-dashboard-speed.md +0 -30
- package/docs/aw-date.md +0 -52
- package/docs/aw-dropdown-button.md +0 -31
- package/docs/aw-dropdown.md +0 -69
- package/docs/aw-fetch-data.md +0 -45
- package/docs/aw-form.md +0 -52
- package/docs/aw-grid.md +0 -48
- package/docs/aw-icon.md +0 -50
- package/docs/aw-info.md +0 -53
- package/docs/aw-input.md +0 -55
- package/docs/aw-layout-default.md +0 -30
- package/docs/aw-layout-frame-center.md +0 -29
- package/docs/aw-layout-simple.md +0 -49
- package/docs/aw-link.md +0 -54
- package/docs/aw-markdown-editor.md +0 -51
- package/docs/aw-modal.md +0 -63
- package/docs/aw-multi-block-builder.md +0 -66
- package/docs/aw-page.md +0 -36
- package/docs/aw-pagination.md +0 -54
- package/docs/aw-password.md +0 -48
- package/docs/aw-radio.md +0 -54
- package/docs/aw-search.md +0 -49
- package/docs/aw-select.md +0 -93
- package/docs/aw-slider.md +0 -40
- package/docs/aw-svg-image.md +0 -19
- package/docs/aw-switcher.md +0 -51
- package/docs/aw-tab-nav.md +0 -55
- package/docs/aw-table-builder.md +0 -58
- package/docs/aw-table-col.md +0 -33
- package/docs/aw-table-head.md +0 -28
- package/docs/aw-table-row.md +0 -33
- package/docs/aw-table.md +0 -59
- package/docs/aw-tel.md +0 -47
- package/docs/aw-textarea.md +0 -47
- package/docs/aw-timeline-builder.md +0 -50
- package/docs/aw-toggler.md +0 -41
- package/docs/aw-uploader-files.md +0 -20
- package/docs/aw-uploader.md +0 -60
- package/docs/aw-user-menu.md +0 -34
- package/docs/aw-userpic.md +0 -34
- /package/components/{3_organisms → 2_molecules}/AwTel.vue +0 -0
|
@@ -0,0 +1,870 @@
|
|
|
1
|
+
# Package Integration Guide
|
|
2
|
+
|
|
3
|
+
Complete guide to integrating all AwesCode UI packages together for a full-stack Nuxt.js + Laravel application.
|
|
4
|
+
|
|
5
|
+
## Framework Architecture
|
|
6
|
+
|
|
7
|
+
The AwesCode UI framework consists of four interconnected packages that work together:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
11
|
+
│ Nuxt.js Application │
|
|
12
|
+
└─────────────────────────────────────────────────────────────┘
|
|
13
|
+
│
|
|
14
|
+
▼
|
|
15
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
16
|
+
│ @awes-io/ui (Components & Pages) │
|
|
17
|
+
│ - AwPage, AwTableBuilder, AwForm │
|
|
18
|
+
│ - Global components (atoms, molecules) │
|
|
19
|
+
│ - Page layouts and navigation │
|
|
20
|
+
└─────────────────────────────────────────────────────────────┘
|
|
21
|
+
│
|
|
22
|
+
▼
|
|
23
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
24
|
+
│ @awes-io/nuxt-auth (Authentication) │
|
|
25
|
+
│ - $auth object and user state │
|
|
26
|
+
│ - Login, register, 2FA, OAuth │
|
|
27
|
+
│ - Route protection middleware │
|
|
28
|
+
│ - JWT token management │
|
|
29
|
+
└─────────────────────────────────────────────────────────────┘
|
|
30
|
+
│
|
|
31
|
+
▼
|
|
32
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
33
|
+
│ @awes-io/nuxt-laravel (Backend Integration) │
|
|
34
|
+
│ - API proxy configuration │
|
|
35
|
+
│ - Axios setup and base URL │
|
|
36
|
+
│ - Build process (Nuxt → Laravel public) │
|
|
37
|
+
│ - Version plugin │
|
|
38
|
+
└─────────────────────────────────────────────────────────────┘
|
|
39
|
+
│
|
|
40
|
+
▼
|
|
41
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
42
|
+
│ @awes-io/vue-mc (Models & Collections) │
|
|
43
|
+
│ - BaseModel for single resources │
|
|
44
|
+
│ - BaseCollection for lists │
|
|
45
|
+
│ - Automatic API communication │
|
|
46
|
+
│ - Validation and error handling │
|
|
47
|
+
└─────────────────────────────────────────────────────────────┘
|
|
48
|
+
│
|
|
49
|
+
▼
|
|
50
|
+
┌─────────────────┐
|
|
51
|
+
│ Laravel Backend │
|
|
52
|
+
│ (API endpoints) │
|
|
53
|
+
└─────────────────┘
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Data Flow
|
|
57
|
+
|
|
58
|
+
**Typical request flow:**
|
|
59
|
+
|
|
60
|
+
1. User interacts with **UI component** (AwTableBuilder, AwForm)
|
|
61
|
+
2. Component uses **vue-mc Model/Collection** for data operations
|
|
62
|
+
3. Model/Collection makes request via **$axios** (configured by nuxt-laravel)
|
|
63
|
+
4. **nuxt-auth** adds JWT token to request headers
|
|
64
|
+
5. **nuxt-laravel proxy** forwards request to Laravel backend
|
|
65
|
+
6. Laravel processes request and returns response
|
|
66
|
+
7. Model/Collection updates and notifies UI component
|
|
67
|
+
8. Component re-renders with new data
|
|
68
|
+
|
|
69
|
+
## Package Overview
|
|
70
|
+
|
|
71
|
+
### 1. UI Components (@awes-io/ui)
|
|
72
|
+
|
|
73
|
+
**Purpose**: Pre-built Vue components for building application interfaces
|
|
74
|
+
|
|
75
|
+
**Key Features**:
|
|
76
|
+
- 102+ components organized by atomic design
|
|
77
|
+
- Page components (AwPage, AwPageSingle)
|
|
78
|
+
- Form components with validation
|
|
79
|
+
- Table builder with auto-fetching
|
|
80
|
+
- Layout system with navigation
|
|
81
|
+
|
|
82
|
+
**Documentation**: [./index.md](./index.md)
|
|
83
|
+
|
|
84
|
+
### 2. Vue-MC (@awes-io/vue-mc)
|
|
85
|
+
|
|
86
|
+
**Purpose**: Model-Collection layer for API data management
|
|
87
|
+
|
|
88
|
+
**Key Features**:
|
|
89
|
+
- BaseModel for single resources
|
|
90
|
+
- BaseCollection for lists with pagination
|
|
91
|
+
- Automatic API communication
|
|
92
|
+
- Built-in validation
|
|
93
|
+
- Lifecycle hooks
|
|
94
|
+
|
|
95
|
+
**Documentation**: [../../vue-mc/docs/](../../vue-mc/docs/)
|
|
96
|
+
|
|
97
|
+
### 3. Nuxt-Auth (@awes-io/nuxt-auth)
|
|
98
|
+
|
|
99
|
+
**Purpose**: Complete authentication solution
|
|
100
|
+
|
|
101
|
+
**Key Features**:
|
|
102
|
+
- JWT authentication with Laravel backend
|
|
103
|
+
- Two-factor authentication (2FA)
|
|
104
|
+
- Social login (OAuth)
|
|
105
|
+
- Email verification
|
|
106
|
+
- Password reset
|
|
107
|
+
- Route protection middleware
|
|
108
|
+
|
|
109
|
+
**Documentation**: [../../nuxt-auth/docs/](../../nuxt-auth/docs/)
|
|
110
|
+
|
|
111
|
+
### 4. Nuxt-Laravel (@awes-io/nuxt-laravel)
|
|
112
|
+
|
|
113
|
+
**Purpose**: Integration layer between Nuxt.js and Laravel
|
|
114
|
+
|
|
115
|
+
**Key Features**:
|
|
116
|
+
- API proxy for development and production
|
|
117
|
+
- Automatic axios configuration
|
|
118
|
+
- Build process (Nuxt → Laravel public)
|
|
119
|
+
- Version plugin for tracking deployments
|
|
120
|
+
|
|
121
|
+
**Documentation**: [../../nuxt-laravel/docs/](../../nuxt-laravel/docs/)
|
|
122
|
+
|
|
123
|
+
## Complete Setup Example
|
|
124
|
+
|
|
125
|
+
### 1. Installation
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Install all packages
|
|
129
|
+
yarn add @awes-io/ui @awes-io/vue-mc @awes-io/nuxt-auth @awes-io/nuxt-laravel
|
|
130
|
+
|
|
131
|
+
# Install peer dependencies
|
|
132
|
+
yarn add @nuxtjs/axios dayjs
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 2. Project Structure
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
project-root/
|
|
139
|
+
├── app/ # Laravel application
|
|
140
|
+
├── resources/
|
|
141
|
+
│ └── nuxt/ # Nuxt source code
|
|
142
|
+
│ ├── assets/
|
|
143
|
+
│ ├── components/
|
|
144
|
+
│ ├── layouts/
|
|
145
|
+
│ ├── pages/
|
|
146
|
+
│ ├── models/ # Vue-MC models
|
|
147
|
+
│ ├── collections/ # Vue-MC collections
|
|
148
|
+
│ └── plugins/
|
|
149
|
+
├── storage/app/nuxt/ # Nuxt build output
|
|
150
|
+
├── public/ # Laravel public (serves SPA)
|
|
151
|
+
├── nuxt.config.js # Nuxt configuration
|
|
152
|
+
├── package.json # NPM dependencies
|
|
153
|
+
└── composer.json # Composer dependencies
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 3. Environment Variables
|
|
157
|
+
|
|
158
|
+
**`.env`** (Laravel root):
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# Laravel backend URL
|
|
162
|
+
LARAVEL_URL=http://localhost:8000
|
|
163
|
+
|
|
164
|
+
# Frontend URL (for CORS)
|
|
165
|
+
FRONTEND_URL=http://localhost:3000
|
|
166
|
+
|
|
167
|
+
# Direct API URL (production, skip proxy)
|
|
168
|
+
NON_PROXY_URL=https://api.example.com
|
|
169
|
+
|
|
170
|
+
# Application info (for version plugin)
|
|
171
|
+
APP_NAME=MyApplication
|
|
172
|
+
APP_VERSION=v1.0.0
|
|
173
|
+
APP_VERSION_DATE=2024-01-15T10:00:00Z
|
|
174
|
+
|
|
175
|
+
# Laravel settings
|
|
176
|
+
APP_URL=http://localhost:8000
|
|
177
|
+
SESSION_DRIVER=cookie
|
|
178
|
+
SESSION_DOMAIN=localhost
|
|
179
|
+
SANCTUM_STATEFUL_DOMAINS=localhost:3000
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 4. Nuxt Configuration
|
|
183
|
+
|
|
184
|
+
**`nuxt.config.js`**:
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
export default {
|
|
188
|
+
// SPA mode
|
|
189
|
+
mode: 'spa',
|
|
190
|
+
|
|
191
|
+
// Nuxt source directory
|
|
192
|
+
srcDir: 'resources/nuxt',
|
|
193
|
+
|
|
194
|
+
// Modules (ORDER MATTERS!)
|
|
195
|
+
modules: [
|
|
196
|
+
// 1. Laravel integration (includes axios)
|
|
197
|
+
'@awes-io/nuxt-laravel',
|
|
198
|
+
|
|
199
|
+
// 2. Authentication
|
|
200
|
+
'@awes-io/nuxt-auth',
|
|
201
|
+
|
|
202
|
+
// 3. UI components
|
|
203
|
+
'@awes-io/ui'
|
|
204
|
+
],
|
|
205
|
+
|
|
206
|
+
// Module options
|
|
207
|
+
awesIo: {
|
|
208
|
+
nuxtLaravel: {
|
|
209
|
+
generateDir: 'storage/app/nuxt',
|
|
210
|
+
versionPlugin: {
|
|
211
|
+
name: process.env.APP_NAME,
|
|
212
|
+
version: process.env.APP_VERSION,
|
|
213
|
+
date: process.env.APP_VERSION_DATE
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
nuxtAuth: {
|
|
217
|
+
register: true, // Enable registration
|
|
218
|
+
socialLogin: true, // Enable OAuth
|
|
219
|
+
twoFactor: true, // Enable 2FA
|
|
220
|
+
emailVerification: true // Enable email verification
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
// Environment variables available in app
|
|
225
|
+
env: {
|
|
226
|
+
laravelUrl: process.env.LARAVEL_URL || 'http://localhost:8000',
|
|
227
|
+
frontendUrl: process.env.FRONTEND_URL || 'http://localhost:3000'
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
// Build configuration
|
|
231
|
+
build: {
|
|
232
|
+
extractCSS: true,
|
|
233
|
+
optimizeCSS: true,
|
|
234
|
+
transpile: ['@awes-io/ui', '@awes-io/vue-mc']
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### 5. Package Scripts
|
|
240
|
+
|
|
241
|
+
**`package.json`**:
|
|
242
|
+
|
|
243
|
+
```json
|
|
244
|
+
{
|
|
245
|
+
"scripts": {
|
|
246
|
+
"dev": "LARAVEL_URL=http://localhost:8000 nuxt",
|
|
247
|
+
"build": "LARAVEL_URL=http://localhost:8000 nuxt build",
|
|
248
|
+
"generate": "LARAVEL_URL=http://localhost:8000 nuxt generate",
|
|
249
|
+
"start": "LARAVEL_URL=http://localhost:8000 nuxt start"
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### 6. Laravel Configuration
|
|
255
|
+
|
|
256
|
+
**`config/cors.php`**:
|
|
257
|
+
|
|
258
|
+
```php
|
|
259
|
+
return [
|
|
260
|
+
'paths' => ['api/*', 'broadcasting/*', 'sanctum/csrf-cookie'],
|
|
261
|
+
'allowed_methods' => ['*'],
|
|
262
|
+
'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:3000')],
|
|
263
|
+
'allowed_origins_patterns' => [],
|
|
264
|
+
'allowed_headers' => ['*'],
|
|
265
|
+
'exposed_headers' => [],
|
|
266
|
+
'max_age' => 0,
|
|
267
|
+
'supports_credentials' => true,
|
|
268
|
+
];
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**`routes/web.php`** (serve Nuxt SPA):
|
|
272
|
+
|
|
273
|
+
```php
|
|
274
|
+
// Serve Nuxt SPA for all routes (except API)
|
|
275
|
+
Route::fallback(function () {
|
|
276
|
+
return file_get_contents(public_path('index.html'));
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Integration Patterns
|
|
281
|
+
|
|
282
|
+
### Pattern 1: Authenticated API Call with Vue-MC
|
|
283
|
+
|
|
284
|
+
**Create a Model** (`resources/nuxt/models/User.js`):
|
|
285
|
+
|
|
286
|
+
```javascript
|
|
287
|
+
import { BaseModel } from '@awes-io/vue-mc'
|
|
288
|
+
|
|
289
|
+
export default class User extends BaseModel {
|
|
290
|
+
defaults() {
|
|
291
|
+
return {
|
|
292
|
+
id: null,
|
|
293
|
+
name: '',
|
|
294
|
+
email: '',
|
|
295
|
+
role: 'user',
|
|
296
|
+
created_at: null
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
routes() {
|
|
301
|
+
return {
|
|
302
|
+
fetch: '/api/users/{id}',
|
|
303
|
+
save: '/api/users',
|
|
304
|
+
update: '/api/users/{id}',
|
|
305
|
+
delete: '/api/users/{id}'
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
validation() {
|
|
310
|
+
return {
|
|
311
|
+
name: 'required|string|min:2',
|
|
312
|
+
email: 'required|email'
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Create a Collection** (`resources/nuxt/collections/Users.js`):
|
|
319
|
+
|
|
320
|
+
```javascript
|
|
321
|
+
import { BaseCollection } from '@awes-io/vue-mc'
|
|
322
|
+
import User from '~/models/User'
|
|
323
|
+
|
|
324
|
+
export default class Users extends BaseCollection {
|
|
325
|
+
model() {
|
|
326
|
+
return User
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
routes() {
|
|
330
|
+
return {
|
|
331
|
+
fetch: '/api/users'
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Use in Protected Page** (`resources/nuxt/pages/users/index.vue`):
|
|
338
|
+
|
|
339
|
+
```markup
|
|
340
|
+
<template>
|
|
341
|
+
<AwPage title="Users">
|
|
342
|
+
<!-- Header actions (create button) -->
|
|
343
|
+
<template #header-actions>
|
|
344
|
+
<AwButton
|
|
345
|
+
href="/users/create"
|
|
346
|
+
text="Create User"
|
|
347
|
+
icon="plus"
|
|
348
|
+
/>
|
|
349
|
+
</template>
|
|
350
|
+
|
|
351
|
+
<!-- Table with automatic fetching -->
|
|
352
|
+
<AwTableBuilder
|
|
353
|
+
:collection="users"
|
|
354
|
+
:options="{ shop_uuid: $auth.user.shop_uuid }"
|
|
355
|
+
>
|
|
356
|
+
<AwTableCol field="name" label="Name" />
|
|
357
|
+
<AwTableCol field="email" label="Email" />
|
|
358
|
+
<AwTableCol field="role" label="Role" />
|
|
359
|
+
<AwTableCol label="Created">
|
|
360
|
+
<template #default="{ data }">
|
|
361
|
+
{{ $dayjs(data.created_at).format('ll') }}
|
|
362
|
+
</template>
|
|
363
|
+
</AwTableCol>
|
|
364
|
+
|
|
365
|
+
<!-- Row actions dropdown -->
|
|
366
|
+
<template #dropdown="{ cell }">
|
|
367
|
+
<AwDropdownButton>
|
|
368
|
+
<AwButton
|
|
369
|
+
:href="`/users/${cell.id}`"
|
|
370
|
+
theme="text"
|
|
371
|
+
text="View"
|
|
372
|
+
/>
|
|
373
|
+
<AwButton
|
|
374
|
+
:href="`/users/${data.id}/edit`"
|
|
375
|
+
theme="text"
|
|
376
|
+
text="Edit"
|
|
377
|
+
/>
|
|
378
|
+
<AwButton
|
|
379
|
+
@click="deleteUser(data)"
|
|
380
|
+
theme="text"
|
|
381
|
+
color="error"
|
|
382
|
+
text="Delete"
|
|
383
|
+
/>
|
|
384
|
+
</AwDropdownButton>
|
|
385
|
+
</template>
|
|
386
|
+
</AwTableBuilder>
|
|
387
|
+
</AwPage>
|
|
388
|
+
</template>
|
|
389
|
+
|
|
390
|
+
<script>
|
|
391
|
+
import Users from '~/collections/Users'
|
|
392
|
+
|
|
393
|
+
export default {
|
|
394
|
+
// Require authentication
|
|
395
|
+
middleware: 'auth',
|
|
396
|
+
|
|
397
|
+
data() {
|
|
398
|
+
return {
|
|
399
|
+
users: new Users()
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
|
|
403
|
+
methods: {
|
|
404
|
+
async deleteUser(user) {
|
|
405
|
+
const isConfirmed = await this.$confirm({
|
|
406
|
+
title: 'Delete User',
|
|
407
|
+
message: `Are you sure you want to delete ${user.name}?`
|
|
408
|
+
})
|
|
409
|
+
|
|
410
|
+
if (!isConfirmed) return
|
|
411
|
+
|
|
412
|
+
try {
|
|
413
|
+
await this.$axios.delete(`/api/users/${user.id}`)
|
|
414
|
+
this.$notify({
|
|
415
|
+
message: 'User deleted successfully',
|
|
416
|
+
type: 'success'
|
|
417
|
+
})
|
|
418
|
+
// Refetch collection
|
|
419
|
+
this.users.fetch()
|
|
420
|
+
} catch (error) {
|
|
421
|
+
this.$notify({
|
|
422
|
+
message: 'Failed to delete user',
|
|
423
|
+
type: 'error'
|
|
424
|
+
})
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
</script>
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**What Happens**:
|
|
433
|
+
1. ✅ **nuxt-auth** middleware checks authentication
|
|
434
|
+
2. ✅ **AwTableBuilder** creates Users collection with shop_uuid
|
|
435
|
+
3. ✅ Collection automatically fetches from `/api/users`
|
|
436
|
+
4. ✅ **nuxt-laravel** proxies request to Laravel backend
|
|
437
|
+
5. ✅ **nuxt-auth** adds JWT token to request
|
|
438
|
+
6. ✅ Laravel returns paginated user data
|
|
439
|
+
7. ✅ Table displays data with automatic pagination
|
|
440
|
+
|
|
441
|
+
### Pattern 2: Create/Edit Page with Form Validation
|
|
442
|
+
|
|
443
|
+
**Create/Edit Page** (`resources/nuxt/pages/users/_id.vue`):
|
|
444
|
+
|
|
445
|
+
```markup
|
|
446
|
+
<template>
|
|
447
|
+
<AwPageSingle
|
|
448
|
+
:title="isNew ? 'Create User' : 'Edit User'"
|
|
449
|
+
hide-menu
|
|
450
|
+
>
|
|
451
|
+
<!-- Save button in header -->
|
|
452
|
+
<template #buttons>
|
|
453
|
+
<AwButton
|
|
454
|
+
@click="save"
|
|
455
|
+
:loading="model.saving"
|
|
456
|
+
text="Save"
|
|
457
|
+
icon="check"
|
|
458
|
+
/>
|
|
459
|
+
</template>
|
|
460
|
+
|
|
461
|
+
<!-- Form with validation -->
|
|
462
|
+
<AwCard>
|
|
463
|
+
<AwGrid>
|
|
464
|
+
<AwInput
|
|
465
|
+
v-model="model.name"
|
|
466
|
+
label="Name"
|
|
467
|
+
:error="model.errors.name"
|
|
468
|
+
required
|
|
469
|
+
/>
|
|
470
|
+
|
|
471
|
+
<AwInput
|
|
472
|
+
v-model="model.email"
|
|
473
|
+
label="Email"
|
|
474
|
+
type="email"
|
|
475
|
+
:error="model.errors.email"
|
|
476
|
+
required
|
|
477
|
+
/>
|
|
478
|
+
|
|
479
|
+
<AwSelect
|
|
480
|
+
v-model="model.role"
|
|
481
|
+
label="Role"
|
|
482
|
+
:options="['user', 'admin', 'manager']"
|
|
483
|
+
:error="model.errors.role"
|
|
484
|
+
/>
|
|
485
|
+
|
|
486
|
+
<AwPassword
|
|
487
|
+
v-if="isNew"
|
|
488
|
+
v-model="model.password"
|
|
489
|
+
label="Password"
|
|
490
|
+
:error="model.errors.password"
|
|
491
|
+
required
|
|
492
|
+
/>
|
|
493
|
+
</AwGrid>
|
|
494
|
+
</AwCard>
|
|
495
|
+
</AwPageSingle>
|
|
496
|
+
</template>
|
|
497
|
+
|
|
498
|
+
<script>
|
|
499
|
+
import User from '~/models/User'
|
|
500
|
+
|
|
501
|
+
export default {
|
|
502
|
+
middleware: 'auth',
|
|
503
|
+
|
|
504
|
+
data() {
|
|
505
|
+
return {
|
|
506
|
+
model: new User({ id: this.$route.params.id })
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
|
|
510
|
+
computed: {
|
|
511
|
+
isNew() {
|
|
512
|
+
return this.model.isNew()
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
|
|
516
|
+
async mounted() {
|
|
517
|
+
if (!this.isNew) {
|
|
518
|
+
try {
|
|
519
|
+
await this.model.fetch()
|
|
520
|
+
} catch (error) {
|
|
521
|
+
// Redirect on 404
|
|
522
|
+
this.$notify({
|
|
523
|
+
message: 'User not found',
|
|
524
|
+
type: 'error'
|
|
525
|
+
})
|
|
526
|
+
this.$router.push('/users')
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
},
|
|
530
|
+
|
|
531
|
+
methods: {
|
|
532
|
+
async save() {
|
|
533
|
+
try {
|
|
534
|
+
await this.model.save()
|
|
535
|
+
|
|
536
|
+
// Check for validation errors
|
|
537
|
+
if (Object.keys(this.model.errors).length > 0) {
|
|
538
|
+
this.$notify({
|
|
539
|
+
message: 'Please fix validation errors',
|
|
540
|
+
type: 'error'
|
|
541
|
+
})
|
|
542
|
+
return
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
this.$notify({
|
|
546
|
+
message: `User ${this.isNew ? 'created' : 'updated'} successfully`,
|
|
547
|
+
type: 'success'
|
|
548
|
+
})
|
|
549
|
+
|
|
550
|
+
this.$router.push('/users')
|
|
551
|
+
} catch (error) {
|
|
552
|
+
this.$notify({
|
|
553
|
+
message: 'Failed to save user',
|
|
554
|
+
type: 'error'
|
|
555
|
+
})
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
</script>
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
**What Happens**:
|
|
564
|
+
1. ✅ Page loads model with ID from route
|
|
565
|
+
2. ✅ If existing user, model.fetch() retrieves data
|
|
566
|
+
3. ✅ Form fields bound to model properties
|
|
567
|
+
4. ✅ On save, model.save() sends POST/PUT request
|
|
568
|
+
5. ✅ Laravel validates and returns errors (422 status)
|
|
569
|
+
6. ✅ Model populates `errors` object
|
|
570
|
+
7. ✅ Error messages display next to fields
|
|
571
|
+
8. ✅ On success, redirect to list page
|
|
572
|
+
|
|
573
|
+
### Pattern 3: Real-Time Data with Broadcasting
|
|
574
|
+
|
|
575
|
+
**Setup** (requires Laravel Broadcasting):
|
|
576
|
+
|
|
577
|
+
```javascript
|
|
578
|
+
// nuxt.config.js
|
|
579
|
+
export default {
|
|
580
|
+
modules: [
|
|
581
|
+
'@awes-io/nuxt-laravel',
|
|
582
|
+
'@awes-io/nuxt-auth',
|
|
583
|
+
'@awes-io/ui',
|
|
584
|
+
'@nuxtjs/socket.io' // Add socket.io
|
|
585
|
+
],
|
|
586
|
+
|
|
587
|
+
io: {
|
|
588
|
+
sockets: [{
|
|
589
|
+
url: process.env.LARAVEL_URL,
|
|
590
|
+
default: true
|
|
591
|
+
}]
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
**Component with Real-Time Updates**:
|
|
597
|
+
|
|
598
|
+
```markup
|
|
599
|
+
<template>
|
|
600
|
+
<AwPage title="Notifications">
|
|
601
|
+
<div v-for="notification in notifications" :key="notification.id">
|
|
602
|
+
<AwAlert :type="notification.type">
|
|
603
|
+
{{ notification.message }}
|
|
604
|
+
</AwAlert>
|
|
605
|
+
</div>
|
|
606
|
+
</AwPage>
|
|
607
|
+
</template>
|
|
608
|
+
|
|
609
|
+
<script>
|
|
610
|
+
export default {
|
|
611
|
+
middleware: 'auth',
|
|
612
|
+
|
|
613
|
+
data() {
|
|
614
|
+
return {
|
|
615
|
+
notifications: []
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
|
|
619
|
+
mounted() {
|
|
620
|
+
// Subscribe to private channel
|
|
621
|
+
this.$socket.private(`user.${this.$auth.user.id}`)
|
|
622
|
+
.listen('NotificationSent', (notification) => {
|
|
623
|
+
this.notifications.unshift(notification)
|
|
624
|
+
this.$notify({
|
|
625
|
+
message: notification.message,
|
|
626
|
+
type: notification.type
|
|
627
|
+
})
|
|
628
|
+
})
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
</script>
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### Pattern 4: Permission-Based UI Rendering
|
|
635
|
+
|
|
636
|
+
```markup
|
|
637
|
+
<template>
|
|
638
|
+
<AwPage title="Dashboard">
|
|
639
|
+
<!-- Admin-only section -->
|
|
640
|
+
<AwCard v-if="$auth.user.role === 'admin'">
|
|
641
|
+
<h2>Admin Statistics</h2>
|
|
642
|
+
<!-- Admin content -->
|
|
643
|
+
</AwCard>
|
|
644
|
+
|
|
645
|
+
<!-- Manager and above -->
|
|
646
|
+
<AwCard v-if="canManage">
|
|
647
|
+
<h2>Team Management</h2>
|
|
648
|
+
<!-- Management content -->
|
|
649
|
+
</AwCard>
|
|
650
|
+
|
|
651
|
+
<!-- Everyone sees this -->
|
|
652
|
+
<AwCard>
|
|
653
|
+
<h2>Your Activity</h2>
|
|
654
|
+
<!-- User activity -->
|
|
655
|
+
</AwCard>
|
|
656
|
+
</AwPage>
|
|
657
|
+
</template>
|
|
658
|
+
|
|
659
|
+
<script>
|
|
660
|
+
export default {
|
|
661
|
+
middleware: 'auth',
|
|
662
|
+
|
|
663
|
+
computed: {
|
|
664
|
+
canManage() {
|
|
665
|
+
return ['admin', 'manager'].includes(this.$auth.user.role)
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
</script>
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
## Common Integration Issues
|
|
673
|
+
|
|
674
|
+
### Issue 1: API Requests Not Proxied
|
|
675
|
+
|
|
676
|
+
**Symptom**: CORS errors or 404 on API calls
|
|
677
|
+
|
|
678
|
+
**Solution**: Check environment variables
|
|
679
|
+
|
|
680
|
+
```bash
|
|
681
|
+
# Verify LARAVEL_URL is set
|
|
682
|
+
echo $LARAVEL_URL
|
|
683
|
+
|
|
684
|
+
# Check proxy configuration in network tab
|
|
685
|
+
# Should see requests to /api/* being proxied
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
**Fix**:
|
|
689
|
+
```bash
|
|
690
|
+
# Set in package.json scripts
|
|
691
|
+
"dev": "LARAVEL_URL=http://localhost:8000 nuxt"
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### Issue 2: Authentication Not Persisting
|
|
695
|
+
|
|
696
|
+
**Symptom**: User logged out on page refresh
|
|
697
|
+
|
|
698
|
+
**Solution**: Check Laravel session/CORS config
|
|
699
|
+
|
|
700
|
+
```php
|
|
701
|
+
// config/cors.php
|
|
702
|
+
'supports_credentials' => true,
|
|
703
|
+
|
|
704
|
+
// config/session.php
|
|
705
|
+
'domain' => env('SESSION_DOMAIN', null), // Set to null for localhost
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
### Issue 3: Models Not Receiving Auth Token
|
|
709
|
+
|
|
710
|
+
**Symptom**: 401 errors on authenticated requests
|
|
711
|
+
|
|
712
|
+
**Solution**: Ensure module order in nuxt.config.js
|
|
713
|
+
|
|
714
|
+
```javascript
|
|
715
|
+
modules: [
|
|
716
|
+
'@awes-io/nuxt-laravel', // FIRST (configures axios)
|
|
717
|
+
'@awes-io/nuxt-auth', // SECOND (adds token interceptor)
|
|
718
|
+
'@awes-io/ui' // THIRD (uses axios)
|
|
719
|
+
]
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
### Issue 4: Build Files Not Copied to Public
|
|
723
|
+
|
|
724
|
+
**Symptom**: `public/_nuxt/` empty after generate
|
|
725
|
+
|
|
726
|
+
**Solution**: Check generateDir matches Laravel structure
|
|
727
|
+
|
|
728
|
+
```javascript
|
|
729
|
+
// nuxt.config.js
|
|
730
|
+
awesIo: {
|
|
731
|
+
nuxtLaravel: {
|
|
732
|
+
generateDir: 'storage/app/nuxt' // Must match Laravel structure
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
### Issue 5: Components Not Rendering
|
|
738
|
+
|
|
739
|
+
**Symptom**: `<AwButton>` renders as empty
|
|
740
|
+
|
|
741
|
+
**Solution**: Ensure UI module is loaded
|
|
742
|
+
|
|
743
|
+
```javascript
|
|
744
|
+
// nuxt.config.js
|
|
745
|
+
modules: [
|
|
746
|
+
'@awes-io/ui' // Registers global components
|
|
747
|
+
]
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
## Development Workflow
|
|
751
|
+
|
|
752
|
+
### 1. Start Development Servers
|
|
753
|
+
|
|
754
|
+
```bash
|
|
755
|
+
# Terminal 1: Laravel backend
|
|
756
|
+
php artisan serve
|
|
757
|
+
# Listening on http://localhost:8000
|
|
758
|
+
|
|
759
|
+
# Terminal 2: Nuxt frontend
|
|
760
|
+
yarn dev
|
|
761
|
+
# Listening on http://localhost:3000
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
### 2. Hot Reload
|
|
765
|
+
|
|
766
|
+
- Frontend changes: Automatic hot reload
|
|
767
|
+
- Backend changes: Restart Laravel server if needed
|
|
768
|
+
|
|
769
|
+
### 3. Database Migrations
|
|
770
|
+
|
|
771
|
+
```bash
|
|
772
|
+
# Run migrations
|
|
773
|
+
php artisan migrate
|
|
774
|
+
|
|
775
|
+
# Seed data
|
|
776
|
+
php artisan db:seed
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
## Production Deployment
|
|
780
|
+
|
|
781
|
+
### 1. Build Frontend
|
|
782
|
+
|
|
783
|
+
```bash
|
|
784
|
+
# Generate static files
|
|
785
|
+
yarn generate
|
|
786
|
+
|
|
787
|
+
# Output: storage/app/nuxt/ → public/_nuxt/
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
### 2. Configure Environment
|
|
791
|
+
|
|
792
|
+
```bash
|
|
793
|
+
# .env (production)
|
|
794
|
+
APP_ENV=production
|
|
795
|
+
LARAVEL_URL=https://api.example.com
|
|
796
|
+
NON_PROXY_URL=https://api.example.com
|
|
797
|
+
FRONTEND_URL=https://example.com
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
### 3. Deploy Laravel
|
|
801
|
+
|
|
802
|
+
```bash
|
|
803
|
+
# Standard Laravel deployment
|
|
804
|
+
composer install --optimize-autoloader --no-dev
|
|
805
|
+
php artisan config:cache
|
|
806
|
+
php artisan route:cache
|
|
807
|
+
php artisan view:cache
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
### 4. Serve Application
|
|
811
|
+
|
|
812
|
+
Laravel serves the Nuxt SPA via `public/index.html` with all routes handled by the SPA router.
|
|
813
|
+
|
|
814
|
+
## Testing Integration
|
|
815
|
+
|
|
816
|
+
### Component Testing
|
|
817
|
+
|
|
818
|
+
```javascript
|
|
819
|
+
// components/__tests__/UserList.spec.js
|
|
820
|
+
import { mount } from '@vue/test-utils'
|
|
821
|
+
import UserList from '~/components/UserList'
|
|
822
|
+
import Users from '~/collections/Users'
|
|
823
|
+
|
|
824
|
+
describe('UserList', () => {
|
|
825
|
+
it('displays users from collection', async () => {
|
|
826
|
+
const users = new Users([
|
|
827
|
+
{ id: 1, name: 'Alice' },
|
|
828
|
+
{ id: 2, name: 'Bob' }
|
|
829
|
+
])
|
|
830
|
+
|
|
831
|
+
const wrapper = mount(UserList, {
|
|
832
|
+
data: () => ({ users })
|
|
833
|
+
})
|
|
834
|
+
|
|
835
|
+
expect(wrapper.text()).toContain('Alice')
|
|
836
|
+
expect(wrapper.text()).toContain('Bob')
|
|
837
|
+
})
|
|
838
|
+
})
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### E2E Testing
|
|
842
|
+
|
|
843
|
+
```javascript
|
|
844
|
+
// tests/e2e/auth.spec.js
|
|
845
|
+
describe('Authentication', () => {
|
|
846
|
+
it('can login and access protected page', () => {
|
|
847
|
+
cy.visit('/login')
|
|
848
|
+
cy.get('[name=email]').type('user@example.com')
|
|
849
|
+
cy.get('[name=password]').type('password')
|
|
850
|
+
cy.get('button[type=submit]').click()
|
|
851
|
+
|
|
852
|
+
cy.url().should('include', '/dashboard')
|
|
853
|
+
cy.contains('Welcome back')
|
|
854
|
+
})
|
|
855
|
+
})
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
## Next Steps
|
|
859
|
+
|
|
860
|
+
- **Build Pages**: See [Page Pattern Guides](./guides/page-patterns/)
|
|
861
|
+
- **Best Practices**: See [Best Practices Guide](./guides/best-practices.md)
|
|
862
|
+
- **Forms**: See [Forms Guide](./guides/forms-guide.md)
|
|
863
|
+
- **Components**: Browse [Component Documentation](./components/)
|
|
864
|
+
|
|
865
|
+
## External Resources
|
|
866
|
+
|
|
867
|
+
- [Nuxt.js Documentation](https://nuxtjs.org/)
|
|
868
|
+
- [Laravel Documentation](https://laravel.com/docs)
|
|
869
|
+
- [Vue.js Guide](https://vuejs.org/guide/)
|
|
870
|
+
- [Axios Documentation](https://axios-http.com/docs/)
|