Appearance
ERP Web Application
The MyWarranties ERP is a modern web-based management interface built with React, TypeScript, and Mantine UI, designed for administrators and suppliers to manage the warranty system.
Overview
The ERP application provides:
- Product Management - Manage all products across all users
- Claims Management - Handle warranty claims from customers
- User Management - Administer user accounts and permissions
- Analytics & Reporting - View system metrics and trends
- Bulk Operations - Efficient management of multiple items
Technology Stack
Frontend
- React 18 - Modern React with hooks and concurrent features
- TypeScript - Full type safety
- Mantine UI 8.3 - Professional component library
- Zustand - Lightweight state management
- TanStack Query - Server state management and caching
- React Router v6 - Client-side routing
- Axios - HTTP client with interceptors
- Vite - Fast build tool
Build & Deployment
- Vite - Lightning-fast HMR and builds
- Docker - Containerized deployment
- Nginx - Static file serving and reverse proxy
- Kubernetes - Orchestration and scaling
Features
Dashboard
Key Metrics:
- Total products registered
- Active warranty claims
- Expiring warranties (next 30 days)
- Recent claim activity
- User growth trends
Quick Actions:
- Create new product
- View pending claims
- Export reports
- Manage users
Product Management
List View:
- Searchable product table
- Filter by brand, category, warranty status
- Sort by various fields
- Pagination for large datasets
- Bulk selection and actions
Product Details:
- Complete product information
- Warranty timeline
- Receipt images
- Associated claims
- Edit and delete options
Create/Edit Products:
- Product details form
- Receipt upload
- Serial number analysis
- Warranty calculation
- Category selection
Claims Management
Claims Dashboard:
- All claims across all users
- Filter by status (Open, In Progress, Resolved, Closed)
- Filter by date range
- Search by customer or product
- Assign to suppliers
Claim Details:
- Full conversation thread
- Customer information
- Product details
- Status timeline
- Resolution actions
Claim Actions:
- Reply to customer
- Update claim status
- Assign to different supplier
- Attach documents
- Close claim
User Management
User List:
- All registered users
- Filter by role (Customer, Supplier, Admin)
- Search by email or name
- Pagination
- User status management
User Details:
- Profile information
- Products owned
- Claims created/handled
- Activity history
- Role management
User Actions:
- Create new users
- Update roles
- Enable/disable accounts
- Reset passwords
- View audit logs
Analytics & Reporting
Reports Available:
- Warranty expiration forecast
- Claim resolution times
- Product categories breakdown
- Supplier performance metrics
- User engagement statistics
Export Options:
- CSV export
- PDF reports
- Excel spreadsheets
- Custom date ranges
Project Structure
mywarranties-ERP/
├── src/
│ ├── api/ # API client and endpoints
│ │ ├── client.ts # Axios instance with interceptors
│ │ ├── products.ts # Product API calls
│ │ ├── claims.ts # Claims API calls
│ │ └── users.ts # User management API
│ ├── store/ # Zustand stores
│ │ ├── authStore.ts # Authentication state
│ │ ├── userStore.ts # User information
│ │ └── uiStore.ts # UI preferences
│ ├── pages/ # Page components
│ │ ├── Dashboard.tsx
│ │ ├── Products/
│ │ │ ├── ProductsList.tsx
│ │ │ ├── ProductDetail.tsx
│ │ │ └── ProductForm.tsx
│ │ ├── Claims/
│ │ │ ├── ClaimsList.tsx
│ │ │ ├── ClaimDetail.tsx
│ │ │ └── ClaimChat.tsx
│ │ ├── Users/
│ │ │ ├── UsersList.tsx
│ │ │ ├── UserDetail.tsx
│ │ │ └── UserForm.tsx
│ │ └── Reports/
│ │ └── ReportsPage.tsx
│ ├── components/ # Reusable components
│ │ ├── Layout/
│ │ │ ├── AppShell.tsx
│ │ │ ├── Navbar.tsx
│ │ │ └── Header.tsx
│ │ ├── Tables/
│ │ │ ├── ProductTable.tsx
│ │ │ ├── ClaimTable.tsx
│ │ │ └── UserTable.tsx
│ │ └── Forms/
│ │ ├── ProductForm.tsx
│ │ └── UserForm.tsx
│ ├── hooks/ # Custom React hooks
│ │ ├── useProducts.ts
│ │ ├── useClaims.ts
│ │ └── useUsers.ts
│ ├── types/ # TypeScript definitions
│ │ ├── product.ts
│ │ ├── claim.ts
│ │ └── user.ts
│ ├── utils/ # Utility functions
│ │ ├── formatters.ts
│ │ ├── validators.ts
│ │ └── exporters.ts
│ ├── App.tsx # Main app with routing
│ └── main.tsx # Entry point
├── public/ # Static assets
├── dist/ # Build output
├── vite.config.ts # Vite configuration
├── tsconfig.json # TypeScript configuration
└── package.json # DependenciesSetup & Development
Prerequisites
- Node.js 18+
- npm or yarn
Installation
Clone and Install:
bashcd /IdeaProjects/mywarranties-ERP npm installConfigure Environment: Create
.env.local:envVITE_API_BASE_URL=https://api.my-warranties.nlStart Development Server:
bashnpm run devAccess at:
http://localhost:5173
Build for Production
bash
npm run buildBuild output in dist/ directory.
Preview Production Build
bash
npm run previewAuthentication Flow
Login Screen:
- User enters email/phone
- System sends 6-digit verification code
- User enters code
Token Storage:
- JWT token stored in localStorage
- Token included in all API requests
- Auto-refresh on expiry
Auto-Login:
- Check for existing token on load
- Validate token with backend
- Redirect to dashboard if valid
Logout:
- Clear localStorage
- Revoke token (optional)
- Redirect to login
State Management
Zustand (Client State)
typescript
// Auth Store
interface AuthState {
token: string | null;
user: User | null;
login: (email: string, code: string) => Promise<void>;
logout: () => void;
}
const useAuthStore = create<AuthState>((set) => ({
token: localStorage.getItem('auth_token'),
user: null,
login: async (email, code) => {
const { token, user } = await api.verifyCode(email, code);
localStorage.setItem('auth_token', token);
set({ token, user });
},
logout: () => {
localStorage.removeItem('auth_token');
set({ token: null, user: null });
}
}));TanStack Query (Server State)
typescript
// Products query
const { data, isLoading, error } = useQuery({
queryKey: ['products'],
queryFn: () => api.getProducts(),
staleTime: 5 * 60 * 1000, // 5 minutes
});
// Create product mutation
const mutation = useMutation({
mutationFn: (product: NewProduct) => api.createProduct(product),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['products'] });
}
});API Integration
Axios Configuration
typescript
// Create instance with base URL
const api = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL
});
// Request interceptor - add auth token
api.interceptors.request.use((config) => {
const token = localStorage.getItem('auth_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Response interceptor - handle 401
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
localStorage.removeItem('auth_token');
window.location.href = '/login';
}
return Promise.reject(error);
}
);API Endpoints
All endpoints use the backend API at https://api.my-warranties.nl.
See API Reference for complete endpoint documentation.
UI Components
Mantine UI Integration
typescript
import {
AppShell,
Navbar,
Header,
Table,
Button,
TextInput,
Select,
Modal
} from '@mantine/core';
// Example: Product table with Mantine
function ProductsTable({ products }) {
return (
<Table striped highlightOnHover>
<thead>
<tr>
<th>Name</th>
<th>Brand</th>
<th>Warranty Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{products.map((product) => (
<tr key={product.id}>
<td>{product.name}</td>
<td>{product.brand}</td>
<td>{product.warrantyStatus}</td>
<td>
<Button size="xs">View</Button>
</td>
</tr>
))}
</tbody>
</Table>
);
}Theme Customization
typescript
// Custom theme
const theme = {
primaryColor: 'blue',
fontFamily: 'Inter, sans-serif',
headings: { fontFamily: 'Inter, sans-serif' },
colors: {
brand: ['#E3F2FD', '#BBDEFB', '#90CAF9', '#64B5F6', '#42A5F5']
}
};Routing
typescript
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route path="/" element={<ProtectedLayout />}>
<Route index element={<Dashboard />} />
<Route path="products" element={<ProductsList />} />
<Route path="products/:id" element={<ProductDetail />} />
<Route path="claims" element={<ClaimsList />} />
<Route path="claims/:id" element={<ClaimDetail />} />
<Route path="users" element={<UsersList />} />
<Route path="reports" element={<ReportsPage />} />
</Route>
</Routes>
</BrowserRouter>
);
}Deployment
Docker Build
dockerfile
# Multi-stage build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]Nginx Configuration
nginx
server {
listen 80;
server_name erp.my-warranties.nl;
root /usr/share/nginx/html;
index index.html;
# Enable gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript;
# SPA routing - always serve index.html
location / {
try_files $uri $uri/ /index.html;
}
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}Kubernetes Deployment
bash
# Build and push
docker build -t mywarranties-erp:latest .
docker push registry.digitalocean.com/delaparra-services-private-registry/mywarranties-erp:latest
# Deploy
kubectl apply -f k8s/Access at: https://erp.my-warranties.nl
Testing
Unit Tests (Vitest)
bash
npm run testE2E Tests (Playwright)
bash
npm run test:e2eComponent Tests
bash
npm run test:componentsPerformance Optimization
Code Splitting
typescript
// Lazy load heavy components
const ProductDetail = lazy(() => import('./pages/ProductDetail'));
const Reports = lazy(() => import('./pages/Reports'));
<Suspense fallback={<LoadingSpinner />}>
<ProductDetail />
</Suspense>Query Caching
typescript
// Configure default cache time
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000,
cacheTime: 10 * 60 * 1000
}
}
});Bundle Size
- Tree-shaking enabled
- Dynamic imports for routes
- Gzip compression
- Mantine components imported individually
Security
- XSS Protection: React escapes by default
- CSRF: Not needed for JWT-based API
- Content Security Policy: Configured in Nginx
- HTTPS Only: Enforced via Kubernetes ingress
- Token Expiry: 1-hour JWT tokens with refresh
Monitoring
Error Tracking
- Console errors logged
- API errors captured
- User actions tracked
Performance Metrics
- Page load times
- API response times
- Render performance
Troubleshooting
Build Fails
bash
rm -rf node_modules package-lock.json
npm install
npm run buildAPI Connection Issues
- Check
VITE_API_BASE_URLin.env.local - Verify API is accessible
- Check CORS configuration in backend
Authentication Problems
- Clear localStorage
- Check JWT token format
- Verify backend auth endpoints
Next Steps
- Getting Started - Set up development
- Architecture - Understand system design
- Mobile App - iOS and Android apps
- API Reference - Explore API
