packages
This commit is contained in:
120
README.md
Normal file
120
README.md
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
# Inventory Frontend Service
|
||||||
|
|
||||||
|
Minimal React frontend for inventory management. Focus: **DevOps/CI-CD demo**, not UI complexity.
|
||||||
|
|
||||||
|
## Features (Minimal by Design)
|
||||||
|
- Display items in simple table
|
||||||
|
- Add new item form (name, quantity, price)
|
||||||
|
- Basic error handling
|
||||||
|
- That's it! No edit, delete, pagination, or filters
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
- React 19 + Vite
|
||||||
|
- Axios for API calls
|
||||||
|
- Basic CSS (no framework)
|
||||||
|
- Nginx for production serving
|
||||||
|
|
||||||
|
## Local Development
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
- Node.js 20+
|
||||||
|
- Backend service running at http://localhost:3000
|
||||||
|
|
||||||
|
### Quick Start
|
||||||
|
```bash
|
||||||
|
# 1. Install dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# 2. Create .env file
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
|
# 3. Start development server
|
||||||
|
npm run dev
|
||||||
|
# Frontend runs on http://localhost:5173
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
```bash
|
||||||
|
# Run tests
|
||||||
|
npm test
|
||||||
|
|
||||||
|
# Run linter
|
||||||
|
npm run lint
|
||||||
|
|
||||||
|
# Build for production
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| VITE_API_URL | http://localhost:3000 | Backend API URL |
|
||||||
|
|
||||||
|
## Docker Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build image
|
||||||
|
docker build -t frontend-service:latest .
|
||||||
|
|
||||||
|
# Run container
|
||||||
|
docker run -d -p 80:80 frontend-service:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## CI/CD Pipeline
|
||||||
|
|
||||||
|
Gitea Actions workflow:
|
||||||
|
1. Checkout → Install → Lint → Test → Build
|
||||||
|
2. SonarQube scan + quality gate
|
||||||
|
3. Build multi-stage Docker image (React build + nginx)
|
||||||
|
4. Push to Gitea registry with tags: `{branch}-{sha}`, `{branch}`, `latest`
|
||||||
|
5. Update k8s-manifests repo
|
||||||
|
|
||||||
|
## Component Structure
|
||||||
|
|
||||||
|
Single component (`App.jsx`) with:
|
||||||
|
- Items list table
|
||||||
|
- Add item form
|
||||||
|
- Loading/error states
|
||||||
|
- API integration via axios
|
||||||
|
|
||||||
|
**~80 lines total** - intentionally minimal!
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
frontend-service/
|
||||||
|
├── src/
|
||||||
|
│ ├── App.jsx # Single component (~80 lines)
|
||||||
|
│ ├── api.js # Axios API calls (~15 lines)
|
||||||
|
│ ├── App.css # Basic styling
|
||||||
|
│ └── main.jsx # Entry point
|
||||||
|
├── tests/
|
||||||
|
│ └── App.test.jsx # Basic component tests
|
||||||
|
├── .gitea/workflows/
|
||||||
|
│ └── ci.yaml # CI/CD pipeline
|
||||||
|
├── Dockerfile # Multi-stage build
|
||||||
|
├── nginx.conf # Production web server config
|
||||||
|
├── package.json
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
**Total: ~8 files** - focus on DevOps, not application!
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
|
Built as static files served by nginx:
|
||||||
|
- React app compiled to `/usr/share/nginx/html`
|
||||||
|
- Non-root nginx user (nginx-app:1001)
|
||||||
|
- Security headers enabled
|
||||||
|
- Gzip compression
|
||||||
|
- Asset caching with cache-busting
|
||||||
|
- SPA routing support
|
||||||
|
|
||||||
|
## API Integration
|
||||||
|
|
||||||
|
Frontend calls backend endpoints:
|
||||||
|
- `GET /api/items` - Fetch all items
|
||||||
|
- `POST /api/items` - Create new item
|
||||||
|
|
||||||
|
Backend URL configured via `VITE_API_URL` environment variable.
|
||||||
6061
package-lock.json
generated
Normal file
6061
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
34
package.json
Normal file
34
package.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend-service",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"description": "Minimal inventory management frontend for DevOps demo",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"test": "vitest"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react": "^19.2.0",
|
||||||
|
"react-dom": "^19.2.0",
|
||||||
|
"axios": "^1.6.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.39.1",
|
||||||
|
"@types/react": "^19.2.5",
|
||||||
|
"@types/react-dom": "^19.2.3",
|
||||||
|
"@vitejs/plugin-react": "^5.1.1",
|
||||||
|
"eslint": "^9.39.1",
|
||||||
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
|
"eslint-plugin-react-refresh": "^0.4.24",
|
||||||
|
"globals": "^16.5.0",
|
||||||
|
"vite": "^7.2.4",
|
||||||
|
"vitest": "^1.0.4",
|
||||||
|
"@testing-library/react": "^14.1.2",
|
||||||
|
"@testing-library/jest-dom": "^6.1.5",
|
||||||
|
"jsdom": "^23.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
14
sonar-project.properties
Normal file
14
sonar-project.properties
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
sonar.projectKey=inventory-frontend
|
||||||
|
sonar.projectName=Inventory Frontend Service
|
||||||
|
sonar.projectVersion=1.0
|
||||||
|
|
||||||
|
# Source and test paths
|
||||||
|
sonar.sources=src
|
||||||
|
sonar.tests=tests
|
||||||
|
sonar.javascript.lcov.reportPaths=coverage/lcov.info
|
||||||
|
|
||||||
|
# Exclusions
|
||||||
|
sonar.exclusions=node_modules/**,dist/**,coverage/**,tests/**,**/*.test.jsx
|
||||||
|
|
||||||
|
# Quality gate
|
||||||
|
sonar.qualitygate.wait=true
|
||||||
7
vite.config.js
Normal file
7
vite.config.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import react from '@vitejs/plugin-react'
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react()],
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user