BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2,或任何藍牙控制器搭配 MyWhoosh、Rouvy、Zwift 等。可於 iOS、Android、Windows 與 macOS 免費試用。
AI 翻譯
Hlaupadagskra.is – Heildarlisti yfir öll hlaup á Íslandi 2026. Finndu götuhlaup, utanvegahlaup og náttúruhlaup, allt frá skemmtiskokkum í últramaraþona. Leitaðu, síaðu og skipuleggðu næsta ævintýri þitt.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
🏔️ Hlaupadagskra.is — Trail Discovery for Iceland A web application for finding races and trails and sharing trails in Iceland. Browse trails on a map, filter by activity type, difficulty, location, and tags — or explore elevation profiles with interactive charts, route playback, and more ...much more. • Node.js 18+ • .NET 9 SDK • PostgreSQL with PostGIS (or a Supabase project) • Docker Desktop (for the local Supabase stack) The backend uses .NET User Secrets for local configuration:檢視完整 README ↗
A web application for finding races and trails and sharing trails in Iceland. Browse trails on a map, filter by activity type, difficulty, location, and tags — or explore elevation profiles with interactive charts, route playback, and more ...much more.
utanvega/
├── frontend/ # Public-facing trail browser (React + Vite + MUI)
├── admin/ # Admin dashboard for trail management (React + Vite + MUI)
├── backend/ # API server (.NET 9, CQRS, PostGIS)
├── backend.Tests/ # Unit & integration tests (xUnit)
└── package.json # Root dev scripts (concurrently)
| Layer | Technology |
|---|---|
| Frontend | React 18, TypeScript, Vite 7, MUI 5, Leaflet, Recharts 3 |
| Admin | React 18, TypeScript, Vite 7, MUI 5, Leaflet, Supabase Auth |
| Backend | .NET 9, MediatR (CQRS), EF Core, PostGIS, JWT Auth |
| Database | PostgreSQL + PostGIS (via Supabase) |
| Tests | xUnit, Moq, SQLite in-memory |
| Hosting | Fly.io (backend), Vercel (frontend) |
git clone https://github.com/svanur/utanvega.git
cd utanvega
npm install
cd frontend && npm install && cd ..
cd admin && npm install && cd ..
The backend uses .NET User Secrets for local configuration:
cd backend
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Host=...;Database=...;Username=...;Password=..."
dotnet user-secrets set "SUPABASE_URL" "https://your-project-ref.supabase.co"
dotnet user-secrets set "SUPABASE_JWT_SECRET" "your-supabase-jwt-secret"
The admin panel can auto-translate Icelandic content to English using DeepL. To enable:
:fx).cd backend
dotnet user-secrets set "DeepL:ApiKey" "your-deepl-api-key"
The key is stored in user-secrets and never committed to source control. Without it, the "Translate to EN" buttons in the admin panel will return a 502 error; the rest of the app works normally.
If the hosted Supabase project is quota-limited or unavailable, use the local stack:
npm run supabase:setup
This generates local env files, starts Postgres + Auth + Kong in Docker, and seeds a local admin login. The generated credentials are printed by the setup script. If a default port is busy, the script automatically picks another free host port and writes it to supabase/.env.local.
cd backend
dotnet ef database update
From the repo root:
npm run dev
This starts all three projects concurrently:
Or run individually:
npm run dev:frontend # Frontend only
npm run dev:admin # Admin only
npm run dev:backend # Backend only (dotnet watch)
cd backend.Tests
dotnet test
Run PostgreSQL + PostGIS + Supabase Auth locally via Docker. This eliminates dependency on the hosted Supabase project for development.
Verify Docker is running:
docker --version
docker compose version
Run from the repo root (utanvega/):
npm run supabase:setup
What this does (in order):
supabase/.env.local — Docker Compose secretsfrontend/.env.local — Vite env pointing to local Supabaseadmin/.env.local — Vite env pointing to local SupabaseConnectionStrings:DefaultConnection, SUPABASE_URL, SUPABASE_JWT_SECRET)Output: The script prints the local admin email and password in the terminal.
The database starts empty. Apply EF Core migrations to create the schema:
cd backend
dotnet ef database update
# 1. Start the local database + auth (if not already running)
npm run supabase:up
# 2. Start the app (frontend + admin + backend)
npm run dev
To stop Supabase when done:
npm run supabase:down
| Command | What it does |
|---|---|
npm run supabase:setup | Full first-time setup (generates env, starts Docker, seeds admin, writes user-secrets) |
npm run supabase:up | Start Docker containers only (assumes env files exist) |
npm run supabase:down | Stop Docker containers (data persists in volume) |
npm run supabase:seed | Re-seed admin user + re-write user-secrets (containers must be running) |
All commands are run from the repo root.
| Service | URL | Notes |
|---|---|---|
| Supabase API gateway | See supabase/.env.local (SUPABASE_PUBLIC_URL) | Kong routes to auth |
| Auth health check | SUPABASE_PUBLIC_URL + /auth/v1/health | Should return {"status":"ok"} |
| Auth (direct) | Internal only | GoTrue runs inside Docker; use the gateway URL above |
| PostgreSQL | See supabase/.env.local (LOCAL_SUPABASE_DB_PORT) | User: postgres, DB: postgres |
| Backend API | http://localhost:8080 | After running npm run dev |
| Frontend | http://localhost:5173 | After running npm run dev |
| Admin | http://localhost:5174 | After running npm run dev |
Use any PostgreSQL client (pgAdmin, DBeaver, DataGrip, psql):
Host: localhost
Port: (check supabase/.env.local → LOCAL_SUPABASE_DB_PORT)
Database: postgres
Username: postgres
Password: (check supabase/.env.local → POSTGRES_PASSWORD)
Destroys all local data and recreates from scratch:
npm run supabase:down
docker volume rm hlaupadagskra-supabase-local_db-data
npm run supabase:setup
cd backend && dotnet ef database update
| Problem | Solution |
|---|---|
port 5432 already in use | Run npm run supabase:setup (or re-run it) to auto-pick and persist a free DB port in supabase/.env.local (LOCAL_SUPABASE_DB_PORT) |
| Auth container keeps restarting | Check logs: docker logs hlaupadagskra-supabase-auth — usually a role password mismatch. Reset with nuclear option above. |
dotnet ef database update fails | Ensure containers are running (npm run supabase:up) and check connection string in user-secrets |
| Admin login doesn't work | Run npm run supabase:seed to re-create the admin user |
| Docker not found | Install Docker Desktop and ensure it's running |
*.env.local files are git-ignored — safe to contain secrets.db-data) persists data across supabase:down / supabase:up cycles.docker volume rm or the nuclear reset destroys data..env.local./tags/:slug)| Method | Path | Description |
|---|---|---|
GET | /api/v1/trails | List all published trails |
GET | /api/v1/trails/{slug} | Get trail by slug |
GET | /api/v1/trails/{slug}/geometry | Get trail GeoJSON geometry |
GET | /api/v1/trails/{slug}/gpx | Download trail GPX file |
GET | /api/v1/locations | List all locations |
GET | /api/v1/locations/{slug} | Get location with trails |
POST | /api/v1/admin/trails/upload-gpx | Upload single GPX |
POST | /api/v1/admin/trails/bulk-upload-gpx | Bulk upload GPX files |
PUT | /api/v1/admin/trails/{id} | Update trail |
DELETE | /api/v1/admin/trails/{id} | Delete trail (soft) |
GET/POST/PUT/DELETE | /api/v1/admin/tags/* | Tag CRUD |
Private — all rights reserved.