Core Components
- UserTable - HiTable-powered data grid
- User Forms - Add/edit with validation
- Mock Data - Development data simulation
- Navigation - React Router v7 integration
Complete user management solution with CRUD operations, HiTable integration, role-based access control, and advanced filtering capabilities.
HiTable Integration User Types Mock DataModular user management system built with HiTable and TypeScript interfaces:
Core Components
Key Features
The main user management page integrates async data loading with HiTable components:
Key Features:
useNavigate
hook// User List Page Implementationimport { useEffect, useState } from 'react'import { useNavigate } from 'react-router-dom'import { Button } from '@/components/ui/button'import { Card, CardContent } from '@/components/ui/card'import { UserPlus, RefreshCw } from 'lucide-react'import { UserTable } from './components/UserTable'import { loadUserData, type UserProfile } from './mockData'
export default function UserListPage() {const navigate = useNavigate()const [users, setUsers] = useState<UserProfile[]>([])const [loading, setLoading] = useState(false)
// Async data loading with error handlingconst loadUsers = async () => { setLoading(true) try { const data = await loadUserData() setUsers(data) } finally { setLoading(false) }}
// Custom toolbar with refresh buttonconst customToolbarActions = () => ( <Button onClick={loadUsers} variant="outline" size="sm" disabled={loading} > <RefreshCw className={`me-2 h-4 w-4 ${loading ? 'animate-spin' : ''}`} /> Refresh </Button>)
// Custom empty state with CTAconst customEmptyState = () => ( <div className="text-center py-12"> <UserIcon className="mx-auto h-12 w-12 text-gray-400" /> <h3 className="mt-4 text-sm font-medium">No users found</h3> <p className="mt-1 text-sm text-gray-500"> Get started by adding a new user to the system. </p> <Button className="mt-6" onClick={() => navigate('/management/users/add')}> <UserPlus className="me-2 h-4 w-4" /> Add User </Button> </div>)
return ( <div className="space-y-6"> {/* Page header with user count */} <div className="flex items-center justify-between"> <div> <h1 className="text-2xl font-semibold">Users</h1> <p className="text-sm text-gray-500">{users.length} users total</p> </div> <Button onClick={() => navigate('/management/users/add')}> <UserPlus className="me-2 h-4 w-4" /> Add User </Button> </div>
{/* User table wrapped in card */} <Card> <CardContent> <UserTable data={users} loading={loading} toolbarActions={customToolbarActions} emptyState={customEmptyState} /> </CardContent> </Card> </div>)}
The UserTable leverages the HiTable component for advanced data management:
Core Features:
// UserTable with HiTable Integrationimport { HiTable } from '@/components/HiTable/HiTable'import type { TableConfig } from '@/components/HiTable/types'import { HiExport } from '@/components/HiExport/HiExport'
interface UserTableProps {data: User[] // Accepts User[] but receives UserProfile[] (compatible types)loading?: booleantoolbarActions?: (table: any) => React.ReactNodeemptyState?: () => React.ReactNode}
export function UserTable({ data, loading, toolbarActions, emptyState }) {// Table configurationconst tableConfig: TableConfig = { pagination: { enabled: true, pageSize: 10, showPageInfo: true }, sorting: { enabled: true, multiSort: false }, columnVisibility: { enabled: true, buttonText: 'Columns' }, rowSelection: { enabled: true, enableSelectAll: true }, styling: { compact: false }}
// Column definitions with avatarsconst columns = useMemo(() => [ { id: 'select', header: ({ table }) => ( <Checkbox checked={table.getIsAllPageRowsSelected()} onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)} /> ), cell: ({ row }) => ( <Checkbox checked={row.getIsSelected()} onCheckedChange={(value) => row.toggleSelected(!!value)} /> ) }, { accessorKey: 'name', header: 'Name', cell: ({ row }) => { const user = row.original return ( <div className="flex items-center space-x-3"> <Avatar className="h-8 w-8"> <AvatarImage src={user.avatar} alt={user.name} /> <AvatarFallback> {user.name.split(' ').map(n => n[0]).join('').toUpperCase()} </AvatarFallback> </Avatar> <div> <p className="font-medium truncate">{user.name}</p> <p className="text-sm text-gray-500 truncate">{user.email}</p> </div> </div> ) } }, { accessorKey: 'role', header: 'Role', cell: ({ row }) => <RoleBadge role={row.getValue('role')} /> }, { accessorKey: 'status', header: 'Status', cell: ({ row }) => <StatusBadge status={row.getValue('status')} /> }, { id: 'actions', header: 'Actions', cell: ({ row }) => <ActionsDropdown user={row.original} /> }], [])
return ( <HiTable data={data} columns={columns} config={tableConfig} loading={loading} toolbarActions={toolbarActions} emptyState={emptyState} />)}
The add user page demonstrates form handling with loading states and navigation:
Key Features:
useNavigate
// Add User Page with Animation and Loading Statesimport { useState } from 'react'import { useNavigate } from 'react-router-dom'import { motion } from 'framer-motion'import { toast } from 'sonner'import { ConfirmDialog } from '@/components/ui/confirm-dialog'import HiLoading from '@/components/HiLoading'import UserForm from './components/UserForm'
export default function AddUser() {const navigate = useNavigate()const [isLoading, setIsLoading] = useState(false)const [showCancelDialog, setShowCancelDialog] = useState(false)
const handleSubmit = async (formData: UserFormData) => { setIsLoading(true) try { // Simulate API call with delay await new Promise(resolve => setTimeout(resolve, 2000))
console.log('Creating new user:', formData)
// Success notification toast.success('User created successfully!', { description: `${formData.name} has been added to the system.` })
// Navigate back to user list navigate('/management/users/list') } catch (error) { console.error('Failed to create user:', error) toast.error('Failed to create user') } finally { setIsLoading(false) }}
return ( <motion.div className="space-y-6" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, ease: 'easeOut' }} > {/* Animated header */} <motion.div className="flex items-center justify-between" initial={{ opacity: 0, x: -20 }} animate={{ opacity: 1, x: 0 }} transition={{ duration: 0.5, delay: 0.1 }} > <div className="flex items-center space-x-4"> <Button onClick={() => navigate(-1)} variant="ghost" size="sm"> <ArrowLeft className="h-4 w-4" /> </Button> <div> <h1 className="text-2xl font-semibold flex items-center"> <UserPlus className="h-6 w-6 me-3 text-blue-600" /> Add New User </h1> <p className="text-sm text-gray-500"> Create a new user account with profile information </p> </div> </div> </motion.div>
{/* User form with animation */} <motion.div initial={{ opacity: 0, y: 30 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: 0.2 }} > <UserForm onSubmit={handleSubmit} onCancel={() => setShowCancelDialog(true)} isLoading={isLoading} /> </motion.div>
{/* Loading overlay */} <HiLoading loading={isLoading} text="Creating user..." overlay />
{/* Cancel confirmation dialog */} <ConfirmDialog open={showCancelDialog} onOpenChange={setShowCancelDialog} title="Discard new user?" description="All entered information will be lost." confirmText="Discard user" variant="destructive" onConfirm={() => navigate(-1)} /> </motion.div>)}
Data Structure Setup Define UserProfile TypeScript interface and mock data generation
HiTable Integration Configure HiTable with column definitions, pagination, and row selection
Form Implementation Create add/edit forms with React Hook Form validation and loading states
Navigation Setup Implement React Router v7 navigation between list, add, and edit pages
UI Components Add status badges, action dropdowns, and responsive design patterns
Export Features Configure HiExport component with custom column definitions
Data export functionality with custom column configuration:
// Export configuration for user dataconst exportColumns: ExportColumn[] = [{ key: 'name', header: 'Name', accessor: (row: UserProfile) => row.name },{ key: 'email', header: 'Email', accessor: (row: UserProfile) => row.email },{ key: 'phone', header: 'Phone', accessor: (row: UserProfile) => row.phone },{ key: 'role', header: 'Role', accessor: (row: UserProfile) => row.role },{ key: 'status', header: 'Status', accessor: (row: UserProfile) => row.status },{ key: 'lastLogin', header: 'Last Login', accessor: (row: UserProfile) => formatDate(row.lastLogin) },{ key: 'createdAt', header: 'Created At', accessor: (row: UserProfile) => formatDate(row.createdAt) }]
// HiExport component usage<HiExporttable={table}originalData={data}columns={exportColumns}filename="users"buttonText="Export Users"buttonVariant="outline"buttonSize="sm"config={{ includeHeaders: true, dateFormat: 'YYYY-MM-DD HH:mm:ss'}}/>
User type definitions and data generation for development:
// User TypeScript interfacesexport interface User {id: stringname: stringemail: stringphone: stringavatar: stringrole: 'admin' | 'user' | 'moderator' | 'guest'status: 'active' | 'inactive' | 'banned' | 'pending'lastLogin: stringcreatedAt: string}
export interface UserProfile extends User {department: stringlocation: stringtimezone: stringbio: stringskills: string[]projects: numbertasksCompleted: numberteamSize: number}
// Mock data generationexport const loadUserData = (): Promise<UserProfile[]> =>new Promise((resolve) => { setTimeout(() => { resolve(mockUsers) }, 1000)})
const mockUsers: UserProfile[] = [{ id: 'u1', name: 'John Doe', phone: '+1 (555) 123-4567', avatar: 'https://vertaui.com/avatar/cartoon/3.png?id=1', role: 'admin', status: 'active', lastLogin: '2024-01-15T10:30:00Z', createdAt: '2023-06-15T08:00:00Z', department: 'Engineering', location: 'San Francisco, CA', timezone: 'UTC-08:00', bio: 'Senior Software Engineer with 8+ years of experience.', skills: ['JavaScript', 'TypeScript', 'React', 'Node.js'], projects: 12, tasksCompleted: 145, teamSize: 8}// Additional mock users...]
The user management system demonstrates modern React patterns with enterprise-grade components, providing a solid foundation for user administration features.