# Package Integration Guide

Complete guide to integrating all AwesCode UI packages together for a full-stack Nuxt.js + Laravel application.

## Framework Architecture

The AwesCode UI framework consists of four interconnected packages that work together:

```
┌─────────────────────────────────────────────────────────────┐
│                     Nuxt.js Application                      │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│  @awes-io/ui (Components & Pages)                           │
│  - AwPage, AwTableBuilder, AwForm                           │
│  - Global components (atoms, molecules)                      │
│  - Page layouts and navigation                               │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│  @awes-io/nuxt-auth (Authentication)                        │
│  - $auth object and user state                              │
│  - Login, register, 2FA, OAuth                               │
│  - Route protection middleware                               │
│  - JWT token management                                      │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│  @awes-io/nuxt-laravel (Backend Integration)                │
│  - API proxy configuration                                   │
│  - Axios setup and base URL                                  │
│  - Build process (Nuxt → Laravel public)                     │
│  - Version plugin                                            │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│  @awes-io/vue-mc (Models & Collections)                     │
│  - BaseModel for single resources                           │
│  - BaseCollection for lists                                  │
│  - Automatic API communication                               │
│  - Validation and error handling                             │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
                    ┌─────────────────┐
                    │  Laravel Backend │
                    │  (API endpoints) │
                    └─────────────────┘
```

## Data Flow

**Typical request flow:**

1. User interacts with **UI component** (AwTableBuilder, AwForm)
2. Component uses **vue-mc Model/Collection** for data operations
3. Model/Collection makes request via **$axios** (configured by nuxt-laravel)
4. **nuxt-auth** adds JWT token to request headers
5. **nuxt-laravel proxy** forwards request to Laravel backend
6. Laravel processes request and returns response
7. Model/Collection updates and notifies UI component
8. Component re-renders with new data

## Package Overview

### 1. UI Components (@awes-io/ui)

**Purpose**: Pre-built Vue components for building application interfaces

**Key Features**:
- 102+ components organized by atomic design
- Page components (AwPage, AwPageSingle)
- Form components with validation
- Table builder with auto-fetching
- Layout system with navigation

**Documentation**: [./index.md](./index.md)

### 2. Vue-MC (@awes-io/vue-mc)

**Purpose**: Model-Collection layer for API data management

**Key Features**:
- BaseModel for single resources
- BaseCollection for lists with pagination
- Automatic API communication
- Built-in validation
- Lifecycle hooks

**Documentation**: [../../vue-mc/docs/](../../vue-mc/docs/)

### 3. Nuxt-Auth (@awes-io/nuxt-auth)

**Purpose**: Complete authentication solution

**Key Features**:
- JWT authentication with Laravel backend
- Two-factor authentication (2FA)
- Social login (OAuth)
- Email verification
- Password reset
- Route protection middleware

**Documentation**: [../../nuxt-auth/docs/](../../nuxt-auth/docs/)

### 4. Nuxt-Laravel (@awes-io/nuxt-laravel)

**Purpose**: Integration layer between Nuxt.js and Laravel

**Key Features**:
- API proxy for development and production
- Automatic axios configuration
- Build process (Nuxt → Laravel public)
- Version plugin for tracking deployments

**Documentation**: [../../nuxt-laravel/docs/](../../nuxt-laravel/docs/)

## Complete Setup Example

### 1. Installation

```bash
# Install all packages
yarn add @awes-io/ui @awes-io/vue-mc @awes-io/nuxt-auth @awes-io/nuxt-laravel

# Install peer dependencies
yarn add @nuxtjs/axios dayjs
```

### 2. Project Structure

```
project-root/
├── app/                        # Laravel application
├── resources/
│   └── nuxt/                   # Nuxt source code
│       ├── assets/
│       ├── components/
│       ├── layouts/
│       ├── pages/
│       ├── models/             # Vue-MC models
│       ├── collections/        # Vue-MC collections
│       └── plugins/
├── storage/app/nuxt/           # Nuxt build output
├── public/                     # Laravel public (serves SPA)
├── nuxt.config.js              # Nuxt configuration
├── package.json                # NPM dependencies
└── composer.json               # Composer dependencies
```

