import type { Meta, StoryObj } from '@storybook/react' import { Home, Users, Settings, Key, Webhook, BarChart, Package, FileText } from 'lucide-react' import { App } from '../components/app' import { AppShell } from '../components/app-shell' import { NavMain } from '../components/nav-main' import { NavUser } from '../components/nav-user' import { AppBreadcrumbs } from '../components/app-breadcrumbs' import type { DataProvider, AuthProvider as AuthProviderInterface, NavItem, ResourceDefinition, GetOneParams, CreateParams, UpdateParams, DeleteParams, } from '../types' // ============================================================================= // Mock Data Provider // ============================================================================= const mockDataProvider: DataProvider = { getList: async (resource: string) => { // Return mock data for demo purposes if (resource === 'users') { return { data: [ { id: '1', name: 'John Doe', email: 'john@example.com' }, { id: '2', name: 'Jane Smith', email: 'jane@example.com' }, ] as T[], total: 2, } } return { data: [] as T[], total: 0 } }, getOne: async (_resource: string, params: GetOneParams) => { return { data: { id: params.id, name: 'Mock Record' } as T } }, getMany: async () => { return { data: [] as T[] } }, create: async (_resource: string, params: CreateParams) => { return { data: { id: 'new-id', ...params.data } as T } }, update: async (_resource: string, params: UpdateParams) => { return { data: { id: params.id, ...params.data } as T } }, delete: async (_resource: string, params: DeleteParams) => { return { data: { id: params.id } as T } }, } // ============================================================================= // Mock Auth Provider // ============================================================================= const mockAuthProvider: AuthProviderInterface = { login: async () => {}, logout: async () => {}, checkAuth: async () => {}, checkError: async () => {}, getIdentity: async () => ({ id: '1', fullName: 'John Doe', email: 'john@example.com', avatar: 'https://github.com/shadcn.png', }), getPermissions: async () => ['admin'], } // ============================================================================= // Mock Navigation Items // ============================================================================= const navItems: NavItem[] = [ { title: 'Dashboard', url: '/admin', icon: Home }, { title: 'Users', url: '/admin/users', icon: Users }, { title: 'API Keys', url: '/admin/api-keys', icon: Key }, { title: 'Webhooks', url: '/admin/webhooks', icon: Webhook, items: [ { title: 'Endpoints', url: '/admin/webhooks/endpoints' }, { title: 'Logs', url: '/admin/webhooks/logs' }, ], }, { title: 'Analytics', url: '/admin/analytics', icon: BarChart }, { title: 'Settings', url: '/admin/settings', icon: Settings }, ] // ============================================================================= // Mock Resources // ============================================================================= const UsersListMock = () => (

Users List

Mock users list component

) const ProductsListMock = () => (

Products List

Mock products list component

) const mockResources: ResourceDefinition[] = [ { name: 'users', label: 'User', labelPlural: 'Users', icon: Users, list: UsersListMock, }, { name: 'products', label: 'Product', labelPlural: 'Products', icon: Package, list: ProductsListMock, }, ] // ============================================================================= // Story Meta // ============================================================================= const meta: Meta = { title: 'App/App', component: App, tags: ['autodocs'], parameters: { layout: 'fullscreen', }, } export default meta type Story = StoryObj // ============================================================================= // Stories // ============================================================================= /** * The App component is the root provider that sets up all necessary contexts. * It wraps the application with Theme, Navigation, Data, Auth, and Resource providers. */ export const Default: Story = { args: { config: { name: 'Admin', description: 'Dashboard', basePath: '/admin', }, dataProvider: mockDataProvider, authProvider: mockAuthProvider, }, render: (args) => ( } footer={} pageHeader={} >

Dashboard

Welcome to the admin dashboard.

), } /** * App with resources defined. Resources are automatically converted to navigation items. */ export const WithResources: Story = { args: { config: { name: 'Admin', description: 'Resource Management', basePath: '/admin', }, dataProvider: mockDataProvider, authProvider: mockAuthProvider, resources: mockResources, }, render: (args) => ( } footer={} pageHeader={ } >

Users

Resources defined: {args.resources?.map((r) => r.name).join(', ')}

), } /** * App with custom logo in the configuration. */ export const WithCustomLogo: Story = { args: { config: { name: 'My App', description: 'Custom Branding', basePath: '/app', logo: (
), }, dataProvider: mockDataProvider, authProvider: mockAuthProvider, }, render: (args) => ( } footer={} pageHeader={} >

My App Dashboard

App with custom logo and branding.

), } /** * Minimal App setup without shell - shows just the provider composition. */ export const MinimalSetup: Story = { args: { config: { name: 'Minimal', basePath: '/', }, dataProvider: mockDataProvider, authProvider: mockAuthProvider, }, render: (args) => (

Minimal App Setup

App provides context - you build the UI.

Config: {args.config.name} at {args.config.basePath}

), }