87dadf1def
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>
6.6 KiB
6.6 KiB
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-uidesign system. UsesHashRouterfor client-side routing.
See docs/ARCHITECTURE.md for the full architecture document.
Prerequisites
- Node.js >= 18
- npm >= 9
- Local sibling packages (linked via
file:references inpackage.json):@ampeco/design-tokensat../design-tokens@ampeco/ewa-uiat../ewa-ui
Setup
- 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
- Copy the example environment file and configure it:
cp .env.example .env
- Edit
.envwith 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 |
- Install dependencies:
npm install
- Start the development servers:
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
developmentmode, if no JWT is provided, the backend falls back to a default session withuserId: 775. - If the fallback session has no
userId(set tonull), the frontend displays aUserIdFallbackpage where you can manually enter a user ID. - Use
POST /dev/jwtto generate a JWT token with custom session overrides. See docs/USER-GUIDE.md for details.