Skip to content

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               # Dependencies

Setup & Development

Prerequisites

  • Node.js 18+
  • npm or yarn

Installation

  1. Clone and Install:

    bash
    cd /IdeaProjects/mywarranties-ERP
    npm install
  2. Configure Environment: Create .env.local:

    env
    VITE_API_BASE_URL=https://api.my-warranties.nl
  3. Start Development Server:

    bash
    npm run dev

    Access at: http://localhost:5173

Build for Production

bash
npm run build

Build output in dist/ directory.

Preview Production Build

bash
npm run preview

Authentication Flow

  1. Login Screen:

    • User enters email/phone
    • System sends 6-digit verification code
    • User enters code
  2. Token Storage:

    • JWT token stored in localStorage
    • Token included in all API requests
    • Auto-refresh on expiry
  3. Auto-Login:

    • Check for existing token on load
    • Validate token with backend
    • Redirect to dashboard if valid
  4. 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 test

E2E Tests (Playwright)

bash
npm run test:e2e

Component Tests

bash
npm run test:components

Performance 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 build

API Connection Issues

  • Check VITE_API_BASE_URL in .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

MyWarranties - Warranty Management System