diff --git a/frontend/components/ListPanel.tsx b/frontend/components/ListPanel.tsx index 53b5a968..a303f94a 100644 --- a/frontend/components/ListPanel.tsx +++ b/frontend/components/ListPanel.tsx @@ -17,9 +17,9 @@ export function ListPanel(
{title && ( -

+

{title} -

+ )} {subtitle && (
diff --git a/frontend/components/NewsCard.tsx b/frontend/components/NewsCard.tsx new file mode 100644 index 00000000..e0b1b392 --- /dev/null +++ b/frontend/components/NewsCard.tsx @@ -0,0 +1,37 @@ +// Copyright 2024 the JSR authors. All rights reserved. MIT license. +export function NewsCard({ + title, + description, + image, + url, +}: { + title: string; + description: string; + image: string; + url: string; +}) { + return ( +
  • + + +
    +

    + {title} +

    +

    + {description} +

    +
    +
    +
  • + ); +} diff --git a/frontend/routes/index.tsx b/frontend/routes/index.tsx index d2f95986..9786fa89 100644 --- a/frontend/routes/index.tsx +++ b/frontend/routes/index.tsx @@ -9,9 +9,18 @@ import { Head } from "$fresh/runtime.ts"; import { ComponentChildren } from "preact"; import { HomepageHero } from "../components/HomepageHero.tsx"; import { Logo } from "../components/Logo.tsx"; +import { NewsCard } from "../components/NewsCard.tsx"; + +interface Post { + title: string; + description: string; + image: string; + link: string; +} interface Data { stats: Stats; + posts: Post[]; } export default function Home({ data }: PageProps) { @@ -32,17 +41,46 @@ export default function Home({ data }: PageProps) { apiKey={Deno.env.get("ORAMA_PACKAGE_PUBLIC_API_KEY")} indexId={Deno.env.get("ORAMA_PACKAGE_PUBLIC_INDEX_ID")} /> -
    - - {data.stats.featured.map(PackageToPanelEntry)} - - - {data.stats.updated.map(PackageVersionToPanelEntry)} - - - {data.stats.newest.map(PackageToPanelEntry)} - -
    + {data.posts.length > 0 && ( +
    +

    + Latest updates +

    +
      + {data?.posts?.slice(0, 3).map((post) => ( + + ))} +
    + + More JSR updates + +
    + )} + +
    +

    + Packages +

    +
    + + {data.stats.featured.map(PackageToPanelEntry)} + + + {data.stats.updated.map(PackageVersionToPanelEntry)} + + + {data.stats.newest.map(PackageToPanelEntry)} + +
    +

    = { const statsResp = await ctx.state.api.get(path`/stats`, undefined, { anonymous: true, }); + + let posts: Post[] = []; + try { + const jsrPosts = await fetch("https://deno.com/blog/json?tag=JSR"); + if (jsrPosts.ok) { + posts = await jsrPosts.json() as Post[]; + console.log(posts); + } + } catch (e) { + // ignore + } + if (!statsResp.ok) throw statsResp; // gracefully handle this - return ctx.render({ stats: statsResp.data }, { + return ctx.render({ stats: statsResp.data, posts: posts || [] }, { headers: ctx.state.api.hasToken() ? undefined : { "Cache-Control": "public, s-maxage=60" },