Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
16986d1
feat(UI): added UI implementation from figma designs
Chunky101 May 14, 2026
bc67e3b
Add Arcane Vi 5K wallpaper for landing carousel.
Chunky101 May 19, 2026
0426094
Add Caitlyn Arcane wallpaper for landing carousel.
Chunky101 May 19, 2026
dd8bfe5
Add Jinx Arcane wallpaper for landing carousel.
Chunky101 May 19, 2026
b3dbf7f
Add Jinx Netflix series wallpaper for landing carousel.
Chunky101 May 19, 2026
349f1db
Add Jinx Arcane PUBG wallpaper for landing carousel.
Chunky101 May 19, 2026
e765b60
Add Jinx BGMI PUBG crossover wallpaper for landing carousel.
Chunky101 May 19, 2026
eaff63a
Add Jinx graffiti wallpaper for landing carousel.
Chunky101 May 19, 2026
0cbc852
Add Jinx pink aesthetic wallpaper for landing carousel.
Chunky101 May 19, 2026
636fbf3
Add Jinx poster Arcane wallpaper for landing carousel.
Chunky101 May 19, 2026
5aebaf4
Add Jinx and Vi Arcane 5K wallpaper for landing carousel.
Chunky101 May 19, 2026
70733c6
Add League of Legends wallpaper for landing carousel.
Chunky101 May 19, 2026
3b33428
Add wide League of Legends wallpaper for landing carousel.
Chunky101 May 19, 2026
aafdcce
Add Prestige Commander wallpaper for landing carousel.
Chunky101 May 19, 2026
2865aad
Add Samira 2021 games wallpaper for landing carousel.
Chunky101 May 19, 2026
08b77cf
Add Samira wallpaper for landing carousel.
Chunky101 May 19, 2026
94f1470
Add Vi PUBG Mobile wallpaper for landing carousel.
Chunky101 May 19, 2026
d997ecd
Add shared LoL wallpaper loader for landing carousels.
Chunky101 May 19, 2026
dba2dbe
Use LoL wallpapers on the landing page carousel.
Chunky101 May 19, 2026
2124b1c
Use LoL wallpapers on the login page carousel.
Chunky101 May 19, 2026
ef3648e
Use LoL wallpapers on the register page carousel.
Chunky101 May 19, 2026
1940a1f
Add MatchDetail types for match expanded view.
Chunky101 May 19, 2026
259a892
Add mock match detail fixtures for dashboard modal.
Chunky101 May 19, 2026
d273764
Add mock fetchMatchDetail client with simulated latency.
Chunky101 May 19, 2026
50fbc0b
Add Data Dragon URL helpers for champion and item icons.
Chunky101 May 19, 2026
39433fa
Add MatchDetailModal for expanded match stats view.
Chunky101 May 19, 2026
aac955c
Wire match detail modal state and URL deep link on dashboard.
Chunky101 May 19, 2026
7712b59
Make dashboard match cards open the match detail modal.
Chunky101 May 19, 2026
16f6f18
Sonar fixes
Chunky101 May 19, 2026
5c084ee
Add TypeScript types for the player profile dashboard view.
Chunky101 May 19, 2026
02ca23d
Add mock player profile data for dashboard profile development.
Chunky101 May 19, 2026
5cc1d14
Add radar chart component for player performance metrics.
Chunky101 May 19, 2026
405c8ed
Add profile view with stats, radar chart, and recent champions.
Chunky101 May 19, 2026
98977ef
Wire dashboard sidebar to switch between matches and profile views.
Chunky101 May 19, 2026
650874e
Manage dashboard active view state for matches and profile tabs.
Chunky101 May 19, 2026
838185b
Add hero headline and subheading to the landing page.
Chunky101 May 19, 2026
3b74e7b
Add champion splash URL helper for match history cards.
Chunky101 May 19, 2026
6d3eed6
Add mock match history data grouped by day.
Chunky101 May 19, 2026
2056a38
Improve dashboard match history with dates, paging, and standard icons.
Chunky101 May 19, 2026
6addbbb
Remove placeholder footer from match detail modal.
Chunky101 May 19, 2026
3e970a6
Update featured game slide types for expandable card states.
Chunky101 May 19, 2026
afbba05
Add profile featured-game asset exports from Figma.
Chunky101 May 19, 2026
0c5c4f6
Add Wild Rift cover image for profile featured card.
Chunky101 May 19, 2026
f50a896
Add Wild Rift card image for collapsed profile featured state.
Chunky101 May 19, 2026
16d47be
Add efficiency score icon for profile featured card.
Chunky101 May 19, 2026
4f3e445
Add time spent icon for profile featured card.
Chunky101 May 19, 2026
02d8d1d
Use local Figma assets for featured game mock profile data.
Chunky101 May 19, 2026
b3236c3
Add expandable featured game card matching Figma open and closed states.
Chunky101 May 19, 2026
58f002b
Map profile achievements to Lucide icons for badge display.
Chunky101 May 19, 2026
7a26c6e
Integrate featured game card and Lucide achievement badges in profile…
Chunky101 May 19, 2026
c215316
Fix sidebar profile avatar layout and rename Dashboard nav label to M…
Chunky101 May 19, 2026
3d7a2a5
Update match detail error copy to refer to matches instead of dashboard.
Chunky101 May 19, 2026
9d45ddc
fixed the landing page to not block the background elements
Chunky101 May 20, 2026
f3514f0
added a list view and removed champion card
Chunky101 May 20, 2026
78a87d8
migrated the user profile dropdown to the top right of the page
Chunky101 May 20, 2026
a61640e
refined left panel
Chunky101 May 20, 2026
4126a86
added loading screen
Chunky101 May 20, 2026
2ba21c6
added the filter and sort
Chunky101 May 20, 2026
84578b8
updated the gamecard
Chunky101 May 21, 2026
85a57e4
Merge branch 'dev' into UI-implementation
Chunky101 May 21, 2026
cdcd23d
Merge pull request #74 from COS301-SE-2026/dev
Life220 May 21, 2026
b8b91d5
Merge pull request #80 from COS301-SE-2026/dev
Life220 May 22, 2026
1e63fcd
frontend ready for demo
Chunky101 May 22, 2026
07a2f64
Merge main into UI-implementation
Chunky101 May 22, 2026
f77b184
Merge branch 'dev' into UI-implementation
Chunky101 May 22, 2026
78b1bb4
fixed vulnerabilities
Chunky101 May 22, 2026
df8ba1e
fixed CI errors
Chunky101 May 22, 2026
f8c1a8f
remove uploads
Chunky101 May 22, 2026
d5d2104
fixed sonar errors
Chunky101 May 22, 2026
15444b8
fixed ci errors
Chunky101 May 22, 2026
8126350
added brand-style-guide
Chunky101 May 22, 2026
4c1b02f
added dev setup
Chunky101 May 22, 2026
8699bbb
Solved conflicts
Life220 May 22, 2026
e505971
Badges updated
Life220 May 22, 2026
90a02bc
Conflict resolution
Life220 May 22, 2026
842e1eb
Updated package-lock.json
Life220 May 22, 2026
eb17fd5
Workflow updates
Life220 May 22, 2026
5139b6c
Weird black fix
Life220 May 22, 2026
5174338
package-lock.json
Life220 May 22, 2026
614b87a
Main.py import fix
Life220 May 22, 2026
476899c
Backend fixes + Updated Pytest
Life220 May 22, 2026
0155f52
Badges + backend fixes
Life220 May 22, 2026
cc1d2b6
Badges + main fix
Life220 May 22, 2026
f234512
Commented out failing tests
Life220 May 22, 2026
c1d2a82
badges
Life220 May 22, 2026
f455e32
Ruff lint fix
Life220 May 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
226 changes: 226 additions & 0 deletions .github/docs/Brand-Style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
# 4.2.1 Brand Style

