# CLAUDE.md - Vuexy Theme Reference
This is the **Vuexy Vue 3 + Laravel Admin Dashboard Template** (TypeScript edition). It serves as the UI reference for the EZSCALE billing application at `../website/`. Do NOT modify files in this directory — use it as a read-only reference for components, patterns, layouts, and styling conventions.
## Purpose
When building UI for the EZSCALE site (`../website/`), consult this theme for:
- Component patterns and TypeScript conventions
- Vuetify component usage and defaults
- Layout structure (vertical nav, navbar, footer)
- Dashboard widget composition
- Data table patterns with server-side pagination
- Form validation patterns
- Navigation item structure
- Color system and theming
- Icon usage (Tabler icons)
## Tech Stack
- **Vue 3.5** with Composition API (`
```
### Stat Card (Horizontal)
```vue
```
### Stat Card (Vertical with Chart)
```vue
```
### Dashboard Page Layout
```vue
```
### Data Table (Server-Side Pagination)
```vue
{{ item.status }}
```
### Form with Validation
```vue
Submit
```
### Status Resolver Pattern
```typescript
const resolveStatusVariant = (status: string): { color: string; icon: string } => {
const map: Record = {
active: { color: 'success', icon: 'tabler-check' },
pending: { color: 'warning', icon: 'tabler-clock' },
suspended: { color: 'error', icon: 'tabler-ban' },
canceled: { color: 'secondary', icon: 'tabler-x' },
}
return map[status] ?? { color: 'secondary', icon: 'tabler-circle' }
}
```
## Navigation Item Types
```typescript
// Single clickable link
interface NavLink {
title: string
to?: string | RouteLocationRaw // Route name or object
href?: string // External URL
icon?: { icon: string } // Tabler icon
badgeContent?: string // Badge text
badgeClass?: string // Badge CSS class (e.g., 'bg-error')
target?: '_blank' | '_self'
action?: string // CASL action
subject?: string // CASL subject
disable?: boolean
}
// Collapsible group with children
interface NavGroup {
title: string
icon?: { icon: string }
children: (NavLink | NavGroup)[]
badgeContent?: string
badgeClass?: string
action?: string
subject?: string
disable?: boolean
}
// Section heading/divider
interface NavSectionTitle {
heading: string
action?: string
subject?: string
}
```
### Navigation Example
```typescript
// navigation/vertical/dashboard.ts
export default [
{
title: 'Dashboards',
icon: { icon: 'tabler-smart-home' },
children: [
{ title: 'Analytics', to: 'dashboards-analytics' },
{ title: 'CRM', to: 'dashboards-crm' },
],
badgeContent: '2',
badgeClass: 'bg-error',
},
]
// navigation/vertical/apps.ts
export default [
{ heading: 'Apps & Pages' }, // Section title
{
title: 'Invoice',
icon: { icon: 'tabler-file-invoice' },
children: [
{ title: 'List', to: 'apps-invoice-list' },
{ title: 'Add', to: 'apps-invoice-add' },
],
},
{
title: 'Users',
icon: { icon: 'tabler-users' },
to: 'apps-users-list',
action: 'read', // CASL permission
subject: 'User',
},
]
```
## API Integration
### useApi Composable
```typescript
// Reactive fetch with Bearer token from cookie
const { data, execute: refetch } = await useApi(
createUrl('/endpoint', {
query: { q: searchQuery, page, itemsPerPage, status: selectedStatus },
})
)
// Non-reactive one-off request
const response = await $api('/endpoint', {
method: 'POST',
body: { key: 'value' },
onResponseError({ response }) {
errors.value = response._data.errors
},
})
// Delete with refetch
const deleteItem = async (id: number) => {
await $api(`/items/${id}`, { method: 'DELETE' })
refetch()
}
```
## Validators
Available at `@validators` (auto-imported):
| Validator | Usage |
|------------------------|-------------------------------------------|
| `requiredValidator` | Field is not empty |
| `emailValidator` | Valid email format |
| `passwordValidator` | Min 8 chars, upper, lower, digit, special |
| `confirmedValidator` | Matches another field value |
| `betweenValidator` | Number within min/max range |
| `urlValidator` | Valid URL format |
| `integerValidator` | Integer only |
| `regexValidator` | Matches regex pattern |
| `alphaValidator` | Alpha characters only |
| `lengthValidator` | Exact string length |
## Layout Selection
Pages use `definePage()` macro for meta configuration:
```vue
```
Default layout (with sidebar + navbar) is used when no layout is specified.
## Route Guards
Authentication flow (`plugins/1.router/guards.ts`):
1. **Public routes** (`meta.public: true`) — No auth check
2. **Unauthenticated-only** (`meta.unauthenticatedOnly: true`) — Redirect to `/` if logged in
3. **CASL permission check** — If `canNavigate(to)` fails:
- Logged in → redirect to `/not-authorized`
- Not logged in → redirect to `/login?to=`
## Auto-Imports (No Explicit Import Needed)
### From Vue
`ref`, `computed`, `watch`, `watchEffect`, `onMounted`, `onUnmounted`, `h`, `nextTick`, `defineProps`, `defineEmits`, `withDefaults`, `defineAsyncComponent`
### From Vue Router
`useRouter()`, `useRoute()`
### From VueUse
`useWindowSize()`, `useElementHover()`, `useMediaQuery()`, `useToggle()`, `useStorage()`, `usePreferredColorScheme()`, `useWindowScroll()`
### From Pinia
`defineStore()`, `storeToRefs()`
### From Vue-i18n
`useI18n()`
### From Theme
`useSkins()`, `useCookie()`, `createUrl()`, validators, helpers
## Icons
Uses **Tabler Icons** via Iconify. Common icons:
| Icon Name | Usage |
|--------------------------|--------------------|
| `tabler-smart-home` | Dashboard |
| `tabler-users` | Users/customers |
| `tabler-file-invoice` | Invoices |
| `tabler-shopping-cart` | Orders/commerce |
| `tabler-chart-bar` | Analytics/charts |
| `tabler-currency-dollar` | Revenue/billing |
| `tabler-server` | Servers/services |
| `tabler-shield-check` | Security |
| `tabler-settings` | Settings |
| `tabler-bell` | Notifications |
| `tabler-check` | Success/confirmed |
| `tabler-x` | Close/cancel |
| `tabler-pencil` | Edit |
| `tabler-trash` | Delete |
| `tabler-eye` | View/preview |
| `tabler-plus` | Add/create |
| `tabler-chevron-down` | Dropdown |
| `tabler-chevron-right` | Navigate |
| `tabler-menu-2` | Mobile menu toggle |
| `tabler-circle` | Default nav icon |
Usage: ``
## TypeScript Path Aliases
```
@/* → resources/ts/*
@themeConfig → themeConfig.ts
@layouts/* → resources/ts/@layouts/*
@core/* → resources/ts/@core/*
@images/* → resources/images/*
@styles/* → resources/styles/*
@validators → resources/ts/@core/utils/validators
```
## Key Files to Reference
| Need | Look at |
|-------------------------------|------------------------------------------------------|
| Dashboard layout | `pages/dashboards/analytics.vue` |
| Data table with filters | `pages/apps/invoice/list/index.vue` |
| Form with validation | `pages/apps/invoice/add/index.vue` |
| Auth page (login) | `pages/login.vue` |
| Stat cards | `@core/components/cards/CardStatistics*.vue` |
| Sidebar navigation | `layouts/components/DefaultLayoutWithVerticalNav.vue` |
| Nav item definitions | `navigation/vertical/dashboard.ts` |
| Theme colors | `plugins/vuetify/theme.ts` |
| Component defaults | `plugins/vuetify/defaults.ts` |
| API fetching | `composables/useApi.ts` |
| Form validators | `@core/utils/validators.ts` |
| Type definitions | `@core/types.ts`, `views/apps/invoice/types.ts` |
| Route guards | `plugins/1.router/guards.ts` |
| Theme config | `themeConfig.ts` |
| Blank layout (auth) | `layouts/blank.vue` |
| Main layout | `layouts/default.vue` |