### 3. Environment Variables

**`.env`** (Laravel root):

```bash
# Laravel backend URL
LARAVEL_URL=http://localhost:8000

# Frontend URL (for CORS)
FRONTEND_URL=http://localhost:3000

# Direct API URL (production, skip proxy)
NON_PROXY_URL=https://api.example.com

# Application info (for version plugin)
APP_NAME=MyApplication
APP_VERSION=v1.0.0
APP_VERSION_DATE=2024-01-15T10:00:00Z

# Laravel settings
APP_URL=http://localhost:8000
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:3000
```

### 4. Nuxt Configuration

**`nuxt.config.js`**:

```javascript
export default {
    // SPA mode
    mode: 'spa',

    // Nuxt source directory
    srcDir: 'resources/nuxt',

    // Modules (ORDER MATTERS!)
    modules: [
        // 1. Laravel integration (includes axios)
        '@awes-io/nuxt-laravel',

        // 2. Authentication
        '@awes-io/nuxt-auth',

        // 3. UI components
        '@awes-io/ui'
    ],

    // Module options
    awesIo: {
        nuxtLaravel: {
            generateDir: 'storage/app/nuxt',
            versionPlugin: {
                name: process.env.APP_NAME,
                version: process.env.APP_VERSION,
                date: process.env.APP_VERSION_DATE
            }
        },
        nuxtAuth: {
            register: true,           // Enable registration
            socialLogin: true,        // Enable OAuth
            twoFactor: true,         // Enable 2FA
            emailVerification: true  // Enable email verification
        }
    },

    // Environment variables available in app
    env: {
        laravelUrl: process.env.LARAVEL_URL || 'http://localhost:8000',
        frontendUrl: process.env.FRONTEND_URL || 'http://localhost:3000'
    },

    // Build configuration
    build: {
        extractCSS: true,
        optimizeCSS: true,
        transpile: ['@awes-io/ui', '@awes-io/vue-mc']
    }
}
```

### 5. Package Scripts

**`package.json`**:

```json
{
    "scripts": {
        "dev": "LARAVEL_URL=http://localhost:8000 nuxt",
        "build": "LARAVEL_URL=http://localhost:8000 nuxt build",
        "generate": "LARAVEL_URL=http://localhost:8000 nuxt generate",
        "start": "LARAVEL_URL=http://localhost:8000 nuxt start"
    }
}
```

### 6. Laravel Configuration

**`config/cors.php`**:

```php
return [
    'paths' => ['api/*', 'broadcasting/*', 'sanctum/csrf-cookie'],
    'allowed_methods' => ['*'],
    'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:3000')],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true,
];
```

**`routes/web.php`** (serve Nuxt SPA):

```php
// Serve Nuxt SPA for all routes (except API)
Route::fallback(function () {
    return file_get_contents(public_path('index.html'));
});
```

## Integration Patterns

### Pattern 1: Authenticated API Call with Vue-MC

**Create a Model** (`resources/nuxt/models/User.js`):

```javascript
import { BaseModel } from '@awes-io/vue-mc'

export default class User extends BaseModel {
    defaults() {
        return {
            id: null,
            name: '',
            email: '',
            role: 'user',
            created_at: null
        }
    }

    routes() {
        return {
            fetch: '/api/users/{id}',
            save: '/api/users',
            update: '/api/users/{id}',
            delete: '/api/users/{id}'
        }
    }

    validation() {
        return {
            name: 'required|string|min:2',
            email: 'required|email'
        }
    }
}
```

**Create a Collection** (`resources/nuxt/collections/Users.js`):

