# AdAstra App Frontend of the AdAstra platform — a multi-domain Angular application covering e-commerce, CMS, skydive club management, and Hero Wars guild analytics. ## Tech stack | Layer | Choice | | --------- | ------------------------------------------------------------------ | | Framework | Angular 21 (standalone components, no NgModules) | | Language | TypeScript 5.9 — strict mode + strictTemplates | | UI | Angular Material 21, Bootstrap 5 | | Charts | Chart.js 4 (ng2-charts), Chartist | | HTTP | Angular HttpClient with three interceptors (base URL, JWT, errors) | | Tests | Karma + Jasmine | | Linting | angular-eslint + Prettier (enforced via lint-staged) | | Node | `^20.19.0 \|\| ^22.12.0` | ## Related repository The backend API lives in [`adastra_api`](../adastra_api) — an Express + Sequelize stack, routes grouped under `/api/ecommerce`, `/api/cms`, `/api/skydive`, `/api/herowars`. ## Getting started ```bash npm install npm run local # dev server on :4400, uses environment.local.ts ``` Copy and configure your local environment: ```bash cp src/environments/environment.example.ts src/environments/environment.local.ts # fill in: apiBaseUrl, apiKey, googleMapApiKey, … ``` ## Commands | Command | Description | | --------------- | ----------------------------------------------------- | | `npm start` | Dev server on :4200 with production config | | `npm run dev` | Dev server on :4300 with `environment.development.ts` | | `npm run local` | Dev server on :4400 with `environment.local.ts` | | `npm run build` | Production build → `dist/adastra_angular/` | | `npm run watch` | Incremental build in development configuration | | `npm run lint` | angular-eslint on `**/*.ts` and `**/*.html` | | `npm test` | Karma + Jasmine unit tests | Run a single spec: ```bash ng test --include src/path/to/file.spec.ts ``` ## Architecture ### Bootstrap `AppComponent` renders a single `FullComponent` shell (Material sidenav + toolbar). Routes are split into two arrays in `app.routes.ts`: - `auth.routes.ts` — protected by `authGuard`; admin sections additionally require `adminGuard` - `noauth.routes.ts` — public pages and auth entry points, blocked by `noauthGuard` when already authenticated Data is pre-fetched by resolvers under `src/app/core/resolvers/` — new route components should follow this pattern rather than fetching in `ngOnInit`. ### HTTP pipeline Three interceptors applied in order: 1. **`apiInterceptor`** — prepends `environment.apiBaseUrl` to every request. Services use relative paths (`/cms/user`, `/skydive/jumps`, …), never absolute URLs. 2. **`tokenInterceptor`** — attaches `Authorization: Token ` when a token exists in `localStorage['jwtToken']`. 3. **`errorInterceptor`** — unwraps `err.error` and rethrows. ### Feature domains | Domain | Routes | Backend prefix | | ---------- | ------------------------------------------------------ | ---------------- | | E-commerce | `products`, `product/:slug`, `products/:category` | `/api/ecommerce` | | CMS | `pages`, `page/:slug`, `home`, profiles, articles | `/api/cms` | | Skydive | `skydive/*` — aeronefs, canopies, dropzones, jumps | `/api/skydive` | | Hero Wars | Guild analytics, weekly snapshots in `src/files-data/` | `/api/herowars` | ### Path aliases Defined in `tsconfig.json`; always prefer them over relative imports: ``` @components @services @models @guards @interceptors @resolvers @viewmodels @interfaces @constants @core/* @environments/* @data/* @assets/* @styles/* ``` When adding a new file, export it from the appropriate `index.ts` barrel so the alias resolves correctly. ### Styling SCSS with `includePaths: ["src/styles"]` — imports like `@use 'variables'` resolve globally. Material date locale is set to `fr-FR` with `DD/MM/YYYY` format.