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