The brand style defines the visual identity of Vantage Point and ensures a consistent, professional appearance across all interfaces. This document reflects what is **implemented in the codebase** today (`frontend/src`), not aspirational guidelines.

---

## Color Palette

Vantage Point uses two complementary colour systems:

1. **Design tokens** — CSS variables in `frontend/src/styles/theme.css`, consumed by shadcn/ui components via Tailwind (`bg-primary`, `text-muted-foreground`, etc.).
2. **Figma / screen-specific hex values** — hard-coded on auth screens, the dashboard shell, and match views (primarily Inter-based layouts).

### Semantic tokens (light mode)

Defined in `:root` in `theme.css`:

| Role | Value | Usage |
|------|-------|--------|
| Background | `#ffffff` | Page and card surfaces |
| Foreground | `oklch(0.145 0 0)` | Primary text |
| Primary | `#030213` | Primary actions, emphasis |
| Primary foreground | `oklch(1 0 0)` | Text on primary |
| Secondary | `oklch(0.95 0.0058 264.53)` | Secondary surfaces |
| Muted | `#ececf0` / muted-foreground `#717182` | Subtle UI, secondary text |
| Accent | `#e9ebef` | Hover / highlight surfaces |
| Destructive | `#d4183d` | Errors, destructive actions |
| Border | `rgba(0, 0, 0, 0.1)` | Dividers and outlines |
| Input background | `#f3f3f5` | Form fields (shadcn `Input`) |
| Ring (focus) | `oklch(0.708 0 0)` | Focus rings on interactive controls |
| Chart 1–5 | OKLCH palette | Radar chart and data viz |

