Skip to content

Commit c6e9ca1

Browse files
committed
add blog with Sanity integration
1 parent 0c99b1e commit c6e9ca1

File tree

145 files changed

+40724
-11297
lines changed

Some content is hidden

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

145 files changed

+40724
-11297
lines changed

app/api/sentry-tunnel/route.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ export async function POST(req: NextRequest) {
3838
});
3939

4040
const response = await fetch(newRequest);
41-
console.error("Sentry proxy response status:", response.status);
4241

4342
return new Response(response.body, {
4443
status: response.status,

app/apis/[providerSlug]/[serviceSlug]/page.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function stripMarkdown(markdown: string): string {
2424
}
2525
export function getData(
2626
providerSlug: string,
27-
serviceSlug?: string | null
27+
serviceSlug?: string | null,
2828
): any | null {
2929
const apiList = list as Record<string, any>;
3030

@@ -46,7 +46,7 @@ export function getData(
4646
}
4747

4848
console.warn(
49-
`No API found for provider: ${providerSlug}, service: ${serviceSlug}`
49+
`No API found for provider: ${providerSlug}, service: ${serviceSlug}`,
5050
);
5151
return null;
5252
}
@@ -89,7 +89,7 @@ function processApiData(key: string, api: any) {
8989
version,
9090
swaggerUrl: details?.swaggerUrl || "",
9191
swaggerYamlUrl: details?.swaggerYamlUrl || "",
92-
})
92+
}),
9393
);
9494

9595
const description = info.description || "No description available";
@@ -146,7 +146,7 @@ export async function generateMetadata(
146146
{
147147
params,
148148
}: { params: Promise<{ providerSlug: string; serviceSlug: string }> },
149-
parent: ResolvingMetadata
149+
parent: ResolvingMetadata,
150150
): Promise<Metadata> {
151151
const { providerSlug, serviceSlug } = await params;
152152
const api = getData(providerSlug, serviceSlug);

app/blog/[slug]/page.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { notFound } from "next/navigation";
2+
3+
import PostHero from "@/components/blocks/post-hero";
4+
5+
import PortableTextRenderer from "@/components/portable-text-renderer";
6+
import {
7+
fetchSanityPostBySlug,
8+
fetchSanityPostsStaticParams,
9+
} from "@/sanity/lib/fetch";
10+
import { generatePageMetadata } from "@/sanity/lib/metadata";
11+
12+
export async function generateStaticParams() {
13+
const posts = await fetchSanityPostsStaticParams();
14+
15+
return posts.map((post) => ({
16+
slug: post.slug?.current,
17+
}));
18+
}
19+
20+
export async function generateMetadata(props: {
21+
params: Promise<{ slug: string }>;
22+
}) {
23+
const params = await props.params;
24+
const post = await fetchSanityPostBySlug({ slug: params.slug });
25+
26+
if (!post) {
27+
notFound();
28+
}
29+
30+
return generatePageMetadata({ page: post, slug: `/blog/${params.slug}` });
31+
}
32+
33+
export default async function PostPage(props: {
34+
params: Promise<{ slug: string }>;
35+
}) {
36+
const params = await props.params;
37+
const post = await fetchSanityPostBySlug(params);
38+
39+
if (!post) {
40+
notFound();
41+
}
42+
43+
return (
44+
<section>
45+
<div className="container py-16 xl:py-20">
46+
<article className="max-w-3xl mx-auto">
47+
<PostHero {...post} />
48+
{post.body && <PortableTextRenderer value={post.body} />}
49+
</article>
50+
</div>
51+
</section>
52+
);
53+
}

app/blog/layout.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { DisableDraftMode } from "@/components/disable-draft-mode";
2+
import { VisualEditing } from "next-sanity";
3+
import { draftMode } from "next/headers";
4+
import { SanityLive } from "@/sanity/lib/live";
5+
6+
export default async function MainLayout({
7+
children,
8+
}: {
9+
children: React.ReactNode;
10+
}) {
11+
return (
12+
<>
13+
<div>{children}</div>
14+
<SanityLive />
15+
{(await draftMode()).isEnabled && (
16+
<>
17+
<DisableDraftMode />
18+
<VisualEditing />
19+
</>
20+
)}
21+
</>
22+
);
23+
}

app/blog/page.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Blocks from "@/components/blocks";
2+
import { fetchSanityPageBySlug } from "@/sanity/lib/fetch";
3+
import { generatePageMetadata } from "@/sanity/lib/metadata";
4+
import MissingSanityPage from "@/components/ui/missing-sanity-page";
5+
6+
export async function generateMetadata() {
7+
const page = await fetchSanityPageBySlug({ slug: "blog" });
8+
9+
return generatePageMetadata({ page, slug: "blog" });
10+
}
11+
12+
export default async function IndexPage() {
13+
const page = await fetchSanityPageBySlug({ slug: "blog" });
14+
15+
if (!page) {
16+
return MissingSanityPage({ document: "page", slug: "blog" });
17+
}
18+
19+
return <Blocks blocks={page?.blocks ?? []} />;
20+
}

app/globals.css

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,29 @@
7777
--secondary-color: var(--sec);
7878
--secondary-color-light: var(--sec-light);
7979
}
80-
80+
@utility container {
81+
width: 100%;
82+
margin-left: auto;
83+
margin-right: auto;
84+
padding-left: 1rem;
85+
padding-right: 1rem;
86+
@media (width >= theme(--breakpoint-sm)) {
87+
max-width: 640px;
88+
padding-left: 2rem;
89+
padding-right: 2rem;
90+
}
91+
@media (width >= theme(--breakpoint-md)) {
92+
max-width: 768px;
93+
}
94+
@media (width >= theme(--breakpoint-lg)) {
95+
max-width: 1024px;
96+
}
97+
@media (width >= theme(--breakpoint-xl)) {
98+
max-width: 1280px;
99+
padding-left: 4rem;
100+
padding-right: 4rem;
101+
}
102+
}
81103
:root {
82104
--radius: 0.625rem;
83105
--background: #ffffff;
@@ -191,4 +213,3 @@
191213
font-size: var(--small-font-size, 14px);
192214
}
193215
}
194-

