Skip to content

Commit af08310

Browse files
committed
Design tweaks
1 parent 9b6673f commit af08310

39 files changed

+2251
-687
lines changed

.vscode/settings.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
{
2-
"css.customData": [
3-
"./vscode.tailwind.json"
4-
],
2+
"css.customData": ["./vscode.tailwind.json"],
53
"typescript.tsdk": "node_modules/typescript/lib",
64
"typescript.enablePromptUseWorkspaceTsdk": true
7-
}
5+
}

app/(blog)/[slug]/page.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
export const dynamicParams = false;
2+
3+
import fs from 'fs';
4+
import { join } from 'path';
5+
import matter from 'gray-matter';
6+
7+
import md from 'markdown-it';
8+
import { notFound } from 'next/navigation';
9+
import { findLatestPosts } from '../../../src/utils/posts';
10+
11+
const postsDirectory = join(process.cwd(), 'src/blog');
12+
const getFormattedDate = (date) => date;
13+
14+
export async function generateStaticParams() {
15+
const posts = await findLatestPosts();
16+
return posts.map(({ slug }) => ({ slug }));
17+
}
18+
19+
async function fetchData(params) {
20+
const slug = params?.slug;
21+
try {
22+
const readFile = fs.readFileSync(join(postsDirectory, `${slug}.md`), 'utf-8');
23+
const { data: frontmatter, content } = matter(readFile);
24+
return {
25+
slug,
26+
...frontmatter,
27+
content,
28+
};
29+
} catch (e) {}
30+
31+
return null;
32+
}
33+
34+
export default async function Page({ params }) {
35+
const post = await fetchData(params);
36+
37+
if (!post) {
38+
return notFound();
39+
}
40+
return (
41+
<section class="mx-auto py-8 sm:py-16 lg:py-20">
42+
<article>
43+
<header class={post.image ? 'text-center' : ''}>
44+
<p class="mx-auto max-w-3xl px-4 sm:px-6">
45+
<time dateTime={post.publishDate}>{getFormattedDate(post.publishDate)}</time> ~{' '}
46+
{/* {Math.ceil(post.readingTime)} min read */}
47+
</p>
48+
<h1 className="leading-tighter font-heading mx-auto mb-8 max-w-3xl px-4 text-4xl font-bold tracking-tighter sm:px-6 md:text-5xl">
49+
{post.title}
50+
</h1>
51+
</header>
52+
<div
53+
className="prose-md prose-headings:font-heading prose-headings:leading-tighter container prose prose-lg mx-auto mt-8 max-w-3xl px-6 prose-headings:font-bold prose-headings:tracking-tighter prose-a:text-primary-600 prose-img:rounded-md prose-img:shadow-lg dark:prose-invert dark:prose-headings:text-slate-300 dark:prose-a:text-primary-400 sm:px-6 lg:prose-xl"
54+
dangerouslySetInnerHTML={{ __html: md().render(post.content) }}
55+
/>
56+
</article>
57+
</section>
58+
);
59+
}

app/(blog)/blog/page.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Image from 'next/image';
2+
import Link from 'next/link';
3+
4+
import { findLatestPosts } from '~/utils/posts';
5+
6+
export default async function Home({}) {
7+
const posts = await findLatestPosts();
8+
return (
9+
<div className="grid grid-cols-1 p-4 md:grid-cols-3 md:p-0 lg:grid-cols-4">
10+
{posts.map(({ slug, frontmatter }) => (
11+
<div key={slug} className="m-2 flex flex-col overflow-hidden rounded-xl border border-gray-200 shadow-lg">
12+
<Link href={`/${slug}`}>
13+
<Image width={650} height={340} alt={frontmatter.title} src={`/${frontmatter.image}`} />
14+
<h1 className="p-4">{frontmatter.title}</h1>
15+
</Link>
16+
</div>
17+
))}
18+
</div>
19+
);
20+
}

app/page.js

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,25 @@
1-
import Header from "~/components/widgets/Header";
2-
import Hero from "~/components/widgets/Hero";
3-
import Features3 from "~/components/widgets/Features3";
4-
import Announcement from "~/components/widgets/Announcement";
5-
import Steps from "~/components/widgets/Steps";
6-
import Features2 from "~/components/widgets/Features2";
7-
import SocialProof from "../src/components/widgets/SocialProof";
8-
import Testimonial from "~/components/widgets/Testimonial";
9-
import FAQs from "~/components/widgets/FAQs";
10-
import Pricing from "~/components/widgets/Pricing";
11-
import CallToAction from "~/components/widgets/CallToAction";
12-
import Footer from "~/components/widgets/Footer";
1+
import Hero from '~/components/widgets/Hero';
2+
import Features3 from '~/components/widgets/Features3';
3+
import Steps from '~/components/widgets/Steps';
4+
import Features2 from '~/components/widgets/Features2';
5+
import SocialProof from '../src/components/widgets/SocialProof';
6+
import Testimonial from '~/components/widgets/Testimonial';
7+
import FAQs from '~/components/widgets/FAQs';
8+
import Pricing from '~/components/widgets/Pricing';
9+
import CallToAction from '~/components/widgets/CallToAction';
1310

1411
export default function Page() {
1512
return (
1613
<>
17-
<Announcement />
18-
<Header />
19-
<main>
20-
<Hero />
21-
<SocialProof />
22-
<Features3 />
23-
<Features2 />
24-
<Steps />
25-
<Testimonial />
26-
<FAQs />
27-
<Pricing />
28-
<CallToAction />
29-
</main>
30-
<Footer />
14+
<Hero />
15+
<SocialProof />
16+
<Features3 />
17+
<Features2 />
18+
<Steps />
19+
<Testimonial />
20+
<FAQs />
21+
<Pricing />
22+
<CallToAction />
3123
</>
3224
);
3325
}

next-sitemap.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
module.exports = {
33
siteUrl: process.env.SITE_URL || 'https://tailnext.vercel.app',
44
generateRobotsTxt: true,
5-
}
5+
};

next.config.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
/** @type {import('next').NextConfig} */
22
module.exports = {
33
reactStrictMode: true,
4+
swcMinify: true,
45
images: {
5-
unoptimized: true,
6+
remotePatterns: [
7+
{
8+
protocol: 'https',
9+
hostname: 'images.unsplash.com',
10+
},
11+
{
12+
protocol: 'https',
13+
hostname: 'source.unsplash.com',
14+
},
15+
],
616
},
717
experimental: { appDir: true },
818
};

0 commit comments

Comments
 (0)