A **dark mode** palette is also defined under `.dark` in the same file (used by shadcn primitives). The main app screens (auth, dashboard) currently render in **light mode** with explicit hex colours rather than toggling `.dark`.

### Application UI colours (hex)

Used across login, register, dashboard, profile, and matches:

| Role | HEX | Where used |
|------|-----|------------|
| Body text | `#1e1e1e` | Labels, match rows, profile copy |
| Strong emphasis | `#0b0b0b` | Auth links (e.g. “Sign up”) |
| Secondary text | `#525252`, `#757575` | Section labels, metadata |
| Placeholder | `#b3b3b3` | Auth input placeholders |
| Borders | `#d9d9d9`, `#eee` | Inputs, match list dividers |
| Primary button | `#2c2c2c` (hover `#3c3c3c`) | Sign in / register CTAs |
| Button label | `#f5f5f5` | Text on dark CTAs |
| Hover surface | `#f5f5f5` | Profile edit button hover |
| Victory | `#1e7e34` | Win outcome, match result |
| Defeat / error | `#c44a4a` | Loss outcome, API errors |
| Blue side (LoL) | `#4a7fd4` | Match detail team 100 |
| Red side background | `#fce8e8` | Defeat team chip in match detail |
| Avatar fallback | `#404040` | Initials when no profile image |
| Sidebar panel | `rgba(117, 117, 117, 0.12)` | Dashboard nav background |
| Landing backdrop | `#000000` | Full-screen landing (`LandingPage`) |
| Loading brand text | `#0f172a` | Loading screen wordmark |

**Loading animation accents** (`theme.css` utilities): `#1d4ed8`, `#0f766e`, `#6d28d9`, `#0e7490` cycle in `animate-vantage-pulse`.

### Layout tokens

| Token | Value | Purpose |
|-------|-------|---------|
| `--vp-layout-max` | `1512px` | Max dashboard artboard width |
| `--vp-dashboard-header` | `94px` | Fixed header height |
| `--vp-sidebar-width` | `220px` | Sidebar width |
| `--radius` | `0.625rem` (10px) | Default border radius; sm/md/lg/xl derived |

### Accessibility (colour)

- Auth inputs use `#1e1e1e` on white with `#d9d9d9` borders; focus darkens border to `#2c2c2c`.
- Victory (`#1e7e34`) and defeat (`#c44a4a`) are distinct for outcome scanning.
- shadcn controls use `focus-visible:ring-[3px]` with `--ring` for keyboard focus visibility.

---

## Typography

Fonts are loaded from Google Fonts in `frontend/src/styles/fonts.css` and applied per screen.

### Font families

| Family | Role | Implementation |
|--------|------|----------------|
| **Sarina** | Brand wordmark “Vantage Point” | `font-sarina` token in `theme.css`; `font-sarina` class on login, register, loading, Riot ID screens |
| **Inter** | Primary UI typeface | `font-['Inter:Regular',sans-serif]` (body), `Inter:Semi_Bold` (headings, labels, buttons) |
| **Geist** | Featured-game card badges | `font-['Geist:Medium',sans-serif]` at 14px on `FeaturedGameCard` |
| **Sora** | Loaded globally | Available via `fonts.css`; not heavily used in current screens |