```javascript
import { BaseCollection } from '@awes-io/vue-mc'
import User from '~/models/User'

export default class Users extends BaseCollection {
    model() {
        return User
    }

    routes() {
        return {
            fetch: '/api/users'
        }
    }
}
```

**Use in Protected Page** (`resources/nuxt/pages/users/index.vue`):

```markup
<template>
    <AwPage title="Users">
        <!-- Header actions (create button) -->
        <template #header-actions>
            <AwButton
                href="/users/create"
                text="Create User"
                icon="plus"
            />
        </template>

        <!-- Table with automatic fetching -->
        <AwTableBuilder
            :collection="users"
            :options="{ shop_uuid: $auth.user.shop_uuid }"
        >
            <AwTableCol field="name" label="Name" />
            <AwTableCol field="email" label="Email" />
            <AwTableCol field="role" label="Role" />
            <AwTableCol label="Created">
                <template #default="{ data }">
                    {{ $dayjs(data.created_at).format('ll') }}
                </template>
            </AwTableCol>

            <!-- Row actions dropdown -->
            <template #dropdown="{ cell }">
                <AwDropdownButton>
                    <AwButton
                        :href="`/users/${cell.id}`"
                        theme="text"
                        text="View"
                    />
                    <AwButton
                        :href="`/users/${data.id}/edit`"
                        theme="text"
                        text="Edit"
                    />
                    <AwButton
                        @click="deleteUser(data)"
                        theme="text"
                        color="error"
                        text="Delete"
                    />
                </AwDropdownButton>
            </template>
        </AwTableBuilder>
    </AwPage>
</template>

<script>
import Users from '~/collections/Users'

export default {
    // Require authentication
    middleware: 'auth',

    data() {
        return {
            users: new Users()
        }
    },

    methods: {
        async deleteUser(user) {
            const isConfirmed = await this.$confirm({
                title: 'Delete User',
                message: `Are you sure you want to delete ${user.name}?`
            })

            if (!isConfirmed) return

            try {
                await this.$axios.delete(`/api/users/${user.id}`)
                this.$notify({
                    message: 'User deleted successfully',
                    type: 'success'
                })
                // Refetch collection
                this.users.fetch()
            } catch (error) {
                this.$notify({
                    message: 'Failed to delete user',
                    type: 'error'
                })
            }
        }
    }
}
</script>
```

**What Happens**:
1. ✅ **nuxt-auth** middleware checks authentication
2. ✅ **AwTableBuilder** creates Users collection with shop_uuid
3. ✅ Collection automatically fetches from `/api/users`
4. ✅ **nuxt-laravel** proxies request to Laravel backend
5. ✅ **nuxt-auth** adds JWT token to request
6. ✅ Laravel returns paginated user data
7. ✅ Table displays data with automatic pagination

### Pattern 2: Create/Edit Page with Form Validation

**Create/Edit Page** (`resources/nuxt/pages/users/_id.vue`):

```markup
<template>
    <AwPageSingle
        :title="isNew ? 'Create User' : 'Edit User'"
        hide-menu
    >
        <!-- Save button in header -->
        <template #buttons>
            <AwButton
                @click="save"
                :loading="model.saving"
                text="Save"
                icon="check"
            />
        </template>

        <!-- Form with validation -->
        <AwCard>
            <AwGrid>
                <AwInput
                    v-model="model.name"
                    label="Name"
                    :error="model.errors.name"
                    required
                />

                <AwInput
                    v-model="model.email"
                    label="Email"
                    type="email"
                    :error="model.errors.email"
                    required
                />

                <AwSelect
                    v-model="model.role"
                    label="Role"
                    :options="['user', 'admin', 'manager']"
                    :error="model.errors.role"
                />

                <AwPassword
                    v-if="isNew"
                    v-model="model.password"
                    label="Password"
                    :error="model.errors.password"
                    required
                />
            </AwGrid>
        </AwCard>
    </AwPageSingle>
</template>

<script>
import User from '~/models/User'

export default {
    middleware: 'auth',

    data() {
        return {
            model: new User({ id: this.$route.params.id })
        }
    },

    computed: {
        isNew() {
            return this.model.isNew()
        }
    },

    async mounted() {
        if (!this.isNew) {
            try {
                await this.model.fetch()
            } catch (error) {
                // Redirect on 404
                this.$notify({
                    message: 'User not found',
                    type: 'error'
                })
                this.$router.push('/users')
            }
        }
    },

    methods: {
        async save() {
            try {
                await this.model.save()

                // Check for validation errors
                if (Object.keys(this.model.errors).length > 0) {
                    this.$notify({
                        message: 'Please fix validation errors',
                        type: 'error'
                    })
                    return
                }

                this.$notify({
                    message: `User ${this.isNew ? 'created' : 'updated'} successfully`,
                    type: 'success'
                })

                this.$router.push('/users')
            } catch (error) {
                this.$notify({
                    message: 'Failed to save user',
                    type: 'error'
                })
            }
        }
    }
}
</script>
```

