# Troubleshooting Guide

Solutions to common issues when working with AwesCode UI framework.

## Component Issues

### Component Not Rendering

**Problem:** Component doesn't appear on the page.

**Possible Causes:**

1. **Component not registered**
```markup
<!-- ❌ Component not found -->
<AwCustomComponent />
```

**Solution:** Check if component is globally registered (atoms, molecules) or needs dynamic import (organisms, pages, layouts):
```javascript
// For organisms, pages, layouts
export default {
    components: {
        AwForm: () => import('@awes-io/ui/components/3_organisms/AwForm.vue')
    }
}
```

2. **Component hidden by v-if**
```markup
<!-- ❌ Never renders if loading=true initially -->
<AwTableBuilder v-if="!loading" :collection="customers" />
```

**Solution:** Let component handle its own loading state:
```markup
<!-- ✅ Component mounts and shows internal loading -->
<AwTableBuilder :collection="customers" />
```

3. **Wrong component path**
```javascript
// ❌ Old path after reorganization
import AwButton from '@awes-io/ui/docs/aw-button.md'

// ✅ Correct path
// AwButton is globally registered, no import needed
```

### Component Props Not Working

**Problem:** Props don't seem to have any effect.

**Debugging Steps:**

1. Check prop name spelling:
```markup
<!-- ❌ Wrong prop name -->
<AwButton colour="accent">Save</AwButton>

<!-- ✅ Correct prop name -->
<AwButton color="accent">Save</AwButton>
```

2. Check prop type:
```markup
<!-- ❌ String instead of boolean -->
<AwButton loading="true">Save</AwButton>

<!-- ✅ Boolean -->
<AwButton :loading="true">Save</AwButton>
```

3. Check component documentation:
```markup
<!-- ✅ Refer to component docs for correct props -->
<!-- See: packages/ui/docs/components/molecules/aw-button.md -->
```

### Events Not Firing

**Problem:** Component events don't trigger methods.

**Common Causes:**

1. **Missing v-on or @**
```markup
<!-- ❌ Missing @ -->
<AwButton click="save">Save</AwButton>

<!-- ✅ Correct -->
<AwButton @click="save">Save</AwButton>
```

2. **Wrong event name**
```markup
<!-- ❌ Wrong event name -->
<AwTableBuilder @row-click="viewRow">

<!-- ✅ Correct event name -->
<AwTableBuilder @click:row="viewRow">
```

3. **Event bubbling stopped**
```markup
<!-- ❌ Click event stopped by child -->
<AwTableBuilder @click:row="viewRow">
    <template #dropdown="{ cell }">
        <AwDropdownButton>
            <!-- This stops row click -->
        </AwDropdownButton>
    </template>
</AwTableBuilder>

<!-- ✅ Use dropdown slot OR click:row, not both -->
<AwTableBuilder :collection="customers">
    <template #dropdown="{ cell }">
        <AwDropdownButton>
            <AwButton @click="edit(cell)">Edit</AwButton>
        </AwDropdownButton>
    </template>
</AwTableBuilder>
```

## Data Fetching Issues

### AwTableBuilder Not Fetching Data

**Problem:** Table shows empty, data never loads.

**Cause:** Table wrapped in v-if/v-else, preventing mount:
```markup
<!-- ❌ BAD - Table never mounts if loading=true -->
<template>
    <AwPage title="Customers">
        <div v-if="loading">Loading...</div>
        <AwTableBuilder v-else :collection="customers">
            <!-- Never mounts! -->
        </AwTableBuilder>
    </AwPage>
</template>

<script>
export default {
    data() {
        return {
            loading: true,  // Starts true
            customers: new Customers([])
        }
    }
}
</script>
```

**Solution:** Let AwTableBuilder handle loading:
```markup
<!-- ✅ GOOD - Table mounts and fetches automatically -->
<template>
    <AwPage title="Customers">
        <AwTableBuilder :collection="customers">
            <!-- Mounts immediately, shows internal loading state -->
        </AwTableBuilder>
    </AwPage>
</template>

<script>
export default {
    data() {
        return {
            customers: new Customers([], {
                shop_uuid: this.$route.params.shop_uuid
            })
        }
    }
    // No loading flag needed!
}
</script>
```

### Collection Returns Empty Array

