forked from Mike/freno-dev
feat(gaze): add Gaze subdomain landing page with direct download
Move the Gaze marketing home from the legacy /marketing/gaze route to a dedicated gaze subdomain landing page (src/routes/gaze). The new page adds a richer hero, feature highlights, and a direct .dmg download flow that resolves a signed S3 URL via the tRPC downloads.getDownloadUrl endpoint. Extract the download-resolution logic into a shared, testable downloadAsset helper (src/lib/download-asset) so current and future subdomain landing pages (InputHalo, Lineage, …) share one code path. The helper is pure over an injected DownloadApi + redirect sink, keeping it unit-testable without importing solid-js / CSRF cookie code. Replace the old marketing/gaze route with a permanent 308 redirect to https://gaze.freno.me so existing inbound links keep resolving to the canonical home. Add unit tests covering the tRPC call shape, redirect sink, and error handling.
This commit is contained in:
@@ -1,57 +1,21 @@
|
||||
import { PageHead } from "~/components/PageHead";
|
||||
import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark";
|
||||
import { useDarkMode } from "~/context/darkMode";
|
||||
|
||||
export default function GazeMarketing() {
|
||||
const { isDark } = useDarkMode();
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHead
|
||||
title="Gaze - Eye Health Reminder"
|
||||
description="A macOS menu bar app that helps you remember to take breaks and rest your eyes. Download Gaze today."
|
||||
/>
|
||||
<div class="relative h-full">
|
||||
<div class="fixed inset-0 z-0 overflow-hidden brightness-75">
|
||||
<img
|
||||
src="/look-away.png"
|
||||
alt="background"
|
||||
class="h-full w-full object-cover select-none"
|
||||
style={{
|
||||
"pointer-events": "none"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="relative z-10 flex h-full flex-col items-center justify-center text-white backdrop-blur">
|
||||
<div>
|
||||
<img
|
||||
src={
|
||||
isDark()
|
||||
? "/Gaze Exports/Gaze-iOS-Dark-1024x1024@1x.png"
|
||||
: "/Gaze Exports/Gaze-iOS-Default-1024x1024@1x.png"
|
||||
}
|
||||
alt="Gaze App Icon"
|
||||
height={128}
|
||||
width={128}
|
||||
class="object-cover object-center"
|
||||
/>
|
||||
</div>
|
||||
<h1 class="py-4 text-center text-5xl font-bold">Gaze</h1>
|
||||
<p class="text-text mb-8 text-xl">
|
||||
Eye and posture health reminder for macOS
|
||||
</p>
|
||||
<div class="flex space-x-4">
|
||||
<a
|
||||
class="my-auto transition-all duration-200 ease-out active:scale-95"
|
||||
href="https://apps.apple.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<DownloadOnAppStoreDark size={50} />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
/**
|
||||
* Legacy `/marketing/gaze` route — redirected (task 05) to the new Gaze
|
||||
* subdomain landing page at `gaze.freno.me`.
|
||||
*
|
||||
* Kept as a permanent 308 redirect so existing inbound links keep resolving
|
||||
* to the canonical Gaze marketing home.
|
||||
*
|
||||
* Implemented as a thrown `Response` (rather than `@solidjs/router`'s
|
||||
* `redirect()`) because the target is a *cross-origin* absolute URL; throwing
|
||||
* a `Response` from a SolidStart page component propagates as the actual HTTP
|
||||
* response, with no router base-path rewriting.
|
||||
*/
|
||||
export default function GazeMarketingRedirect(): never {
|
||||
throw new Response(null, {
|
||||
status: 308,
|
||||
headers: {
|
||||
Location: "https://gaze.freno.me",
|
||||
"Cache-Control": "public, max-age=86400"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user