From 0d67d659fccfdc98ad66bd926e5fca23ef006d3a Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Thu, 28 May 2026 18:21:33 -0500 Subject: [PATCH] feat(stats): polish rankings page --- bun.lock | 1 + packages/stats/app/package.json | 1 + packages/stats/app/src/resource.d.ts | 10 + .../stats/app/src/routes/api/newsletter.ts | 29 +++ packages/stats/app/src/routes/index.css | 234 +++++++++++++++--- packages/stats/app/src/routes/index.tsx | 170 +++++++++---- 6 files changed, 369 insertions(+), 76 deletions(-) create mode 100644 packages/stats/app/src/resource.d.ts create mode 100644 packages/stats/app/src/routes/api/newsletter.ts diff --git a/bun.lock b/bun.lock index a9e9a694e6..276bfa376a 100644 --- a/bun.lock +++ b/bun.lock @@ -639,6 +639,7 @@ "effect": "catalog:", "nitro": "3.0.1-alpha.1", "solid-js": "catalog:", + "sst": "catalog:", "vite": "catalog:", }, "devDependencies": { diff --git a/packages/stats/app/package.json b/packages/stats/app/package.json index ed8d6cd285..14e5264d13 100644 --- a/packages/stats/app/package.json +++ b/packages/stats/app/package.json @@ -21,6 +21,7 @@ "d3-scale": "4.0.2", "effect": "catalog:", "nitro": "3.0.1-alpha.1", + "sst": "catalog:", "solid-js": "catalog:", "vite": "catalog:" }, diff --git a/packages/stats/app/src/resource.d.ts b/packages/stats/app/src/resource.d.ts new file mode 100644 index 0000000000..098ea852ad --- /dev/null +++ b/packages/stats/app/src/resource.d.ts @@ -0,0 +1,10 @@ +import "sst/resource" + +declare module "sst/resource" { + export interface Resource { + EMAILOCTOPUS_API_KEY: { + type: "sst.sst.Secret" + value: string + } + } +} diff --git a/packages/stats/app/src/routes/api/newsletter.ts b/packages/stats/app/src/routes/api/newsletter.ts new file mode 100644 index 0000000000..50485fb485 --- /dev/null +++ b/packages/stats/app/src/routes/api/newsletter.ts @@ -0,0 +1,29 @@ +import { Resource } from "sst/resource" + +const listId = "8b9bb82c-9d5f-11f0-975f-0df6fd1e4945" + +export async function POST(event: { request: Request }) { + const contentType = event.request.headers.get("content-type") ?? "" + if (!contentType.includes("multipart/form-data") && !contentType.includes("application/x-www-form-urlencoded")) { + return Response.json({ error: "Email address is required" }, { status: 400 }) + } + + const form = await event.request.formData() + const emailAddress = form.get("email") + if (typeof emailAddress !== "string" || emailAddress.trim().length === 0) { + return Response.json({ error: "Email address is required" }, { status: 400 }) + } + + const response = await fetch(`https://api.emailoctopus.com/lists/${listId}/contacts`, { + method: "PUT", + headers: { + Authorization: `Bearer ${Resource.EMAILOCTOPUS_API_KEY.value}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email_address: emailAddress.trim(), + }), + }) + if (!response.ok) return Response.json({ error: "Failed to subscribe" }, { status: 502 }) + return Response.json({ success: true }) +} diff --git a/packages/stats/app/src/routes/index.css b/packages/stats/app/src/routes/index.css index 5c8286a853..862d11b876 100644 --- a/packages/stats/app/src/routes/index.css +++ b/packages/stats/app/src/routes/index.css @@ -67,6 +67,9 @@ --stats-dot: #d4d4d4; --stats-hero-muted: #5c5c5c; --stats-hero-pattern: #eeeeee; + --stats-logo-bg: #161616; + --stats-logo-fill: #454545; + --stats-logo-stroke: #e2e2e2; --stats-page-padding: 5rem; --stats-section-padding: 6rem; min-height: 100vh; @@ -343,7 +346,7 @@ gap: 56px; box-sizing: border-box; min-height: 0; - padding: 112px 0 24px; + padding: 112px clamp(32px, 4vw, 48px) 24px; color: var(--stats-text); font-family: "IBM Plex Mono", @@ -364,9 +367,10 @@ color: var(--stats-text); } -[data-page="stats"] [data-slot="footer-mark"] [data-slot="brand-mark"] { - width: 24px; - height: 30px; +[data-page="stats"] [data-slot="footer-mark"] [data-slot="opencode-mark"] { + display: block; + width: 40px; + height: 40px; } [data-page="stats"] [data-slot="footer-column"] { @@ -415,10 +419,19 @@ justify-content: center; width: fit-content; height: 28px; + margin: 0; padding: 0 12px; border: 1px solid var(--stats-line); + border-radius: 0; + appearance: none; background: var(--stats-bg); color: var(--stats-text) !important; + font: inherit; + font-size: 11px; + font-weight: 500; + line-height: 1; + text-decoration: none; + cursor: pointer; } [data-page="stats"] [data-slot="subscribe-button"]:hover { @@ -426,6 +439,176 @@ background: var(--stats-layer); } +[data-page="stats"] [data-slot="subscribe-button"]:focus-visible, +[data-page="stats"] [data-component="subscribe-modal"] button:focus-visible, +[data-page="stats"] [data-component="subscribe-modal"] input:focus-visible { + outline: 2px solid var(--stats-accent); + outline-offset: 2px; +} + +[data-page="stats"] [data-component="subscribe-modal"] { + position: fixed; + inset: 0; + z-index: 80; + display: grid; + place-items: center; + box-sizing: border-box; + padding: 8px; + color: var(--stats-text); + font-family: + "IBM Plex Mono", + var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace); +} + +[data-page="stats"] [data-slot="modal-scrim"] { + position: absolute; + inset: 0; + background: #00000066; + backdrop-filter: blur(2px); +} + +[data-page="stats"] [data-slot="modal-panel"] { + position: relative; + z-index: 1; + width: min(374px, calc(100vw - 16px)); + overflow: hidden; + background: var(--stats-layer); + box-shadow: + 0 0 0 0.5px #00000024, + 0 16px 32px #0000001f, + 0 8px 16px #00000014; +} + +[data-page="stats"] [data-slot="modal-brand"] { + position: relative; + display: flex; + align-items: center; + justify-content: center; + min-height: 122px; + background: #242424; + color: #ffffff; +} + +[data-page="stats"] [data-slot="modal-logo"] { + display: block; + width: 234px; + height: 42px; +} + +[data-page="stats"] [data-slot="modal-close"] { + position: absolute; + top: 0; + right: 0; + display: grid; + place-items: center; + width: 32px; + height: 32px; + margin: 0; + padding: 0; + border: 0; + border-radius: 0; + appearance: none; + background: transparent; + color: #ffffff; + cursor: pointer; +} + +[data-page="stats"] [data-slot="modal-close"]:hover { + background: #ffffff1a; +} + +[data-page="stats"] [data-slot="modal-body"] { + display: grid; + gap: 24px; + padding: 24px 12px 12px; + background: var(--stats-layer); +} + +[data-page="stats"] [data-slot="modal-intro"] { + display: grid; + gap: 8px; + text-align: center; +} + +[data-page="stats"] [data-slot="modal-intro"] h2 { + color: var(--stats-text); + font-size: 16px; + font-weight: 500; + line-height: 24px; + letter-spacing: 0; +} + +[data-page="stats"] [data-slot="modal-intro"] p { + color: var(--stats-muted); + font-size: 16px; + font-weight: 400; + line-height: 24px; +} + +[data-page="stats"] [data-slot="subscribe-form"] { + display: grid; + gap: 8px; +} + +[data-page="stats"] [data-slot="subscribe-form"] input, +[data-page="stats"] [data-slot="subscribe-form"] button { + box-sizing: border-box; + width: 100%; + height: 40px; + margin: 0; + border-radius: 0; + appearance: none; + font: inherit; + font-size: 13px; + line-height: 1; +} + +[data-page="stats"] [data-slot="subscribe-form"] input { + padding: 0 12px; + border: 1px solid var(--stats-line); + background: var(--stats-bg); + color: var(--stats-text); +} + +[data-page="stats"] [data-slot="subscribe-form"] input::placeholder { + color: var(--stats-faint); +} + +[data-page="stats"] [data-slot="subscribe-form"] button { + display: flex; + align-items: center; + justify-content: center; + border: 0; + background: #242424; + color: #ffffff; + font-weight: 500; + cursor: pointer; +} + +[data-page="stats"] [data-slot="subscribe-form"] button:disabled { + cursor: progress; + opacity: 0.7; +} + +[data-page="stats"] [data-slot="subscribe-feedback"]:empty { + display: none; +} + +[data-page="stats"] [data-slot="subscribe-feedback"] p { + text-align: center; + font-size: 11px; + font-weight: 500; + line-height: 16px; +} + +[data-page="stats"] [data-slot="subscribe-feedback"] p[data-state="success"] { + color: #198b43; +} + +[data-page="stats"] [data-slot="subscribe-feedback"] p[data-state="error"] { + color: #b82d35; +} + [data-page="stats"] [data-slot="footer-pattern"] { height: 16px; overflow: hidden; @@ -470,30 +653,6 @@ background: #198b43; } -[data-page="stats"] [data-slot="theme-toggle"] { - display: flex; - align-items: center; - height: 20px; - padding: 2px; - background: var(--stats-layer); -} - -[data-page="stats"] [data-slot="theme-toggle"] button { - display: grid; - place-items: center; - width: 18px; - height: 16px; - padding: 0; - border-radius: 0; - color: var(--stats-muted); - background: transparent; -} - -[data-page="stats"] [data-slot="theme-toggle"] button[data-active="true"] { - color: var(--stats-text); - background: var(--stats-bg); -} - [data-page="stats"] [data-component="content"] a { color: var(--stats-text); text-decoration: none; @@ -1373,6 +1532,10 @@ font-weight: 600; } +[data-page="stats"] [data-component="section-bridge"] { + display: none; +} + [data-page="stats"] [data-slot="section-title"] { max-width: 1200px; margin-bottom: 40px; @@ -1779,7 +1942,7 @@ background: transparent; color: var(--stats-text); font-size: 11px; - line-height: 1; + line-height: 16px; text-align: left; } @@ -1804,6 +1967,7 @@ overflow: hidden; color: var(--stats-muted); font-weight: 400; + line-height: 16px; text-overflow: ellipsis; white-space: nowrap; } @@ -1907,7 +2071,7 @@ } [data-page="stats"] [data-component="live-filter"] { - display: flex; + display: none; align-items: center; gap: 6px; padding: 0; @@ -1960,6 +2124,9 @@ --stats-dot: #303030; --stats-hero-muted: #808080; --stats-hero-pattern: #303030; + --stats-logo-bg: #f1ecec; + --stats-logo-fill: #b7b1b1; + --stats-logo-stroke: #211e1e; } [data-page="stats"] [data-component="chart-tooltip"] { @@ -2040,6 +2207,13 @@ } } +@media (min-width: 90rem) { + [data-page="stats"] [data-component="footer"] { + padding-right: 0; + padding-left: 0; + } +} + @media (max-width: 74rem) { [data-page="stats"] [data-section="top-models"], [data-page="stats"] [data-section="leaderboard"], diff --git a/packages/stats/app/src/routes/index.tsx b/packages/stats/app/src/routes/index.tsx index 42ec8f798e..0b1a801e7c 100644 --- a/packages/stats/app/src/routes/index.tsx +++ b/packages/stats/app/src/routes/index.tsx @@ -5,6 +5,7 @@ import ibmPlexMonoRegularLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/ import ibmPlexMonoMediumLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-Medium-Latin1.woff2?url" import ibmPlexMonoSemiBoldLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-SemiBold-Latin1.woff2?url" import ibmPlexMonoBoldLatin1 from "@ibm/plex/IBM-Plex-Mono/fonts/split/woff2/IBMPlexMono-Bold-Latin1.woff2?url" +import opencodeWordmarkDark from "../asset/logo-ornate-dark.svg" import { getStatsHomeData, type LeaderboardEntry, @@ -1318,7 +1319,18 @@ function StatsMark() { ) } +function OpenCodeMark() { + return ( + + ) +} + function Footer() { + const [subscribeOpen, setSubscribeOpen] = createSignal(false) const modelStats = [ { href: "#top-models", label: "Top Models" }, { href: "#leaderboard", label: "Leaderboard" }, @@ -1333,17 +1345,17 @@ function Footer() { const connect = [ { href: "mailto:hello@opencode.ai", label: "Contact us" }, { href: "https://opencode.ai/discord", label: "Community" }, - { href: "https://x.com/opencode_ai", label: "X" }, - { href: "https://github.com/sst/opencode", label: "GitHub" }, - { href: "https://youtube.com/@opencode-ai", label: "YouTube" }, + { href: "https://x.com/opencode", label: "X" }, + { href: "https://github.com/anomalyco/opencode", label: "GitHub" }, + { href: "https://www.youtube.com/@anomaly-co", label: "YouTube" }, ] return ( + ) +} + +function SubscribeModal(props: { onClose: () => void }) { + const [status, setStatus] = createSignal<"idle" | "pending" | "success" | "error">("idle") + const [message, setMessage] = createSignal("") + let input: HTMLInputElement | undefined + + onMount(() => { + if (typeof document === "undefined") return + const activeElement = document.activeElement instanceof HTMLElement ? document.activeElement : undefined + const htmlOverflow = document.documentElement.style.overflow + const bodyOverflow = document.body.style.overflow + document.documentElement.style.overflow = "hidden" + document.body.style.overflow = "hidden" + const focusTimeout = window.setTimeout(() => input?.focus(), 0) + const onKeyDown = (event: KeyboardEvent) => { + if (event.key === "Escape") props.onClose() + } + document.addEventListener("keydown", onKeyDown) + onCleanup(() => { + window.clearTimeout(focusTimeout) + document.documentElement.style.overflow = htmlOverflow + document.body.style.overflow = bodyOverflow + document.removeEventListener("keydown", onKeyDown) + activeElement?.focus() + }) + }) + + return ( +
+ Be the first to know
+
+ about new releases.
+
You're subscribed.
+{message()}
+