**Problem:** API request succeeds but collection.models is empty.

**Debugging Steps:**

1. **Check response structure**
```javascript
// Expected structure
{
    "data": [...],  // Array of items
    "meta": {...}   // Pagination meta
}

// If your API returns different structure, configure collection
```

2. **Check collection route**
```javascript
// In collection file
routes() {
    return {
        fetch: '/api/shops/:shop_uuid/customers'  // Must match backend route
    }
}
```

3. **Check collection options**
```javascript
// ✅ Include shop_uuid in options
customers: new Customers([], {
    shop_uuid: this.$route.params.shop_uuid
})

// ❌ Missing shop_uuid
customers: new Customers([])
```

4. **Inspect network request**
```javascript
// Open browser DevTools → Network tab
// Check request URL and response
```

### Model Fetch Returns 404

**Problem:** Fetching model returns 404 Not Found.

**Debugging Steps:**

1. **Check if model is new**
```javascript
// ✅ Don't fetch new models
if (!this.model.isNew()) {
    await this.model.fetch()
}

// ❌ Fetching new model fails
await this.model.fetch()  // 404 if no ID
```

2. **Check model route**
```javascript
// In model file
routes() {
    return {
        fetch: '/api/shops/:shop_uuid/customers/:id'
    }
}
```

3. **Check model has ID**
```javascript
// ✅ Model has ID
const customer = new Customer(
    { id: this.$route.params.id },
    null,
    { shop_uuid: this.$route.params.shop_uuid }
)

// ❌ Model has no ID
const customer = new Customer({}, null, {})
```

### Infinite Loading / Fetch Loop

**Problem:** Component keeps fetching data repeatedly.

**Cause:** Watch triggers refetch, which triggers watch again:
```javascript
// ❌ Creates infinite loop
watch: {
    collection: {
        handler() {
            this.collection.fetch()  // Triggers watch again
        },
        deep: true
    }
}
```

**Solution:** Watch specific properties:
```javascript
// ✅ Watch route params instead
watch: {
    '$route.query.search': {
        handler() {
            this.collection.fetch()
        }
    }
}

// ✅ Or use AwTableBuilder watch-params
<AwTableBuilder
    :collection="customers"
    :watch-params="['search', 'status']"
/>
```

## Form & Validation Issues

### Validation Errors Not Showing

**Problem:** Form submits with errors but errors don't display.

**Debugging Steps:**

1. **Check :error binding**
```markup
<!-- ❌ No error binding -->
<AwInput v-model="customer.name" label="Name" />

<!-- ✅ Bind error from model -->
<AwInput
    v-model="customer.name"
    :error="customer.errors.name"
    label="Name"
/>
```

2. **Check if errors exist**
```javascript
async save() {
    await this.customer.save()

    // ✅ Check for errors
    if (Object.keys(this.customer.errors).length > 0) {
        console.log('Errors:', this.customer.errors)
        return
    }
}
```

3. **Check backend response format**
```json
// Expected format for 422 validation errors
{
    "message": "The given data was invalid.",
    "errors": {
        "name": ["The name field is required."],
        "email": ["The email has already been taken."]
    }
}
```

### Form Not Submitting

**Problem:** Clicking submit button does nothing.

**Debugging Steps:**

1. **Check button type**
```markup
<!-- ❌ Missing @click -->
<AwButton color="accent">Save</AwButton>

<!-- ✅ With click handler -->
<AwButton color="accent" @click="save">Save</AwButton>
```

2. **Check for errors in method**
```javascript
async save() {
    console.log('Save called')  // Add debug log

    try {
        await this.customer.save()
        console.log('Save successful')
    } catch (error) {
        console.error('Save failed:', error)
    }
}
```

3. **Check button not disabled**
```markup
<!-- May be disabled during loading -->
<AwButton
    :disabled="saving"
    :loading="saving"
    @click="save"
>
    Save
</AwButton>
```

### Model Save Succeeds but Errors Remain

**Problem:** save() succeeds but model.errors still has errors.

**Cause:** Validation errors return 422, which vue-mc treats as "success" with errors:
```javascript
// ✅ Always check errors after save
await this.customer.save()

if (Object.keys(this.customer.errors).length > 0) {
    // Has validation errors even though save() didn't throw
    this.$notify({
        message: 'Please fix validation errors',
        type: 'error'
    })
    return
}

// Actually saved successfully
```