**What Happens**:
1. ✅ Page loads model with ID from route
2. ✅ If existing user, model.fetch() retrieves data
3. ✅ Form fields bound to model properties
4. ✅ On save, model.save() sends POST/PUT request
5. ✅ Laravel validates and returns errors (422 status)
6. ✅ Model populates `errors` object
7. ✅ Error messages display next to fields
8. ✅ On success, redirect to list page

### Pattern 3: Real-Time Data with Broadcasting

**Setup** (requires Laravel Broadcasting):

```javascript
// nuxt.config.js
export default {
    modules: [
        '@awes-io/nuxt-laravel',
        '@awes-io/nuxt-auth',
        '@awes-io/ui',
        '@nuxtjs/socket.io' // Add socket.io
    ],

    io: {
        sockets: [{
            url: process.env.LARAVEL_URL,
            default: true
        }]
    }
}
```

**Component with Real-Time Updates**:

```markup
<template>
    <AwPage title="Notifications">
        <div v-for="notification in notifications" :key="notification.id">
            <AwAlert :type="notification.type">
                {{ notification.message }}
            </AwAlert>
        </div>
    </AwPage>
</template>

<script>
export default {
    middleware: 'auth',

    data() {
        return {
            notifications: []
        }
    },

    mounted() {
        // Subscribe to private channel
        this.$socket.private(`user.${this.$auth.user.id}`)
            .listen('NotificationSent', (notification) => {
                this.notifications.unshift(notification)
                this.$notify({
                    message: notification.message,
                    type: notification.type
                })
            })
    }
}
</script>
```

### Pattern 4: Permission-Based UI Rendering

```markup
<template>
    <AwPage title="Dashboard">
        <!-- Admin-only section -->
        <AwCard v-if="$auth.user.role === 'admin'">
            <h2>Admin Statistics</h2>
            <!-- Admin content -->
        </AwCard>

        <!-- Manager and above -->
        <AwCard v-if="canManage">
            <h2>Team Management</h2>
            <!-- Management content -->
        </AwCard>

        <!-- Everyone sees this -->
        <AwCard>
            <h2>Your Activity</h2>
            <!-- User activity -->
        </AwCard>
    </AwPage>
</template>

<script>
export default {
    middleware: 'auth',

    computed: {
        canManage() {
            return ['admin', 'manager'].includes(this.$auth.user.role)
        }
    }
}
</script>
```

## Common Integration Issues

### Issue 1: API Requests Not Proxied

**Symptom**: CORS errors or 404 on API calls

**Solution**: Check environment variables

```bash
# Verify LARAVEL_URL is set
echo $LARAVEL_URL

# Check proxy configuration in network tab
# Should see requests to /api/* being proxied
```

**Fix**:
```bash
# Set in package.json scripts
"dev": "LARAVEL_URL=http://localhost:8000 nuxt"
```

### Issue 2: Authentication Not Persisting

