diff --git a/apps/web/app/api/sponsors-webhook/route.ts b/apps/web/app/api/sponsors-webhook/route.ts
new file mode 100644
index 00000000..9c29a1e7
--- /dev/null
+++ b/apps/web/app/api/sponsors-webhook/route.ts
@@ -0,0 +1,18 @@
+import { revalidatePath } from "next/cache"
+
+export async function POST(request: Request) {
+ try {
+ const text = await request.text()
+ console.log("[GitHub] Webhook received", text)
+
+ revalidatePath("/test")
+ } catch (error: any) {
+ return new Response(`Webhook error: ${error.message}`, {
+ status: 400,
+ })
+ }
+
+ return new Response("Success!", {
+ status: 200,
+ })
+}
diff --git a/apps/web/app/landing/sponsors.tsx b/apps/web/app/landing/sponsors.tsx
index c63a072e..1747c074 100644
--- a/apps/web/app/landing/sponsors.tsx
+++ b/apps/web/app/landing/sponsors.tsx
@@ -8,6 +8,8 @@ import Image from "next/image"
import Link from "next/link"
import sponsorData from "./sponsors.json"
import { Check, CheckCheck, GithubIcon, Heart, Star } from "lucide-react"
+import { cn } from "@/lib/utils"
+import { TimeAgo } from "@/components/time-ago"
export function Pricing() {
const current = 625
@@ -84,6 +86,65 @@ export function Pricing() {
)
}
+export async function LatestSponsor({ className }: { className?: string }) {
+ const GITHUB_TOKEN = process.env.GITHUB_TOKEN
+ if (!GITHUB_TOKEN) {
+ throw new Error("Missing process.env.GITHUB_TOKEN")
+ }
+
+ const r = await fetch("https://api.github.com/graphql", {
+ method: "POST",
+ body: JSON.stringify({ query: latestSponsorsQuery }),
+ headers: { Authorization: "bearer " + GITHUB_TOKEN },
+ })
+ if (!r.ok) {
+ throw new Error(`Failed to fetch: ${r.status} ${r.statusText}`)
+ }
+ const { data, errors } = await r.json()
+ if (errors) {
+ throw new Error(JSON.stringify(errors))
+ }
+
+ const sponsors = data.organization.sponsorshipsAsMaintainer.edges
+ if (!sponsors.length) {
+ throw new Error("No sponsors found")
+ }
+
+ const latest = sponsors[0].node
+
+ return (
+
+ {JSON.stringify(latest, null, 2)}
*/}
+
+ )
+}
+
export function TopSponsors({
title = "Top Sponsors",
scale = 1,
@@ -440,3 +501,37 @@ function BrowserStack() {
)
}
+
+const latestSponsorsQuery = `query {
+ organization(login: "code-hike") {
+ sponsorshipsAsMaintainer(first: 50, orderBy: {field: CREATED_AT, direction: DESC}, activeOnly: false) {
+ edges {
+ node {
+ createdAt
+ privacyLevel
+ tier {
+ name
+ monthlyPriceInDollars
+ }
+ sponsorEntity {
+ ... on User {
+ login
+ name
+ avatarUrl
+ websiteUrl
+ location
+ }
+ ... on Organization {
+ login
+ name
+ avatarUrl
+ websiteUrl
+ location
+ }
+ }
+ }
+ }
+ }
+ }
+}
+`
diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx
index 3f700551..a43fb71b 100644
--- a/apps/web/app/page.tsx
+++ b/apps/web/app/page.tsx
@@ -1,6 +1,7 @@
import Link from "next/link"
import {
AllSponsors,
+ LatestSponsor,
PoweredBy,
Pricing,
TopSponsors,
@@ -38,7 +39,9 @@ export default function HomePage() {