## Table Issues

### Rows Not Reactive When Using vue-mc Models

**Problem:** Table rows (for example in `AwTableBuilder`) update only for the first row or only after calling `$forceUpdate` when using `@awes-io/vue-mc` models.

**Cause:** The project uses different Vue versions for `@awes-io/ui` and `@awes-io/vue-mc`, so models are created in one Vue instance and rendered in another, breaking reactivity.

**Solution:** Ensure the project has a single Vue version by configuring root `resolutions`:

```json
// package.json (root of monorepo)
"resolutions": {
    "vue": "2.7.16",
    "vue-template-compiler": "2.7.16",
    "vue-server-renderer": "2.7.16"
}
```

Remove any Vue-specific `overrides` / `resolutions` from package-level configs (for example `packages/vue-mc/package.json`), reinstall dependencies, and verify a single Vue version with `yarn why vue`.

### @click:row and #dropdown Conflict

**Problem:** Row click doesn't work when dropdown is present.

**Cause:** Cannot use both @click:row and #dropdown slot simultaneously:
```markup
<!-- ❌ BAD - Both click:row and dropdown -->
<AwTableBuilder
    :collection="customers"
    @click:row="viewCustomer"
>
    <template #dropdown="{ cell }">
        <AwDropdownButton>
            <!-- This prevents row click -->
        </AwDropdownButton>
    </template>
</AwTableBuilder>
```

**Solution:** Use ONLY #dropdown slot:
```markup
<!-- ✅ GOOD - Dropdown only -->
<AwTableBuilder :collection="customers">
    <AwTableCol field="name" title="Name" />

    <template #dropdown="{ cell }">
        <AwDropdownButton>
            <AwButton @click="viewCustomer(cell)">View</AwButton>
            <AwButton @click="editCustomer(cell)">Edit</AwButton>
            <AwButton @click="deleteCustomer(cell)">Delete</AwButton>
        </AwDropdownButton>
    </template>
</AwTableBuilder>
```

### Table Column Shows [object Object]

**Problem:** Table cell displays "[object Object]" instead of value.

**Cause:** Field prop behavior - with field prop, cell = value only; without field, cell = entire row:
```markup
<!-- ❌ BAD - Trying to access object property with field prop -->
<AwTableCol field="address" title="Address">
    <template #default="{ cell }">
        {{ cell.city }}  <!-- cell is just address object, not whole row -->
    </template>
</AwTableCol>
```

**Solution 1:** Don't use field prop:
```markup
<!-- ✅ GOOD - No field prop, cell = entire row -->
<AwTableCol title="Address">
    <template #default="{ cell }">
        {{ cell.address.city }}
    </template>
</AwTableCol>
```

**Solution 2:** Use field prop correctly:
```markup
<!-- ✅ GOOD - Format the field value directly -->
<AwTableCol field="address" title="Address">
    <template #default="{ cell }">
        {{ cell.city }}, {{ cell.state }}
    </template>
</AwTableCol>
```

### Table Pagination Not Working

**Problem:** Pagination controls don't appear or don't work.

**Debugging Steps:**

1. **Check backend returns pagination meta**
```json
{
    "data": [...],
    "meta": {
        "current_page": 1,
        "last_page": 10,
        "per_page": 15,
        "total": 145
    }
}
```

2. **Check collection route accepts page param**
```javascript
// Backend should handle ?page=2
GET /api/customers?page=2
```

3. **Check AwTableBuilder has pagination prop (if needed)**
```markup
<!-- Usually automatic, but can disable -->
<AwTableBuilder
    :collection="customers"
    :pagination="true"
/>
```

## Styling Issues

### Styles Not Applying

**Problem:** Custom styles don't apply to component.

**Common Causes:**

1. **CSS specificity**
```scss
// ❌ Not specific enough
.aw-button {
    background: red;
}

// ✅ More specific or use !important
.custom-btn.aw-button {
    background: red !important;
}
```

