970 lines
28 KiB
Markdown
970 lines
28 KiB
Markdown
# RE Workflow Management System - Frontend Setup Guide
|
|
**Version:** 1.0
|
|
**Date:** October 16, 2025
|
|
**Technology Stack:** React 19 + TypeScript 5.7 + Vite 6.0 + Redux Toolkit 2.5 + Material-UI 6.3
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
1. [Frontend Architecture Overview](#frontend-architecture-overview)
|
|
2. [Technology Stack](#technology-stack)
|
|
3. [Project Folder Structure](#project-folder-structure)
|
|
4. [TypeScript Configuration](#typescript-configuration)
|
|
5. [State Management (Redux Toolkit)](#state-management-redux-toolkit)
|
|
6. [Component Structure](#component-structure)
|
|
7. [Configuration Management](#configuration-management)
|
|
8. [Deployment Architecture](#deployment-architecture)
|
|
9. [Development Setup Instructions](#development-setup-instructions)
|
|
|
|
---
|
|
|
|
## 1. Frontend Architecture Overview
|
|
|
|
### High-Level Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ CLIENT LAYER │
|
|
│ React.js SPA (Single Page Application) │
|
|
│ - Material-UI / Ant Design Components │
|
|
│ - Redux Toolkit for State Management │
|
|
│ - React Router for Navigation │
|
|
│ - Axios for API Communication │
|
|
│ - Vite for Build & Development │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
↕ HTTPS/REST API
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ BACKEND API LAYER │
|
|
│ Express.js REST API Server │
|
|
│ - Node.js + TypeScript │
|
|
│ - PostgreSQL Database │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Technology Stack
|
|
|
|
| Component | Technology | Version | Purpose |
|
|
|-----------|-----------|---------|---------|
|
|
| **Frontend Library** | React.js | 19.0.x | UI component library |
|
|
| **Frontend Language** | TypeScript (TSX) | 5.7.x | Type-safe frontend development |
|
|
| **UI Framework** | Material-UI (MUI) | 6.3.x | Component design system |
|
|
| **Build Tool** | Vite | 6.0.x | Ultra-fast build & dev server |
|
|
| **State Management** | Redux Toolkit | 2.5.x | Application state management |
|
|
| **Routing** | React Router DOM | 7.1.x | Client-side routing |
|
|
| **HTTP Client** | Axios | 1.7.x | API communication |
|
|
| **Form Management** | Formik | 2.4.x | Form state management |
|
|
| **Form Validation** | Yup | 1.6.x | Schema validation |
|
|
| **Date Utilities** | date-fns | 4.1.x | Date manipulation |
|
|
| **Charts** | Recharts | 2.15.x | Data visualization |
|
|
| **Notifications** | React Toastify | 11.0.x | Toast notifications |
|
|
| **File Upload** | React Dropzone | 14.3.x | File upload UI |
|
|
| **Testing** | Vitest + React Testing Library | 2.1.x/16.1.x | Component testing |
|
|
| **Code Quality** | ESLint + Prettier | 9.x/3.x | Code linting & formatting |
|
|
|
|
---
|
|
|
|
## 3. Project Folder Structure
|
|
|
|
### Frontend Repository (`re-workflow-frontend`)
|
|
|
|
```
|
|
re-workflow-frontend/
|
|
│
|
|
├── public/ # Static assets
|
|
│ ├── index.html
|
|
│ ├── favicon.ico
|
|
│ ├── robots.txt
|
|
│ └── manifest.json
|
|
│
|
|
├── src/ # Source code
|
|
│ ├── index.tsx # Application entry point
|
|
│ ├── App.tsx # Root component
|
|
│ ├── App.css
|
|
│ ├── react-app-env.d.ts # React TypeScript declarations
|
|
│ │
|
|
│ ├── types/ # TypeScript type definitions
|
|
│ │ ├── index.ts # Main types export
|
|
│ │ ├── user.types.ts # User types
|
|
│ │ ├── workflow.types.ts # Workflow types
|
|
│ │ ├── approval.types.ts # Approval types
|
|
│ │ ├── document.types.ts # Document types
|
|
│ │ ├── notification.types.ts # Notification types
|
|
│ │ ├── common.types.ts # Common types
|
|
│ │ └── api.types.ts # API response types
|
|
│ │
|
|
│ ├── assets/ # Static assets
|
|
│ │ ├── images/
|
|
│ │ ├── icons/
|
|
│ │ ├── fonts/
|
|
│ │ └── styles/
|
|
│ │ ├── global.css
|
|
│ │ ├── variables.css
|
|
│ │ └── theme.ts
|
|
│ │
|
|
│ ├── components/ # Reusable components
|
|
│ │ ├── common/ # Generic components
|
|
│ │ │ ├── Button/
|
|
│ │ │ │ ├── Button.tsx
|
|
│ │ │ │ ├── Button.module.css
|
|
│ │ │ │ ├── Button.types.ts
|
|
│ │ │ │ └── Button.test.tsx
|
|
│ │ │ ├── Input/
|
|
│ │ │ ├── Dropdown/
|
|
│ │ │ ├── Modal/
|
|
│ │ │ ├── Card/
|
|
│ │ │ ├── Table/
|
|
│ │ │ ├── Tabs/
|
|
│ │ │ ├── Pagination/
|
|
│ │ │ ├── Loader/
|
|
│ │ │ ├── Notification/
|
|
│ │ │ └── ErrorBoundary/
|
|
│ │ │
|
|
│ │ ├── layout/ # Layout components
|
|
│ │ │ ├── Header/
|
|
│ │ │ │ ├── Header.tsx
|
|
│ │ │ │ ├── Header.module.css
|
|
│ │ │ │ └── Header.types.ts
|
|
│ │ │ ├── Sidebar/
|
|
│ │ │ ├── Footer/
|
|
│ │ │ ├── Navigation/
|
|
│ │ │ └── PageLayout/
|
|
│ │ │
|
|
│ │ ├── workflow/ # Workflow-specific components
|
|
│ │ │ ├── TemplateSelector/
|
|
│ │ │ ├── BasicInformation/
|
|
│ │ │ ├── ApprovalWorkflow/
|
|
│ │ │ │ ├── ApprovalWorkflow.tsx
|
|
│ │ │ │ ├── ApproverLevel.tsx
|
|
│ │ │ │ ├── TATCalculator.tsx
|
|
│ │ │ │ ├── ApprovalSummary.tsx
|
|
│ │ │ │ └── types.ts
|
|
│ │ │ ├── ParticipantAccess/
|
|
│ │ │ │ ├── ParticipantAccess.tsx
|
|
│ │ │ │ ├── SpectatorList.tsx
|
|
│ │ │ │ ├── UserTagging.tsx
|
|
│ │ │ │ └── types.ts
|
|
│ │ │ ├── DocumentUpload/
|
|
│ │ │ │ ├── DocumentUpload.tsx
|
|
│ │ │ │ ├── FilePreview.tsx
|
|
│ │ │ │ ├── GoogleDocsLink.tsx
|
|
│ │ │ │ └── types.ts
|
|
│ │ │ ├── ReviewSubmit/
|
|
│ │ │ └── WizardStepper/
|
|
│ │ │
|
|
│ │ ├── request/ # Request management components
|
|
│ │ │ ├── RequestCard/
|
|
│ │ │ ├── RequestList/
|
|
│ │ │ ├── RequestDetail/
|
|
│ │ │ │ ├── RequestOverview.tsx
|
|
│ │ │ │ ├── WorkflowTab.tsx
|
|
│ │ │ │ ├── DocumentTab.tsx
|
|
│ │ │ │ ├── ActivityTab.tsx
|
|
│ │ │ │ ├── TATProgressBar.tsx
|
|
│ │ │ │ └── types.ts
|
|
│ │ │ ├── StatusBadge/
|
|
│ │ │ └── PriorityIndicator/
|
|
│ │ │
|
|
│ │ ├── approval/ # Approval action components
|
|
│ │ │ ├── ApprovalModal/
|
|
│ │ │ ├── RejectionModal/
|
|
│ │ │ ├── ApprovalHistory/
|
|
│ │ │ └── ConclusionRemark/
|
|
│ │ │
|
|
│ │ ├── workNote/ # Work notes / chat components
|
|
│ │ │ ├── WorkNoteChat/
|
|
│ │ │ ├── MessageItem/
|
|
│ │ │ ├── MessageComposer/
|
|
│ │ │ ├── FileAttachment/
|
|
│ │ │ └── UserMention/
|
|
│ │ │
|
|
│ │ ├── notification/ # Notification components
|
|
│ │ │ ├── NotificationBell/
|
|
│ │ │ ├── NotificationList/
|
|
│ │ │ ├── NotificationItem/
|
|
│ │ │ └── NotificationSettings/
|
|
│ │ │
|
|
│ │ └── dashboard/ # Dashboard components
|
|
│ │ ├── DashboardCard/
|
|
│ │ ├── StatisticsWidget/
|
|
│ │ ├── RecentRequests/
|
|
│ │ └── QuickActions/
|
|
│ │
|
|
│ ├── pages/ # Page components (routes)
|
|
│ │ ├── Auth/
|
|
│ │ │ ├── Login.tsx
|
|
│ │ │ └── SSOCallback.tsx
|
|
│ │ ├── Dashboard/
|
|
│ │ │ └── Dashboard.tsx
|
|
│ │ ├── CreateRequest/
|
|
│ │ │ └── CreateRequest.tsx
|
|
│ │ ├── MyRequests/
|
|
│ │ │ └── MyRequests.tsx
|
|
│ │ ├── OpenRequests/
|
|
│ │ │ └── OpenRequests.tsx
|
|
│ │ ├── ClosedRequests/
|
|
│ │ │ └── ClosedRequests.tsx
|
|
│ │ ├── RequestDetail/
|
|
│ │ │ └── RequestDetail.tsx
|
|
│ │ ├── NotFound/
|
|
│ │ │ └── NotFound.tsx
|
|
│ │ └── Unauthorized/
|
|
│ │ └── Unauthorized.tsx
|
|
│ │
|
|
│ ├── redux/ # Redux state management
|
|
│ │ ├── store.ts # Redux store configuration
|
|
│ │ ├── hooks.ts # Typed Redux hooks
|
|
│ │ ├── slices/
|
|
│ │ │ ├── authSlice.ts
|
|
│ │ │ ├── workflowSlice.ts
|
|
│ │ │ ├── approvalSlice.ts
|
|
│ │ │ ├── notificationSlice.ts
|
|
│ │ │ ├── documentSlice.ts
|
|
│ │ │ ├── workNoteSlice.ts
|
|
│ │ │ ├── participantSlice.ts
|
|
│ │ │ └── uiSlice.ts
|
|
│ │ └── middleware/
|
|
│ │ └── apiMiddleware.ts
|
|
│ │
|
|
│ ├── services/ # API service layer
|
|
│ │ ├── api.ts # Axios instance configuration
|
|
│ │ ├── auth.service.ts
|
|
│ │ ├── workflow.service.ts
|
|
│ │ ├── approval.service.ts
|
|
│ │ ├── document.service.ts
|
|
│ │ ├── notification.service.ts
|
|
│ │ ├── workNote.service.ts
|
|
│ │ ├── participant.service.ts
|
|
│ │ ├── dashboard.service.ts
|
|
│ │ └── user.service.ts
|
|
│ │
|
|
│ ├── hooks/ # Custom React hooks
|
|
│ │ ├── useAuth.ts
|
|
│ │ ├── useWorkflow.ts
|
|
│ │ ├── useNotification.ts
|
|
│ │ ├── useDebounce.ts
|
|
│ │ ├── useInfiniteScroll.ts
|
|
│ │ ├── useLocalStorage.ts
|
|
│ │ └── useWebSocket.ts
|
|
│ │
|
|
│ ├── utils/ # Utility functions
|
|
│ │ ├── constants.ts
|
|
│ │ ├── validators.ts
|
|
│ │ ├── formatters.ts
|
|
│ │ ├── dateUtils.ts
|
|
│ │ ├── fileUtils.ts
|
|
│ │ ├── errorHandler.ts
|
|
│ │ └── helpers.ts
|
|
│ │
|
|
│ ├── routes/ # React Router configuration
|
|
│ │ ├── AppRoutes.tsx
|
|
│ │ ├── PrivateRoute.tsx
|
|
│ │ └── PublicRoute.tsx
|
|
│ │
|
|
│ └── config/ # Frontend configuration
|
|
│ ├── api.config.ts
|
|
│ ├── theme.config.ts
|
|
│ └── constants.config.ts
|
|
│
|
|
├── dist/ # Build output (Vite)
|
|
│
|
|
├── tests/ # Test files
|
|
│ ├── components/
|
|
│ ├── pages/
|
|
│ ├── redux/
|
|
│ ├── services/
|
|
│ └── setup.js
|
|
│
|
|
├── docs/ # Component documentation
|
|
│ └── storybook/
|
|
│
|
|
├── nginx/ # Nginx configuration for production
|
|
│ └── default.conf
|
|
│
|
|
├── .env.example
|
|
├── .env.development
|
|
├── .env.production
|
|
├── .eslintrc.json
|
|
├── .prettierrc
|
|
├── .gitignore
|
|
├── .dockerignore
|
|
├── Dockerfile
|
|
├── vite.config.ts # Vite configuration
|
|
├── tsconfig.json # TypeScript configuration
|
|
├── package.json
|
|
├── package-lock.json
|
|
└── README.md
|
|
```
|
|
|
|
---
|
|
|
|
## 4. TypeScript Configuration
|
|
|
|
### `tsconfig.json`
|
|
|
|
```json
|
|
{
|
|
"compilerOptions": {
|
|
"target": "ES2020",
|
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
"jsx": "react-jsx",
|
|
"module": "esnext",
|
|
"moduleResolution": "node",
|
|
"resolveJsonModule": true,
|
|
"allowJs": true,
|
|
"strict": true,
|
|
"esModuleInterop": true,
|
|
"skipLibCheck": true,
|
|
"forceConsistentCasingInFileNames": true,
|
|
"noImplicitAny": true,
|
|
"strictNullChecks": true,
|
|
"strictFunctionTypes": true,
|
|
"noUnusedLocals": true,
|
|
"noUnusedParameters": true,
|
|
"noImplicitReturns": true,
|
|
"noFallthroughCasesInSwitch": true,
|
|
"allowSyntheticDefaultImports": true,
|
|
"isolatedModules": true,
|
|
"noEmit": true,
|
|
"baseUrl": "./src",
|
|
"paths": {
|
|
"@/*": ["./*"],
|
|
"@components/*": ["components/*"],
|
|
"@pages/*": ["pages/*"],
|
|
"@services/*": ["services/*"],
|
|
"@redux/*": ["redux/*"],
|
|
"@hooks/*": ["hooks/*"],
|
|
"@utils/*": ["utils/*"],
|
|
"@types/*": ["types/*"],
|
|
"@config/*": ["config/*"],
|
|
"@assets/*": ["assets/*"]
|
|
}
|
|
},
|
|
"include": ["src"],
|
|
"exclude": ["node_modules", "build", "dist"]
|
|
}
|
|
```
|
|
|
|
### `vite.config.ts`
|
|
|
|
```typescript
|
|
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import path from 'path';
|
|
|
|
export default defineConfig({
|
|
plugins: [react()],
|
|
resolve: {
|
|
alias: {
|
|
'@': path.resolve(__dirname, './src'),
|
|
'@components': path.resolve(__dirname, './src/components'),
|
|
'@pages': path.resolve(__dirname, './src/pages'),
|
|
'@services': path.resolve(__dirname, './src/services'),
|
|
'@redux': path.resolve(__dirname, './src/redux'),
|
|
'@hooks': path.resolve(__dirname, './src/hooks'),
|
|
'@utils': path.resolve(__dirname, './src/utils'),
|
|
'@types': path.resolve(__dirname, './src/types'),
|
|
'@config': path.resolve(__dirname, './src/config'),
|
|
'@assets': path.resolve(__dirname, './src/assets'),
|
|
},
|
|
},
|
|
server: {
|
|
port: 3000,
|
|
proxy: {
|
|
'/api': {
|
|
target: 'http://localhost:5000',
|
|
changeOrigin: true,
|
|
},
|
|
},
|
|
},
|
|
build: {
|
|
outDir: 'dist',
|
|
sourcemap: true,
|
|
},
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## 5. State Management (Redux Toolkit)
|
|
|
|
### Redux Store Configuration
|
|
|
|
#### `src/redux/store.ts`
|
|
|
|
```typescript
|
|
import { configureStore } from '@reduxjs/toolkit';
|
|
import authReducer from './slices/authSlice';
|
|
import workflowReducer from './slices/workflowSlice';
|
|
import approvalReducer from './slices/approvalSlice';
|
|
import notificationReducer from './slices/notificationSlice';
|
|
import documentReducer from './slices/documentSlice';
|
|
import workNoteReducer from './slices/workNoteSlice';
|
|
import participantReducer from './slices/participantSlice';
|
|
import uiReducer from './slices/uiSlice';
|
|
|
|
export const store = configureStore({
|
|
reducer: {
|
|
auth: authReducer,
|
|
workflow: workflowReducer,
|
|
approval: approvalReducer,
|
|
notification: notificationReducer,
|
|
document: documentReducer,
|
|
workNote: workNoteReducer,
|
|
participant: participantReducer,
|
|
ui: uiReducer,
|
|
},
|
|
middleware: (getDefaultMiddleware) =>
|
|
getDefaultMiddleware({
|
|
serializableCheck: {
|
|
ignoredActions: ['persist/PERSIST'],
|
|
},
|
|
}),
|
|
});
|
|
|
|
export type RootState = ReturnType<typeof store.getState>;
|
|
export type AppDispatch = typeof store.dispatch;
|
|
```
|
|
|
|
### Typed Redux Hooks
|
|
|
|
#### `src/redux/hooks.ts`
|
|
|
|
```typescript
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
import type { TypedUseSelectorHook } from 'react-redux';
|
|
import type { RootState, AppDispatch } from './store';
|
|
|
|
// Use throughout your app instead of plain `useDispatch` and `useSelector`
|
|
export const useAppDispatch: () => AppDispatch = useDispatch;
|
|
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|
|
```
|
|
|
|
### Type Definitions
|
|
|
|
#### `src/types/common.types.ts`
|
|
|
|
```typescript
|
|
export enum Priority {
|
|
STANDARD = 'STANDARD',
|
|
EXPRESS = 'EXPRESS'
|
|
}
|
|
|
|
export enum WorkflowStatus {
|
|
DRAFT = 'DRAFT',
|
|
PENDING = 'PENDING',
|
|
IN_PROGRESS = 'IN_PROGRESS',
|
|
APPROVED = 'APPROVED',
|
|
REJECTED = 'REJECTED',
|
|
CLOSED = 'CLOSED'
|
|
}
|
|
|
|
export interface ApiResponse<T = any> {
|
|
success: boolean;
|
|
message: string;
|
|
data?: T;
|
|
error?: string;
|
|
timestamp: string;
|
|
}
|
|
|
|
export interface PaginatedResponse<T> {
|
|
data: T[];
|
|
pagination: {
|
|
page: number;
|
|
limit: number;
|
|
total: number;
|
|
totalPages: number;
|
|
};
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Component Structure
|
|
|
|
### Example: Button Component
|
|
|
|
#### `src/components/common/Button/Button.tsx`
|
|
|
|
```typescript
|
|
import React from 'react';
|
|
import styles from './Button.module.css';
|
|
|
|
interface ButtonProps {
|
|
label: string;
|
|
onClick: () => void;
|
|
variant?: 'primary' | 'secondary' | 'danger';
|
|
disabled?: boolean;
|
|
fullWidth?: boolean;
|
|
}
|
|
|
|
const Button: React.FC<ButtonProps> = ({
|
|
label,
|
|
onClick,
|
|
variant = 'primary',
|
|
disabled = false,
|
|
fullWidth = false,
|
|
}) => {
|
|
return (
|
|
<button
|
|
className={`${styles.button} ${styles[variant]} ${
|
|
fullWidth ? styles.fullWidth : ''
|
|
}`}
|
|
onClick={onClick}
|
|
disabled={disabled}
|
|
>
|
|
{label}
|
|
</button>
|
|
);
|
|
};
|
|
|
|
export default Button;
|
|
```
|
|
|
|
#### `src/components/common/Button/Button.types.ts`
|
|
|
|
```typescript
|
|
export interface ButtonProps {
|
|
label: string;
|
|
onClick: () => void;
|
|
variant?: 'primary' | 'secondary' | 'danger';
|
|
disabled?: boolean;
|
|
fullWidth?: boolean;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Configuration Management
|
|
|
|
### Environment Variables
|
|
|
|
#### `.env.example`
|
|
|
|
```bash
|
|
# frontend/.env.example
|
|
|
|
# Application
|
|
REACT_APP_ENV=development
|
|
REACT_APP_NAME=RE Workflow Management
|
|
REACT_APP_VERSION=1.0.0
|
|
|
|
# API Configuration
|
|
REACT_APP_API_BASE_URL=http://localhost:5000/api/v1
|
|
REACT_APP_API_TIMEOUT=30000
|
|
|
|
# SSO Configuration
|
|
REACT_APP_SSO_LOGIN_URL=http://localhost:5000/api/v1/auth/login
|
|
REACT_APP_SSO_LOGOUT_URL=http://localhost:5000/api/v1/auth/logout
|
|
|
|
# Feature Flags
|
|
REACT_APP_ENABLE_NOTIFICATIONS=true
|
|
REACT_APP_ENABLE_EMAIL_NOTIFICATIONS=false
|
|
REACT_APP_ENABLE_ANALYTICS=true
|
|
|
|
# File Upload
|
|
REACT_APP_MAX_FILE_SIZE_MB=10
|
|
REACT_APP_ALLOWED_FILE_TYPES=pdf,doc,docx,xls,xlsx,ppt,pptx,jpg,jpeg,png,gif
|
|
|
|
# Google Integration
|
|
REACT_APP_GOOGLE_API_KEY=your_google_api_key
|
|
|
|
# UI Configuration
|
|
REACT_APP_THEME_PRIMARY_COLOR=#1976d2
|
|
REACT_APP_ITEMS_PER_PAGE=20
|
|
```
|
|
|
|
### API Configuration
|
|
|
|
#### `src/config/api.config.ts`
|
|
|
|
```typescript
|
|
export const API_CONFIG = {
|
|
baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:5000/api/v1',
|
|
timeout: parseInt(import.meta.env.VITE_API_TIMEOUT || '30000'),
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
};
|
|
|
|
export const API_ENDPOINTS = {
|
|
auth: {
|
|
login: '/auth/login',
|
|
logout: '/auth/logout',
|
|
me: '/auth/me',
|
|
},
|
|
workflows: {
|
|
getAll: '/workflows',
|
|
create: '/workflows',
|
|
getById: (id: string) => `/workflows/${id}`,
|
|
update: (id: string) => `/workflows/${id}`,
|
|
submit: (id: string) => `/workflows/${id}/submit`,
|
|
},
|
|
// ... more endpoints
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Deployment Architecture
|
|
|
|
### Dockerfile
|
|
|
|
#### `Dockerfile`
|
|
|
|
```dockerfile
|
|
# re-workflow-frontend/Dockerfile
|
|
|
|
FROM node:22-alpine AS builder
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy package files
|
|
COPY package*.json ./
|
|
|
|
# Install dependencies
|
|
RUN npm ci
|
|
|
|
# Copy source code
|
|
COPY . .
|
|
|
|
# Build application with Vite
|
|
RUN npm run build
|
|
|
|
# =====================================
|
|
# Production Image with Nginx
|
|
# =====================================
|
|
FROM nginx:alpine
|
|
|
|
# Copy custom nginx config
|
|
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
|
|
|
|
# Copy built files from builder (Vite outputs to 'dist' by default)
|
|
COPY --from=builder /app/dist /usr/share/nginx/html
|
|
|
|
# Expose port
|
|
EXPOSE 80
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=3s \
|
|
CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1
|
|
|
|
CMD ["nginx", "-g", "daemon off;"]
|
|
```
|
|
|
|
### Nginx Configuration
|
|
|
|
#### `nginx/default.conf`
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name localhost;
|
|
root /usr/share/nginx/html;
|
|
index index.html;
|
|
|
|
# Gzip compression
|
|
gzip on;
|
|
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
|
|
|
# Security headers
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header X-XSS-Protection "1; mode=block" always;
|
|
|
|
# React Router support
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
|
|
# Cache static assets
|
|
location /assets/ {
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable";
|
|
}
|
|
|
|
# Health check endpoint
|
|
location /health {
|
|
access_log off;
|
|
return 200 "healthy\n";
|
|
add_header Content-Type text/plain;
|
|
}
|
|
}
|
|
```
|
|
|
|
### CI/CD Pipeline (GitHub Actions)
|
|
|
|
#### `.github/workflows/frontend-deploy.yml`
|
|
|
|
```yaml
|
|
# .github/workflows/frontend-deploy.yml
|
|
|
|
name: Frontend CI/CD
|
|
|
|
on:
|
|
push:
|
|
branches: [main, develop]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
test-and-build:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '22'
|
|
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
- name: Run linter
|
|
run: npm run lint
|
|
|
|
- name: Run tests
|
|
run: npm test
|
|
|
|
- name: Build application
|
|
run: npm run build
|
|
|
|
- name: Build Docker image
|
|
run: docker build -t gcr.io/re-project/re-workflow-frontend:${{ github.sha }} .
|
|
|
|
- name: Push to GCR
|
|
run: docker push gcr.io/re-project/re-workflow-frontend:${{ github.sha }}
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Development Setup Instructions
|
|
|
|
### 9.1 Prerequisites
|
|
|
|
- **Node.js:** v22.x LTS
|
|
- **npm:** v10.x or higher
|
|
- **Git:** Latest version
|
|
- **TypeScript:** v5.7.x (installed as dev dependency)
|
|
- **Backend API:** Running on `http://localhost:5000` (see backend documentation)
|
|
|
|
### 9.2 Local Development Setup
|
|
|
|
#### Step 1: Clone Frontend Repository
|
|
|
|
```bash
|
|
git clone https://github.com/royalenfield/re-workflow-frontend.git
|
|
cd re-workflow-frontend
|
|
```
|
|
|
|
#### Step 2: Configure Frontend Environment
|
|
|
|
```bash
|
|
# Copy environment file
|
|
cp .env.example .env
|
|
|
|
# Edit .env with backend API URL
|
|
nano .env # or use your preferred editor
|
|
|
|
# Set REACT_APP_API_BASE_URL=http://localhost:5000/api/v1
|
|
```
|
|
|
|
#### Step 3: Install Dependencies & Run Frontend
|
|
|
|
```bash
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Run TypeScript type checking
|
|
npm run type-check
|
|
|
|
# Start development server (Vite with hot reload)
|
|
npm run dev
|
|
|
|
# Frontend will run on: http://localhost:3000
|
|
```
|
|
|
|
#### Step 4: Access Application
|
|
|
|
- **Frontend:** http://localhost:3000
|
|
- **Backend API:** http://localhost:5000
|
|
- **API Documentation:** http://localhost:5000/api-docs
|
|
- **Health Check:** http://localhost:5000/health
|
|
|
|
### 9.3 Docker Setup
|
|
|
|
```bash
|
|
# From frontend repository root
|
|
cd re-workflow-frontend
|
|
|
|
# Copy environment file
|
|
cp .env.example .env
|
|
|
|
# Build Docker image
|
|
docker build -t re-workflow-frontend .
|
|
|
|
# Run frontend container
|
|
docker run -d -p 3000:80 --name frontend re-workflow-frontend
|
|
|
|
# Access frontend: http://localhost:3000
|
|
|
|
# Stop container
|
|
docker stop frontend
|
|
docker rm frontend
|
|
```
|
|
|
|
### 9.4 Running Tests
|
|
|
|
```bash
|
|
# From frontend repository
|
|
cd re-workflow-frontend
|
|
|
|
npm test # Run all tests (Vitest)
|
|
npm run test:ui # Interactive UI mode (Vitest)
|
|
npm run test:coverage # With coverage report
|
|
|
|
# Coverage report will be in: coverage/
|
|
```
|
|
|
|
### 9.5 Code Quality Checks
|
|
|
|
```bash
|
|
# From frontend repository
|
|
cd re-workflow-frontend
|
|
|
|
npm run lint # ESLint check (React + TypeScript rules)
|
|
npm run lint:fix # Auto-fix issues
|
|
npm run format # Prettier formatting
|
|
npm run type-check # TypeScript type checking only (no build)
|
|
|
|
# Run all quality checks together
|
|
npm run lint && npm run type-check && npm test
|
|
```
|
|
|
|
### 9.6 Git Workflow
|
|
|
|
```bash
|
|
# Feature branch workflow
|
|
git checkout -b feature/your-feature-name
|
|
git add .
|
|
git commit -m "feat: add your feature description"
|
|
git push origin feature/your-feature-name
|
|
|
|
# Create Pull Request on GitHub/GitLab
|
|
# After approval and merge:
|
|
git checkout main
|
|
git pull origin main
|
|
```
|
|
|
|
**Branch Strategy:**
|
|
- `main` - Production-ready code
|
|
- `develop` - Integration branch for features
|
|
- `feature/*` - New features
|
|
- `bugfix/*` - Bug fixes
|
|
- `hotfix/*` - Production hotfixes
|
|
|
|
**Commit Message Convention (Conventional Commits):**
|
|
- `feat:` - New feature
|
|
- `fix:` - Bug fix
|
|
- `docs:` - Documentation changes
|
|
- `style:` - Code style changes (formatting)
|
|
- `refactor:` - Code refactoring
|
|
- `test:` - Test additions or changes
|
|
- `chore:` - Build process or tool changes
|
|
|
|
---
|
|
|
|
## 10. Package.json
|
|
|
|
```json
|
|
{
|
|
"name": "re-workflow-frontend",
|
|
"version": "1.0.0",
|
|
"description": "Royal Enfield Workflow Management System - Frontend (TypeScript)",
|
|
"private": true,
|
|
"dependencies": {
|
|
"react": "^19.0.0",
|
|
"react-dom": "^19.0.0",
|
|
"react-router-dom": "^7.1.1",
|
|
"@reduxjs/toolkit": "^2.5.0",
|
|
"react-redux": "^9.2.0",
|
|
"@mui/material": "^6.3.0",
|
|
"@mui/icons-material": "^6.3.0",
|
|
"@emotion/react": "^11.14.0",
|
|
"@emotion/styled": "^11.14.0",
|
|
"axios": "^1.7.9",
|
|
"formik": "^2.4.6",
|
|
"yup": "^1.6.3",
|
|
"zod": "^3.24.1",
|
|
"react-dropzone": "^14.3.5",
|
|
"date-fns": "^4.1.0",
|
|
"recharts": "^2.15.0",
|
|
"react-toastify": "^11.0.2"
|
|
},
|
|
"devDependencies": {
|
|
"@types/react": "^19.0.6",
|
|
"@types/react-dom": "^19.0.2",
|
|
"@types/node": "^22.10.5",
|
|
"typescript": "^5.7.2",
|
|
"vite": "^6.0.7",
|
|
"@vitejs/plugin-react": "^4.3.4",
|
|
"@testing-library/react": "^16.1.0",
|
|
"@testing-library/jest-dom": "^6.6.3",
|
|
"@testing-library/user-event": "^14.5.2",
|
|
"eslint": "^9.17.0",
|
|
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
"@typescript-eslint/parser": "^8.19.1",
|
|
"prettier": "^3.4.2",
|
|
"vitest": "^2.1.8"
|
|
},
|
|
"scripts": {
|
|
"dev": "vite",
|
|
"build": "tsc && vite build",
|
|
"preview": "vite preview",
|
|
"test": "vitest",
|
|
"test:ui": "vitest --ui",
|
|
"test:coverage": "vitest --coverage",
|
|
"lint": "eslint src/**/*.{ts,tsx}",
|
|
"lint:fix": "eslint src/**/*.{ts,tsx} --fix",
|
|
"format": "prettier --write \"src/**/*.{ts,tsx,css}\"",
|
|
"type-check": "tsc --noEmit"
|
|
},
|
|
"eslintConfig": {
|
|
"extends": ["react-app", "react-app/jest"]
|
|
},
|
|
"browserslist": {
|
|
"production": [">0.2%", "not dead", "not op_mini all"],
|
|
"development": ["last 1 chrome version", "last 1 firefox version", "last 1 safari version"]
|
|
},
|
|
"engines": {
|
|
"node": ">=22.0.0",
|
|
"npm": ">=10.0.0"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
This frontend documentation provides:
|
|
|
|
✅ **Complete Frontend Architecture** - React SPA with Vite, Redux Toolkit, TypeScript
|
|
✅ **Technology Stack** - React 19 + TypeScript 5.7 + Vite 6.0 + Material-UI 6.3
|
|
✅ **Folder Structure** - Detailed organization with TypeScript conventions
|
|
✅ **Type Definitions** - Comprehensive type safety with interfaces and enums
|
|
✅ **Redux Toolkit Setup** - Fully typed state management
|
|
✅ **Component Structure** - Reusable, testable components
|
|
✅ **Configuration Management** - Environment variables and settings
|
|
✅ **Deployment Architecture** - Docker, Nginx, CI/CD pipelines
|
|
✅ **Development Setup** - Step-by-step installation and configuration
|
|
✅ **Testing Strategy** - Vitest and React Testing Library
|
|
✅ **Code Quality** - ESLint, Prettier, TypeScript best practices
|
|
|
|
**Technology Stack:** React 19 + TypeScript 5.7 + Vite 6.0 + Redux Toolkit 2.5 + Material-UI 6.3
|
|
**Repository:** `re-workflow-frontend` (Independent Repository)
|
|
**Status:** ✅ Ready for Implementation
|
|
|