- Overview
- Technology Stack
- Project Structure
- Getting Started
- Features & Pages
- Components Library
- State Management
- API Integration
- Authentication & Authorization
- Routing
- Styling
- Development
- Build & Deployment
The Analify frontend is a modern, responsive React application built with TypeScript and Vite. It provides an intuitive interface for:
- Multi-store analytics dashboards with real-time charts
- Order processing with multi-item support
- Product and inventory management
- Employee directory and management
- Monthly bidding system for product sections
- Role-based access control with personalized experiences
✅ Modern UI with shadcn/ui component library
✅ Type-safe with TypeScript
✅ Fast development with Vite HMR
✅ Data fetching with React Query (TanStack Query)
✅ Form validation with React Hook Form + Zod
✅ Responsive design with Tailwind CSS
✅ Interactive charts with Recharts
✅ JWT authentication with automatic token management
- React 18.3.1 - UI library
- TypeScript 5.6+ - Type safety
- Vite 6.0+ - Build tool & dev server
- Tailwind CSS 3.4.17 - Utility-first CSS
- shadcn/ui - High-quality component library (built on Radix UI)
- Radix UI - Accessible component primitives
- Lucide React - Beautiful icon library
- class-variance-authority - Variant management
- clsx - Conditional class names
- TanStack Query (React Query) 5.83.0 - Server state management
- React Router 7.1.3 - Client-side routing
- React Hook Form 7.54.3 - Form management
- Zod 3.24.1 - Schema validation
- Recharts 2.15.1 - Chart library
- date-fns 3.6.0 - Date utilities
- cmdk - Command menu
- embla-carousel-react - Carousel component
- input-otp - OTP input component
- next-themes - Theme management
frontAnalify/
├── public/ # Static assets
│ └── robots.txt
│
├── src/
│ ├── components/ # React components
│ │ ├── charts/ # Chart components
│ │ │ ├── AreaChartCard.tsx # Area chart wrapper
│ │ │ ├── BarChartCard.tsx # Bar chart wrapper
│ │ │ ├── LineChartCard.tsx # Line chart wrapper
│ │ │ ├── PieChartCard.tsx # Pie chart wrapper
│ │ │ └── index.ts
│ │ │
│ │ ├── layout/ # Layout components
│ │ │ ├── DashboardLayout.tsx # Main dashboard layout
│ │ │ └── Sidebar.tsx # Navigation sidebar
│ │ │
│ │ ├── shared/ # Shared components
│ │ │ ├── ChartPlaceholder.tsx # Loading placeholder
│ │ │ ├── DataTable.tsx # Generic data table
│ │ │ ├── FilterPanel.tsx # Filter UI component
│ │ │ ├── ProfileForm.tsx # User profile form
│ │ │ └── StatCard.tsx # KPI card component
│ │ │
│ │ ├── ui/ # shadcn/ui components (60+ components)
│ │ │ ├── button.tsx
│ │ │ ├── card.tsx
│ │ │ ├── dialog.tsx
│ │ │ ├── form.tsx
│ │ │ ├── input.tsx
│ │ │ ├── select.tsx
│ │ │ ├── table.tsx
│ │ │ └── ... (50+ more)
│ │ │
│ │ └── NavLink.tsx # Navigation link component
│ │
│ ├── contexts/ # React Context
│ │ └── AuthContext.tsx # Authentication state
│ │
│ ├── hooks/ # Custom hooks
│ │ ├── use-mobile.tsx # Mobile detection
│ │ └── use-toast.ts # Toast notifications
│ │
│ ├── lib/ # Utilities
│ │ └── utils.ts # Helper functions
│ │
│ ├── pages/ # Page components
│ │ ├── dashboard/ # Dashboard pages
│ │ │ ├── BiddingBrowse.tsx # Browse bidding categories
│ │ │ ├── BiddingCategory.tsx # Category details
│ │ │ ├── BiddingDashboard.tsx # Bidding overview
│ │ │ ├── BiddingSection.tsx # Section details & bidding
│ │ │ ├── Employees.tsx # Employee management
│ │ │ ├── LowStock.tsx # Low stock alerts
│ │ │ ├── MyBids.tsx # My bids page
│ │ │ ├── Orders.tsx # Order management
│ │ │ ├── Products.tsx # Product management
│ │ │ ├── Profile.tsx # User profile
│ │ │ └── Statistics.tsx # Analytics dashboard
│ │ │
│ │ ├── Index.tsx # Dashboard home (redirects)
│ │ ├── Landing.tsx # Landing page
│ │ ├── Login.tsx # Login page
│ │ └── NotFound.tsx # 404 page
│ │
│ ├── services/ # API services
│ │ └── api.ts # All API calls
│ │
│ ├── types/ # TypeScript types
│ │ └── index.ts # Type definitions
│ │
│ ├── App.css # Global styles
│ ├── App.tsx # Root component
│ ├── index.css # Tailwind imports
│ ├── main.tsx # Entry point
│ └── vite-env.d.ts # Vite type definitions
│
├── index.html # HTML entry point
├── package.json # Dependencies
├── tsconfig.json # TypeScript config
├── tailwind.config.ts # Tailwind config
├── vite.config.ts # Vite config
├── components.json # shadcn/ui config
└── README.md # This file
- Node.js 18+ (LTS recommended)
- npm 9+ (comes with Node.js)
- Backend API running on http://localhost:8081
- Navigate to frontend directory:
cd frontAnalify- Install dependencies:
npm install- Start development server:
npm run devThe application will start on http://localhost:5173
- Open in browser:
http://localhost:5173
# Start development server with hot reload
npm run dev
# Build for production
npm run build
# Build for development (no minification)
npm run build:dev
# Preview production build locally
npm run preview
# Run ESLint
npm run lint- Project overview
- Feature highlights
- Call-to-action
- Email/password authentication
- JWT token generation
- Automatic redirect to dashboard
- Redirects to role-appropriate page
- Quick navigation
Access: All roles (filtered by role)
Features:
- Key performance indicators (KPIs)
- Total revenue
- Total orders
- Average order value
- Low stock count
- Interactive charts:
- Revenue over time (area chart)
- Sales by region (bar chart)
- Category distribution (pie chart)
- Top products/stores/investors
- Role-based filters:
- ADMIN_GENERAL: Date, region, state, store
- INVESTOR: Date, region, state
- ADMIN_STORE: Date only
Components Used:
StatCard- KPI displaysAreaChartCard,BarChartCard,PieChartCard- ChartsFilterPanel- Dynamic filtering
Access: CAISSIER, ADMIN_STORE, ADMIN_GENERAL
Features:
- List all orders with filters (date, store, product)
- View order details (items, pricing, cashier)
- Create new order (CAISSIER only)
- Multi-item support
- Discount per item
- Real-time total calculation
- Edit order (ADMIN_STORE, ADMIN_GENERAL)
- Update ship date
- Delete order (CAISSIER, ADMIN_GENERAL)
- Cashier visibility (ADMIN_STORE, ADMIN_GENERAL see who processed order)
Role Permissions:
CAISSIER: Create, view own orders, delete own ordersADMIN_STORE: View store orders, edit ship dates, see cashier namesADMIN_GENERAL: Full access to all orders
Access: INVESTOR, ADMIN_GENERAL
Features:
- Product catalog with search and filters
- Filter by category, subcategory
- Price range filter
- Quantity range filter
- Create new products
- Edit product details (name, price)
- Delete products
- Update stock levels (per store)
- Low stock indicators
API Calls:
productsApi.getAll(filters)productsApi.create(data)productsApi.update(id, data)productsApi.updateStock(id, data)productsApi.delete(id)
Access: INVESTOR, ADMIN_GENERAL
Features:
- Real-time low stock alerts across all stores
- Filter by store city
- Filter by quantity thresholds
- Product details with current stock levels
- Store location information
Data Source: productsApi.getLowStockAlerts()
Access: ADMIN_STORE (own store), ADMIN_GENERAL (all)
Features:
- Employee directory with search and filters
- Search by username, email, user ID
- Filter by role, salary range, start date
- Create employees
- Assign role (CAISSIER, ADMIN_STORE, INVESTOR, ADMIN_GENERAL)
- Assign to store (for CAISSIER, ADMIN_STORE)
- Set salary and start date
- Edit employee profiles
- Delete employees
- Role assignment (promote/demote)
Role-Based Data:
ADMIN_STORE: Only employees from their storeADMIN_GENERAL: All employees (including other admins, investors)
Access: INVESTOR, ADMIN_GENERAL
Features:
- Monthly period information
- Quick stats:
- Total bids placed
- Currently winning bids
- Possessed sections
- Days until period closes
- Current winning bids preview
- Period details (start/end dates, bidding window)
- Quick action buttons
Access: INVESTOR, ADMIN_GENERAL
Features:
- Browse bidding hierarchy:
- Categories
- Rangs (by category)
- Faces (by rang)
- Sections (by face)
- Section cards with:
- Current price
- Status (OPEN/CLOSED)
- Current winner
- Bid button
Access: INVESTOR, ADMIN_GENERAL
Features:
- Full section information
- Current price and base price
- Status and deadline
- Place bid form
- Validates bid > current price
- Real-time feedback
- Bid history table
- All bids on this section
- Bid amounts, dates, statuses
- Current winner highlighted
- Monthly contract description
Access: INVESTOR, ADMIN_GENERAL
Features:
- Three tabs:
- All Bids - Every bid you've placed
- Currently Winning - Bids with PENDING status
- Final Wins - Bids with WINNER status (won sections)
- Bid cards showing:
- Section name
- Bid amount
- Bid time
- Status badge (PENDING, OUTBID, WINNER)
- Cancel bid functionality (for OUTBID bids)
- View section details from bid card
Access: All roles
Features:
- View personal information
- Edit profile details (username, email, date of birth)
- Change password
- View role and permissions
Form Validation: React Hook Form + Zod schema
All chart components use Recharts library with consistent styling:
<AreaChartCard
title="Revenue Over Time"
data={revenueData}
dataKey="value"
xAxisKey="date"
/><BarChartCard
title="Sales by Region"
data={salesData}
dataKey="value"
xAxisKey="name"
color="#8884d8"
/><LineChartCard
title="Monthly Trends"
data={trendsData}
dataKey="value"
xAxisKey="month"
/><PieChartCard
title="Category Distribution"
data={categoryData}
dataKey="value"
nameKey="name"
/>Main layout wrapper with sidebar navigation:
<DashboardLayout>
<YourPageContent />
</DashboardLayout>Navigation menu with role-based menu items:
- Automatic role detection
- Active state management
- Responsive design (collapsible on mobile)
KPI display card:
<StatCard
title="Total Revenue"
value="$156,789"
icon={DollarSign}
description="+12.5% from last month"
/>Generic table component with sorting and pagination:
<DataTable
columns={columns}
data={data}
searchPlaceholder="Search..."
/>Dynamic filter UI:
<FilterPanel
filters={filterConfig}
onFilterChange={handleFilterChange}
onSearch={handleSearch}
searchConfig={searchConfig}
/>Filter Types:
select- Dropdown selectionnumber-range- Min/max inputsdate-range- From/to date pickers
Over 60 pre-built components from shadcn/ui:
Forms:
Button,Input,Select,Checkbox,Radio,SwitchForm,Label,Textarea
Data Display:
Table,Card,Badge,Avatar,Separator
Overlays:
Dialog,Sheet,Popover,Tooltip,Dropdown MenuAlert Dialog,Command,Context Menu
Navigation:
Tabs,Accordion,Navigation Menu,Breadcrumb
Feedback:
Toast,Alert,Progress,Skeleton
Charts:
Chart(Recharts wrapper with shadcn styling)
All components are:
- ✅ Fully accessible (ARIA compliant)
- ✅ Keyboard navigable
- ✅ Customizable with Tailwind
- ✅ TypeScript typed
All server state is managed with React Query:
Benefits:
- Automatic caching
- Background refetching
- Optimistic updates
- Loading and error states
- Mutations with callbacks
Example Usage:
// Fetch data
const { data, isLoading, error } = useQuery({
queryKey: ['orders', filters],
queryFn: () => ordersApi.getAll(filters),
});
// Mutate data
const mutation = useMutation({
mutationFn: ordersApi.create,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['orders'] });
toast({ title: 'Order created successfully' });
},
});Manages authentication state:
- Current user information
- JWT token
- Login/logout functions
- Auto-initialization from localStorage
Usage:
const { user, token, login, logout } = useAuth();
if (user?.role === 'ADMIN_GENERAL') {
// Show admin features
}All API calls are centralized in src/services/api.ts:
Structure:
// Base configuration
const API_BASE_URL = '/api';
// Generic request function
const apiRequest = async <T>(
url: string,
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
body?: unknown
): Promise<T> => {
const token = localStorage.getItem('auth_token');
const response = await fetch(url, {
method,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
},
body: body ? JSON.stringify(body) : undefined,
});
if (!response.ok) {
throw new Error(`API Error: ${response.status}`);
}
return response.json();
};
// API modules
export const ordersApi = { ... };
export const productsApi = { ... };
export const employeesApi = { ... };
export const biddingApi = { ... };Error Handling:
- 401 Unauthorized → Redirect to login
- 403 Forbidden → Show error message
- 404 Not Found → Handle gracefully
- 500 Server Error → Show error toast
1. User enters credentials → Login page
2. POST /api/auth/login
3. Server returns JWT token + user info
4. Frontend stores token in localStorage
5. AuthContext initializes with user data
6. All API requests include: Authorization: Bearer {token}
7. Protected routes check authentication
8. Pages check user role for feature access
Implementation in App.tsx:
<Route path="/dashboard" element={
<ProtectedRoute>
<DashboardLayout />
</ProtectedRoute>
}>
<Route path="orders" element={<Orders />} />
...
</Route>Access Control in Components:
const Orders = () => {
const { user } = useAuth();
const canCreate = user?.role === 'CAISSIER';
const canEdit = ['ADMIN_STORE', 'ADMIN_GENERAL'].includes(user?.role);
return (
<>
{canCreate && <Button onClick={createOrder}>Create</Button>}
{canEdit && <Button onClick={editOrder}>Edit</Button>}
</>
);
};/ → Landing page
/login → Login page
/dashboard → Dashboard home (redirects)
/dashboard/statistics → Analytics dashboard
/dashboard/orders → Order management
/dashboard/products → Product management
/dashboard/low-stock → Low stock alerts
/dashboard/employees → Employee management
/dashboard/bidding-overview → Bidding dashboard
/dashboard/bidding → Browse sections
/dashboard/bidding/section/:id → Section details
/dashboard/my-bids → My bids
/dashboard/profile → User profile
* → 404 Not Found
Navigation: React Router v7 with nested routes
Utility-first CSS framework with custom configuration:
Config (tailwind.config.ts):
export default {
darkMode: ["class"],
content: ["./src/**/*.{ts,tsx}"],
theme: {
extend: {
colors: {
border: "hsl(var(--border))",
primary: "hsl(var(--primary))",
// ... custom color palette
},
},
},
};Usage:
<div className="flex items-center gap-4 p-6 rounded-lg bg-card">
<h2 className="text-2xl font-bold">Title</h2>
</div>Custom properties in index.css:
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--radius: 0.5rem;
/* ... */
}Theme toggle with next-themes:
import { useTheme } from 'next-themes';
const { theme, setTheme } = useTheme();Vite provides instant updates during development:
- Save file → Changes appear immediately
- React Fast Refresh preserves component state
- TypeScript errors shown in browser overlay
Type Safety:
- All components are typed
- API responses have interfaces
- Props are strictly typed
- Type inference reduces boilerplate
Example:
interface OrderProps {
orderId: number;
onDelete: (id: number) => void;
}
const OrderCard: React.FC<OrderProps> = ({ orderId, onDelete }) => {
// TypeScript knows types
};Code quality checks:
npm run lintRules: React, TypeScript, and accessibility best practices
npm run buildOutput: dist/ folder with optimized assets
Optimizations:
- Code splitting
- Tree shaking
- Minification
- Asset compression
npm run previewTest production build locally on http://localhost:4173
Create .env file:
VITE_API_BASE_URL=http://localhost:8081/apiAccess in code:
const API_URL = import.meta.env.VITE_API_BASE_URL || '/api';- Vercel, Netlify, GitHub Pages
- Simply upload
dist/folder
Create Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 5173
CMD ["npm", "run", "preview"]Serve dist/ folder:
server {
listen 80;
root /var/www/analify/dist;
location / {
try_files $uri $uri/ /index.html;
}
}Node modules errors:
rm -rf node_modules package-lock.json
npm installBuild fails:
npm run build -- --debugTypeScript errors:
npx tsc --noEmitPort already in use:
# Change port in vite.config.ts
server: { port: 5174 }- Main README:
../README.md - Backend README:
../backAnalify/README.md - Bidding Docs:
../BIDDING_SYSTEM_COMPLETE_FEATURES.md
Built with React 18, TypeScript, and Vite
- Edit files directly within the Codespace and commit and push your changes once you're done.
This project is built with:
- Vite
- TypeScript
- React
- shadcn-ui
- Tailwind CSS
Simply open Lovable and click on Share -> Publish.
Yes, you can!
To connect a domain, navigate to Project > Settings > Domains and click Connect Domain.
Read more here: Setting up a custom domain