Skip to content

User Management System

Complete user management solution with CRUD operations, HiTable integration, role-based access control, and advanced filtering capabilities.

HiTable Integration User Types Mock Data

Modular user management system built with HiTable and TypeScript interfaces:

Core Components

  • UserTable - HiTable-powered data grid
  • User Forms - Add/edit with validation
  • Mock Data - Development data simulation
  • Navigation - React Router v7 integration

Key Features

  • Async data loading with loading states
  • Custom toolbar actions and empty states
  • Responsive design patterns
  • TypeScript interface definitions

The main user management page integrates async data loading with HiTable components:

Key Features:

  • React Router v7 navigation with useNavigate hook
  • Async data loading with proper loading states
  • Custom toolbar actions with refresh functionality
  • Custom empty state with call-to-action
  • TypeScript interface for User data structures
User List Structure
// User List Page Implementation
import { 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 handling
const loadUsers = async () => {
setLoading(true)
try {
const data = await loadUserData()
setUsers(data)
} finally {
setLoading(false)
}
}
// Custom toolbar with refresh button
const 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 CTA
const 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:

  • TanStack Table integration through HiTable
  • Advanced filtering with search and dropdowns
  • Row selection with checkboxes
  • Export functionality with HiExport
  • Custom column definitions with avatars
  • Action dropdowns for each row
UserTable Structure
// UserTable with HiTable Integration
import { 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?: boolean
toolbarActions?: (table: any) => React.ReactNode
emptyState?: () => React.ReactNode
}
export function UserTable({ data, loading, toolbarActions, emptyState }) {
// Table configuration
const 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 avatars
const 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:

  • React Router v7 navigation with useNavigate
  • Framer Motion animations for smooth transitions
  • Sonner toast notifications for user feedback
  • Confirmation dialogs for destructive actions
  • HiLoading component for loading overlays
Add User Implementation
// Add User Page with Animation and Loading States
import { 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>
)
}
  1. Data Structure Setup Define UserProfile TypeScript interface and mock data generation

  2. HiTable Integration Configure HiTable with column definitions, pagination, and row selection

  3. Form Implementation Create add/edit forms with React Hook Form validation and loading states

  4. Navigation Setup Implement React Router v7 navigation between list, add, and edit pages

  5. UI Components Add status badges, action dropdowns, and responsive design patterns

  6. Export Features Configure HiExport component with custom column definitions

  • TanStack Table integration with sorting and filtering
  • Row selection with bulk operations support
  • Column visibility controls and responsive design
  • Custom toolbar actions and empty state handling

Data export functionality with custom column configuration:

Export Configuration
// Export configuration for user data
const 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
<HiExport
table={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:

Data Structure
// User TypeScript interfaces
export interface User {
id: string
name: string
email: string
phone: string
avatar: string
role: 'admin' | 'user' | 'moderator' | 'guest'
status: 'active' | 'inactive' | 'banned' | 'pending'
lastLogin: string
createdAt: string
}
export interface UserProfile extends User {
department: string
location: string
timezone: string
bio: string
skills: string[]
projects: number
tasksCompleted: number
teamSize: number
}
// Mock data generation
export 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...
]
  • TypeScript interfaces for all data structures (User, UserProfile, UserFormData)
  • HiTable integration for consistent table functionality across modules
  • Custom hooks for data loading and form handling
  • Modular components for reusability and maintainability
  • Mock data simulation with realistic async delays
  • Loading states for better user experience during data operations
  • Error handling with try/catch blocks and toast notifications
  • Navigation integration with React Router v7
  • Smooth animations with Framer Motion for page transitions
  • Interactive elements with hover states and loading indicators
  • Confirmation dialogs for destructive actions
  • Responsive design with Tailwind CSS utility classes

The user management system demonstrates modern React patterns with enterprise-grade components, providing a solid foundation for user administration features.