2. **Scoped styles**
```markup
<!-- ❌ Scoped styles don't affect child components -->
<style scoped>
.aw-button {
    background: red;  // Won't work
}
</style>

<!-- ✅ Use deep selector -->
<style scoped>
::v-deep .aw-button {
    background: red;
}
</style>

<!-- ✅ Or remove scoped -->
<style>
.custom-page .aw-button {
    background: red;
}
</style>
```

3. **Loading state preventing styles**
```scss
// ❌ Applies even during loading
.custom-btn {
    background-color: var(--c-accent) !important;
}

// ✅ Exclude loading state
.custom-btn:not([disabled]):not(.loading) {
    background-color: var(--c-accent) !important;
}
```

### Dark Theme Not Working

**Problem:** Dark theme colors don't apply.

**Debugging Steps:**

1. **Check theme plugin loaded**
```javascript
// In nuxt.config.js, @awes-io/ui module should be registered
modules: [
    '@awes-io/ui'
]
```

2. **Use CSS custom properties**
```scss
// ✅ Use theme variables
.custom-element {
    background: var(--c-background);
    color: var(--c-text);
}

// ❌ Hard-coded colors
.custom-element {
    background: #fff;
    color: #000;
}
```

3. **Check dark class on html**
```javascript
// Should add .dark class to <html> when dark theme active
document.documentElement.classList.contains('dark')
```

## Date & Time Issues

### Dates Not Formatting Correctly

**Problem:** Dates show as raw strings or errors.

**Solution:** Use $dayjs, not native Date:
```markup
<!-- ❌ BAD - Raw date string -->
{{ customer.created_at }}

<!-- ❌ BAD - Native Date -->
{{ new Date(customer.created_at).toLocaleDateString() }}

<!-- ✅ GOOD - Use $dayjs -->
{{ $dayjs(customer.created_at).format('ll') }}
```

**Remember template vs method usage:**
```markup
<template>
    <!-- ✅ Without this in templates -->
    {{ $dayjs(date).format('ll') }}
</template>

<script>
export default {
    methods: {
        formatDate(date) {
            // ✅ With this in methods
            return this.$dayjs(date).format('ll')
        }
    }
}
</script>
```

### Dates in Wrong Timezone

**Problem:** Dates show in wrong timezone.

**Solution:** Configure Day.js timezone plugin:
```javascript
// In plugin or component
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'

dayjs.extend(utc)
dayjs.extend(timezone)

// Set timezone
dayjs.tz.setDefault('America/New_York')

// Use in templates
this.$dayjs(date).tz('America/New_York').format('ll')
```

## Router Issues

### Navigation Not Working

**Problem:** Clicking link/button doesn't navigate.

**Debugging Steps:**

1. **Check href vs @click**
```markup
<!-- ✅ For navigation, use href -->
<AwButton :href="`/customers/${customer.id}`">
    View
</AwButton>

<!-- ✅ Or use @click with router.push -->
<AwButton @click="$router.push(`/customers/${customer.id}`)">
    View
</AwButton>

<!-- ❌ Missing navigation -->
<AwButton>View</AwButton>
```

2. **Check route exists**
```javascript
// Verify route exists in pages/ directory
pages/
  shops/
    _shop_uuid/
      customers/
        _id.vue  // Must exist
```

3. **Check route params**
```javascript
// ✅ Include all required params
this.$router.push({
    name: 'shops-shop_uuid-customers-id',
    params: {
        shop_uuid: this.$route.params.shop_uuid,
        id: customer.id
    }
})
```

### pushBack Not Going Anywhere

**Problem:** router.pushBack() doesn't navigate.

**Cause:** Back route not set with setBack:
```javascript
// ❌ pushBack without setBack
this.$router.pushBack()  // Does nothing
```

**Solution:** Set back route first:
```javascript
// ✅ On list page
mounted() {
    this.$router.setBack(`/shops/${this.$route.params.shop_uuid}/customers`)
}

// ✅ On detail page
methods: {
    cancel() {
        // Goes to route set by setBack
        this.$router.pushBack()
    }
}
```

## Performance Issues

### Page Slow to Load

**Problem:** Page takes long time to render.

**Common Causes:**

1. **Loading too much data**
```javascript
// ❌ Fetching all records
customers: new Customers([])  // Could be thousands

// ✅ Use pagination
customers: new Customers([], {
    shop_uuid: this.$route.params.shop_uuid,
    per_page: 25
})
```

