Skip to content

Commit b8580c2

Browse files
committed
refactor: tidy up some old code
- extract prop typings into its own separate type definition - dedupe type definition - remove props destructuring since it makes it less clear if a value comes from props - fix hydration mismatch when rendering caused by figure nested inside p - safer null/undefined check by enforcing the value to be boolean - added missing type annotations in some components - updated svgr config according to docs
1 parent 9e1ef79 commit b8580c2

26 files changed

+1381
-758
lines changed

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"typescript.tsdk": "node_modules/typescript/lib"
3+
}

components/AuthorCard.tsx

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,47 @@
11
import type { Author } from "~/types/post";
22
import { TelegramIcon, TwitterIcon } from "~/icons";
33

4-
export function AuthorCard({ author, github, twitter, telegram }: Partial<Author>) {
4+
type AuthorCardProps = Partial<Author>;
5+
6+
export function AuthorCard(props: AuthorCardProps) {
57
return (
68
<div className="text-center md:text-left md:inline-grid md:grid-cols-[3.5rem,1fr] md:grid-rows-2 md:items-center md:justify-center font-sans">
79
<div className="grid place-items-center row-start-1 row-end-3 pr-3">
8-
<a href={`https://github.com/${github}`}>
10+
<a href={`https://github.com/${props.github}`}>
911
<img
1012
className="rounded-full print:border print:border-gray-200"
11-
src={`https://github.com/${github}.png`}
13+
src={`https://github.com/${props.github}.png`}
1214
width="42"
1315
height="42"
1416
alt="author"
1517
/>
1618
</a>
1719
</div>
18-
<span className="md:text-left text-gray-700 dark:text-gray-300">{author}</span>
19-
<div className="flex flex-row items-center justify-center">
20-
{twitter && (
20+
<span className="md:text-left text-gray-700 dark:text-gray-300">{props.author}</span>
21+
<div className="flex flex-row items-center justify-center gap-4">
22+
{!!props.twitter && (
2123
<div className="flex-initial pr-3">
2224
<a
23-
href={`https://twitter.com/${twitter}`}
25+
href={`https://twitter.com/${props.twitter}`}
2426
className="flex items-center justify-center md:justify-start gap-2 text-gray-700 hover:text-primary-600 dark:text-gray-300 dark:hover:text-primary-200"
2527
>
2628
<span className="text-primary-600">
2729
<TwitterIcon />
2830
</span>
29-
@{twitter}{" "}
31+
@{props.twitter}
3032
</a>
3133
</div>
3234
)}
33-
{telegram && (
35+
{!!props.telegram && (
3436
<div className="flex-initial">
3537
<a
36-
href={`https://t.me/${telegram}`}
38+
href={`https://t.me/${props.telegram}`}
3739
className="flex items-center justify-center md:justify-start gap-2 text-gray-700 hover:text-primary-600 dark:text-gray-300 dark:hover:text-primary-200"
3840
>
3941
<span className="-mr-1 text-primary-600">
4042
<TelegramIcon width="1.5rem" height="1.5rem" />
4143
</span>
42-
@{telegram}{" "}
44+
@{props.telegram}
4345
</a>
4446
</div>
4547
)}

components/BrowseTopic.tsx

+13-16
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ type BrowseTopicProps = {
77
categories: string[];
88
};
99

10-
export function BrowseTopic({ categories }: BrowseTopicProps) {
10+
export function BrowseTopic(props: BrowseTopicProps) {
1111
const [showMoreTopics, toggleShownTopics] = useReducer((s) => !s, false);
1212

1313
return (
@@ -16,21 +16,18 @@ export function BrowseTopic({ categories }: BrowseTopicProps) {
1616
<h2 className="uppercase font-bold text-xl mb-10 dark:text-neutral-100">Browse Interesting Topics</h2>
1717

1818
<div className="flex flex-wrap gap-6 items-center justify-center">
19-
{categories
20-
.slice(0, showMoreTopics ? -1 : SHOWN_TOPICS_LIMIT)
21-
.map((category: string, i: number) => (
22-
<Link
23-
key={i}
24-
href={{
25-
pathname: "/search",
26-
query: { q: category },
27-
}}
28-
>
29-
<a className="flex-[0_0_calc(20%-1.5rem)] text-lg pb-3 border-b border-black text-center lowercase hover:text-primary-600 dark:text-neutral-100 dark:hover:text-primary-200 whitespace-nowrap">
30-
{category}
31-
</a>
32-
</Link>
33-
))}
19+
{props.categories.slice(0, showMoreTopics ? -1 : SHOWN_TOPICS_LIMIT).map((category: string) => (
20+
<Link
21+
key={category}
22+
href={{
23+
pathname: "/search",
24+
query: { q: category },
25+
}}
26+
className="flex-[0_0_calc(20%-1.5rem)] text-lg pb-3 border-b border-black text-center lowercase hover:text-primary-600 dark:text-neutral-100 dark:hover:text-primary-200 whitespace-nowrap"
27+
>
28+
{category}
29+
</Link>
30+
))}
3431
</div>
3532

3633
<button

components/Contributing.tsx

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
import { GithubIcon } from "~/icons";
2-
3-
export type Contributor = {
4-
id: number;
5-
login: string;
6-
contribution: number;
7-
html_url: string;
8-
avatar_url: string;
9-
};
2+
import { Contributor } from "~/types/contributor";
103

114
type ContributingProps = {
125
contributors: Contributor[];

components/EnhancedSection.tsx

+8-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ function getNodeText(node: ReactNode | number | string) {
1818
}
1919
}
2020

21-
function CopyButton({ text = "" }) {
21+
type CopyButtonProps = {
22+
text?: string;
23+
};
24+
25+
function CopyButton({ text = "" }: CopyButtonProps) {
2226
const [clicked, setClicked] = useState(false);
2327

2428
const handleBlur = () => {
@@ -45,7 +49,9 @@ function CopyButton({ text = "" }) {
4549
);
4650
}
4751

48-
export function CopyableCodeBlocks({ children }: PropsWithChildren<{}>) {
52+
type CopyableCodeBlocksProps = PropsWithChildren<{}>;
53+
54+
export function CopyableCodeBlocks({ children }: CopyableCodeBlocksProps) {
4955
return (
5056
<section className="relative">
5157
<pre>{children}</pre>

components/FeaturedPost.tsx

+14-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import Link from "next/link";
2+
import { PostField } from "~/types/post";
23

3-
export function FeaturedPost({ post }) {
4+
type FeaturedPostProps = {
5+
post: Pick<PostField, "slug" | "title" | "github" | "author" | "desc" | "cover">;
6+
};
7+
8+
export function FeaturedPost({ post }: FeaturedPostProps) {
49
return (
510
<div className="grid lg:grid-cols-2 grid-cols-1 items-center mt-12 md:-mx-12 lg:gap-x-20 gap-y-10 lg:gap-y-0">
611
<div className="lg:text-left text-center">
712
<p className="text-black dark:text-neutral-100 font-medium">FEATURED</p>
813
<Link href={`/posts/${post.slug}`}>
9-
<a>
10-
<h1 className="sm:text-5xl text-3xl mb-4 mt-2 font-bold text-black dark:text-neutral-100">
11-
{post.title}
12-
</h1>
13-
</a>
14+
<h1 className="sm:text-5xl text-3xl mb-4 mt-2 font-bold text-black dark:text-neutral-100">
15+
{post.title}
16+
</h1>
1417
</Link>
1518
<a className="group inline-block" href={`https://github.com/${post.github}`}>
1619
<div className="flex space-x-2 items-center justify-start">
@@ -27,10 +30,11 @@ export function FeaturedPost({ post }) {
2730
</div>
2831
</a>
2932
<p className="mt-4 leading-relaxed font-serif text-gray-500 dark:text-gray-100">{post.desc}</p>
30-
<Link href={`/posts/${post.slug}`}>
31-
<a className="bg-primary-900 hover:bg-primary-700 dark:bg-primary-500 dark:hover:bg-primary-300 inline-block text-white dark:hover:text-black mt-4 py-1.5 px-10 transition duration-300 print:hidden">
32-
READ MORE
33-
</a>
33+
<Link
34+
href={`/posts/${post.slug}`}
35+
className="bg-primary-900 hover:bg-primary-700 dark:bg-primary-500 dark:hover:bg-primary-300 inline-block text-white dark:hover:text-black mt-4 py-1.5 px-10 transition duration-300 print:hidden"
36+
>
37+
READ MORE
3438
</Link>
3539
</div>
3640
<div className="w-5/6 lg:w-full mx-auto lg:mx-0">

components/ImageWithFrame.tsx

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import type { DetailedHTMLProps, ImgHTMLAttributes } from "react";
22

3-
export function ImageWithFrame({ src, alt }: DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>) {
3+
type ImageWithFrameProps = DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>;
4+
5+
export function ImageWithFrame(props: ImageWithFrameProps) {
6+
if (props.src === undefined) return null;
47
return (
58
<figure className="text-center">
6-
<img className="inline-block p-0 overflow-hidden rounded-md" src={src} alt={alt} />
7-
<figcaption className="break-words">{alt}</figcaption>
9+
<img className="inline-block p-0 overflow-hidden rounded-md" src={props.src} alt={props.alt ?? "-"} />
10+
<figcaption className="break-words">{props.alt}</figcaption>
811
</figure>
912
);
1013
}

components/Layout.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { Navbar } from "~/components/Navbar";
22
import { Footer } from "~/components/Footer";
33
import { BackToTop } from "~/components/BackToTop";
4+
import { PropsWithChildren } from "react";
45

5-
export function Layout({ children }) {
6+
type LayoutProps = PropsWithChildren<{}>;
7+
8+
export function Layout({ children }: LayoutProps) {
69
return (
710
<div className="bg-white dark:bg-neutral-900 ">
811
<BackToTop />

components/Navbar.tsx

+14-16
Original file line numberDiff line numberDiff line change
@@ -19,39 +19,37 @@ export function Navbar() {
1919
<div className="container flex flex-col md:flex-row justify-between items-center space-y-1 mx-auto py-5 px-8 sm:px-16 md:px-32 lg:px-40 xl:px-56 2xl:px-72 h-full">
2020
<div className="flex-1 space-x-6 print:hidden">
2121
{["home", "blog", "about"].map((route, idx) => (
22-
<Link href={`/${route === "home" ? "" : route}`} key={`${idx}-${route}`}>
23-
<a
24-
className={clsx(
25-
"flex-inline uppercase text-center hover:text-primary-600 dark:text-neutral-300 dark:hover:text-neutral-50 transition duration-300",
26-
getActiveClass(route, route === "home"),
27-
)}
28-
>
29-
{route}
30-
</a>
22+
<Link
23+
href={`/${route === "home" ? "" : route}`}
24+
key={`${idx}-${route}`}
25+
className={clsx(
26+
"flex-inline uppercase text-center hover:text-primary-600 dark:text-neutral-300 dark:hover:text-neutral-50 transition duration-300",
27+
getActiveClass(route, route === "home"),
28+
)}
29+
>
30+
{route}
3131
</Link>
3232
))}
3333
</div>
3434
<div className="flex-2 lg:flex-1 text-center dark:text-neutral-100 text-3xl mb-2 lg:mb-0">
35-
<Link href="/">
36-
<a className="font-black">Teknologi Umum</a>
35+
<Link href="/" className="font-black">
36+
Teknologi Umum
3737
</Link>
3838
</div>
3939
<div className="flex-1 text-right text-lg print:hidden">
4040
<div className="flex flex-row items-center justify-end space-x-4">
4141
<div className="flex-initial opacity-60 hover:text-primary-600/100 dark:text-neutral-300 dark:hover:text-neutral-50 transition duration-300">
4242
<Link href="/search">
43-
<a>
44-
<SearchIcon width="1.5rem" height="1.5rem" />
45-
</a>
43+
<SearchIcon width="1.5rem" height="1.5rem" />
4644
</Link>
4745
</div>
4846

49-
<div className="flex-initial opacity-60 hover:text-primary-600/100 dark:text-neutral-300 dark:hover:text-neutral-50 transition duration-300 transition duration-300">
47+
<div className="flex-initial opacity-60 hover:text-primary-600/100 dark:text-neutral-300 dark:hover:text-neutral-50 transition duration-300">
5048
<a href="https://github.com/teknologi-umum">
5149
<GithubIcon width="1.5rem" height="1.5rem" />
5250
</a>
5351
</div>
54-
<div className="flex-initial opacity-60 hover:text-primary-600/100 dark:text-neutral-300 dark:hover:text-neutral-50 transition duration-300 transition duration-300">
52+
<div className="flex-initial opacity-60 hover:text-primary-600/100 dark:text-neutral-300 dark:hover:text-neutral-50 transition duration-300">
5553
<a href="https://t.me/teknologi_umum">
5654
<TelegramIcon width="2rem" height="2rem" />
5755
</a>

components/PostCard.tsx

+13-20
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,7 @@ type PostCardProps = Pick<PostField, "slug" | "title" | "desc" | "categories" |
55
cover?: string;
66
};
77

8-
export function PostCard({
9-
slug,
10-
title,
11-
desc,
12-
categories,
13-
author,
14-
github,
15-
cover = "/image/sample.jpg",
16-
}: PostCardProps) {
8+
export function PostCard(props: PostCardProps) {
179
return (
1810
<>
1911
<style jsx>
@@ -28,11 +20,11 @@ export function PostCard({
2820
`}
2921
</style>
3022
<div className="flex flex-col flex-wrap justify-start shadow-lg rounded-md overflow-hidden font-sans print:shadow-none print:border dark:bg-neutral-800">
31-
<img className="h-[10rem] object-cover w-full bg-neutral-100" src={cover} alt={slug} />
23+
<img className="h-[10rem] object-cover w-full bg-neutral-100" src={props.cover} alt={props.slug} />
3224
<div className="p-4 print:p-2">
3325
<div className="flex flex-wrap gap-1 mb-2">
34-
{categories &&
35-
categories.map((category: string, idx: number) => (
26+
{props.categories &&
27+
props.categories.map((category: string, idx: number) => (
3628
<span
3729
className="text-xs px-2 py-1 rounded-sm bg-gray-200 text-gray-700 dark:bg-gray-600 dark:text-gray-300 uppercase font-semibold print:px-1 print:border"
3830
key={`${idx}-${category}`}
@@ -42,26 +34,27 @@ export function PostCard({
4234
))}
4335
</div>
4436
<div className="py-1">
45-
<Link href={`/posts/${slug}`}>
46-
<a className="text-xl font-bold capitalize font-display text-gray-800 hover:text-primary-600 dark:text-gray-400 dark:hover:text-primary-200 ">
47-
{title}
48-
</a>
37+
<Link
38+
href={`/posts/${props.slug}`}
39+
className="text-xl font-bold capitalize font-display text-gray-800 hover:text-primary-600 dark:text-gray-400 dark:hover:text-primary-200 "
40+
>
41+
{props.title}
4942
</Link>
5043
<p className="text-base leading-relaxed text-gray-500 dark:text-gray-100 mb-2 font-serif">
51-
{desc}
44+
{props.desc}
5245
</p>
5346
</div>
54-
<a className="group" href={`https://github.com/${github}`}>
47+
<a className="group" href={`https://github.com/${props.github}`}>
5548
<div className="flex items-center justify-start">
5649
<img
5750
className="rounded-full shadow-md"
58-
src={`https://github.com/${github}.png`}
51+
src={`https://github.com/${props.github}.png`}
5952
width="32"
6053
height="32"
6154
alt="author"
6255
/>
6356
<span className="text-sm ml-2 text-left text-gray-700 group-hover:text-primary-600 dark:text-gray-300 dark:group-hover:text-primary-200">
64-
{author}
57+
{props.author}
6558
</span>
6659
</div>
6760
</a>

components/ReadAnyway.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ export function ReadAnyway({ posts }: ReadAnywayProps) {
2727
))}
2828
</div>
2929

30-
<Link href="/blog">
31-
<a className="w-full font-bold text-black dark:text-white text-center block mt-10 hover:text-primary-600 dark:hover:text-primary-200 transition duration-300">
32-
FIND MORE POST
33-
</a>
30+
<Link
31+
href="/blog"
32+
className="w-full font-bold text-black dark:text-white text-center block mt-10 hover:text-primary-600 dark:hover:text-primary-200 transition duration-300"
33+
>
34+
FIND MORE POST
3435
</Link>
3536
</div>
3637
</>

content/berkenalan-dengan-scout.md

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Sekarang, ijinkan gue untuk malakukan sedikit eksperimen dalam menggunakan Larav
3434
## Initialize
3535

3636
Ritual pertama yaitu gue membuat project laravel dengan perintah `laravel new laravel-scout`
37+
3738
![init laravel project](/image/berkenalan-dengan-laravel-scout/init-laravel-project.png)
3839

3940
## Setup environment
@@ -53,7 +54,9 @@ DB_PASSWORD=
5354

5455
Jika sudah setup basis data, ritual selanjutnya adalah lakukan migrasi database dengan perintah `php artisan migrate`.
5556
Jika basis data yang kita deklarasikan di file `.env` belum dibuat, maka Laravel secara otomatis akan 'bertanya' via cli (atau terminal) apakah mau 'dibuatkan' atau tidak.
57+
5658
![menjalankan migrasi](/image/berkenalan-dengan-laravel-scout/migrate-table.png)
59+
5760
![dan ya, ini hasil migrasinya](/image/berkenalan-dengan-laravel-scout/hasil-migrasi.png)
5861

5962
## Installing Laravel Scout
@@ -162,6 +165,7 @@ Perlu dicatat bahwa di sini gue hanya ingin membahas apa dan bagaimana cara meng
162165
![halaman users](/image/berkenalan-dengan-laravel-scout/users-index.png)
163166

164167
Gue mencoba melakukan pencarian dengan kata kunci krido (narsis banget gila lol)
168+
165169
![hasil pencarian](/image/berkenalan-dengan-laravel-scout/hasil-pencarian.png)
166170

167171
## Penutup

data/site.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
const siteData = {
22
siteName: "Blog Teknologi Umum",
33
description: "Website yang berisi informasi seputar teknologi.",
4-
};
4+
giscus: {
5+
repo: "teknologi-umum/blog",
6+
repoId: "MDEwOlJlcG9zaXRvcnkzOTU1NzU1NTk=",
7+
category: "General",
8+
categoryId: "DIC_kwDOF5QBB84B-uOk",
9+
mapping: "pathname",
10+
term: "...",
11+
reactionsEnabled: "1",
12+
emitMetadata: "1",
13+
},
14+
} as const;
515

616
export default siteData;

0 commit comments

Comments
 (0)