### Sizes and weights

| Element | Size | Weight | Line height |
|---------|------|--------|-------------|
| Root / `html` | `16px` (`--font-size`) | — | — |
| Brand title (auth) | `clamp(20px, 2.5vw, 32px)` | Sarina regular | `leading-normal` |
| Brand title (loading) | `clamp(22px, 4.2vw, 40px)` | Sarina regular | `leading-tight` |
| Body / inputs | `16px` | Inter 400 | `1.4` or `leading-none` |
| Dashboard nav | `14px` | Inter 400 | `1.4` |
| Section headings (profile) | `14px` uppercase | Inter 600 | — |
| Profile display name | `28px` | Inter 600 | `leading-tight` |
| Match stat labels | `11px` uppercase | Inter 500 | `tracking-wide` |
| shadcn `Button` / `Input` | `text-sm` / `text-base` | medium (500) per `theme.css` base layer | `1.5` |

Base heading scale in `theme.css` (`h1`–`h4`) uses `--font-weight-medium` (500) with Tailwind text scale variables; Figma screens override with explicit Inter sizes.

---

## Logo and Iconography

### Logo

- **Primary mark:** WebP asset `798001aef0b2686ac929f8c349135d3326ab65bb.webp` (imported in `Login.tsx`, `Register.tsx`, `RiotId.tsx`, `LoadingPage.tsx`, `Group14.tsx`).
- **Sizing:**
- Auth / Riot ID: `clamp(120px, 18vw, 200px)` square, with Sarina wordmark below.
- Dashboard header: `97×99px` absolute top-left (`Group14.tsx`).
- Loading: responsive clamp, paired with animated wordmark.
- **Wordmark:** “Vantage Point” in Sarina, black on light auth screens, `#0f172a` on loading.

### Favicon

- `index.html` references `/favicon.svg` as the site icon; page title is **Vantage Point**.

### Icons

| Source | Usage |
|--------|--------|
| **Lucide React** | UI chrome (chevrons, checks, carousel controls, achievement mapping in `achievementIcons.ts`) |
| **Inline SVG** (`svg-*.ts` in imports) | Dashboard sidebar toggle, decorative vectors |
| **Figma-exported PNG/WebP** | Profile featured game (`league-wild-rift-*.png`), `icon-lightning-bolt.png`, `icon-time-machine.png` |
| **Social providers** | Google, Apple, Riot Games WebP buttons on auth (60×60px, `alt` describes action) |
| **Riot Data Dragon** | Champion and item images via `ddragon.ts` |

### Placement rules (as implemented)

- Logo is **centred above** auth forms; on dashboard it is **fixed top-left** with account menu top-right.
- Decorative carousel/background images use `alt=""` (presentational); interactive controls and social buttons have descriptive `alt` text.
- Achievement icons sit in a grid with optional count badges (`ProfileView.tsx`).

---

## Design Principles

Patterns observed in the implementation:

| Principle | How it appears in Vantage Point |
|-----------|----------------------------------|
| **Consistency** | Shared auth input class (`authInputClassName`), shared logo asset, repeated dashboard layout constants (`dashboardLayout.ts`, `Group14.tsx`) |
| **Simplicity** | White dashboard canvas, minimal sidebar (Matches / Analysis / Settings labels), clear win/loss colour coding |
| **Responsiveness** | `clamp()` typography and logo on auth; match list grid adds columns at `sm:` breakpoint; sidebar collapses with animated width/position |
| **Accessibility** | Radix primitives, ARIA on navigation and match rows, focus rings on shadcn controls (see Accessibility) |
| **Brand personality** | League/Arcane full-bleed wallpapers on auth; Sarina script wordmark; subtle loading animations (`animate-vantage-pulse`, `animate-vantage-breathe`) |
| **Design–dev alignment** | Figma imports under `frontend/src/landing/imports/`; profile assets documented as Figma exports in `assets/profile/index.ts` |

---

## UI Component Styling

### Auth (login / register / Riot ID)

