39294-vm/03_FRONTEND_PAGES.md
2026-03-24 15:28:07 +00:00

15 KiB

Frontend Pages Specification — Swish Auto Care GMS

React 18 + TypeScript + Vite + React Router v6 + CSS Modules


Global Layout

The app uses a persistent shell layout after login:

┌─────────────────────────────────────────────────────────┐
│ TOP BAR: Logo | "Swish Auto Care GMS" | Date | Admin ▼  │
├──────────┬──────────────────────────────────────────────┤
│          │                                              │
│ SIDEBAR  │           PAGE CONTENT                       │
│ (Left)   │                                              │
│          │                                              │
└──────────┴──────────────────────────────────────────────┘

Sidebar Nav Items (in order):

  1. 🏠 Dashboard
  2. 🔧 Job Cards
  3. 📋 Status Board
  4. 👤 Staff
  5. 📅 Attendance
  6. 💰 Salary & Payments
  7. 🔩 Parts & Inventory
  8. 🛒 Parts Sales
  9. 💵 Cash Ledger
  10. 📊 Accounts
  11. 📈 Daily Report
  12. 📤 Excel Exports

TopBar shows: Current date in DD/MM/YYYY format | "Admin" label | Logout button


Page 1 — Login (/login)

Full-screen centered card. No sidebar/topbar.

Fields:

  • Username (text input)
  • Password (password input)
  • "Login" button

Behavior:

  • On submit: POST /api/auth/login
  • On success: Store JWT in localStorage, store user in AuthContext, redirect to /dashboard
  • On fail: Show "Invalid username or password" error below form
  • Auto-redirect to /dashboard if already logged in

Design: Clean card, Swish logo placeholder at top, business colors.


Page 2 — Dashboard (/dashboard)

Today's overview. Data from GET /api/dashboard/today.

6 Widget Cards:

┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Active Jobs      │ │ Completed Jobs   │ │ Today's Revenue  │
│    4  🔧         │ │    7  ✅         │ │  ₹28,500 💰      │
└──────────────────┘ └──────────────────┘ └──────────────────┘
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Cash Balance     │ │ Staff Present    │ │ Quick Actions    │
│  ₹14,200        │ │   3 / 4 👤        │ │ + New Job Card   │
│                  │ │                  │ │ Mark Attendance  │
└──────────────────┘ └──────────────────┘ └──────────────────┘

Quick action buttons: "New Job Card" → /job-cards/new | "Mark Attendance" → /attendance | "Daily Report" → /daily-report

Data refresh: On page load only (no auto-refresh needed for demo).


Page 3 — Job Cards (/job-cards)

List of all job cards with search, filter, and create button.

Top bar:

  • Search by Reg No. (text input, real-time filter)
  • Filter by Status (All / Active / Done) — dropdown
  • Filter by Date (date picker, default today)
  • "+ New Job Card" button (primary, top right)

Table columns:

Job No Type Reg No Car Owner Service Staff Amount Status Date Actions
  • Type badge: "Full" (blue) / "Wash" (teal)
  • Status badge: "Active" (amber) / "Done" (green)
  • Actions: View 👁 | Edit ✏ (only if Active) | Close ✓ (only if Active)

"Close Job" action: Opens a modal:

  • Final Amount (₹) — required
  • Payment Mode — Cash / UPI / Card dropdown
  • "Mark as Done" button

Page 4 — New Job Card (/job-cards/new)

Toggle at top: "Full Service Job" | "Quick Wash Job" — determines which form shows.

Full Job Form:

  • Registration No. * (text)
  • Car Model / Name * (text)
  • Owner Name * (text)
  • Mobile No. * (text, 10 digits)
  • Service Type * (dropdown: Wash, Polish, PPF, Detailing, Interior Cleaning, Ceramic Coating, Underbody Coating, Other)
  • Assigned Staff * (dropdown — fetched from active staff list)
  • Estimated Amount ₹ (number)
  • Notes / Remarks (textarea)

Quick Wash Form (simplified):

  • Registration No. * (text)
  • Car Name * (text)
  • Mobile No. (optional)
  • Wash Type * (dropdown: Basic Wash, Premium Wash, Interior Clean)
  • Assigned Staff * (dropdown)
  • Amount ₹ * (number)

