A complete, scalable SaaS Dashboard application built with React, Redux Toolkit, and a mock API layer. This project demonstrates enterprise-level architecture patterns and best practices for modern web applications.
- KPI Statistics Cards: Real-time metrics (Total Users, Revenue, Active Subscriptions, Growth)
- Revenue Chart: Interactive 12-month revenue visualization
- Recent Users Table: Latest user registrations with details
- Loading States: Skeleton loaders for excellent UX
- Error Handling: User-friendly error boundaries
- Complete User Listing: Full table with all user details
- Pagination: Navigate through users efficiently
- Status Indicators: Visual badges for user status
- Responsive Design: Mobile and desktop optimized
- Login System: Email/password authentication (demo:
[email protected]/password) - Protected Routes: Guards authenticated pages
- Session Persistence: Token storage with localStorage
- Secure Logout: Clean session management
- Node.js 16+
- npm or yarn
# Install dependencies
npm install
# Start development server
npm startThe app opens at http://localhost:3000/
Email: [email protected]
Password: password
This project uses a layered architecture for maximum scalability and maintainability:
┌─────────────────────────────┐
│ React Components (UI) │ ← User Interface
├─────────────────────────────┤
│ Redux Toolkit (State) │ ← Predictable State Management
├─────────────────────────────┤
│ Services (API Layer) │ ← Business Logic
├─────────────────────────────┤
│ Mock Server / Real API │ ← Data Source
└─────────────────────────────┘
✅ Separation of Concerns: Each layer has a single responsibility ✅ Easy Testing: Mock APIs can be replaced without code changes ✅ Scalability: Add new features following the established pattern ✅ Team Friendly: Clear structure for new developers ✅ Backend Agnostic: Works with any REST API
src/
├── app/ # Redux configuration
│ ├── store.js # Redux store setup
│ └── rootReducer.js # Combined reducers
│
├── features/ # Domain-based features
│ ├── auth/ # Authentication feature
│ ├── dashboard/ # Dashboard feature with components
│ └── users/ # Users management feature
│
├── services/ # API layer
│ ├── apiClient.js # Axios configuration
│ └── mockServer.js # Mock API responses
│
├── pages/ # Page-level components
│ ├── LoginPage.jsx
│ ├── DashboardPage.jsx
│ └── UsersPage.jsx
│
├── components/ # Reusable components
│ ├── Topbar.jsx
│ ├── Sidebar.jsx
│ ├── Loader.jsx
│ └── EmptyState.jsx
│
├── styles/ # Global & component styles
├── utils/ # Helper functions
└── App.jsx # Main routing
// 1. Component dispatches action
dispatch(fetchDashboardStats())
// 2. Redux Thunk calls service
↓ dashboardService.fetchStats()
// 3. Service calls mock API (or real backend)
↓ mockGetDashboardStats()
// 4. Redux reducer updates state
↓ state.dashboard.stats = data
// 5. Component re-renders with new data
↓ {stats} = useSelector(state => state.dashboard)The architecture makes migration to real APIs incredibly simple:
// dashboardService.js
import { mockGetDashboardStats } from '../../services/mockServer';
export const dashboardService = {
fetchStats: async () => {
const result = await mockGetDashboardStats(); // ← Mock
if (!result.success) throw new Error(result.error);
return result.data;
},
};// dashboardService.js
import apiClient from '../../services/apiClient';
export const dashboardService = {
fetchStats: async () => {
const response = await apiClient.get('/dashboard/stats'); // ← Real API
return response.data;
},
};That's it! No Redux changes needed. No component changes needed.
👉 See ARCHITECTURE.md for detailed migration guide
| Practice | Implementation |
|---|---|
| Redux Toolkit | createSlice, createAsyncThunk, createSelector |
| Async Operations | RTK async thunks with error handling |
| Loading States | Separate loading, success, error states |
| Error Boundaries | Proper try-catch and error messages |
| Service Layer | Single point for API changes |
| Route Protection | ProtectedRoute component for auth |
| Responsive Design | Mobile-first CSS with media queries |
| Code Organization | Feature-based folder structure |
npm start # Start dev server (runs on port 3000)
npm run build # Production build
npm run preview # Preview production build
npm test # Run tests- React 18: Modern React with hooks
- Redux Toolkit: Simplified Redux with best practices
- React Router v6: Client-side routing
- Axios: HTTP client with interceptors
- CSS3: Modern CSS with Grid and Flexbox
- Vite: Fast build tool
- Skeleton loaders while fetching data
- Progress indicators
- Smooth transitions
- User-friendly error messages
- Retry mechanisms
- Error boundaries
- Clear messaging when no data
- Call-to-action suggestions
- Consistent design
- Desktop: Full-featured layout
- Tablet: Optimized spacing
- Mobile: Stack-based layout
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
- ✅ CORS configuration via axios
- ✅ XSS prevention (React escaping)
- ✅ Protected routes
- ✅ Secure token storage (can upgrade to secure httpOnly cookies)
- ✅ Request/response interceptors
All endpoints simulate realistic network latency (400-800ms):
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /auth/login |
User authentication |
| GET | /dashboard/stats |
KPI metrics |
| GET | /dashboard/revenue |
Revenue trends |
| GET | /users |
User list (paginated) |
| GET | /users/:id |
Single user |
| GET | /dashboard/recent-users |
Latest users |
// redux/auth
{
user: { id, name, email, role },
isAuthenticated: boolean,
isLoading: boolean,
error: null | string
}
// redux/dashboard
{
stats: { totalUsers, totalRevenue, activeSubscriptions, monthlyGrowth },
revenueChart: [{ month, revenue }],
recentUsers: [{ id, name, email, ... }],
loadingStats: boolean,
loadingRevenue: boolean,
loadingRecentUsers: boolean,
error: null | string
}
// redux/users
{
list: [{ id, name, email, ... }],
selectedUser: null | user,
total: number,
currentPage: number,
pageSize: number,
loading: boolean,
error: null | string
}- Start Here: Understand the architecture in ARCHITECTURE.md
- Explore: Navigate through components and Redux slices
- Modify: Try adding a new statistic card
- Experiment: Replace mock data with real API calls
- Deploy: Build and deploy to production
-
"I built this with enterprise-level architecture in mind"
- Redux Toolkit for state management
- Clear separation of concerns
- Service layer abstraction
-
"The mock API layer is production-ready"
- Can swap real endpoints in minutes
- Zero Redux/component changes needed
- Design your own API contract
-
"This demonstrates real-world best practices"
- Error handling and loading states
- Protected authentication
- Responsive design
- Accessibility considerations
-
"It's built for scalability"
- Easy to add new features
- Team-friendly codebase
- Well-documented decisions
- Add unit tests (Jest + React Testing Library)
- Implement dark mode
- Add data export (CSV/PDF)
- Set up CI/CD pipeline
- Add international localization (i18n)
- Implement real WebSocket updates
- Add advanced filtering/sorting
- Create admin analytics dashboard
# Use a different port
PORT=3001 npm start# Clear npm cache and reinstall
rm -rf node_modules package-lock.json
npm install- Check Redux DevTools to see state
- Verify component is wrapped with
<Provider store={store}> - Check console for errors
For questions about the architecture or implementation:
- Review ARCHITECTURE.md
- Check Redux DevTools in browser for state inspection
- Review Redux thunk implementations for async patterns
MIT - Feel free to use this for learning and portfolio projects
Created with ❤️ for modern React development
Ready for production or portfolio showcase ✨