β NOVA ASTRO
Space Tourism Agency β Web Platform
Nova Astro is a fullstack web platform for a fictional space tourism agency. Users can browse a catalog of space expeditions, view mission specifications, explore the fleet and crew training program, and book a seat β all through a responsive interface backed by a REST API.
Built for: Digital Wind web development competition (Π¦ΠΈΡΡΠΎΠ²ΠΎΠΉ Π²Π΅ΡΠ΅Ρ) β π₯ 1st place winner
| Layer | Technology | Why |
|---|---|---|
| Framework | Next.js 16 (App Router) | SSR, file-based routing, built-in API proxy, font optimization, standalone builds |
| UI | React 19 + TypeScript | Component architecture, type safety, IDE autocompletion |
| Styling | Tailwind CSS 4 | Utility-first, purged production CSS, design consistency |
| Animations | Framer Motion | Declarative animations, AnimatePresence for mount/unmount transitions, whileInView for scroll |
| UI Primitives | shadcn/ui + @base-ui/react | Accessible headless components (Button, Badge, Dialog) with CVA variants |
| Backend | FastAPI (Python 3.11) | Async ASGI, Pydantic validation, auto-generated OpenAPI docs |
| Validation | Pydantic v2 | 13 data models with type checking, range constraints, email validation |
| Server | Uvicorn | ASGI server with hot reload |
| Package Manager | Poetry | Deterministic builds via poetry.lock, PEP 621 compliant |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FRONTEND (Next.js) β
β β
β page.tsx βββ Preloader β
β βββ Navbar β
β βββ Hero βββββββ fetchStats() βββ β
β βββ Tours ββββββ fetchTours() βββ€ lib/api.ts β
β βββ Fleet β request<T>() β
β βββ Training β β
β βββ About β β
β βββ Footer β β
β βββ BookingModal β createBooking() β
ββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββ
β
/api/v1/* (proxy via next.config.ts)
β
ββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββ
β BACKEND (FastAPI) β
β β
β main.py βββββ services.py βββββ storage.py β
β (routes) (business logic) (in-memory data) β
β β β
β ββββ schemas.py (Pydantic models) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Layer | File | Responsibility |
|---|---|---|
| Routing | main.py |
HTTP endpoints, CORS, error handlers |
| Business Logic | app/services.py |
Tour filtering, booking management, route builder (greedy algorithm) |
| Storage | app/storage.py |
In-memory dictionaries (TOURS, BOOKINGS, ROUTE_MODULES) |
| Component | Role |
|---|---|
Preloader |
Loading animation (SVG ring, progress bar, status lines) |
Navbar |
Navigation with scroll effect, mobile burger menu |
Hero |
HUD panel with live API data, SVG trajectory diagram, news ticker |
Tours |
Mission catalog with API data, launch countdown, seat status |
Fleet |
4 vessels with SVG blueprints, floating animation |
Training |
4 training phases with descriptions and durations |
About |
Agency info, statistics, SVG operations topology |
Footer |
Contacts, uptime timer, coordinates |
BookingModal |
Spec view / booking form β POST /api/v1/bookings |
| Method | Path | Description |
|---|---|---|
GET |
/api/health |
Health check |
GET |
/api/v1/tours |
List tours (filters: price, duration, difficulty, search) |
GET |
/api/v1/tours/{id} |
Single tour |
POST |
/api/v1/routes/custom |
Generate custom route (greedy algorithm) |
POST |
/api/v1/bookings |
Create booking (validates seats, email, count) |
GET |
/api/v1/bookings |
List bookings |
GET |
/api/v1/bookings/{id} |
Single booking |
PATCH |
/api/v1/bookings/{id}/status |
Update booking status |
POST |
/api/v1/bookings/{id}/cancel |
Cancel booking (idempotent, restores seats) |
GET |
/api/v1/stats |
Aggregated agency statistics |
All errors follow a unified format: { "error": { "code", "message", "details" } }
Interactive API docs available at http://localhost:8000/docs (Swagger UI).
Visual style: Mission Control HUD β dark theme with angular markers, monospace data readouts, glowing accents.
| Token | Value | Purpose |
|---|---|---|
--void |
#05070d |
Primary background |
--panel |
#0d1424 |
Card/panel background |
--accent |
oklch(0.70 0.18 295) |
Accent violet |
--ink |
#e7ecf5 |
Primary text |
--ink-dim |
#8b97b3 |
Secondary text |
Typography: Space Grotesk (headings) β Inter (body) β JetBrains Mono (HUD/technical data)
Animations (12): pulse-dot, ticker, orbit-spin, preloader-rotate, scanline, twinkle, glow-breathe, float-y, section-scan, count-reveal, hover-lift, preloader-scanline
All diagrams (trajectories, vessel blueprints, ops topology) are hand-crafted inline SVGs styled with project CSS variables β no charting libraries.
- Desktop (
md:+): multi-column grids (3β4 cols), full navbar, trajectory diagram - Mobile (
<768px): single column, burger menu withAnimatePresence, trajectory hidden - Fluid typography:
clamp(44px, 6.8vw, 96px)for headings - Graceful degradation: site renders with static fallback data when backend is unavailable
βββ main.py # FastAPI entry point, routes, CORS, error handling
βββ app/
β βββ schemas.py # Pydantic models (Tour, Booking, AgencyStats, etc.)
β βββ services.py # Business logic (filtering, booking, route builder)
β βββ storage.py # In-memory data store
βββ app/ # Next.js App Router
β βββ layout.tsx # Root layout, fonts, global CSS
β βββ page.tsx # Main page, preloader β sections β modal
β βββ globals.css # Design tokens, animations, Tailwind
βββ components/
β βββ nova/ # 9 business components
β βββ ui/ # shadcn/ui primitives (Button, Badge, Dialog)
βββ lib/
β βββ api.ts # API client (fetchTours, fetchStats, createBooking)
β βββ utils.ts # cn() = clsx + tailwind-merge
βββ next.config.ts # Standalone build, API proxy rewrites
βββ pyproject.toml # Poetry dependencies
βββ package.json # npm dependencies
βββ Procfile # PaaS deployment command
- Node.js 18+
- Python 3.11+
pip install fastapi uvicorn pydantic[email]
python -m uvicorn main:app --host 127.0.0.1 --port 8000 --reloadAPI docs: http://localhost:8000/docs
npm install
npm run devOpen http://localhost:3000. The frontend proxies /api/* requests to the backend via next.config.ts rewrites.
| Decision | Rationale |
|---|---|
| FastAPI over Flask/Django | Async, built-in validation, auto Swagger; Django's ORM/admin unnecessary |
| In-memory storage | No external dependencies for a competition project; replaceable by swapping storage.py |
| Lifting State Up | bookingTarget in root page.tsx β no Redux/Zustand needed for a single-page app |
| Inline SVG | Scalable, styled with CSS vars, no D3/Chart.js dependency |
| Greedy algorithm for route builder | 6 modules β simple and sufficient vs dynamic programming overhead |
oklch() colors |
Perceptually uniform β same lightness across violet, gold, and red accents |
| Standalone build | output: "standalone" reduces deploy size from ~200 MB to ~30 MB |
| Unified error format | Three global handlers ensure frontend always gets error.message |
| Contributor | Role | GitHub |
|---|---|---|
| Saveliy Golubev | Backend (FastAPI, Pydantic, API design) | @NovaCode37 |
| XenonZeon | Frontend (Next.js, React, Tailwind, animations) | @XenonZeon |
Competition: Π¦ΠΈΡΡΠΎΠ²ΠΎΠΉ Π²Π΅ΡΠ΅Ρ 2026 β Web Development category β π₯ 1st place