Initial commit: booking-ewa v1.0.0

Embedded Web App for EV charging slot bookings. Express backend with JWT
auth and AMPECO Public API proxy. React SPA with booking CRUD, availability
checking, and runtime design token theming.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kaloyan Danchev
2026-03-18 19:34:13 +02:00
commit 87dadf1def
44 changed files with 8126 additions and 0 deletions
+162
View File
@@ -0,0 +1,162 @@
# Booking EWA
Embedded Web App (EWA) for managing EV charging station bookings. The application provides a mobile-optimized UI for creating, viewing, updating, and cancelling charger bookings. It is designed to be embedded within a native mobile app via a JWT-based session handoff.
## Architecture Overview
The application consists of two parts:
- **Backend** -- Express.js server (port 3001) that validates JWT tokens, manages sessions, and proxies API requests to the AMPECO public API.
- **Frontend** -- React SPA (Vite dev server on port 5173) using Tailwind CSS and the `@ampeco/ewa-ui` design system. Uses `HashRouter` for client-side routing.
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full architecture document.
## Prerequisites
- Node.js >= 18
- npm >= 9
- Local sibling packages (linked via `file:` references in `package.json`):
- `@ampeco/design-tokens` at `../design-tokens`
- `@ampeco/ewa-ui` at `../ewa-ui`
## Setup
1. Clone the repository and ensure sibling packages are present:
```
parent-directory/
booking-ewa/ <-- this project
design-tokens/ <-- @ampeco/design-tokens
ewa-ui/ <-- @ampeco/ewa-ui
```
2. Copy the example environment file and configure it:
```bash
cp .env.example .env
```
3. Edit `.env` with your values:
```
API_BASE_URL=https://your-instance.charge.ampeco.tech/public-api
API_TOKEN=your-api-token-here
JWT_SECRET=your-jwt-secret-here
PORT=3001
NODE_ENV=development
```
| Variable | Description |
|----------------|----------------------------------------------------------------|
| `API_BASE_URL` | Base URL of the AMPECO public API instance |
| `API_TOKEN` | Bearer token for authenticating with the public API |
| `JWT_SECRET` | Shared secret for signing/verifying HS256 JWT tokens |
| `PORT` | Port for the Express backend server (default: `3001`) |
| `NODE_ENV` | Set to `development` to enable dev fallback session and `/dev/jwt` endpoint |
4. Install dependencies:
```bash
npm install
```
5. Start the development servers:
```bash
npm run dev
```
This starts both the Vite dev server (http://localhost:5173) and the Express backend (http://localhost:3001) concurrently.
## Available Scripts
| Script | Description |
|-----------------|-------------------------------------------------------------|
| `npm run dev` | Start Vite frontend and Express backend in parallel |
| `npm run build` | Build the frontend (Vite) and compile the backend (TypeScript) |
| `npm run typecheck` | Run TypeScript type checking (no emit) |
## Project Structure
```
booking-ewa/
.env.example # Environment variable template
index.html # Vite HTML entry point
package.json # Dependencies and scripts
vite.config.ts # Vite config (proxy /api and /dev to backend)
tailwind.config.ts # Tailwind CSS with ewa-ui plugin
postcss.config.js # PostCSS (Tailwind + Autoprefixer)
tsconfig.json # Frontend TypeScript config
backend/
tsconfig.json # Backend TypeScript config
src/
index.ts # Express server entry, JWT middleware, dev fallback
jwt.ts # JWT verification and dev token creation
proxy.ts # Generic API proxy utility
routes.ts # Route definitions (session, bookings, availability)
types.ts # Backend type definitions (JwtPayload, SessionData)
src/
main.tsx # React entry point
App.tsx # Root component (SessionProvider + routing guard)
app.css # Global styles (design-tokens CSS variables, Tailwind)
env.d.ts # TypeScript ambient declarations
api/
client.ts # Fetch wrapper with error handling (ApiRequestError)
bookings.ts # Booking list/detail API functions
bookingRequests.ts # Create/update/cancel booking request API
availability.ts # Check availability API
context/
SessionContext.tsx # React context for session state and theme application
hooks/
useSession.ts # Hook to consume SessionContext
useBookings.ts # Hooks for booking list and detail (with polling)
useAvailability.ts # Hook for availability checking
components/
Layout/Layout.tsx # App shell with bottom tab navigation
BookingCard/BookingCard.tsx # Booking summary card
AvailabilitySlots/AvailabilitySlots.tsx # Slot selection grid
DateTimePicker/DateTimePicker.tsx # datetime-local input wrapper
pages/
Home/Home.tsx # Dashboard with upcoming bookings
CreateBooking/CreateBooking.tsx # Two-step booking creation flow
MyBookings/MyBookings.tsx # Upcoming/Past tabs
BookingDetail/BookingDetail.tsx # Detail view with cancel action
UpdateBooking/UpdateBooking.tsx # Edit booking time range
UserIdFallback/UserIdFallback.tsx # Manual user ID entry (dev mode)
router/
index.tsx # HashRouter route definitions
types/
index.ts # Frontend type definitions (Booking, BookingRequest, etc.)
i18n/
init.ts # i18next initialization
locales/
en.json # English translations
```
## Key Dependencies
| Package | Purpose |
|-------------------------|------------------------------------------------------|
| `@ampeco/design-tokens` | CSS custom properties for theming (LIGHT/DARK) |
| `@ampeco/ewa-ui` | Shared UI component library and Tailwind plugin |
| `react-router-dom` | Client-side routing (HashRouter) |
| `i18next` / `react-i18next` | Internationalization |
| `lucide-react` | Icon library |
| `express` | Backend HTTP server |
| `jsonwebtoken` | JWT signing and verification |
## Development Notes
- In `development` mode, if no JWT is provided, the backend falls back to a default session with `userId: 775`.
- If the fallback session has no `userId` (set to `null`), the frontend displays a `UserIdFallback` page where you can manually enter a user ID.
- Use `POST /dev/jwt` to generate a JWT token with custom session overrides. See [docs/USER-GUIDE.md](docs/USER-GUIDE.md) for details.