**Symptom**: User logged out on page refresh

**Solution**: Check Laravel session/CORS config

```php
// config/cors.php
'supports_credentials' => true,

// config/session.php
'domain' => env('SESSION_DOMAIN', null), // Set to null for localhost
```

### Issue 3: Models Not Receiving Auth Token

**Symptom**: 401 errors on authenticated requests

**Solution**: Ensure module order in nuxt.config.js

```javascript
modules: [
    '@awes-io/nuxt-laravel',  // FIRST (configures axios)
    '@awes-io/nuxt-auth',     // SECOND (adds token interceptor)
    '@awes-io/ui'             // THIRD (uses axios)
]
```

### Issue 4: Build Files Not Copied to Public

**Symptom**: `public/_nuxt/` empty after generate

**Solution**: Check generateDir matches Laravel structure

```javascript
// nuxt.config.js
awesIo: {
    nuxtLaravel: {
        generateDir: 'storage/app/nuxt'  // Must match Laravel structure
    }
}
```

### Issue 5: Components Not Rendering

**Symptom**: `<AwButton>` renders as empty

**Solution**: Ensure UI module is loaded

```javascript
// nuxt.config.js
modules: [
    '@awes-io/ui'  // Registers global components
]
```

## Development Workflow

### 1. Start Development Servers

```bash
# Terminal 1: Laravel backend
php artisan serve
# Listening on http://localhost:8000

# Terminal 2: Nuxt frontend
yarn dev
# Listening on http://localhost:3000
```

### 2. Hot Reload

- Frontend changes: Automatic hot reload
- Backend changes: Restart Laravel server if needed

### 3. Database Migrations

```bash
# Run migrations
php artisan migrate

# Seed data
php artisan db:seed
```

## Production Deployment

### 1. Build Frontend

```bash
# Generate static files
yarn generate

# Output: storage/app/nuxt/ → public/_nuxt/
```

### 2. Configure Environment

```bash
# .env (production)
APP_ENV=production
LARAVEL_URL=https://api.example.com
NON_PROXY_URL=https://api.example.com
FRONTEND_URL=https://example.com
```

### 3. Deploy Laravel

```bash
# Standard Laravel deployment
composer install --optimize-autoloader --no-dev
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

### 4. Serve Application

Laravel serves the Nuxt SPA via `public/index.html` with all routes handled by the SPA router.

## Testing Integration

### Component Testing

```javascript
// components/__tests__/UserList.spec.js
import { mount } from '@vue/test-utils'
import UserList from '~/components/UserList'
import Users from '~/collections/Users'

describe('UserList', () => {
    it('displays users from collection', async () => {
        const users = new Users([
            { id: 1, name: 'Alice' },
            { id: 2, name: 'Bob' }
        ])

        const wrapper = mount(UserList, {
            data: () => ({ users })
        })

        expect(wrapper.text()).toContain('Alice')
        expect(wrapper.text()).toContain('Bob')
    })
})
```

### E2E Testing

```javascript
// tests/e2e/auth.spec.js
describe('Authentication', () => {
    it('can login and access protected page', () => {
        cy.visit('/login')
        cy.get('[name=email]').type('user@example.com')
        cy.get('[name=password]').type('password')
        cy.get('button[type=submit]').click()

        cy.url().should('include', '/dashboard')
        cy.contains('Welcome back')
    })
})
```

## Next Steps

- **Build Pages**: See [Page Pattern Guides](./guides/page-patterns/)
- **Best Practices**: See [Best Practices Guide](./guides/best-practices.md)
- **Forms**: See [Forms Guide](./guides/forms-guide.md)
- **Components**: Browse [Component Documentation](./components/)

## External Resources

- [Nuxt.js Documentation](https://nuxtjs.org/)
- [Laravel Documentation](https://laravel.com/docs)
- [Vue.js Guide](https://vuejs.org/guide/)
- [Axios Documentation](https://axios-http.com/docs/)
