import type { ComponentType, ReactNode } from 'react' import type { LucideIcon } from 'lucide-react' // ============================================================================= // Core Types (self-contained, no external deps) // ============================================================================= /** * Identifier - The type for record IDs * * Can be string or number. Most APIs return string IDs, but numeric IDs are * also common in relational databases. */ export type Identifier = string | number /** * RaRecord - Base type for all data records * * Every record must have an `id` field. Additional fields are dynamic. */ export type RaRecord = { id: IdentifierType [key: string]: unknown } // ============================================================================= // User & Auth Types // ============================================================================= /** * User identity returned by auth providers */ export interface UserIdentity { id: string fullName?: string email?: string avatar?: string [key: string]: unknown } /** * Auth provider interface for authentication operations */ export interface AuthProvider { login: (params: LoginParams) => Promise logout: () => Promise checkAuth: () => Promise checkError: (error: Error) => Promise getIdentity: () => Promise getPermissions: () => Promise } export interface LoginParams { username?: string password?: string [key: string]: unknown } // ============================================================================= // Navigation Types // ============================================================================= /** * Navigation item for sidebar menus */ export interface NavItem { title: string url: string icon?: LucideIcon isActive?: boolean items?: NavItem[] } /** * Navigation group containing items */ export interface NavGroup { label: string items: NavItem[] } /** * Breadcrumb item data */ export interface BreadcrumbItemData { label: string href?: string } /** * User menu action item */ export interface UserMenuAction { label: string icon?: LucideIcon onClick?: () => void href?: string } /** * Props for custom link components (router integration) */ export interface LinkProps { href: string children: ReactNode className?: string } /** * Navigation provider interface for router integration */ export interface NavigationProvider { navigate: (to: string, options?: NavigateOptions) => void getCurrentPath: () => string LinkComponent: ComponentType } export interface NavigateOptions { replace?: boolean state?: unknown } // ============================================================================= // DataProvider Types (simplified, self-contained) // ============================================================================= /** * DataProvider interface for basic CRUD operations. * * This is a **simplified 6-method interface** designed for basic apps that just * need CRUD operations without the complexity of a full admin framework. * * ## Design Philosophy * * - **Optional params**: `getList` accepts optional pagination/sort/filter to allow * simpler usage without requiring all parameters * - **Minimal surface area**: Only the 6 core CRUD methods, no bulk operations * - **Generic types**: Uses `` for flexibility, not constrained to RaRecord * * ## Relationship to mdxui/admin DataProvider * * `mdxui/admin` exports a **more comprehensive DataProvider** interface designed * for full admin frameworks (React Admin patterns): * * | Aspect | @mdxui/app | mdxui/admin | * |--------|------------|-------------| * | Methods | 6 (CRUD only) | 9 (+getManyReference, updateMany, deleteMany) | * | getList params | Optional | Required | * | Meta support | No | Yes (QueryMeta, MutationMeta) | * | Type constraints | `` | `` | * | Custom methods | No | Yes (`[key: string]: unknown`) | * * **When to use which:** * - Use `@mdxui/app` DataProvider for simple apps, dashboards, or when implementing * custom data providers that don't need admin framework features * - Use `mdxui/admin` DataProvider when building full admin interfaces with bulk * operations, reference queries, and React Admin-style patterns * * **Type compatibility:** * An `@mdxui/app` DataProvider is NOT directly assignable to `mdxui/admin` DataProvider * because it lacks required methods and has optional params where admin requires required ones. * If you need both, implement the admin interface (superset) and it will satisfy both. * * @example * ```tsx * const myDataProvider: DataProvider = { * getList: async (resource, params) => { * const response = await fetch(`/api/${resource}?page=${params?.pagination?.page}`) * const data = await response.json() * return { data: data.items, total: data.total } * }, * getOne: async (resource, params) => { * const response = await fetch(`/api/${resource}/${params.id}`) * return { data: await response.json() } * }, * // ... other methods * } * ``` * * @see {@link https://mdxui.dev/docs/data-provider} for detailed documentation */ export interface DataProvider { getList: (resource: string, params?: GetListParams) => Promise> getOne: (resource: string, params: GetOneParams) => Promise> getMany: (resource: string, params: GetManyParams) => Promise> create: (resource: string, params: CreateParams) => Promise> update: (resource: string, params: UpdateParams) => Promise> delete: (resource: string, params: DeleteParams) => Promise> } /** * GetListParams with optional fields for simpler app usage. */ export interface GetListParams { pagination?: { page: number; perPage: number } sort?: { field: string; order: 'ASC' | 'DESC' } filter?: Record } /** * GetListResult */ export interface GetListResult { data: T[] total?: number pageInfo?: { hasNextPage?: boolean hasPreviousPage?: boolean } } /** * GetOneParams */ export interface GetOneParams { id: Identifier } /** * GetOneResult */ export interface GetOneResult { data: T } /** * GetManyParams */ export interface GetManyParams { ids: Identifier[] } /** * GetManyResult */ export interface GetManyResult { data: T[] } /** * CreateParams */ export interface CreateParams { data: Partial } /** * CreateResult */ export interface CreateResult { data: T } /** * UpdateParams */ export interface UpdateParams { id: Identifier data: Partial previousData?: T } /** * UpdateResult */ export interface UpdateResult { data: T } /** * DeleteParams */ export interface DeleteParams { id: Identifier previousData?: unknown } /** * DeleteResult */ export interface DeleteResult { data: T } // ============================================================================= // App Configuration Types // ============================================================================= /** * App configuration for the shell */ export interface AppConfig { /** App name displayed in sidebar header */ name: string /** App description/tagline */ description?: string /** App logo component or element */ logo?: ReactNode /** Base path for the app (e.g., '/admin') */ basePath?: string } /** * Theme configuration */ export type Theme = 'light' | 'dark' | 'system' export interface ThemeProvider { theme: Theme setTheme: (theme: Theme) => void } // ============================================================================= // Resource Types // ============================================================================= /** * ResourceDefinition describes a CRUD resource that can be managed by the app. * * Resources are the core building blocks of admin applications. Each resource * represents an entity that can be listed, created, edited, and deleted. * * @example * ```tsx * const usersResource: ResourceDefinition = { * name: 'users', * label: 'Users', * labelPlural: 'Users', * icon: Users, * list: UsersList, * show: UserShow, * create: UserCreate, * edit: UserEdit, * } * ``` */ export interface ResourceDefinition { /** Resource identifier used in URLs and data provider calls */ name: string /** Human-readable singular label */ label?: string /** Human-readable plural label */ labelPlural?: string /** Icon component for navigation */ icon?: LucideIcon /** Component to render the list view */ list?: ComponentType /** Component to render the show/detail view */ show?: ComponentType<{ id: Identifier }> /** Component to render the create view */ create?: ComponentType /** Component to render the edit view */ edit?: ComponentType<{ id: Identifier }> /** Custom options for this resource */ options?: Record } /** * ResourceContext provides information about the current resource being viewed */ export interface ResourceContextValue { /** Resource name */ resource: string /** Resource definition */ definition?: ResourceDefinition /** Current record ID (if viewing/editing) */ id?: Identifier /** Whether to show the list view */ hasList: boolean /** Whether to show the create view */ hasCreate: boolean /** Whether to show the edit view */ hasEdit: boolean /** Whether to show the show view */ hasShow: boolean }