2. **Too many watchers**
```javascript
// ❌ Deep watchers on large objects
watch: {
    customers: {
        handler() { ... },
        deep: true  // Expensive
    }
}

// ✅ Watch specific properties
watch: {
    'customers.models.length': {
        handler() { ... }
    }
}
```

3. **Inefficient computed properties**
```javascript
// ❌ Filters array every time
computed: {
    activeCustomers() {
        return this.customers.models.filter(c => c.active)  // Runs on every change
    }
}

// ✅ Cache or use backend filtering
customers: new Customers([], {
    shop_uuid: this.$route.params.shop_uuid,
    status: 'active'  // Filter on backend
})
```

### Table Slow to Render

**Problem:** AwTableBuilder slow with many rows.

**Solutions:**

1. **Reduce per_page**
```javascript
customers: new Customers([], {
    shop_uuid: this.$route.params.shop_uuid,
    per_page: 15  // Fewer rows per page
})
```

2. **Simplify cell templates**
```markup
<!-- ❌ Complex calculations in cell -->
<AwTableCol field="total" title="Total">
    <template #default="{ cell, row }">
        {{ complexCalculation(row) }}
    </template>
</AwTableCol>

<!-- ✅ Calculate on backend or cache -->
<AwTableCol field="total_formatted" title="Total" />
```

3. **Use field prop when possible**
```markup
<!-- ✅ Fast - direct field access -->
<AwTableCol field="name" title="Name" />

<!-- ❌ Slower - custom template -->
<AwTableCol title="Name">
    <template #default="{ cell }">
        {{ cell.name }}
    </template>
</AwTableCol>
```

## Authentication Issues

### User Not Redirected to Login

**Problem:** Accessing protected page doesn't redirect to login.

**Debugging Steps:**

1. **Check middleware**
```javascript
// ✅ Page has auth middleware
export default {
    middleware: 'auth'
}
```

2. **Check nuxt-auth config**
```javascript
// In nuxt.config.js
auth: {
    strategies: {
        laravelJWT: {
            // ...
            redirect: {
                login: '/login',
                logout: '/login',
                home: '/dashboard'
            }
        }
    }
}
```

3. **Check token**
```javascript
// In browser console
console.log(this.$auth.loggedIn)
console.log(this.$auth.token)
```

### API Requests Return 401

**Problem:** API requests fail with 401 Unauthorized.

**Debugging Steps:**

1. **Check token in request headers**
```javascript
// Open DevTools → Network → Select request → Headers
// Should have: Authorization: Bearer <token>
```

2. **Check token expiration**
```javascript
// In browser console
const payload = JSON.parse(atob(this.$auth.token.split('.')[1]))
console.log('Expires:', new Date(payload.exp * 1000))
```

3. **Check nuxt-auth strategy config**
```javascript
auth: {
    strategies: {
        laravelJWT: {
            url: process.env.LARAVEL_URL,
            endpoints: {
                login: { url: '/api/auth/login', method: 'post' },
                refresh: { url: '/api/auth/refresh', method: 'post' },
                user: { url: '/api/auth/me', method: 'get' }
            }
        }
    }
}
```

## Getting Help

If you can't find a solution here:

1. **Check component documentation**
   - [Component Index](../index.md)
   - Individual component docs in [components/](../components/)

2. **Check integration guides**
   - [Integration Guide](../integrations.md)
   - [Best Practices](../guides/best-practices.md)

3. **Enable debug mode**
```javascript
// In nuxt.config.js
export default {
    build: {
        extend(config, { isDev }) {
            if (isDev) {
                config.devtool = 'source-map'
            }
        }
    }
}
```

4. **Check browser console**
   - Look for errors or warnings
   - Check network requests (DevTools → Network)
   - Inspect Vue component tree (Vue DevTools)

5. **Minimal reproduction**
   - Create minimal example that reproduces issue
   - Isolate component causing problem
   - Test with default props

## See Also

- [Error Handling Guide](../guides/error-handling.md) - Handling errors properly
- [Data Fetching Guide](../guides/data-fetching.md) - Collection and model patterns
- [Best Practices Guide](../guides/best-practices.md) - Avoiding common issues
- [Plugins Reference](./plugins.md) - Using framework utilities