- **Inputs:** 8px radius, 16px horizontal padding, `#d9d9d9` border, transparent background, Inter 16px (`authInputClassName` in `Login.tsx` / `Register.tsx`).
- **Primary CTA:** Full-width, 58px height, `#2c2c2c` background, `#f5f5f5` label, disabled at 60% opacity.
- **Social login:** Three 60×60 image buttons in a centred row.
- **Background carousel:** Dot tablist (`role="tablist"`), 8px dots, active `bg-black` / inactive 30% opacity.

### Dashboard shell (`Group14.tsx`)

- **Frame:** White full-viewport background, min-width fluid.
- **Sidebar:** 220px wide, 400px tall panel, 15px radius, grey translucent fill; nav items 47px tall, 10px radius white pills for active state.
- **Header:** 94px (`--vp-dashboard-header`); content offset when sidebar open (`DASHBOARD_CONTENT_LEFT_OPEN` = 299px).
- **Toggle:** 24px icon button with `aria-expanded`, `aria-controls="dashboard-sidebar"`.

### shadcn/ui library (`frontend/src/landing/app/components/ui/`)

Shared primitives for newer or composable UI:

| Component | Styling summary |
|-----------|-----------------|
| **Button** | Variants: default, destructive, outline, secondary, ghost, link; sizes sm/default/lg/icon; `rounded-md`, `focus-visible:ring-[3px]` |
| **Input / Textarea / Select** | `h-9`, `rounded-md`, `bg-input-background`, ring on focus, `aria-invalid` destructive styling |
| **Dialog** | Overlay `bg-black/50`, animated open/close (Radix) |
| **Card, Badge, Avatar, Chart** | Token-driven colours; chart uses theme chart-1–5 |
| **Dropdown / Navigation menu** | Accent hover states, keyboard focus rings |

Auth screens use **custom Figma buttons**; dashboard match/profile views mix **custom layout** with selective shadcn pieces (e.g. `Avatar`, `Button` in profile editor).

### Match list and detail

- **List row:** CSS grid, bordered with `#eee`, tabular numerals for stats.
- **Outcome:** Green `#1e7e34` / red `#c44a4a` semibold labels.
- **Detail:** Team colours blue/red; result banner uses same win/loss palette.

---

## Accessibility

Implemented practices (targeting WCAG-oriented behaviour):

| Area | Implementation |
|------|----------------|
| **Language** | `<html lang="en">` in `index.html` |
| **Keyboard focus** | shadcn components: `focus-visible:border-ring`, `focus-visible:ring-[3px]`; auth inputs: visible border change on focus |
| **Screen readers** | `aria-label` on dashboard sidebar toggle, nav (“Matches”), profile sections (“Performance radar”, “Achievements”, etc.); `aria-current="page"` for active nav; match rows expose `matchRowAriaLabel()`; carousel previous/next use `sr-only` text; login errors use `role="alert"` |
| **Semantic structure** | Match list uses `role="row"` / `role="columnheader"`; carousel uses `role="region"` and `aria-roledescription` |
| **Forms** | Labels associated with fields on auth screens; `aria-invalid` styling on shadcn inputs when invalid |
| **Motion** | CSS animations on loading screen; no `prefers-reduced-motion` override yet |
| **Colour contrast** | Light dashboards rely on dark grey text on white; known gap: some decorative images use empty `alt` |

### Gaps / follow-ups

- Dark-mode tokens exist but are not wired as the default experience for main routes.
- Not all images have descriptive `alt` (logo and wallpapers are decorative).
- No documented WCAG conformance level or automated a11y test suite in repo.

---

## Source reference

| Topic | Primary files |
|-------|----------------|
| Theme tokens | `frontend/src/styles/theme.css` |
| Fonts | `frontend/src/styles/fonts.css`, `frontend/src/styles/index.css` |
| shadcn components | `frontend/src/landing/app/components/ui/` |
| Auth branding | `frontend/src/landing/imports/Login/Login.tsx`, `Register/Register.tsx` |
| Dashboard shell | `frontend/src/landing/imports/Group14/Group14.tsx` |
| Layout constants | `frontend/src/landing/app/lib/dashboardLayout.ts` |
| Profile assets | `frontend/src/landing/app/assets/profile/` |
146 changes: 146 additions & 0 deletions .github/docs/Dev-Quickstart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Dev Quickstart — Seed, Backend, Login

