Track income, expenses, and financial insights with a sleek, role-based analytics platform.
- Overview
- Features
- Tech Stack
- Project Structure
- Getting Started
- Environment Variables
- API Endpoints
- Scripts
- Mock Data
- License
Flowlytics is a full-stack finance dashboard application that provides users with a comprehensive view of their financial data through interactive charts, transaction management, and smart insights. It features JWT-based authentication with role-based access control — Admins get full CRUD capabilities while Users (viewers) get a read-only experience.
- Login / Sign Up — Beautiful glassmorphism auth page with animated logo
- JWT Authentication — Secure token-based auth with 7-day expiry
- Role Selection — Choose Admin or User role during registration
- Password Hashing — bcrypt with 12 salt rounds
- Auto Token Verification — Validates stored token on app mount
- Protected Routes — Unauthenticated users see only the login page
- Summary Cards — Total Balance, Income, Expenses, and Transaction Count at a glance
- Income vs Expenses Chart — Area chart showing monthly trends over the past 6 months
- Spending Breakdown — Donut chart with category-wise expense distribution
- Recent Transactions — Quick view of the latest 5 transactions
- Full transaction list with pagination (15 per page)
- Search by description or category
- Filter by type (income/expense), category, and date range
- Sort by date or amount (click column headers)
- Add / Edit / Delete transactions (admin role only)
- CSV Export of filtered results
- Highest spending category identification
- Savings rate calculation
- Average transaction amounts
- Month-over-month comparison (income & expense % change)
- Expense categories ranked with visual progress bars
- Notable transactions (largest income & expense)
- Admin — Full access: can add, edit, and delete transactions
- Viewer (User) — Read-only: can view all data but cannot modify
- Role is assigned at registration and enforced from the server
- Dark Mode with toggle and localStorage persistence
- Responsive Design — works on mobile, tablet, and desktop
- Data Persistence — transactions, auth tokens, and preferences saved to localStorage
- Animated Logo — Custom SVG logo with animated bars, flowing waves, and particles
- Error Boundary — Catches and recovers from unexpected React errors
- Empty State Handling — Graceful UI when no data is available
- Smooth Transitions — Hover effects, backdrop blur, and animated charts
| Layer | Technology | Version | Purpose |
|---|---|---|---|
| Frontend | React | 18.3 | UI framework |
| Build Tool | Vite | 6 | Dev server & bundler |
| Styling | Tailwind CSS | v4 | Utility-first CSS |
| State | Zustand | 5 | State management with persist middleware |
| Charts | Recharts | 2.15 | Area, Pie, and Bar charts |
| Icons | Lucide React | 0.468 | Modern icon library |
| Backend | Express.js | 4.21 | REST API server |
| Database | MongoDB + Mongoose | 8.9 | NoSQL data storage & ODM |
| Auth | JSON Web Tokens | 9.0 | Token-based authentication |
| Security | bcryptjs | 2.4 | Password hashing (12 salt rounds) |
| HTTP | CORS | 2.8 | Cross-origin request handling |
| Config | dotenv | 16.4 | Environment variable management |
Finance Dashboard UI/
├── server/ # Backend (Express + MongoDB)
│ ├── models/
│ │ └── User.js # Mongoose user schema, bcrypt hashing
│ ├── routes/
│ │ └── auth.js # Register, Login, Token verification
│ ├── .env # Environment variables
│ ├── index.js # Express entry point, MongoDB connection
│ └── package.json # Backend dependencies
│
├── src/ # Frontend (React)
│ ├── components/
│ │ ├── AnimatedLogo.jsx # SVG animated logo with particles
│ │ ├── BalanceTrendChart.jsx # Area chart – income vs expenses
│ │ ├── ErrorBoundary.jsx # React error boundary wrapper
│ │ ├── Header.jsx # Top bar with page title, role badge, avatar
│ │ ├── RecentTransactions.jsx # Latest 5 transactions display
│ │ ├── Sidebar.jsx # Navigation, user info, logout, dark mode
│ │ ├── SpendingBreakdownChart.jsx # Donut chart – spending by category
│ │ └── SummaryCards.jsx # Balance, income, expense, count cards
│ ├── pages/
│ │ ├── AuthPage.jsx # Login/Sign Up with role selection
│ │ ├── DashboardPage.jsx # Main dashboard overview
│ │ ├── TransactionsPage.jsx # Transaction list with CRUD & filters
│ │ └── InsightsPage.jsx # Analytics and financial insights
│ ├── store/
│ │ └── useStore.js # Zustand store (auth, transactions, UI)
│ ├── data/
│ │ └── mockData.js # 120 mock transactions generator
│ ├── App.jsx # Root layout, auth guard, page routing
│ ├── main.jsx # Entry point, localStorage validation
│ └── index.css # Tailwind imports, dark mode config
│
├── index.html # HTML entry point
├── vite.config.js # Vite config with Tailwind & API proxy
├── package.json # Frontend dependencies & scripts
└── README.md # This file
- Node.js 18+ and npm
- MongoDB running locally or a remote connection URI
git clone <repo-url>
cd "Finance Dashboard UI"# Frontend dependencies
npm install
# Backend dependencies
cd server
npm install
cd ..Create or edit server/.env:
PORT=5000
MONGODB_URI=mongodb://127.0.0.1:27017/flowlytics
JWT_SECRET=your_secure_secret_key_hereNote: Replace
JWT_SECRETwith a strong random string in production.
Make sure MongoDB is running on your system:
# If using local MongoDB
mongodOpen two terminals:
# Terminal 1 — Backend server
cd server
npm run dev
# → Server running on port 5000
# → Connected to MongoDB# Terminal 2 — Frontend dev server
npm run dev
# → http://localhost:5173The Vite dev server automatically proxies /api requests to the backend at http://localhost:5000.
npm run build
npm run preview| Variable | Default | Description |
|---|---|---|
PORT |
5000 |
Backend server port |
MONGODB_URI |
mongodb://127.0.0.1:27017/flowlytics |
MongoDB connection string |
JWT_SECRET |
— | Secret key for signing JWT tokens |
All routes are prefixed with /api.
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
POST |
/api/auth/register |
Create a new account | No |
POST |
/api/auth/login |
Sign in and receive JWT | No |
GET |
/api/auth/me |
Verify token & get user info | Yes (Bearer) |
GET |
/api/health |
Server health check | No |
{
"name": "John Doe",
"email": "john@example.com",
"password": "securepass123",
"role": "admin"
}{
"email": "john@example.com",
"password": "securepass123"
}{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"_id": "...",
"name": "John Doe",
"email": "john@example.com",
"role": "admin",
"createdAt": "..."
}
}| Script | Command | Description |
|---|---|---|
dev |
vite |
Start development server with HMR |
build |
vite build |
Create optimized production build |
preview |
vite preview |
Preview the production build locally |
| Script | Command | Description |
|---|---|---|
dev |
node index.js |
Start Express server |
The app ships with 120 pre-generated transactions spanning October 2025 – April 2026:
| Category Type | Categories | Amount Range |
|---|---|---|
| Income | Salary, Freelance, Investment, Other Income | $100 – $8,000 |
| Expense | Food & Dining, Transportation, Shopping, Entertainment, Bills & Utilities, Healthcare, Education, Travel | $5 – $500 |
- Distribution: ~70% expenses, ~30% income
- Data is generated at runtime — each session starts with fresh realistic data
- Transactions persist to localStorage after first load
- Zustand for state management — minimal boilerplate, built-in
persistmiddleware for localStorage, individual selectors prevent unnecessary re-renders - No client-side router — simple page state in the Zustand store avoids complexity for a 3-page SPA
- Tailwind CSS v4 with
@tailwindcss/viteplugin — zero-config, class-based dark mode via@custom-variant - JWT auth with role from server — role is assigned during registration and stored in MongoDB, not just toggled on the frontend
- Vite proxy —
/apiroutes forwarded to Express during development, no CORS issues - React 18 — downgraded from 19 for Recharts compatibility (
react-transition-groupusesfindDOMNode) - Standalone derived functions —
getSummary()andgetFilteredTransactions()extracted outside the Zustand store and used withuseMemoto avoid infinite re-render loops
This project is for educational and portfolio purposes.