|
1 | 1 | import { formatDistance } from "date-fns"; |
2 | | -import { ArrowRightIcon } from "lucide-react"; |
| 2 | +import { ArrowRightIcon, FileTextIcon } from "lucide-react"; |
3 | 3 | import { unstable_cache } from "next/cache"; |
4 | 4 | import Link from "next/link"; |
| 5 | +import { Img } from "@/components/blocks/Img"; |
| 6 | +import { Button } from "@/components/ui/button"; |
5 | 7 |
|
6 | 8 | type ChangelogItem = { |
7 | 9 | published_at: string; |
8 | 10 | title: string; |
9 | 11 | url: string; |
| 12 | + feature_image: string; |
10 | 13 | }; |
11 | 14 |
|
12 | 15 | export async function Changelog() { |
13 | 16 | const changelog = await getChangelog(); |
14 | 17 |
|
15 | 18 | return ( |
16 | | - <div className="relative flex flex-col gap-6 border-border border-l py-2"> |
17 | | - {changelog.map((item) => ( |
18 | | - <div className="flex flex-row gap-2" key={item.title}> |
19 | | - <div className="-translate-x-1/2 size-2.5 shrink-0 translate-y-1/2 rounded-full bg-border" /> |
| 19 | + <div className="relative flex grow flex-col"> |
| 20 | + <div className="mb-4 flex items-center justify-between gap-4"> |
| 21 | + <div> |
| 22 | + <h2 className="mb-1 font-semibold text-2xl tracking-tight"> |
| 23 | + Changelog |
| 24 | + </h2> |
| 25 | + <p className="text-muted-foreground text-sm"> |
| 26 | + View the latest updates to thirdweb products and services |
| 27 | + </p> |
| 28 | + </div> |
| 29 | + |
| 30 | + <Button |
| 31 | + asChild |
| 32 | + className="gap-2 rounded-full bg-card" |
| 33 | + variant="outline" |
| 34 | + > |
| 35 | + <Link |
| 36 | + href="https://blog.thirdweb.com/changelog?utm_source=thirdweb&utm_campaign=changelog" |
| 37 | + rel="noopener noreferrer" |
| 38 | + target="_blank" |
| 39 | + > |
| 40 | + View All <ArrowRightIcon className="size-4" /> |
| 41 | + </Link> |
| 42 | + </Button> |
| 43 | + </div> |
| 44 | + |
| 45 | + <div className="grid grid-cols-1 gap-4 lg:grid-cols-3"> |
| 46 | + {changelog.map((item) => ( |
| 47 | + <div |
| 48 | + className="relative overflow-hidden rounded-xl border bg-card hover:border-active-border" |
| 49 | + key={item.title} |
| 50 | + > |
| 51 | + <Img |
| 52 | + alt={item.title} |
| 53 | + className="aspect-video w-full object-cover" |
| 54 | + fallback={ |
| 55 | + <div className="flex items-center justify-center bg-gradient-to-b from-card to-accent"> |
| 56 | + <div className="rounded-full border p-3"> |
| 57 | + <FileTextIcon className="size-5 text-muted-foreground" /> |
| 58 | + </div> |
| 59 | + </div> |
| 60 | + } |
| 61 | + src={item.feature_image} |
| 62 | + /> |
20 | 63 |
|
21 | | - <div className="flex flex-col"> |
22 | | - <Link |
23 | | - className="line-clamp-2 text-foreground text-sm hover:underline" |
24 | | - href={`${item.url}?utm_source=thirdweb&utm_campaign=changelog`} |
25 | | - target="_blank" |
26 | | - > |
27 | | - {item.title} |
28 | | - </Link> |
29 | | - <div className="mt-1 text-muted-foreground text-xs"> |
30 | | - {formatDistance(new Date(item.published_at), Date.now(), { |
31 | | - addSuffix: true, |
32 | | - })} |
| 64 | + <div className="border-t px-3 py-4"> |
| 65 | + <Link |
| 66 | + className="mb-2 line-clamp-2 font-medium text-base text-foreground before:absolute before:inset-0" |
| 67 | + href={`${item.url}?utm_source=thirdweb&utm_campaign=changelog`} |
| 68 | + target="_blank" |
| 69 | + > |
| 70 | + {item.title} |
| 71 | + </Link> |
| 72 | + |
| 73 | + <div className="text-muted-foreground text-sm"> |
| 74 | + {formatDistance(new Date(item.published_at), Date.now(), { |
| 75 | + addSuffix: true, |
| 76 | + })} |
| 77 | + </div> |
33 | 78 | </div> |
34 | 79 | </div> |
35 | | - </div> |
36 | | - ))} |
37 | | - <Link |
38 | | - className="flex items-center gap-2 pl-5 text-foreground text-sm hover:underline" |
39 | | - href="https://blog.thirdweb.com/changelog?utm_source=thirdweb&utm_campaign=changelog" |
40 | | - rel="noopener noreferrer" |
41 | | - target="_blank" |
42 | | - > |
43 | | - View More <ArrowRightIcon className="size-4" /> |
44 | | - </Link> |
| 80 | + ))} |
| 81 | + </div> |
45 | 82 | </div> |
46 | 83 | ); |
47 | 84 | } |
48 | 85 |
|
49 | 86 | const getChangelog = unstable_cache( |
50 | 87 | async () => { |
51 | 88 | const res = await fetch( |
52 | | - "https://thirdweb.ghost.io/ghost/api/content/posts/?key=49c62b5137df1c17ab6b9e46e3&fields=title,url,published_at&filter=tag:changelog&visibility:public&limit=10", |
| 89 | + "https://thirdweb.ghost.io/ghost/api/content/posts/?key=49c62b5137df1c17ab6b9e46e3&fields=title,url,published_at,feature_image&filter=tag:changelog&visibility:public&limit=12", |
53 | 90 | ); |
54 | 91 | if (!res.ok) { |
55 | 92 | return []; |
|
0 commit comments