Short runbook for getting a local dev environment with seeded test data and signing in as the demo user.

For full infrastructure setup (Dev Container, database schema, troubleshooting), see [Setup.md](./Setup.md).

---

## Prerequisites

- Project opened in the **Dev Container** (recommended), or local Postgres with `DATABASE_URL` pointing at `localhost:5432`
- **`backend/.env`** — copy from `backend/.env.example`
- **`frontend/.env`** — copy from `frontend/.env.example`

### Required `backend/.env` values

```env
DATABASE_URL=postgresql+asyncpg://riot_user:riot_password@db:5432/riot_db
JWT_SECRET=change-me-to-a-long-random-string
SEED_DEV_PASSWORD=your-team-dev-password
RIOT_API_KEY=your_key_here
```

Inside the dev container, the database host must be **`db`**, not `localhost`.

### Required `frontend/.env` values

```env
VITE_API_URL=http://localhost:8000
```

---

## Step 1 — Seed the database

From inside the dev container:

```bash
cd /workspaces/backend
python -m app.database.seed
```

Outside the container (with a local venv and Postgres on port 5432):

```bash
cd backend
python -m app.database.seed
```

**Success:** output ends with `--- Seed complete ---` and a line like:

```text
Dev login: testuser1@vantagepoint.dev (password from SEED_DEV_PASSWORD)
```

**Important:**

- `SEED_DEV_PASSWORD` must be set in `backend/.env` before running seed.
- Seed **drops and recreates all tables**. Re-run it whenever you need a clean dev dataset or after schema changes.

---

## Step 2 — Start the backend

```bash
cd /workspaces/backend
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```

**Verify:** open [http://localhost:8000](http://localhost:8000). Expected response:

```json
{"message": "Vantage Point API running", "db_status": "Ready"}
```

---

## Step 3 — Start the frontend

In a **second terminal**:

```bash
cd /workspaces/frontend
npm run dev
```

Open the URL Vite prints (usually [http://localhost:5173](http://localhost:5173)).

---

## Step 4 — Log in

| Field | Value |
|--------|--------|
| **Email** | `testuser1@vantagepoint.dev` |
| **Password** | The value of `SEED_DEV_PASSWORD` in `backend/.env` |

Use **testuser1** for the full demo dataset (matches, profile, achievements).
`testuser2@vantagepoint.dev` uses the same password but has a different, mostly empty game account.

---

## What seed provides

| Item | Details |
|------|---------|
| Dev users | `testuser1@vantagepoint.dev`, `testuser2@vantagepoint.dev` |
| Demo account (testuser1) | Riot ID **You#EUW**, PUUID `seed-viewer-puuid` |
| Match history | 8 seeded games with scoreboards |
| Profile extras | Achievements, featured-game banners, `profile_matches_sampled=20` |
| Champions | Static champion catalog populated |

Newly registered accounts without seeded rows will have empty match history until they link a Riot ID and data is ingested.

---

## Copy-paste checklist

```text
1. backend/.env + frontend/.env (from .env.example)
2. cd backend && python -m app.database.seed
3. cd backend && uvicorn app.main:app --reload
4. cd frontend && npm run dev
5. Login: testuser1@vantagepoint.dev / <SEED_DEV_PASSWORD>
```

---

## Troubleshooting

| Problem | What to do |
|---------|------------|
| Seed fails: `SEED_DEV_PASSWORD` | Add `SEED_DEV_PASSWORD=...` to `backend/.env`. |
| Seed / backend cannot connect to DB | Run inside the dev container; use host `db` in `DATABASE_URL`. |
| Login fails after re-seed | Password must match the **current** `SEED_DEV_PASSWORD`, not an old value. |
| Empty matches after login | Sign in as **testuser1**, not a new account without seeded data. |
| Frontend cannot reach API | Set `VITE_API_URL=http://localhost:8000` in `frontend/.env`. |
| Backend run outside container | Change `DATABASE_URL` host from `db` to `localhost`. |

---

## Related docs

- [Setup.md](./Setup.md) — Dev Container, database schema, verification
- [Backend-Development-Guide.md](./Backend-Development-Guide.md) — API and backend development
- [Frontend-Development-Guide.md](./Frontend-Development-Guide.md) — UI development
Loading
Loading