diff --git a/backend/src/routes/install.ts b/backend/src/routes/install.ts new file mode 100644 index 0000000..0bbbb58 --- /dev/null +++ b/backend/src/routes/install.ts @@ -0,0 +1,117 @@ +import type { FastifyInstance } from "fastify"; + +// Public install landing page. Points Obtainium at the Forgejo repo and gives +// iPhone PWA instructions. Served unauthenticated at /install. +const REPO_URL = "https://git.mowden.top/Beartaria/CampgroundTickets"; +const OBTAINIUM_ADD = `obtainium://add/${REPO_URL}`; +const RELEASES_URL = `${REPO_URL}/releases`; +const OBTAINIUM_GET = "https://github.com/ImranR98/Obtainium/releases/latest"; +const PWA_URL = "https://scan.beartariacampgrounds.com/"; + +export async function installRoutes(app: FastifyInstance): Promise { + app.get("/install", async (_req, reply) => { + reply.type("text/html").send(PAGE); + }); +} + +const PAGE = ` + + + + + +Install Camp Scan + + + +
+
+ +

Install Camp Scan

+

Ticket scanner for Beartaria Campgrounds gate staff

+
+ + +
+ Android +

๐Ÿ“ฒ Install & auto-update via Obtainium

+

Obtainium keeps the app updated straight from our server โ€” no Play Store needed.

+
    +
  1. Don't have Obtainium yet? Download it here and install the APK (you may need to allow "install unknown apps").
  2. +
  3. Then tap the button below โ€” it opens Obtainium with Camp Scan ready to add:
  4. +
+ โž• Add Camp Scan to Obtainium +

If the button doesn't open Obtainium: open Obtainium โ†’ Add App โ†’ paste ${REPO_URL} โ†’ Add.

+
โ€” or โ€”
+ โฌ‡๏ธŽ Download the APK directly +

Direct installs won't auto-update โ€” Obtainium is recommended.

+
+ + +
+ iPhone & iPad +

๐ŸŽ Add to Home Screen

+

No App Store needed โ€” it runs as a full-screen web app.

+
    +
  1. Open this page in Safari (not Chrome): ${PWA_URL}install
  2. +
  3. Tap the Share button, then Add to Home Screen โ†’ Add.
  4. +
  5. Launch Camp Scan from your home screen and allow the camera.
  6. +
+ Open Camp Scan now +
+ +
+

๐Ÿ”‘ First launch

+

Open the app, enter the gate PIN, then type your name (recorded with every check-in). You stay signed in for the event.

+
+ +
Beartaria Campgrounds ยท scan.beartariacampgrounds.com
+
+ + + +`; diff --git a/backend/src/server.ts b/backend/src/server.ts index cd5f362..eda5d68 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -11,6 +11,7 @@ import { authRoutes } from "./routes/auth.js"; import { webhookRoutes } from "./routes/webhook.js"; import { ticketRoutes } from "./routes/tickets.js"; import { testRoutes } from "./routes/test.js"; +import { installRoutes } from "./routes/install.js"; export async function build() { const config = loadConfig(); @@ -30,6 +31,7 @@ export async function build() { await app.register(webhookRoutes); await app.register(ticketRoutes); await app.register(testRoutes); + await app.register(installRoutes); // Serve the exported Expo web build (if present) with SPA fallback. const webDir = config.WEB_DIR ?? join(process.cwd(), "web");