Buttons: "Create Job Card" (primary) | "Cancel" (secondary)

On success: Show toast "Job card SAC-YYYYMMDD-001 created" | Redirect to /job-cards


Page 5 — Status Board (/status-board)

Two-column Kanban-style view:

┌─────── ACTIVE (4) ──────────┐  ┌─────── DONE (7) ────────────┐
│ SAC-20260324-001            │  │ SAC-20260324-003            │
│ GJ06AB1234 — Swift          │  │ GJ05XY9900 — Fortuner       │
│ Full Detailing | Rajan M.   │  │ Quick Wash | Suresh K.      │
│ Est. ₹5,000 | 10:30 AM      │  │ ₹350 | 09:15 AM ✅           │
│ [Mark Done]                 │  │                             │
└─────────────────────────────┘  └─────────────────────────────┘

Each active card has a "Mark Done" button that opens the Close Job modal (same as in Job Cards list).


Page 6 — Staff (/staff)

Top bar: "+ Add Staff" button | Search by name

Table:

Staff Code Name Role Mobile Joining Salary Status Actions
  • Status: "Active" (green toggle) / "Inactive" (gray toggle) — click to toggle
  • Actions: Edit ✏

Add/Edit Staff Modal:

  • Full Name *
  • Role / Designation *
  • Mobile No.
  • Date of Joining (date picker)
  • Monthly Salary ₹ *
  • Active toggle

Page 7 — Attendance (/attendance)

Date selector at top (date picker, default today).

Attendance grid (bulk mark):

┌─────────────────────────────────────────────────────────┐
│ Date: 24/03/2026                    [Save Attendance]   │
├──────────────────┬─────────────────────────────────────┤
│ Rajan Mehta      │ ● Present  ○ Absent  ○ Half Day     │
│ Suresh Kumar     │ ○ Present  ● Absent  ○ Half Day     │
│ Vikram Patel     │ ○ Present  ○ Absent  ● Half Day     │
│ Arjun Shah       │ ○ Present  ○ Absent  ○ Half Day     │
└──────────────────┴─────────────────────────────────────┘

All staff listed. Radio button per row. "Save Attendance" calls POST /api/attendance/bulk.

Below grid: "View Monthly Summary" → Modal or accordion per staff showing month grid.


Page 8 — Salary & Payments (/salary)

Two sections:

Section A — New Payment:

  • Select Staff * (dropdown)
  • Payment Month * (month/year picker or text e.g. "March 2026")
  • [Auto-calculate button] → calls GET /api/salary/calculate/:id → fills Days Present & Calculated Salary fields
  • Days Present (auto-filled, editable)
  • Calculated Salary ₹ (auto-filled, read-only display)
  • Payment Amount ₹ * (editable — admin override)
  • Payment Type * (Full Salary / Advance / Bonus / Deduction)
  • Payment Mode * (Cash / Bank / UPI)
  • Notes (textarea)
  • "Record Payment" button

Section B — Payment History Table:

  • Filter by Staff and Month
  • Columns: Date | Staff | Month | Type | Mode | Amount | Notes

Page 9 — Parts & Inventory (/parts)

Top bar: "+ Add Part" | Search | Filter by Category | Low Stock toggle

Table:

Part Code Name Category Unit Buy Price Sell Price Stock Low Stock? Actions
  • Low Stock?: Red badge if stock_qty ≤ low_stock_alert
  • Actions: Edit ✏ | Restock + (opens restock modal)

Add/Edit Part Modal: All fields from parts table. Restock Modal: Adjustment quantity input + reason.


Page 10 — Parts Sales (/parts-sales)

Top bar: "+ Record Sale" button | Date filter

Sales history table:

Date Part Qty Unit Price Total Customer Payment Job Card

New Sale Modal:

  • Select Part * (searchable dropdown showing part name + stock)
  • Link to Job Card? (optional — searchable dropdown of active + recent job cards)
  • Quantity * (number — validated against stock)
  • Unit Price ₹ (auto-filled from part.selling_price, editable)
  • Total Amount (auto-calculated, display only)
  • Customer Name (optional text)
  • Payment Mode * (Cash / UPI / Card)
  • "Record Sale" button

