Skip to content

Commit 77c0ac7

Browse files
authored
Merge pull request #40 from thedevdavid/release/0.6.0
Release/0.6.0
2 parents 395405a + 603d17b commit 77c0ac7

Some content is hidden

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

48 files changed

+4567
-2658
lines changed

.env.example

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
#Next
22
NEXT_PUBLIC_BASE_URL=https://localhost:3000
3+
4+
#Analytics
35
NEXT_PUBLIC_UMAMI_SCRIPT_URL=
4-
NEXT_PUBLIC_UMAMI_WEBSITE_ID=
6+
NEXT_PUBLIC_UMAMI_WEBSITE_ID=
7+
8+
#Email
9+
EMAIL_API_BASE=
10+
NEXT_PUBLIC_EMAIL_API_KEY=
11+
NEXT_PUBLIC_EMAIL_GROUP_ID=

.github/ISSUE_TEMPLATE/bug_report.md

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
---
22
name: Bug report
33
about: Create a report to help us improve
4-
title: ''
5-
labels: ''
6-
assignees: ''
7-
4+
title: ""
5+
labels: ""
6+
assignees: ""
87
---
98

109
**Describe the bug**
1110
A clear and concise description of what the bug is.
1211

1312
**To Reproduce**
1413
Steps to reproduce the behavior:
14+
1515
1. Go to '...'
1616
2. Click on '....'
1717
3. Scroll down to '....'
@@ -24,15 +24,17 @@ A clear and concise description of what you expected to happen.
2424
If applicable, add screenshots to help explain your problem.
2525

2626
**Desktop (please complete the following information):**
27-
- OS: [e.g. iOS]
28-
- Browser [e.g. chrome, safari]
29-
- Version [e.g. 22]
27+
28+
- OS: [e.g. iOS]
29+
- Browser [e.g. chrome, safari]
30+
- Version [e.g. 22]
3031

3132
**Smartphone (please complete the following information):**
32-
- Device: [e.g. iPhone6]
33-
- OS: [e.g. iOS8.1]
34-
- Browser [e.g. stock browser, safari]
35-
- Version [e.g. 22]
33+
34+
- Device: [e.g. iPhone6]
35+
- OS: [e.g. iOS8.1]
36+
- Browser [e.g. stock browser, safari]
37+
- Version [e.g. 22]
3638

3739
**Additional context**
3840
Add any other context about the problem here.

.github/ISSUE_TEMPLATE/feature_request.md

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
---
22
name: Feature request
33
about: Suggest an idea for this project
4-
title: ''
5-
labels: ''
6-
assignees: ''
7-
4+
title: ""
5+
labels: ""
6+
assignees: ""
87
---
98

109
**Is your feature request related to a problem? Please describe.**

.husky/pre-commit

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
pnpm lint-staged

.lintstagedrc.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const path = require("path");
2+
3+
const buildEslintCommand = (filenames) =>
4+
`next lint --fix --file ${filenames.map((f) => path.relative(process.cwd(), f)).join(" --file ")}`;
5+
6+
module.exports = {
7+
"*.{js,jsx,ts,tsx}": [buildEslintCommand],
8+
"*": "prettier --ignore-unknown --write",
9+
};

CHANGELOG.md

