Skip to content

Commit e61d8aa

Browse files
authored
Merge branch 'main' into main
2 parents 2200f97 + bcf9c0b commit e61d8aa

File tree

71 files changed

+6415
-2805
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+6415
-2805
lines changed

apps/www/app/(blog)/blog/[...slug]/page.tsx

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1+
/* eslint-disable @next/next/no-img-element */
12
import type { Metadata } from "next"
23
import Link from "next/link"
34
import { notFound } from "next/navigation"
45
import { mdxComponents } from "@/mdx-components"
56
import { ArrowLeftIcon } from "lucide-react"
7+
import { Badge } from "@/components/ui/badge"
68
import type { BlogPosting, BreadcrumbList, WithContext } from "schema-dts"
7-
89
import { siteConfig } from "@/config/site"
910
import { blogSource } from "@/lib/source"
1011
import { absoluteUrl, calculateReadingTime, formatDate } from "@/lib/utils"
1112
import { buttonVariants } from "@/components/ui/button"
1213
import { BlogTableOfContents } from "@/components/blog/table-of-contents"
14+
import { MobileTOC } from "@/components/blog/mobile-toc"
1315
import { SidebarCTA } from "@/components/sidebar-cta"
1416

1517
export const revalidate = false
@@ -182,29 +184,31 @@ export default async function BlogPage({ params }: PageProps) {
182184
<article className="mx-auto mt-5 max-w-6xl rounded-xl">
183185
{doc && (
184186
<div>
185-
<div className="relative overflow-hidden rounded-xl p-5 md:p-10">
187+
<div className="relative overflow-hidden rounded-xl p-5">
186188
<img
187189
src={doc.image}
188190
alt={doc.title}
189-
className="border-border size-full rounded-xl border object-cover object-left"
191+
className="size-full rounded-xl object-cover object-left border border-border"
190192
/>
191193
</div>
192-
<div className="border-border mx-auto flex flex-col items-center justify-center gap-y-2 border-y p-5">
193-
<div className="mx-auto flex max-w-4xl flex-col items-center justify-center gap-y-2">
194+
<div className="mx-auto flex flex-col items-center justify-center gap-y-2 p-5">
195+
<div className="mx-auto flex max-w-3xl flex-col items-center justify-center gap-y-4">
194196
<h1 className="text-center text-3xl font-semibold tracking-tighter text-balance md:text-5xl">
195197
{doc.title}
196198
</h1>
197199
<p className="text-secondary-foreground text-center text-balance md:text-lg">
198200
{doc.description}
199201
</p>
200-
{doc.publishedOn && (
201-
<time className="text-secondary-foreground text-sm">
202-
{formatDate(doc.publishedOn)}
203-
</time>
204-
)}
202+
<div className="text-secondary-foreground flex items-center justify-center gap-x-2 text-sm">
203+
{doc.publishedOn && (
204+
<time>{formatDate(doc.publishedOn)}</time>
205+
)}
206+
{doc.publishedOn && <span>·</span>}
207+
<span>{calculateReadingTime(content)} min read</span>
208+
</div>
205209
</div>
206210
</div>
207-
<div className="border-border text-secondary-foreground flex items-center justify-center gap-x-2 border-b p-3 text-sm">
211+
<div className="text-secondary-foreground flex items-center justify-center gap-x-2 p-3 text-sm">
208212
{(() => {
209213
const docTag = doc.tags
210214
const tags = docTag
@@ -215,21 +219,19 @@ export default async function BlogPage({ params }: PageProps) {
215219

216220
return (
217221
tags.length > 0 && (
218-
<>
219-
<span>{calculateReadingTime(content)} min read</span>
220-
<span>·</span>
221-
<div className="flex flex-wrap gap-1">
222-
{tags.map((tag) => (
223-
<Link
224-
key={tag}
225-
href={`/blog?tag=${encodeURIComponent(tag)}`}
226-
className="border-border bg-primary/5 hover:bg-primary/10 rounded-full border px-2.5 py-0.5 transition-colors"
227-
>
222+
<div className="flex flex-wrap gap-1 items-center justify-center">
223+
{tags.map((tag) => (
224+
<Link
225+
key={tag}
226+
href={`/blog?tag=${encodeURIComponent(tag)}`}
227+
228+
>
229+
<Badge variant="secondary" className="border border-border text-xs">
228230
{tag}
229-
</Link>
230-
))}
231-
</div>
232-
</>
231+
</Badge>
232+
</Link>
233+
))}
234+
</div>
233235
)
234236
)
235237
})()}
@@ -247,6 +249,7 @@ export default async function BlogPage({ params }: PageProps) {
247249
</div>
248250
</div>
249251
</article>
252+
<MobileTOC />
250253
</div>
251254
</>
252255
)

apps/www/app/(blog)/blog/page.tsx

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable @next/next/no-img-element */
12
import type { Metadata } from "next"
23
import Link from "next/link"
34
import type { Blog, BreadcrumbList, WithContext } from "schema-dts"
@@ -12,6 +13,7 @@ import {
1213
normalizeTag,
1314
pluralize,
1415
} from "@/lib/utils"
16+
import { Badge } from "@/components/ui/badge"
1517

1618
export const revalidate = false
1719
export const dynamic = "force-static"
@@ -43,8 +45,6 @@ export default async function Page({
4345
return dateB - dateA
4446
})
4547

46-
const allTags = posts.flatMap((p) => normalizeTag(p.data?.tags))
47-
const tags = [...new Set(allTags)].filter(Boolean).sort()
4848
const filteredPosts = selectedTag
4949
? posts.filter((p) => normalizeTag(p.data?.tags).includes(selectedTag))
5050
: posts
@@ -127,21 +127,21 @@ export default async function Page({
127127
__html: serializedBreadcrumbStructuredData,
128128
}}
129129
/>
130-
<main className="mx-auto w-full max-w-6xl px-6 py-8">
131-
<header className="mb-8 space-y-4">
130+
<main className="container mx-auto py-10 md:py-14 px-10">
131+
<header className="mb-12 space-y-3">
132132
<div>
133-
<h1 className="text-3xl font-bold tracking-tight">Blog</h1>
133+
<h1 className="text-3xl font-semibold tracking-tight">Blog</h1>
134134
<p className="text-muted-foreground mt-2 text-lg">
135135
{BLOG_DESCRIPTION}
136136
</p>
137137
</div>
138138

139139
{filteredPosts.length > 0 && (
140-
<p className="text-muted-foreground text-sm">
140+
<Badge variant="default" className="text-xs shadow-none">
141141
{selectedTag
142142
? `${pluralize(filteredPosts.length, "article")} tagged with "${selectedTag}"`
143143
: `${pluralize(filteredPosts.length, "article")} total`}
144-
</p>
144+
</Badge>
145145
)}
146146
</header>
147147

@@ -192,65 +192,64 @@ export default async function Page({
192192
)}
193193
</div>
194194
) : (
195-
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
195+
<div className="grid gap-8 sm:grid-cols-2 lg:grid-cols-3">
196196
{filteredPosts.map(async (post) => {
197197
const content = await post.data?.getText("raw")
198198
return (
199199
<article
200200
key={post.url}
201-
className="group bg-card hover:bg-accent/5 flex flex-col overflow-hidden rounded-xl border transition-all duration-200"
201+
className="group flex flex-col rounded-lg border"
202202
>
203203
<Link href={post.url} className="flex h-full flex-col">
204204
{post.data?.image && (
205-
<div className="aspect-video overflow-hidden">
205+
<div className="border-b overflow-hidden rounded-t-lg">
206206
<img
207207
src={post.data.image}
208208
alt={post.data?.title ?? post.url}
209209
width={640}
210210
height={360}
211-
className="h-full w-full object-cover"
211+
className="w-full h-auto object-contain transition-transform duration-300 group-hover:scale-[1.02]"
212212
/>
213213
</div>
214214
)}
215215

216-
<div className="flex flex-1 flex-col space-y-4 p-6">
216+
<div className="flex flex-1 flex-col space-y-3 p-6">
217217
<div className="flex-1 space-y-2">
218-
<h2 className="group-hover:text-primary line-clamp-2 text-xl leading-tight font-semibold transition-colors">
218+
<h2 className="group-hover:text-primary line-clamp-2 text-xl font-semibold leading-tight transition-colors">
219219
{post.data?.title ?? post.url}
220220
</h2>
221221
{post.data?.description && (
222-
<p className="text-muted-foreground line-clamp-3 text-sm leading-relaxed">
222+
<p className="text-muted-foreground line-clamp-2 text-sm leading-relaxed">
223223
{post.data.description}
224224
</p>
225225
)}
226226
</div>
227227

228-
<div className="text-muted-foreground flex flex-col gap-2 text-xs">
229-
<div className="flex items-center gap-2">
230-
{post.data?.publishedOn && (
231-
<time dateTime={post.data.publishedOn}>
232-
{formatDate(post.data.publishedOn)}
233-
</time>
234-
)}
235-
{post.data?.publishedOn && <span>·</span>}
236-
<span>
237-
{calculateReadingTime(content ?? "")} min read
238-
</span>
239-
</div>
240-
241-
{normalizeTag(post.data?.tags).length > 0 && (
242-
<div className="flex flex-wrap gap-1">
243-
{normalizeTag(post.data.tags).map((tag) => (
244-
<span
245-
key={tag}
246-
className="bg-muted/50 rounded-md border px-2 py-1 text-xs"
247-
>
248-
{tag}
249-
</span>
250-
))}
251-
</div>
228+
<div className="text-muted-foreground flex items-center gap-2 text-xs">
229+
{post.data?.publishedOn && (
230+
<time dateTime={post.data.publishedOn}>
231+
{formatDate(post.data.publishedOn)}
232+
</time>
252233
)}
234+
{post.data?.publishedOn && <span>·</span>}
235+
<span>
236+
{calculateReadingTime(content ?? "")} min read
237+
</span>
253238
</div>
239+
240+
{normalizeTag(post.data?.tags).length > 0 && (
241+
<div className="flex flex-wrap gap-1.5">
242+
{normalizeTag(post.data.tags).slice(0, 3).map((tag) => (
243+
<Badge
244+
key={tag}
245+
variant="secondary"
246+
className="border border-border text-xs"
247+
>
248+
{tag}
249+
</Badge>
250+
))}
251+
</div>
252+
)}
254253
</div>
255254
</Link>
256255
</article>

apps/www/app/(marketing)/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default async function MarketingLayout({
1515
<SiteHeader />
1616
<main className="flex-1">{children}</main>
1717
<SiteFooter />
18-
<div className="before:animate-rainbow pointer-events-none absolute inset-0 h-24 w-full before:absolute before:bottom-[-20%] before:left-1/2 before:z-0 before:h-4/5 before:w-3/5 before:-translate-x-1/2 before:bg-[linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))] before:bg-[length:200%] before:opacity-20 before:[filter:blur(calc(4*1rem))]" />
18+
<div className="before:animate-rainbow pointer-events-none absolute inset-0 h-24 w-full before:absolute before:bottom-[-20%] before:left-1/2 before:z-0 before:h-4/5 before:w-3/5 before:-translate-x-1/2 before:bg-[linear-gradient(90deg,var(--color-1),var(--color-5),var(--color-3),var(--color-4),var(--color-2))] before:bg-size-[200%] before:opacity-20 before:filter-[blur(calc(4*1rem))]" />
1919
</>
2020
)
2121
}

apps/www/app/og/route.tsx

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -45,55 +45,53 @@ export async function GET(request: Request) {
4545
const [fonts] = await Promise.all([loadAssets()])
4646

4747
return new ImageResponse(
48-
(
49-
<div
50-
tw="flex h-full w-full bg-white text-black"
51-
style={{ fontFamily: "Geist Sans" }}
52-
>
53-
<div tw="flex border absolute border-neutral-200 border-dashed inset-y-0 left-16 w-[1px]" />
54-
<div tw="flex border absolute border-neutral-200 border-dashed inset-y-0 right-16 w-[1px]" />
55-
<div tw="flex border absolute border-neutral-200 inset-x-0 h-[1px] top-16" />
56-
<div tw="flex border absolute border-neutral-200 inset-x-0 h-[1px] bottom-16" />
57-
{(title || description) && (
58-
<div tw="flex absolute flex-row items-center justify-center bottom-24 right-24 text-white">
59-
<Icons.logo width={48} height={48} />
60-
<div tw="text-black flex text-[32px] font-semibold tracking-tight ml-2">
61-
Magic UI
48+
<div
49+
tw="flex h-full w-full bg-white text-black"
50+
style={{ fontFamily: "Geist Sans" }}
51+
>
52+
<div tw="flex border absolute border-neutral-200 border-dashed inset-y-0 left-16 w-[1px]" />
53+
<div tw="flex border absolute border-neutral-200 border-dashed inset-y-0 right-16 w-[1px]" />
54+
<div tw="flex border absolute border-neutral-200 inset-x-0 h-[1px] top-16" />
55+
<div tw="flex border absolute border-neutral-200 inset-x-0 h-[1px] bottom-16" />
56+
{(title || description) && (
57+
<div tw="flex absolute flex-row items-center justify-center bottom-24 right-24 text-white">
58+
<Icons.logo width={48} height={48} />
59+
<div tw="text-black flex text-[32px] font-semibold tracking-tight ml-2">
60+
Magic UI
61+
</div>
62+
</div>
63+
)}
64+
<div tw="flex flex-col absolute justify-center items-center inset-0 p-24 w-full h-full">
65+
{title || description ? (
66+
<div tw="flex flex-col items-center justify-center text-center w-full h-full">
67+
<div tw="tracking-tight flex flex-col justify-center text-black text-balance font-semibold text-[80px]">
68+
{title}
69+
</div>
70+
<div tw="text-[40px] text-gray-600 mt-6 text-balance font-normal">
71+
{description}
6272
</div>
6373
</div>
64-
)}
65-
<div tw="flex flex-col absolute justify-center items-center inset-0 p-24 w-full h-full">
66-
{title || description ? (
67-
<div tw="flex flex-col items-center justify-center text-center w-full h-full">
68-
<div tw="tracking-tight flex flex-col justify-center text-black text-balance font-semibold text-[80px]">
69-
{title}
70-
</div>
71-
<div tw="text-[40px] text-gray-600 mt-6 text-balance font-normal">
72-
{description}
74+
) : (
75+
<div tw="flex flex-col items-center justify-center text-center w-full h-full">
76+
<div tw="flex flex-row items-center justify-center space-x-4">
77+
<Icons.logo width={48} height={48} />
78+
<div tw="text-black flex text-[32px] font-semibold tracking-tight ml-2">
79+
Magic UI
7380
</div>
7481
</div>
75-
) : (
76-
<div tw="flex flex-col items-center justify-center text-center w-full h-full">
77-
<div tw="flex flex-row items-center justify-center space-x-4">
78-
<Icons.logo width={48} height={48} />
79-
<div tw="text-black flex text-[32px] font-semibold tracking-tight ml-2">
80-
Magic UI
81-
</div>
82-
</div>
83-
<div tw="text-black flex text-[80px] font-semibold tracking-tight">
84-
Modern Next.js Templates
85-
</div>
86-
<div tw="text-gray-600 text-2xl flex">
87-
<p>
88-
Built with React, Typescript, shadcn/ui, Tailwind CSS, and
89-
Motion.
90-
</p>
91-
</div>
82+
<div tw="text-black flex text-[80px] font-semibold tracking-tight">
83+
Modern Next.js Templates
9284
</div>
93-
)}
94-
</div>
85+
<div tw="text-gray-600 text-2xl flex">
86+
<p>
87+
Built with React, Typescript, shadcn/ui, Tailwind CSS, and
88+
Motion.
89+
</p>
90+
</div>
91+
</div>
92+
)}
9593
</div>
96-
),
94+
</div>,
9795
{
9896
width: 1200,
9997
height: 628,

0 commit comments

Comments
 (0)