diff --git a/.env.example b/.env.example index 9eefb4d..927ff37 100644 --- a/.env.example +++ b/.env.example @@ -16,3 +16,7 @@ # Password required to view the site (login page at /login). # Leave empty/unset to disable the gate. SITE_PASSWORD="" + +# Umami analytics (optional). Omit NEXT_PUBLIC_UMAMI_WEBSITE_ID to disable tracking. +# NEXT_PUBLIC_UMAMI_WEBSITE_ID="your-website-uuid" +# NEXT_PUBLIC_UMAMI_SCRIPT_URL="https://cloud.umami.is/script.js" diff --git a/README.md b/README.md index 1d6b4ce..3597f38 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Medscribe Web -Marketing homepage for [Medscribe](../README.md) — a privacy-first, on-device medical companion for iOS. +Marketing homepage for [Medscribe](../README.md) — a privacy-first, on-device medical companion for iOS and Android. Built with [create-t3-app](https://create.t3.gg/) (Next.js + TypeScript + Tailwind). Single-page site; no database or API routes. @@ -15,6 +15,15 @@ bun run dev Open [http://localhost:3000](http://localhost:3000). +### Analytics (optional) + +Set in `.env` (see `.env.example`): + +- `NEXT_PUBLIC_UMAMI_WEBSITE_ID` — website UUID from your Umami dashboard +- `NEXT_PUBLIC_UMAMI_SCRIPT_URL` — optional; defaults to `https://cloud.umami.is/script.js` (use your self-hosted URL if needed) + +Leave the website ID unset to disable tracking (default for local dev). + ## Build ```bash @@ -26,10 +35,10 @@ Screenshots live in `public/screenshots/`. They are wrapped in an iPhone-style f ### Capturing raw screenshots for the site -Export **in-app content only** from the simulator or device — no simulator chrome or macOS capture toolbar. A normal in-app iOS status bar/tab bar is fine. +Export **in-app content only** from the simulator or device — no simulator chrome or macOS capture toolbar. A normal in-app status bar/tab bar is fine. -1. Run the app on **iPhone 17 Pro** (or 16 Pro) simulator or device. -2. Capture each screen (⌘S in Simulator saves to Desktop). +1. Run the app on **iPhone 17 Pro** (or 16 Pro) simulator or device, or on an **Android** emulator/device. +2. Capture each screen (⌘S in Simulator saves to Desktop; `adb exec-out screencap -p` on Android). 3. Drop PNGs into `public/screenshots/` and update paths in `src/app/page.tsx` / `src/components/feature-showcase.tsx`. The frame dimensions assume tall iPhone screenshots and are controlled in `src/components/phone-mockup.tsx`. Use `captureMode="simulator"` only for old captures that already include device chrome. diff --git a/src/app/(marketing)/executive-summary/page.tsx b/src/app/(marketing)/executive-summary/page.tsx index 0fc83e0..aed9a8d 100644 --- a/src/app/(marketing)/executive-summary/page.tsx +++ b/src/app/(marketing)/executive-summary/page.tsx @@ -9,6 +9,7 @@ import { MedscribeLogo } from "~/components/medscribe-logo"; import { PhoneMockup } from "~/components/phone-mockup"; import { PrintButton } from "~/components/print-button"; import { SectionLabel } from "~/components/section-label"; +import { BETA_FOOTER_NOTE, BETA_SUMMARY } from "~/lib/beta"; import { Badge } from "~/components/ui/badge"; import { Card, @@ -326,9 +327,7 @@ export default function ExecutiveSummaryPage() { {/* Beta */}

- A beta is available on iOS through TestFlight. Everything runs - privately on the device, so no health data leaves the phone. If - you'd like to try it, reach out. + {BETA_SUMMARY} If you'd like to try it, reach out.

@@ -459,9 +458,7 @@ export default function ExecutiveSummaryPage() { diff --git a/src/app/(marketing)/page.tsx b/src/app/(marketing)/page.tsx index e8ceed6..b235ad3 100644 --- a/src/app/(marketing)/page.tsx +++ b/src/app/(marketing)/page.tsx @@ -13,6 +13,11 @@ import { import { FeatureShowcase } from "~/components/feature-showcase"; import { PhoneMockup } from "~/components/phone-mockup"; import { SectionLabel } from "~/components/section-label"; +import { + BETA_CTA_BODY, + BETA_CTA_TITLE, + BETA_INVITE_MAILTO, +} from "~/lib/beta"; import { Badge } from "~/components/ui/badge"; import { Button } from "~/components/ui/button"; import { @@ -119,8 +124,9 @@ export default function HomePage() {
- On TestFlight - iOS + Beta available + iOS · TestFlight + Android · Play internal Emergency-ready No cloud AI
@@ -319,11 +325,9 @@ export default function HomePage() {
- Try Medscribe on iOS + {BETA_CTA_TITLE} - The app is live on TestFlight. Reach out for an invite if - you're managing medications, visits, or emergency context for - someone you love. + {BETA_CTA_BODY}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx index ecc238f..c4283e2 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -3,6 +3,8 @@ import "~/styles/globals.css"; import { type Metadata } from "next"; import { Instrument_Sans, Playfair_Display } from "next/font/google"; +import { UmamiAnalytics } from "~/components/umami-analytics"; + const instrumentSans = Instrument_Sans({ subsets: ["latin"], variable: "--font-instrument-sans", @@ -42,7 +44,10 @@ export default function RootLayout({ }: Readonly<{ children: React.ReactNode }>) { return ( - {children} + + {children} + + ); } diff --git a/src/components/umami-analytics.tsx b/src/components/umami-analytics.tsx new file mode 100644 index 0000000..42cc0ba --- /dev/null +++ b/src/components/umami-analytics.tsx @@ -0,0 +1,25 @@ +import Script from "next/script"; + +import { env } from "~/env"; + +const DEFAULT_UMAMI_SCRIPT_URL = "https://cloud.umami.is/script.js"; + +/** + * Privacy-friendly page analytics via Umami. Enabled when + * `NEXT_PUBLIC_UMAMI_WEBSITE_ID` is set in `.env`. + */ +export function UmamiAnalytics() { + const websiteId = env.NEXT_PUBLIC_UMAMI_WEBSITE_ID; + if (!websiteId) return null; + + const src = env.NEXT_PUBLIC_UMAMI_SCRIPT_URL ?? DEFAULT_UMAMI_SCRIPT_URL; + + return ( +