app/layout.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ export default function RootLayout({
6767
<main className="min-h-[calc(100vh-7rem)] bg-white">{children}</main>
6868

6969
<Footer />
70-
7170
</body>
7271
</html>
7372
);

components/ApiButtons.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export default function ApiButtons({
4343
onClick={() =>
4444
downloadFile(
4545
swaggerUrl,
46-
`${title}${version ? `-v${version}` : ""}-swagger.json`
46+
`${title}${version ? `-v${version}` : ""}-swagger.json`,
4747
)
4848
}
4949
className="py-2 px-4 bg-[#388c9a] rounded text-white hover:bg-[#2a6b77] flex items-center gap-2 transition-colors duration-200"
@@ -57,7 +57,7 @@ export default function ApiButtons({
5757
onClick={() =>
5858
downloadFile(
5959
swaggerYamlUrl,
60-
`${title}${version ? `-v${version}` : ""}-swagger.yaml`
60+
`${title}${version ? `-v${version}` : ""}-swagger.yaml`,
6161
)
6262
}
6363
className="py-2 px-4 bg-[#388c9a] rounded text-white hover:bg-[#2a6b77] flex items-center gap-2 transition-colors duration-200"
@@ -71,7 +71,7 @@ export default function ApiButtons({
7171
onClick={() =>
7272
downloadFile(
7373
origUrl,
74-
`${title}${version ? `-v${version}` : ""}-original.json`
74+
`${title}${version ? `-v${version}` : ""}-original.json`,
7575
)
7676
}
7777
className="py-2 px-4 bg-[#388c9a] rounded text-white hover:bg-[#2a6b77] flex items-center gap-2 transition-colors duration-200"

components/ApiGrid.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export function ApiGrid({ gridColumns, pageSize }: ApiGridProps) {
5656
showMore();
5757
}
5858
},
59-
[hasMore, loading, stalled, showMore]
59+
[hasMore, loading, stalled, showMore],
6060
);
6161

6262
useEffect(() => {
@@ -92,7 +92,7 @@ export function ApiGrid({ gridColumns, pageSize }: ApiGridProps) {
9292
{Array.from({ length: Math.min(pageSize, gridColumns * 2) }).map(
9393
(_, index) => (
9494
<CardSkeleton key={`skeleton-loading-${index}`} />
95-
)
95+
),
9696
)}
9797
</div>
9898
) : (
@@ -114,7 +114,7 @@ export function ApiGrid({ gridColumns, pageSize }: ApiGridProps) {
114114
{Array.from({ length: Math.min(pageSize, gridColumns) }).map(
115115
(_, index) => (
116116
<CardSkeleton key={`skeleton-more-${index}`} />
117-
)
117+
),
118118
)}
119119
</div>
120120
)}

components/FormAddApi.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,13 @@ export default function FormAddApi() {
111111
const up = new URL(formData.url);
112112
if (!up.pathname || up.pathname === "/") {
113113
alert(
114-
"Please specify a machine-readable API definition location, not a website root URL"
114+
"Please specify a machine-readable API definition location, not a website root URL",
115115
);
116116
return false;
117117
}
118118
if (up.pathname.endsWith(".html")) {
119119
alert(
120-
"Please specify a machine-readable API definition location, not an html page"
120+
"Please specify a machine-readable API definition location, not an html page",
121121
);
122122
return false;
123123
}
@@ -145,7 +145,7 @@ export default function FormAddApi() {
145145
}
146146
if (res.ok && ct && ct.startsWith("text/html")) {
147147
alert(
148-
"That looks like a web-page, not a machine-readable API definition"
148+
"That looks like a web-page, not a machine-readable API definition",
149149
);
150150
return false;
151151
}
@@ -188,7 +188,7 @@ export default function FormAddApi() {
188188
};
189189

190190
const handleInputChange = (
191-
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>
191+
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>,
192192
) => {
193193
const { name, value } = e.target;
194194
setFormData((prev) => ({

0 commit comments

Comments
 (0)