Validation: If quantity > stock_qty, show error "Insufficient stock (X available)".


Page 11 — Cash Ledger (/cash-ledger)

Top bar: "+ Cash In" | "+ Cash Out" | Date range filter

Ledger table:

Date Type Category Description Amount
  • Type badge: "IN" (green) / "OUT" (red)
  • Running balance column (optional — nice to have)

New Entry Modal (shared for In and Out, pre-fills type):

  • Entry Type (pre-selected Cash In or Cash Out)
  • Amount ₹ *
  • Category * (dropdown: Utilities, Supplies, Advance, Refund, Other)
  • Description * (mandatory free text)
  • Date & Time (auto-filled, editable)

Page 12 — Accounts (/accounts)

Date Range filter at top: Today | This Week | This Month | Custom Range

Summary cards:

┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Total Income │ │ Total Expense│ │ Net Balance  │
│  ₹38,000    │ │  ₹15,800     │ │  ₹22,200     │
└──────────────┘ └──────────────┘ └──────────────┘

Breakdown table (Income): | Source | Amount | | Job Revenue | ₹28,500 | | Parts Sales | ₹7,500 | | Cash In (Other) | ₹2,000 |

Breakdown table (Expenses): | Source | Amount | | Staff Payments | ₹15,000 | | Cash Out (Other) | ₹800 |

All Transactions tab: Unified chronological list, clickable to see source.


Page 13 — Daily Report (/daily-report)

Date picker (default today).

On-screen preview sections:

  1. Header: Business name, date, summary totals
  2. Completed Jobs (table)
  3. Parts Sales (table)
  4. Cash In entries (table)
  5. Cash Out entries (table)
  6. Staff Payments (table)
  7. Day Totals (summary row)

"Download Excel" button → calls GET /api/reports/daily/download?date=YYYY-MM-DD → browser saves .xlsx file.


Page 14 — Excel Exports (/exports)

4 export cards, each with description and download button:

┌───────────────────────────────────────┐
│ 📥 Job Cards Database                 │
│ Export all job cards with date filter  │
│ [From Date] [To Date] [Download xlsx] │
└───────────────────────────────────────┘
┌───────────────────────────────────────┐
│ 📥 Staff & Attendance                 │
│ Export staff list + monthly attendance│
│ [Month] [Year] [Download xlsx]        │
└───────────────────────────────────────┘
┌───────────────────────────────────────┐
│ 📥 Parts Inventory                    │
│ Full parts catalog with stock levels  │
│ [Download xlsx]                       │
└───────────────────────────────────────┘
┌───────────────────────────────────────┐
│ 📥 Accounts Ledger                    │
│ All financial transactions            │
│ [From Date] [To Date] [Download xlsx] │
└───────────────────────────────────────┘

Shared Components

<Badge status="active|done|in|out|full|wash" />

Colored pill badge for statuses.

<Modal title onClose>children</Modal>

Overlay modal with close button.

<DataTable columns data loading onAction />

Reusable table with loading skeleton.

<ConfirmDialog message onConfirm onCancel />

Simple yes/no confirmation popup.

Toast Notifications

Use a simple toast system: success (green), error (red), info (blue). Auto-dismiss in 3s.


AuthContext & Protected Routes

// context/AuthContext.tsx
interface AuthContextType {
  user: { id: number; username: string; full_name: string } | null;
  token: string | null;
  login: (token: string, user: object) => void;
  logout: () => void;
  isAuthenticated: boolean;
}

// Protected route wrapper
<ProtectedRoute> wraps all pages except /login
// Redirects to /login if !isAuthenticated

Axios Instance

// api/axios.ts
import axios from 'axios';
const api = axios.create({ baseURL: 'http://localhost:5000/api' });

// Request interceptor — attach JWT
api.interceptors.request.use(config => {
  const token = localStorage.getItem('gms_token');
  if (token) config.headers.Authorization = `Bearer ${token}`;
  return config;
});

// Response interceptor — handle 401 (auto logout)
api.interceptors.response.use(
  r => r,
  err => {
    if (err.response?.status === 401) {
      localStorage.removeItem('gms_token');
      window.location.href = '/login';
    }
    return Promise.reject(err);
  }
);

export default api;