Add calendar export, SEO, error monitoring, backups, audit trail, and a starter test suite
Six site improvements picked from a "what could be better" review, plus a Jest test suite covering the two areas with the trickiest money-handling history in this project (early-bird pricing tranches, donation-leg accounting): - "Add to calendar" .ics download on event pages and in confirmation emails - sitemap.xml, robots.txt, and Open Graph/Twitter metadata for public pages - Sentry error monitoring (backend + frontend), a no-op until SENTRY_DSN is set - Nightly local pg_dump backups with a Site Settings tab to browse/trigger/download - Admin audit trail for refunds, donations, manual registrations, event and settings changes, and staff-initiated cancellations - Jest tests reproducing and guarding against the 1.8.0 tranche-pricing bug and the 1.4.2 donation-balance-inflation bug Wallet passes (Google/Apple) were scoped out of this round — Apple Wallet needs a paid Apple Developer account the project doesn't have yet, and the user preferred shipping both together later rather than Google alone now. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { SetupGuard } from "@/components/shared/SetupGuard";
|
||||
import HelpFab from "@/components/shared/HelpFab";
|
||||
import { API_BASE, resolveToApiOrigin } from "@/lib/api";
|
||||
import { buildThemeCssVars } from "@/lib/colorScale";
|
||||
import { appUrl } from "@/lib/siteConfig";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
@@ -44,14 +45,30 @@ async function getServerSettings(): Promise<SiteSettings> {
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
const settings = await getServerSettings();
|
||||
const faviconUrl = settings.favicon_url ? resolveToApiOrigin(settings.favicon_url) : null;
|
||||
const logoUrl = settings.logo_url ? resolveToApiOrigin(settings.logo_url) : null;
|
||||
const displayName = settings.org_name || appName;
|
||||
const description = settings.org_tagline || `Manage and register for events with ${displayName}`;
|
||||
|
||||
return {
|
||||
title: displayName,
|
||||
description: `Manage and register for events with ${displayName}`,
|
||||
metadataBase: new URL(appUrl),
|
||||
title: { default: displayName, template: `%s | ${displayName}` },
|
||||
description,
|
||||
icons: {
|
||||
icon: faviconUrl || "/favicon.ico",
|
||||
},
|
||||
openGraph: {
|
||||
type: "website",
|
||||
siteName: displayName,
|
||||
title: { default: displayName, template: `%s | ${displayName}` },
|
||||
description,
|
||||
...(logoUrl ? { images: [{ url: logoUrl }] } : {}),
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: displayName,
|
||||
description,
|
||||
...(logoUrl ? { images: [logoUrl] } : {}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user