+24
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Convertkit newsletter provider
13+
- Plausible analytics provider
14+
15+
## [0.6.0] - 2023-07-16
16+
17+
### Added
18+
19+
- Back to top button
20+
- SocialIcon component
21+
- Share post component
22+
- Lint staged files
23+
- Tag generation and routing
24+
- Newsletter feature
25+
- MailerLite integration
26+
27+
### Changed
28+
29+
- Changed social icons to use [simple-icons](https://simpleicons.org)
30+
- New post preview component
31+
- Updated package dependencies
32+
- Formatted codebase with updated Prettier
33+
1034
## [0.5.0] - 2023-07-06
1135

1236
### Added

README.md

+31-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ If you love this template and/or use it, please give it a star on GitHub. This w
2424
- [Colors](#colors)
2525
- [Metadata](#metadata)
2626
- [Analytics](#analytics)
27+
- [Vercel](#vercel)
28+
- [Umami](#umami)
29+
- [Other analytics providers](#other-analytics-providers)
2730
- [Newsletter subscription](#newsletter-subscription)
31+
- [MailerLite](#mailerlite)
32+
- [Other newsletter providers](#other-newsletter-providers)
2833
- [Hero section](#hero-section)
2934
- [Other tips & tricks](#other-tips--tricks)
3035
- [Image optimization](#image-optimization)
@@ -116,13 +121,22 @@ Umami is a simple, easy to use, web analytics solution with self-hosting option!
116121
Configure:
117122
Set `NEXT_PUBLIC_UMAMI_SCRIPT_URL` & `NEXT_PUBLIC_UMAMI_WEBSITE_ID` environment variables on your `.env.local` file and on Vercel dashboard.
118123

119-
#### Others
124+
#### Other analytics providers
120125

121126
Supporting other analytics providers are in progress. Feel free to open an issue if you have any suggestions or a PR if you want to implement it yourself.
122127

123128
### Newsletter subscription
124129

125-
_WIP_ as I'm still deciding which email tools to support. Feel free to open an issue if you have any suggestions or a PR if you want to implement it yourself.
130+
#### MailerLite
131+
132+
MailerLite is a simple email marketing tool for all types of businesses. You can read more about it on [MailerLite website](https://www.mailerlite.com/).
133+
134+
Configure:
135+
Set `EMAIL_API_BASE`, `EMAIL_API_KEY`, and `EMAIL_GROUP_ID` environment variables on your `.env.local` file and on Vercel dashboard.
136+
137+
#### Other newsletter providers
138+
139+
Supporting other newsletter providers are in progress. Feel free to open an issue if you have any suggestions or a PR if you want to implement it yourself.
126140

127141
### Hero section
128142

@@ -171,19 +185,30 @@ Note: DO NOT overdo it. You can easily make images look bad with lossy compressi
171185
- [x] Not found page
172186
- [x] contributing docs
173187
- [x] Docs refresh
174-
- [ ] Social sharing buttons
175-
- [ ] newsletter integration (form, api route, keys, welcome page, previous issues)
188+
- [x] Back to top button
189+
- [x] Social icons component
190+
- [x] Social sharing buttons
191+
- [x] Tags
192+
- [x] newsletter integration (form, api route, keys, thank you/welcome page, MailerLite provider)
193+
- [ ] Other newsletter providers (Convertkit, Substack, Buttondown, Mailchimp, etc)
176194
- [ ] Other analytics providers (fathom, simplelytics, plausible, etc)
177-
- [ ] Tags, categories
195+
- [ ] CLI and/or recipes
178196
- [ ] Post series page
197+
- [ ] prev/next post links
198+
- [ ] related posts
199+
- [ ] Newsletter previous issues page
179200
- [ ] Layouts/templates system
201+
- [ ] Notion data source
202+
- [ ] Sanity data source
180203
- [ ] hero title and subtitle text HTML support(?)
181204
- [ ] Design improvements (whitespace, layout, etc.)
182205
- [ ] error, and loading pages
183206
- [ ] Code preview component
184207
- [ ] Code highlight improvements (copy code, theme)
185208
- [ ] `manifest.json`
186-
- [ ] Hidden content (behind email subscription)
209+
- [ ] Rich project cards
210+
- [ ] CV template
211+
- [ ] Authenticated pages and/or hidden content (behind email address)
187212
- [ ] 100 lighthouse score
188213
- [ ] Command bar fuzzy search in content
189214
- [ ] Pagination

app/(site)/not-found.tsx

+19-12
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
1-
"use client"
1+
"use client";
22

3-
import { Button } from "@/components/ui/button"
4-
import { useRouter } from "next/navigation"
3+
import { useRouter } from "next/navigation";
4+
5+
import { Button } from "@/components/ui/button";
56

67
export default function NotFound() {
7-
const router = useRouter()
8+
const router = useRouter();
89

910
return (
10-
<div className="text-center justify-center items-center mb-16">
11-
<span className="font-extrabold leading-none text-transparent text-[10rem] bg-clip-text bg-gradient-to-b from-foreground to-transparent">404</span>
12-
<h2 className="font-heading text-2xl my-2 font-bold">Something&apos;s missing</h2>
11+
<div className="mb-16 items-center justify-center text-center">
12+
<span className="bg-gradient-to-b from-foreground to-transparent bg-clip-text text-[10rem] font-extrabold leading-none text-transparent">
13+
404
14+
</span>
15+
<h2 className="my-2 font-heading text-2xl font-bold">Something&apos;s missing</h2>
1316
<p>Sorry, the page you are looking for doesn&apos;t exist or has been moved.</p>
14-
<div className="flex gap-2 justify-center mt-8">
15-
<Button onClick={() => router.back()} variant="default" size="lg">Go back</Button>
16-
<Button onClick={() => router.push("/")} variant="ghost" size="lg">Back to Home</Button>
17+
<div className="mt-8 flex justify-center gap-2">
18+
<Button onClick={() => router.back()} variant="default" size="lg">
19+
Go back
20+
</Button>
21+
<Button onClick={() => router.push("/")} variant="ghost" size="lg">
22+
Back to Home
23+
</Button>
1724
</div>
1825
</div>
19-
)
20-
}
26+
);
27+
}

app/(site)/page.tsx

+12-25
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
import Image from "next/image";
22
import Link from "next/link";
3+
import { notFound } from "next/navigation";
34
import { allPages, allPosts } from "@/.contentlayer/generated";
4-
import { compareDesc, format, parseISO } from "date-fns";
5+
import { compareDesc } from "date-fns";
56
import { ArrowRight } from "lucide-react";
67

78
import { defaultAuthor } from "@/lib/metadata";
89
import { cn } from "@/lib/utils";
9-
import CTA from "@/components/cta";
1010
import { HeroImage } from "@/components/hero-image";
1111
import { HeroMinimal } from "@/components/hero-minimal";
1212
import { HeroSimple } from "@/components/hero-simple";
1313
import { HeroVideo } from "@/components/hero-video";
1414
import { Sidebar } from "@/components/home-sidebar";
1515
import { Mdx } from "@/components/mdx-components";
16+
import NewsletterSubscribe from "@/components/newsletter-subscribe";
17+
import PostPreview from "@/components/post-preview";
1618

1719
async function getAboutPage() {
18-
const page = allPages.find((page) => page.slug === "about");
20+
const aboutPage = allPages.find((page) => page.slug === "about");
1921

20-
if (!page) {
22+
if (!aboutPage) {
2123
null;
2224
}
2325

24-
return page;
26+
return aboutPage;
2527
}
2628

2729
export default async function Home() {
@@ -30,7 +32,8 @@ export default async function Home() {
3032
.filter((post) => post.status === "published")
3133
.sort((a, b) =>
3234
compareDesc(new Date(a.lastUpdatedDate || a.publishedDate), new Date(b.lastUpdatedDate || b.publishedDate))
33-
);
35+
)
36+
.slice(0, 8);
3437

3538
return (
3639
<div className="pb-10">
@@ -41,25 +44,9 @@ export default async function Home() {
4144
<div className="container mt-12 max-w-6xl">
4245
<div className="grid grid-cols-1 place-items-start justify-between gap-12 lg:grid-cols-3">
4346
<div className="col-span-1 lg:col-span-2">
44-
<div className="prose grid grid-flow-row gap-3">
47+
<div className="grid grid-flow-row gap-2">
4548
{posts.map((post) => (
46-
<article key={post._id} className="w-full">
47-
<Link
48-
href={`posts/${post.slug}`}
49-
className={cn(
50-
"select-rounded-md block w-full rounded-md px-3 py-6 leading-none no-underline outline-none transition hover:bg-foreground/20 hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground"
51-
)}
52-
>
53-
<h2 className="m-0 text-2xl font-bold leading-none text-foreground">{post.title}</h2>
54-
<div className="mb-4 mt-1 text-sm leading-snug text-muted-foreground">
55-
<time dateTime={post.publishedDate}>{format(parseISO(post.publishedDate), "LLLL d, yyyy")}</time>
56-
<span>{` // ${post.readTimeMinutes} mins read`}</span>
57-
</div>
58-
{post.description && (
59-
<p className="line-clamp-2 text-sm leading-snug text-muted-foreground">{post.description}</p>
60-
)}
61-
</Link>
62-
</article>
49+
<PostPreview key={post._id} post={post} />
6350
))}
6451
</div>
6552
<Link
@@ -74,7 +61,7 @@ export default async function Home() {
7461
</aside>
7562
</div>
7663
</div>
77-
<CTA
64+
<NewsletterSubscribe
7865
title="I also write deep dives in email"
7966
description="I write about coding, design, digital nomad life, and solopreneurship. Join over 1,000 other developers in
8067
getting better in business. Unsubscribe whenever."

app/(site)/posts/[slug]/page.tsx

+21-11
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import { Metadata } from "next";
22
import Link from "next/link";
33
import { notFound } from "next/navigation";
4-
import { PostSeries, PostWithSeries, SeriesItem } from "@/types";
5-
import { allPosts, Post } from "contentlayer/generated";
4+
import { PostSeries, SeriesItem } from "@/types";
5+
import { allPosts } from "contentlayer/generated";
66
import { format, parseISO } from "date-fns";
77
import { Home } from "lucide-react";
88

9+
import { BASE_URL, defaultAuthor } from "@/lib/metadata";
910
import { cn } from "@/lib/utils";
1011
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
1112
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
1213
import { Separator } from "@/components/ui/separator";
1314
import { Mdx } from "@/components/mdx-components";
1415
import { PostSeriesBox } from "@/components/post-series-box";
16+
import { SocialShare } from "@/components/social-share";
1517
import { TableOfContents } from "@/components/table-of-contents";
1618

1719
interface PostProps {
@@ -156,15 +158,23 @@ export default async function PostPage({ params }: PostProps) {
156158
)}
157159
<Mdx code={post.body.code} />
158160
<hr className="my-4" />
159-
{post.tags && (
160-
<ul className="m-0 list-none space-x-2 p-0 text-sm text-muted-foreground">
161-
{post.tags.map((tag: any) => (
162-
<li className="inline-block p-0" key={tag.trim()}>
163-
{tag}
164-
</li>
165-
))}
166-
</ul>
167-
)}
161+
<div className="flex flex-row items-center justify-between">
162+
{post.tags && (
163+
<ul className="m-0 list-none space-x-2 p-0 text-sm text-muted-foreground">
164+
{post.tags.map((tag: string) => (
165+
<li className="inline-block p-0" key={tag}>
166+
<Link href={`/tags/${tag}`} className="inline-block transition hover:text-muted-foreground/70">
167+
{tag}
168+
</Link>
169+
</li>
170+
))}
171+
</ul>
172+
)}
173+
<SocialShare
174+
text={`${post.title} via ${defaultAuthor.handle}`}
175+
url={`${BASE_URL}/${post._raw.flattenedPath}`}
176+
/>
177+
</div>
168178
</article>
169179
<aside className="hidden lg:block">
170180
<Card className={cn("sticky top-28 mb-4")}>

0 commit comments

Comments
 (0)