feat(release): publish minimal self-contained Magent source

This commit is contained in:
Magent release tooling
2026-09-19 16:58:12 +12:00
commit 5fa5d45535
272 changed files with 79305 additions and 0 deletions
+145
View File
@@ -0,0 +1,145 @@
"use client";
import { useEffect, useState } from "react";
import { getApiBase } from "../lib/auth";
import BrandingLogo from "../ui/BrandingLogo";
import "./recaps.css";
type LinkAction = { action: "confirm" | "unsubscribe"; token: string };
export default function EmailRecapLinkPage() {
const [link, setLink] = useState<LinkAction | null>(null);
const [state, setState] = useState("loading");
const [error, setError] = useState("");
const [busy, setBusy] = useState(false);
useEffect(() => {
let controller: AbortController | null = null;
const checkLink = () => {
controller?.abort();
const abort = new AbortController();
controller = abort;
setError("");
setState("loading");
setLink(null);
// Fragments stay out of web-server access logs and referrers. Opening the link only checks it.
const params = new URLSearchParams(window.location.hash.slice(1));
const action = params.get("action");
const token = params.get("token") || "";
if ((action !== "confirm" && action !== "unsubscribe") || !/^[A-Za-z0-9_-]{40,100}$/.test(token)) {
setError("This email link is incomplete. Open Profile to manage your monthly recaps.");
setState("error");
return;
}
const payload = { action, token } as LinkAction;
setLink(payload);
void fetch(`${getApiBase()}/email-recaps/check`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
signal: abort.signal,
credentials: "omit",
})
.then(async (response) => {
const result = await response.json().catch(() => ({}));
if (!response.ok)
throw new Error(
typeof result.detail === "string"
? result.detail
: "Could not check this email link. Please open it again.",
);
if (!abort.signal.aborted) setState(result.state);
})
.catch((err: Error) => {
if (!abort.signal.aborted) {
setError(err.message);
setState("error");
}
});
};
checkLink();
window.addEventListener("hashchange", checkLink);
return () => {
controller?.abort();
window.removeEventListener("hashchange", checkLink);
};
}, []);
const apply = async () => {
if (!link || busy) return;
setBusy(true);
setError("");
try {
const response = await fetch(`${getApiBase()}/email-recaps/confirm`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(link),
credentials: "omit",
});
const result = await response.json().catch(() => ({}));
if (!response.ok)
throw new Error(
typeof result.detail === "string" ? result.detail : "Could not update your preference. Please try again.",
);
setState(result.state);
window.history.replaceState(null, "", "/email-recaps");
} catch (err) {
setError(err instanceof Error ? err.message : "Could not update your preference.");
} finally {
setBusy(false);
}
};
const done = state === "enabled" || state === "off";
return (
<main className="recap-link-page">
<a className="recap-brand" href="/login">
<BrandingLogo className="brand-logo" />
<span>Magent</span>
</a>
<section className="account-panel">
<span className="recap-eyebrow">Personal viewing reports</span>
<h1>
{state === "enabled"
? "Youre on the list."
: state === "off"
? "Recaps are turned off."
: state === "loading"
? "Checking your email link"
: state === "error"
? "This link needs another look"
: link?.action === "unsubscribe"
? "Unsubscribe from recaps?"
: "Your month, delivered."}
</h1>
<p>
{state === "enabled"
? "Your email is confirmed. Youll receive your personal viewing recap when the monthly schedule runs."
: state === "off"
? "You wont receive further monthly recaps. You can turn them back on in Profile."
: state === "ready" && link?.action === "unsubscribe"
? "This turns off all personal viewing report emails. You can still explore all your reports in Magent."
: state === "ready"
? "Confirm to email yourself your minutes, movies, episodes, longest run and requests. Manage automatic monthly delivery separately in Profile."
: ""}
</p>
{error && (
<p className="account-notice is-error" role="alert">
{error}
</p>
)}
{state === "ready" && (
<button type="button" className="account-primary" disabled={busy} onClick={() => void apply()}>
{busy ? "Updating…" : link?.action === "unsubscribe" ? "Unsubscribe from recaps" : "Confirm email recaps"}
</button>
)}
{(done || state === "error") && (
<a className="recap-text-link" href="/profile#monthly-recaps">
Manage email preferences
</a>
)}
{state === "loading" && <p role="status">One moment</p>}
</section>
</main>
);
}