A comprehensive, production-ready fintech platform frontend built with React, TypeScript, Vite, Chakra UI, and Redux Toolkit.
β οΈ Important Notice: The live backend server will be discontinued on February 14th, 2026 due to hosting costs. This is a demonstration project. The frontend will gracefully display a friendly error message when the server becomes unreachable. You can run both projects locally following the setup instructions.
π Performance Note: The live URL may experience slower response times. This is not due to the application or implementation itself, but rather the hosting service configuration. The free/basic tier uses limited RAM and server resources. For optimal performance, please run the project locally using the setup instructions below.
- Backend API: kayprogrammer/paycore-api-1
- Live Demo: https://paycore-fe.netlify.app
PayCore is a complete financial services platform that consumes 137 API endpoints across 13 modules:
- π° Wallets - Multi-currency wallet management with virtual account numbers
- π³ Cards - Virtual and physical card issuance and management
- π Transactions - Transfers, deposits, withdrawals, and disputes
- π± Bill Payments - Airtime, data, electricity, cable TV, and more
- π΅ Payment Links & Invoices - Merchant payment solutions
- π¦ Loans - Personal, business, payday, and student loans with auto-repayment
- π Investments - Fixed deposits, bonds, mutual funds, stocks, real estate
- π« Support - Ticketing system and FAQs
- π Compliance - KYC verification with multi-tier levels
- π Notifications - Real-time push and in-app notifications
- π Audit Logs - Complete activity tracking
- π€ Profile Management - User profiles with avatar upload
- βοΈ Settings - Security, notifications, devices, and account management
- π Google OAuth - Primary authentication method (Sign in with Google)
- π§ Email/OTP - Alternative authentication with OTP verification
- π JWT Token Management - Auto-refresh with secure storage
- π± Multi-device Support - Session management across devices
- π‘οΈ PIN-based Authorization - Transaction security with wallet PINs
The project follows a feature-based modular architecture, where each feature is organized like a microservice:
src/
βββ features/
β βββ auth/
β β βββ components/
β β βββ services/ # RTK Query API
β β βββ types/ # TypeScript interfaces
β β βββ hooks/ # Custom hooks
β β βββ utils/ # Feature utilities
β βββ wallets/
β βββ cards/
β βββ transactions/
β βββ bills/
β βββ payments/
β βββ loans/
β βββ investments/
β βββ support/
β βββ compliance/
β βββ notifications/
β βββ audit/
β βββ profile/
βββ components/
β βββ common/ # Reusable components
β βββ layout/ # Layouts (MainLayout, AuthLayout)
β βββ ui/ # UI components
β βββ forms/ # Form components
βββ pages/ # Page components
βββ store/ # Redux store
β βββ api/ # RTK Query base API
β βββ slices/ # Redux slices
βββ hooks/ # Global hooks
βββ services/ # API services
βββ types/ # Global types
βββ utils/ # Utilities
βββ theme/ # Chakra UI theme
βββ assets/ # Static assets
- React 18 - UI library
- TypeScript - Type safety
- Vite - Build tool
- React Router v7 - Routing
- Redux Toolkit - State management
- RTK Query - API integration and caching
- Chakra UI - Component library
- Emotion - CSS-in-JS
- Framer Motion - Animations
- React Icons - Icons
- Recharts - Data visualization
- React Hook Form - Form management
- Yup - Schema validation
- Axios - HTTP client
- date-fns - Date utilities
- jwt-decode - JWT token decoding
- Node.js 20.19+ or 22.12+ and npm (for local development, required by Vite 7.x)
- Docker & Docker Compose (for containerized deployment)
- Backend API running (Django PayCore API)
- Google OAuth Client ID (for authentication)
# Navigate to project
cd /Users/mac/Documents/Projects/ViteJs/paycore-frontend
# Quick start for development
make quick-start
# Or for production with Docker
make quick-prod- Navigate to the repository
cd /Users/mac/Documents/Projects/ViteJs/paycore-frontend- Install dependencies
npm install
# Or using Makefile
make install- Configure environment variables
cp .env.example .env.development
# Or using Makefile
make env-exampleEdit .env.development:
VITE_API_BASE_URL=http://localhost:8000/api/v1
VITE_APP_NAME=PayCore
VITE_GOOGLE_CLIENT_ID=your_google_oauth_client_id- Start development server
npm run dev
# Or using Makefile
make devThe app will be available at http://localhost:3000
# Build and run development container with hot reload
make docker-dev
# Or manually
docker-compose -f docker-compose.dev.yml up# Build production image
make docker-build
# Run production container
make docker-run
# Or build and run in one command
make quick-prod
# Or manually
docker-compose up -dThe app will be available at http://localhost:3000
npm run dev # Start development server
npm run build # Build for production
npm run preview # Preview production build
npm run lint # Run ESLint
npm run type-check # TypeScript type checking# Development
make dev # Start development server
make build # Build for production
make clean # Clean build artifacts
make install # Install dependencies
# Code Quality
make lint # Run ESLint
make lint-fix # Run ESLint with auto-fix
make type-check # TypeScript type checking
make format # Format code with Prettier
# Docker - Production
make docker-build # Build production Docker image
make docker-run # Run production container
make docker-stop # Stop production container
make docker-logs # View container logs
make docker-shell # Open shell in container
# Docker - Development
make docker-dev # Run dev container with hot reload
make docker-dev-stop # Stop development container
make docker-dev-logs # View dev container logs
# Utilities
make help # Show all available commands
make info # Display project information
make backend-check # Check if backend is runningSee full command list with: make help
| Module | Endpoints | Status |
|---|---|---|
| Authentication | 13 | β Complete |
| Profile | 3 | β Complete |
| Wallets | 19 | β Complete |
| Cards | 12 | β Complete |
| Transactions | 14 | β Complete |
| Bills | 7 | β Complete |
| Payments | 16 | β Complete |
| Loans | 20 | β Complete |
| Investments | 10 | β Complete |
| Support | 9 | β Complete |
| Compliance | 4 | β Complete |
| Notifications | 4 | β Complete |
| Audit Logs | 3 | β Complete |
| Total | 137 | β 100% |
Custom Chakra UI theme with brand colors:
brand: {
50: '#EEF2FF',
500: '#6366F1', // Primary
600: '#4F46E5',
900: '#312E81',
}- Modern sidebar navigation with active states
- Header with notifications and user menu
- Custom button styles with brand colors
- Card components with shadows and hover effects
- Input fields with focus states
- Toast notifications for feedback
- Modal dialogs for forms
- Responsive breakpoints (sm, md, lg, xl, 2xl)
- Click "Sign in with Google" β Google OAuth popup
- Authorize β Select Google account
- Token Exchange β Google ID token sent to backend
- Profile Fetch β User profile and tokens received
- Auto-Login β Redirect to dashboard
- Login β Enter email β OTP sent to email
- Verify OTP β Enter 6-digit code β Tokens received
- Token Storage β Access & refresh tokens stored in Redux + localStorage
- Auto-Refresh β Expired tokens automatically refreshed
- Protected Routes β Redirect to login if not authenticated
- Single Source of Truth β Profile data fetched directly from API endpoint
- RTK Query Caching β Automatic cache management and invalidation
- Real-time Updates β Avatar and profile changes reflect immediately
- Redux Persistence β Auth state persists across page reloads
When the backend server is unreachable (discontinued, network issues, etc.), the app displays a friendly error screen instead of confusing error messages.
- Health Check on Load β App checks server availability when it loads (5-second timeout)
- Server Unreachable β Shows friendly screen with crying emoji π’ immediately
- Server Available β App loads normally
- Backup Detection β If server goes down during usage, also caught by API interceptor
Instead of seeing:
β Google Login Failed
β Could not sign in with Google
β CORS errors in console
Users see:
π’
Server Unavailable
The PayCore API server has been stopped and is now unreachable.
This was a demonstration project hosted on a paid server.
The live server was discontinued on February 14th, 2026.
[Try Again Button]
[View Backend Repository Button]
You can run the project locally by following the setup instructions in the repository.
- Health Check Hook:
src/hooks/useHealthCheck.ts- Runs on app load - Error Detection:
src/utils/errorHandlers.ts- Detects network/server errors - UI Component:
src/components/common/ServerUnavailable.tsx- Friendly error screen - Redux State:
src/store/slices/serverStatusSlice.ts- Tracks server status
{
api: RTKQueryState, // All API cache
auth: {
user: User | null,
accessToken: string | null,
refreshToken: string | null,
isAuthenticated: boolean,
},
serverStatus: {
isServerAvailable: boolean,
lastChecked: number | null,
}
}- Automatic cache management with tags
- Optimistic updates
- Automatic refetching on focus/reconnect
- Request deduplication
- Polling support
All API services are created using RTK Query with automatic:
- Token injection in headers
- Token refresh on 401 errors
- Error handling
- Loading states
- Cache invalidation
import { useListWalletsQuery } from '@/features/wallets/services/walletsApi';
function WalletsPage() {
const { data, isLoading, error } = useListWalletsQuery();
if (isLoading) return <LoadingSpinner />;
if (error) return <ErrorAlert message="Failed to load" />;
return <WalletsList wallets={data.data.items} />;
}- LoginPage - Google OAuth sign-in (primary method)
- RegisterPage - Google OAuth sign-up (primary method)
- VerifyOTPPage - 6-digit OTP verification (alternative method)
- ForgotPasswordPage - Multi-step password reset
- DashboardPage - Overview with charts and quick actions
- WalletsPage - Wallet management with security settings
- CardsPage - Card display and controls
- TransactionsPage - Transaction history with filters
- BillsPage - Bill payment interface
- LoansPage - Loan marketplace and management
- InvestmentsPage - Investment portfolio
- ProfilePage - User profile and KYC
- SettingsPage - Security and preferences
formatCurrency(50000, 'NGN') // β¦50,000.00
formatDate('2024-01-01') // Jan 01, 2024
formatRelativeTime(date) // 2 hours ago
maskCardNumber(cardNumber) // 5399 **** **** 1234
getStatusColor('completed') // 'green'Charts implemented using Recharts:
- Line Charts - Transaction trends
- Area Charts - Balance over time
- Pie Charts - Portfolio distribution
- Bar Charts - Monthly comparisons
- Mobile-first approach
- Sidebar becomes drawer on mobile
- Responsive tables with horizontal scroll
- Stack layouts on small screens
- Touch-friendly buttons and inputs
- Create types in
src/features/[feature]/types/index.ts - Create RTK Query API in
src/features/[feature]/services/[feature]Api.ts - Build components in
src/features/[feature]/components/ - Create page in
src/pages/[feature]/ - Add route in
App.tsx - Update sidebar navigation if needed
- Use TypeScript for type safety
- Follow existing naming conventions
- Use Chakra UI components
- Implement proper error handling
- Add loading states everywhere
- Use formatters for display
- Write clean, readable code
- β Google OAuth Integration - Secure third-party authentication
- β JWT Tokens - Auto-refresh mechanism for seamless sessions
- β Secure Token Storage - Redux Persist with localStorage
- β PIN Authorization - Transaction-level security
- β Data Masking - Sensitive data (card numbers, etc.)
- β Input Validation - Client-side form validation
- β Protected Routes - Authentication guards
- β Multi-factor Authentication - OTP verification
- β Profile Security - Avatar upload, password management removed (Google-only auth)
# Development with hot reload
make docker-dev
# Production deployment
make docker-build
make docker-run
# View logs
make docker-logs
# Stop containers
make docker-stopProduction Image (Multi-stage build):
- Based on
node:20-alpine(builder) +nginx:alpine(runtime) - Optimized for production with minimal size
- Includes Nginx for serving static files
- Health checks configured
- Security headers enabled
- Gzip compression enabled
Development Image:
- Based on
node:20-alpine - Hot reload enabled with Vite HMR
- Volume mounting for live code updates
- Full development tooling
- Accessible at http://localhost:3000
Production:
docker-compose up -dDevelopment:
docker-compose -f docker-compose.dev.yml upSet in docker-compose.yml or via command line:
docker build \
--build-arg VITE_API_BASE_URL=https://api.paycore.com/api/v1 \
--build-arg VITE_GOOGLE_CLIENT_ID=your_google_client_id \
-t paycore-frontend:latest .Required Environment Variables:
VITE_API_BASE_URL- Backend API URLVITE_GOOGLE_CLIENT_ID- Google OAuth Client IDVITE_APP_NAME- Application name (default: PayCore)
Port Configuration:
- Development: Container port 5173 β Host port 3000
- Production: Container port 80 β Host port (configurable in docker-compose.yml)
# View running containers
docker ps
# View logs
docker logs -f paycore-frontend
# Open shell in container
docker exec -it paycore-frontend sh
# Restart container
docker restart paycore-frontend
# Remove container
docker rm -f paycore-frontend# Build and deploy with Docker
make docker-build
make docker-run
# Or use docker-compose
docker-compose up -d# Build for production
npm run build
# Or
make buildOutput in dist/ folder (optimized, minified, code-split)
Create .env.production:
VITE_API_BASE_URL=https://api.paycore.com/api/v1
VITE_APP_NAME=PayCore
VITE_GOOGLE_CLIENT_ID=your_google_client_idnpm install -g vercel
vercel --prod
# Or
make deploy-vercelnpm install -g netlify-cli
netlify deploy --prod --dir=dist
# Or
make deploy-netlifyImportant for Netlify: The project includes a _redirects file in the public/ folder and netlify.toml at the root to handle SPA routing. This ensures that direct URL access (like /dashboard, /login) works correctly by serving index.html for all routes.
Files for Netlify:
public/_redirects- Redirect configurationnetlify.toml- Netlify configuration (alternative to_redirects)
If you encounter 404 errors when accessing routes directly, ensure these files are committed to your repository.
# Build first
npm run build
# Upload to S3
aws s3 sync dist/ s3://your-bucket-name
# Invalidate CloudFront cache
aws cloudfront create-invalidation --distribution-id YOUR_DIST_ID --paths "/*"docker stack deploy -c docker-compose.yml paycore# Create deployment and service
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yamlThe production Docker image uses Nginx with:
- Gzip compression
- Security headers (X-Frame-Options, X-Content-Type-Options, etc.)
- SPA routing support
- Static asset caching (1 year)
- Health check endpoint at
/health
Primary Method: Google OAuth
- Click "Sign in with Google" button
- Authorize with your Google account
- Instant access to dashboard
Alternative Method: Email/OTP
- Enter your email address
- Receive 6-digit OTP via email
- Verify OTP to access dashboard
Note: Password-based authentication and change password functionality have been removed in favor of Google OAuth for enhanced security.
| Page | URL | Description |
|---|---|---|
| Dashboard | /dashboard |
Overview, wallet summary, charts |
| Wallets | /wallets |
Manage multi-currency wallets |
| Cards | /cards |
Virtual/physical card management |
| Transactions | /transactions |
Transfer, deposit, withdraw |
| Bills | /bills |
Pay airtime, data, electricity, etc. |
| Loans | /loans |
Apply for loans, repayment |
| Investments | /investments |
Investment portfolio |
| Profile | /profile |
Edit profile, KYC verification |
| Settings | /settings |
Security, notifications |
# Create Wallet: Dashboard β "Add Wallet" β Select currency
# Set PIN: Wallets β Click wallet β Security β "Set PIN"
# View Balance: Toggle eye icon to show/hide balance# Send Money: Transactions β "Transfer" β Enter details + PIN
# Receive: Share your wallet account number# Create Card: Cards β "Create Card" β Choose virtual/physical
# Fund Card: Click card β "Fund Card" β Enter amount + PIN
# Freeze Card: Click card menu β "Freeze Card"# Pay Bills: Bills β Select category β Choose provider β Enter details
# View History: Bills β "Payment History"# Calculate: Loans β Calculator β Adjust sliders
# Apply: Loans β "Apply for Loan" β Fill form
# Repay: Active loans β "Make Repayment"# Invest: Investments β "Create Investment" β Choose product
# Portfolio: View charts and performance metrics
# Liquidate: Active investment β "Liquidate" (if needed)Problem: "Failed to fetch" errors Solution:
- Ensure Django backend is running on port 8000
- Check
VITE_API_BASE_URLin.env.development - Verify CORS settings in Django
Problem: Login works but gets logged out immediately Solution:
- Check browser console for errors
- Verify tokens are being saved (check Redux DevTools)
- Clear localStorage and try again
Problem: OTP not working Solution:
- Check Django terminal for OTP code
- OTP expires after 10 minutes
- Request new OTP if needed
Problem: Styles not loading Solution:
# Clear Vite cache and restart
rm -rf node_modules/.vite
make devProblem: TypeScript errors Solution:
# Run type check
make type-check
# Most errors are auto-fixed by restarting dev server- Total Files Created: 120+
- Total Lines of Code: ~18,000+
- API Endpoints Consumed: 137/137 (100%)
- RTK Query Hooks: 137
- Type Definitions: 60+ interfaces
- Pages: 17 (4 auth + 13 main)
- Features: 13 modules
- Dependencies: 36 production, 14 dev
- Docker Images: 2 (production + development)
- Makefile Commands: 50+
All 137 endpoints from the Django PayCore API have been properly consumed:
| Module | Endpoints | Implementation |
|---|---|---|
| Authentication | 13 | β
src/features/auth/services/authApi.ts |
| Profile | 3 | β
src/features/profile/services/profileApi.ts |
| Wallets | 19 | β
src/features/wallets/services/walletsApi.ts |
| Cards | 12 | β
src/features/cards/services/cardsApi.ts |
| Transactions | 14 | β
src/features/transactions/services/transactionsApi.ts |
| Bills | 7 | β
src/features/bills/services/billsApi.ts |
| Payments | 16 | β
src/features/payments/services/paymentsApi.ts |
| Loans | 20 | β
src/features/loans/services/loansApi.ts |
| Investments | 10 | β
src/features/investments/services/investmentsApi.ts |
| Support | 9 | β
src/features/support/services/supportApi.ts |
| Compliance | 4 | β
src/features/compliance/services/complianceApi.ts |
| Notifications | 4 | β
src/features/notifications/services/notificationsApi.ts |
| Audit Logs | 3 | β
src/features/audit/services/auditApi.ts |
All endpoints are fully functional with:
- β RTK Query hooks
- β TypeScript type definitions
- β Cache management
- β Error handling
- β Loading states
- β UI integration
- Author: Kenechi Ifeanyi
- License: MIT
- Backend: Django PayCore API
- Version: 1.0.0
- Chakra UI - Component library
- Redux Toolkit - State management
- RTK Query - API integration
- React Router - Routing
- Vite - Build tool
- TypeScript - Type safety
For issues or questions:
- Check the Makefile commands:
make help - View backend status:
make backend-check - Review logs:
make docker-logs(for Docker) or check browser console
β PayCore Frontend - Production Ready Built with β€οΈ for modern fintech solutions 100% API Coverage | Fully Dockerized | Comprehensive Documentation

