├── .eslintrc.json
├── .gitignore
├── README.md
├── components.json
├── next.config.mjs
├── package-lock.json
├── package.json
├── postcss.config.mjs
├── prisma
├── migrations
│ ├── 20240712023225_init
│ │ └── migration.sql
│ ├── 20240712034116_init
│ │ └── migration.sql
│ └── migration_lock.toml
└── schema.prisma
├── public
├── android-chrome-192x192.png
├── android-chrome-512x512.png
├── apple-touch-icon.png
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
├── next.svg
└── vercel.svg
├── src
├── app
│ ├── about
│ │ └── page.tsx
│ ├── api
│ │ └── route.ts
│ ├── blog
│ │ ├── [category]
│ │ │ ├── [slug]
│ │ │ │ └── page.tsx
│ │ │ └── page.tsx
│ │ ├── contents
│ │ │ ├── learn-react.mdx
│ │ │ ├── react-19.mdx
│ │ │ ├── spaces-vs-tabs.mdx
│ │ │ ├── static-typing.mdx
│ │ │ └── vim.mdx
│ │ ├── layout.tsx
│ │ └── utils.ts
│ ├── layout.tsx
│ ├── not-found.tsx
│ ├── og
│ │ └── route.tsx
│ ├── page.tsx
│ ├── privacy-policy
│ │ ├── page.tsx
│ │ └── privacy-policy.mdx
│ ├── robots.ts
│ ├── rss
│ │ └── route.ts
│ ├── sitemap.ts
│ └── terms-of-services
│ │ ├── page.tsx
│ │ └── terms-of-services.mdx
├── components
│ ├── Breadcrumb.tsx
│ ├── CardCategory.tsx
│ ├── Container.tsx
│ ├── Header.tsx
│ ├── ReportViews.tsx
│ ├── SubmitButton.tsx
│ ├── footer.tsx
│ ├── home
│ │ ├── latest-posts.tsx
│ │ ├── popular-posts.tsx
│ │ └── top-categories.tsx
│ ├── icons.tsx
│ ├── main-nav.tsx
│ ├── mdx.tsx
│ ├── skeleton
│ │ └── popular_posts_skeleton.tsx
│ ├── theme-provider.tsx
│ └── ui
│ │ ├── breadcrumb.tsx
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── input.tsx
│ │ ├── mode-toggle.tsx
│ │ ├── navigation-menu.tsx
│ │ └── skeleton.tsx
├── config
│ └── site.ts
├── db
│ └── index.ts
├── lib
│ ├── actions.ts
│ ├── constants.ts
│ ├── placeholder-data.ts
│ └── utils.ts
└── styles
│ └── globals.css
├── tailwind.config.ts
└── tsconfig.json
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 | .env
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | [](https://www.youtube.com/watch?v=htgktwXYw6g)
3 |
4 |
5 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
6 |
7 | ## Getting Started
8 |
9 | First, run the development server:
10 |
11 | ```bash
12 | npm run dev
13 | # or
14 | yarn dev
15 | # or
16 | pnpm dev
17 | # or
18 | bun dev
19 | ```
20 |
21 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
22 |
23 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
24 |
25 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
26 |
27 | ## Learn More
28 |
29 | To learn more about Next.js, take a look at the following resources:
30 |
31 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
32 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
33 |
34 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
35 |
36 | ## Deploy on Vercel
37 |
38 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
39 |
40 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
41 |
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "src/styles/globals.css",
9 | "baseColor": "slate",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils"
16 | }
17 | }
--------------------------------------------------------------------------------
/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {};
3 |
4 | export default nextConfig;
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-blog",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "postinstall": "prisma generate",
9 | "start": "next start",
10 | "lint": "next lint"
11 | },
12 | "dependencies": {
13 | "@prisma/client": "^5.16.1",
14 | "@radix-ui/react-dropdown-menu": "^2.1.1",
15 | "@radix-ui/react-navigation-menu": "^1.2.0",
16 | "@radix-ui/react-slot": "^1.1.0",
17 | "class-variance-authority": "^0.7.0",
18 | "clsx": "^2.1.1",
19 | "gray-matter": "^4.0.3",
20 | "lucide-react": "^0.399.0",
21 | "next": "^14.2.18",
22 | "next-mdx-remote": "^5.0.0",
23 | "next-themes": "^0.3.0",
24 | "react": "^18",
25 | "react-dom": "^18",
26 | "sugar-high": "^0.7.0",
27 | "swr": "^2.2.5",
28 | "tailwind-merge": "^2.3.0",
29 | "tailwindcss-animate": "^1.0.7",
30 | "zod": "^3.23.8"
31 | },
32 | "devDependencies": {
33 | "@types/node": "^20",
34 | "@types/react": "^18",
35 | "@types/react-dom": "^18",
36 | "eslint": "^8",
37 | "eslint-config-next": "14.2.4",
38 | "postcss": "^8",
39 | "prisma": "^5.16.1",
40 | "tailwindcss": "^3.4.1",
41 | "typescript": "^5"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/prisma/migrations/20240712023225_init/migration.sql:
--------------------------------------------------------------------------------
1 | -- CreateTable
2 | CREATE TABLE "Blog" (
3 | "id" SERIAL NOT NULL,
4 | "slug" TEXT NOT NULL,
5 | "title" TEXT NOT NULL,
6 | "category" TEXT NOT NULL,
7 | "view_count" INTEGER NOT NULL DEFAULT 1,
8 | "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
9 |
10 | CONSTRAINT "Blog_pkey" PRIMARY KEY ("id")
11 | );
12 |
13 | -- CreateTable
14 | CREATE TABLE "Subscriber" (
15 | "id" SERIAL NOT NULL,
16 | "email" TEXT NOT NULL,
17 | "is_subscribed" BOOLEAN NOT NULL DEFAULT true,
18 |
19 | CONSTRAINT "Subscriber_pkey" PRIMARY KEY ("id")
20 | );
21 |
22 | -- CreateIndex
23 | CREATE UNIQUE INDEX "Blog_slug_key" ON "Blog"("slug");
24 |
--------------------------------------------------------------------------------
/prisma/migrations/20240712034116_init/migration.sql:
--------------------------------------------------------------------------------
1 | /*
2 | Warnings:
3 |
4 | - A unique constraint covering the columns `[email]` on the table `Subscriber` will be added. If there are existing duplicate values, this will fail.
5 |
6 | */
7 | -- CreateIndex
8 | CREATE UNIQUE INDEX "Subscriber_email_key" ON "Subscriber"("email");
9 |
--------------------------------------------------------------------------------
/prisma/migrations/migration_lock.toml:
--------------------------------------------------------------------------------
1 | # Please do not edit this file manually
2 | # It should be added in your version-control system (i.e. Git)
3 | provider = "postgresql"
--------------------------------------------------------------------------------
/prisma/schema.prisma:
--------------------------------------------------------------------------------
1 | // This is your Prisma schema file,
2 | // learn more about it in the docs: https://pris.ly/d/prisma-schema
3 |
4 | // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
5 | // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
6 |
7 | generator client {
8 | provider = "prisma-client-js"
9 | }
10 |
11 | datasource db {
12 | provider = "postgresql"
13 | url = env("POSTGRES_PRISMA_URL") // uses connection pooling
14 | directUrl = env("POSTGRES_URL_NON_POOLING") // uses a direct connection
15 | }
16 |
17 | model Blog {
18 | id Int @id @default(autoincrement())
19 | slug String @unique
20 | title String
21 | category String
22 | view_count Int @default(1)
23 | updatedAt DateTime @default(now())
24 | }
25 |
26 | model Subscriber {
27 | id Int @id @default(autoincrement())
28 | email String @unique
29 | is_subscribed Boolean @default(true)
30 | }
--------------------------------------------------------------------------------
/public/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3tsadev/next-blog/e6c6c8e0e9c45734f16fea8e120c8ea0b5d500d3/public/android-chrome-192x192.png
--------------------------------------------------------------------------------
/public/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3tsadev/next-blog/e6c6c8e0e9c45734f16fea8e120c8ea0b5d500d3/public/android-chrome-512x512.png
--------------------------------------------------------------------------------
/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3tsadev/next-blog/e6c6c8e0e9c45734f16fea8e120c8ea0b5d500d3/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3tsadev/next-blog/e6c6c8e0e9c45734f16fea8e120c8ea0b5d500d3/public/favicon-16x16.png
--------------------------------------------------------------------------------
/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3tsadev/next-blog/e6c6c8e0e9c45734f16fea8e120c8ea0b5d500d3/public/favicon-32x32.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/w3tsadev/next-blog/e6c6c8e0e9c45734f16fea8e120c8ea0b5d500d3/public/favicon.ico
--------------------------------------------------------------------------------
/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/about/page.tsx:
--------------------------------------------------------------------------------
1 | import Container from "@/components/Container";
2 | import Header from "@/components/Header";
3 | import { MainNav } from "@/components/main-nav";
4 | import { Metadata } from "next";
5 |
6 | export const metadata: Metadata = {
7 | title: "About Me",
8 | description: "Information about me",
9 | };
10 |
11 | export default async function AboutPage() {
12 | return (
13 | <>
14 |
15 |
16 |
17 |
18 |
19 | About Me
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | Software Developer
29 |
30 |
31 |
32 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
33 | eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
34 | ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
35 | aliquip ex ea commodo consequat. Duis aute irure dolor in
36 | reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
37 | pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
38 | culpa qui officia deserunt mollit anim id est laborum
39 |
67 |
68 | >
69 | );
70 | }
71 |
--------------------------------------------------------------------------------
/src/app/blog/contents/learn-react.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Learn React in 2024"
3 | publishedAt: "2024-06-13"
4 | summary: "Discover why React, with its steep learning curve, remains a beloved tool among developers for editing code efficiently and effectively."
5 | category: "react"
6 | ---
7 |
8 | In the world of software development, where the latest and greatest tools frequently capture the spotlight, Vim stands out as a timeless classic. Despite its age and initial complexity, Vim has managed to retain a devoted following of developers who swear by its efficiency, versatility, and power.
9 |
10 | This article delves into the reasons behind Vim's enduring appeal and why it continues to be a great tool for coding in the modern era.
11 |
12 | ## Efficiency and Speed
13 |
14 | At the heart of Vim's philosophy is the idea of minimizing keystrokes to achieve maximum efficiency.
15 |
16 | Unlike other text editors where the mouse is often relied upon for navigation and text manipulation, Vim's keyboard-centric design allows developers to perform virtually all coding tasks without leaving the home row. This not only speeds up coding but also reduces the risk of repetitive strain injuries.
17 |
18 | ## Highly Customizable
19 |
20 | Vim can be extensively customized to suit any developer's preferences and workflow. With a vibrant ecosystem of plugins and a robust scripting language, users can tailor the editor to their specific needs, whether it's programming in Python, writing in Markdown, or managing projects.
21 |
22 | This level of customization ensures that Vim remains relevant and highly functional for a wide range of programming tasks and languages.
23 |
24 | ## Ubiquity and Portability
25 |
26 | Vim is virtually everywhere. It's available on all major platforms, and because it's lightweight and terminal-based, it can be used on remote servers through SSH, making it an indispensable tool for sysadmins and developers working in a cloud-based environment.
27 |
28 | The ability to use the same editor across different systems without a graphical interface is a significant advantage for those who need to maintain a consistent workflow across multiple environments.
29 |
30 | ## Vibrant Community
31 |
32 | Despite—or perhaps because of—its learning curve, Vim has cultivated a passionate and active community. Online forums, dedicated websites, and plugins abound, offering support, advice, and improvements.
33 |
34 | This community not only helps newcomers climb the steep learning curve but also continually contributes to Vim's evolution, ensuring it remains adaptable and up-to-date with the latest programming trends and technologies.
35 |
36 | ## Conclusion
37 |
38 | Vim is not just a text editor; it's a way of approaching coding with efficiency and thoughtfulness. Its steep learning curve is a small price to pay for the speed, flexibility, and control it offers.
39 |
40 | For those willing to invest the time to master its commands, Vim proves to be an invaluable tool that enhances productivity and enjoyment in coding. In an age of ever-changing development tools, the continued popularity of Vim is a testament to its enduring value and utility.
41 |
--------------------------------------------------------------------------------
/src/app/blog/contents/react-19.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "React 19 RC"
3 | publishedAt: "2024-06-26"
4 | summary: "In this post, we’ll give an overview of the new features in React 19, and how you can adopt them."
5 | category: "react"
6 | ---
7 |
8 | In our React 19 RC Upgrade Guide, we shared step-by-step instructions for upgrading your app to React 19. In this post, we’ll give an overview of the new features in React 19, and how you can adopt them.
9 |
10 | ## What's new in React 19
11 |
12 | ### Actions
13 |
14 | A common use case in React apps is to perform a data mutation and then update state in response. For example, when a user submits a form to change their name, you will make an API request, and then handle the response. In the past, you would need to handle pending states, errors, optimistic updates, and sequential requests manually.
15 |
16 | For example, you could handle the pending and error state in `useState`:
17 |
18 | ```js
19 | // Before Actions
20 | function UpdateName({}) {
21 | const [name, setName] = useState("");
22 | const [error, setError] = useState(null);
23 | const [isPending, setIsPending] = useState(false);
24 |
25 | const handleSubmit = async () => {
26 | setIsPending(true);
27 | const error = await updateName(name);
28 | setIsPending(false);
29 | if (error) {
30 | setError(error);
31 | return;
32 | }
33 | redirect("/path");
34 | };
35 |
36 | return (
37 |
78 | );
79 | }
80 | ```
81 |
82 | The async transition will immediately set the `isPending` state to true, make the async request(s), and switch `isPending` to false after any transitions. This allows you to keep the current UI responsive and interactive while the data is changing.
83 |
84 | > ### Note
85 | >
86 | > By convention, functions that use async transitions are called “Actions”. Actions
87 | > automatically manage submitting data for you:
88 | >
89 | > - Pending state: Actions provide a pending state that starts at the beginning of a request and automatically resets when the final state update is committed.
90 | > - Optimistic updates: Actions support the new `useOptimistic` hook so you can show users instant feedback while the requests are submitting.
91 | > - Error handling: Actions provide error handling so you can display Error Boundaries when a request fails, and revert optimistic updates to their original value automatically.
92 | > - Forms: `
121 | );
122 | }
123 | ```
124 |
125 | In the next section, we’ll break down each of the new Action features in React 19.
126 |
127 | ## New hook: `useActionState`
128 |
129 | To make the common cases easier for Actions, we’ve added a new hook called `useActionState`:
130 |
131 | ```js
132 | const [error, submitAction, isPending] = useActionState(
133 | async (previousState, newName) => {
134 | const error = await updateName(newName);
135 | if (error) {
136 | // You can return any result of the action.
137 | // Here, we return only the error.
138 | return error;
139 | }
140 |
141 | // handle success
142 | return null;
143 | },
144 | null
145 | );
146 | ```
147 |
148 | `useActionState` accepts a function (the “Action”), and returns a wrapped Action to call. This works because Actions compose. When the wrapped Action is called, `useActionState` will return the last result of the Action as `data`, and the pending state of the Action as `pending`.
149 |
150 | > ### Note
151 | >
152 | > `React.useActionState` was previously called `ReactDOM.useFormState` in the Canary
153 | > releases, but we've renamed it and deprecated `useFormState`.{" "}
154 |
--------------------------------------------------------------------------------
/src/app/blog/contents/spaces-vs-tabs.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Spaces vs. Tabs: The Indentation Debate Continues"
3 | publishedAt: "2024-04-08"
4 | summary: "Explore the enduring debate between using spaces and tabs for code indentation, and why this choice matters more than you might think."
5 | category: "react"
6 | ---
7 |
8 | The debate between using spaces and tabs for indentation in coding may seem trivial to the uninitiated, but it is a topic that continues to inspire passionate discussions among developers. This seemingly minor choice can affect code readability, maintenance, and even team dynamics.
9 |
10 | Let's delve into the arguments for both sides and consider why this debate remains relevant in the software development world.
11 |
12 | ## The Case for Spaces
13 |
14 | Advocates for using spaces argue that it ensures consistent code appearance across different editors, tools, and platforms. Because a space is a universally recognized character with a consistent width, code indented with spaces will look the same no matter where it's viewed. This consistency is crucial for maintaining readability and avoiding formatting issues when code is shared between team members or published online.
15 |
16 | Additionally, some programming languages and style guides explicitly recommend spaces for indentation, suggesting a certain number of spaces (often two or four) per indentation level. Adhering to these recommendations can be essential for projects that aim for best practices in code quality and readability.
17 |
18 | ## The Case for Tabs
19 |
20 | On the other side of the debate, proponents of tabs highlight the flexibility that tabs offer. Because the width of a tab can be adjusted in most text editors, individual developers can choose how much indentation they prefer to see, making the code more accessible and comfortable to read on a personal level. This adaptability can be particularly beneficial in teams with diverse preferences regarding code layout.
21 |
22 | Tabs also have the advantage of semantic meaning. A tab is explicitly meant to represent indentation, whereas a space is used for many purposes within code. This distinction can make automated parsing and manipulation of code simpler, as tools can more easily recognize and adjust indentation levels without confusing them with spaces used for alignment.
23 |
24 | ## Hybrid Approaches and Team Dynamics
25 |
26 | The debate often extends into discussions about hybrid approaches, where teams might use tabs for indentation and spaces for alignment within lines, attempting to combine the best of both worlds. However, such strategies require clear team agreements and disciplined adherence to coding standards to prevent formatting chaos.
27 |
28 | Ultimately, the choice between spaces and tabs often comes down to team consensus and project guidelines. In environments where collaboration and code sharing are common, agreeing on a standard that everyone follows is more important than the individual preferences of spaces versus tabs. Modern development tools and linters can help enforce these standards, making the choice less about technical limitations and more about team dynamics and coding philosophy.
29 |
30 | ## Conclusion
31 |
32 | While the spaces vs. tabs debate might not have a one-size-fits-all answer, it underscores the importance of consistency, readability, and team collaboration in software development. Whether a team chooses spaces, tabs, or a hybrid approach, the key is to make a conscious choice that serves the project's needs and to adhere to it throughout the codebase. As with many aspects of coding, communication and agreement among team members are paramount to navigating this classic programming debate.
33 |
--------------------------------------------------------------------------------
/src/app/blog/contents/static-typing.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "The Power of Static Typing in Programming"
3 | publishedAt: "2024-04-07"
4 | summary: "In the ever-evolving landscape of software development, the debate between dynamic and static typing continues to be a hot topic."
5 | category: "react"
6 | ---
7 |
8 | In the ever-evolving landscape of software development, the debate between dynamic and static typing continues to be a hot topic. While dynamic typing offers flexibility and rapid development, static typing brings its own set of powerful advantages that can significantly improve the quality and maintainability of code. In this post, we'll explore why static typing is crucial for developers, accompanied by practical examples through markdown code snippets.
9 |
10 | ## Improved Code Quality and Safety
11 |
12 | One of the most compelling reasons to use static typing is the improvement it brings to code quality and safety. By enforcing type checks at compile time, static typing catches errors early in the development process, reducing the chances of runtime errors.
13 |
14 | ```ts
15 | function greet(name: string): string {
16 | return `Hello, ${name}!`;
17 | }
18 |
19 | // This will throw an error at compile time, preventing potential runtime issues.
20 | let message: string = greet(123);
21 | ```
22 |
23 | ## Enhanced Readability and Maintainability
24 |
25 | Static typing makes code more readable and maintainable. By explicitly declaring types, developers provide a clear contract of what the code does, making it easier for others (or themselves in the future) to understand and modify the codebase.
26 |
27 | ## Facilitates Tooling and Refactoring
28 |
29 | Modern IDEs leverage static typing to offer advanced features like code completion, refactoring, and static analysis. These tools can automatically detect issues, suggest fixes, and safely refactor code, enhancing developer productivity and reducing the likelihood of introducing bugs during refactoring.
30 |
31 | ```csharp
32 | // Refactoring example: Renaming a method in C#
33 | public class Calculator {
34 | public int Add(int a, int b) {
35 | return a + b;
36 | }
37 | }
38 |
39 | // After refactoring `Add` to `Sum`, all references are automatically updated.
40 | public class Calculator {
41 | public int Sum(int a, int b) {
42 | return a + b;
43 | }
44 | }
45 | ```
46 |
47 | ## Performance Optimizations
48 |
49 | Static typing can lead to better performance. Since types are known at compile time, compilers can optimize the generated code more effectively. This can result in faster execution times and lower resource consumption.
50 |
51 | ## Conclusion
52 |
53 | Static typing offers numerous benefits that contribute to the development of robust, efficient, and maintainable software. By catching errors early, enhancing readability, facilitating tooling, and enabling optimizations, static typing is an invaluable asset for developers. As the software industry continues to mature, the importance of static typing in ensuring code quality and performance cannot be overstated. Whether you're working on a large-scale enterprise application or a small project, embracing static typing can lead to better software development outcomes.
54 |
--------------------------------------------------------------------------------
/src/app/blog/contents/vim.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Embracing Vim: The Unsung Hero of Code Editors"
3 | publishedAt: "2024-04-09"
4 | summary: "Discover why Vim, with its steep learning curve, remains a beloved tool among developers for editing code efficiently and effectively."
5 | category: "css"
6 | ---
7 |
8 | In the world of software development, where the latest and greatest tools frequently capture the spotlight, Vim stands out as a timeless classic. Despite its age and initial complexity, Vim has managed to retain a devoted following of developers who swear by its efficiency, versatility, and power.
9 |
10 | This article delves into the reasons behind Vim's enduring appeal and why it continues to be a great tool for coding in the modern era.
11 |
12 | ## Efficiency and Speed
13 |
14 | At the heart of Vim's philosophy is the idea of minimizing keystrokes to achieve maximum efficiency.
15 |
16 | Unlike other text editors where the mouse is often relied upon for navigation and text manipulation, Vim's keyboard-centric design allows developers to perform virtually all coding tasks without leaving the home row. This not only speeds up coding but also reduces the risk of repetitive strain injuries.
17 |
18 | ## Highly Customizable
19 |
20 | Vim can be extensively customized to suit any developer's preferences and workflow. With a vibrant ecosystem of plugins and a robust scripting language, users can tailor the editor to their specific needs, whether it's programming in Python, writing in Markdown, or managing projects.
21 |
22 | This level of customization ensures that Vim remains relevant and highly functional for a wide range of programming tasks and languages.
23 |
24 | ## Ubiquity and Portability
25 |
26 | Vim is virtually everywhere. It's available on all major platforms, and because it's lightweight and terminal-based, it can be used on remote servers through SSH, making it an indispensable tool for sysadmins and developers working in a cloud-based environment.
27 |
28 | The ability to use the same editor across different systems without a graphical interface is a significant advantage for those who need to maintain a consistent workflow across multiple environments.
29 |
30 | ## Vibrant Community
31 |
32 | Despite—or perhaps because of—its learning curve, Vim has cultivated a passionate and active community. Online forums, dedicated websites, and plugins abound, offering support, advice, and improvements.
33 |
34 | This community not only helps newcomers climb the steep learning curve but also continually contributes to Vim's evolution, ensuring it remains adaptable and up-to-date with the latest programming trends and technologies.
35 |
36 | ## Conclusion
37 |
38 | Vim is not just a text editor; it's a way of approaching coding with efficiency and thoughtfulness. Its steep learning curve is a small price to pay for the speed, flexibility, and control it offers.
39 |
40 | For those willing to invest the time to master its commands, Vim proves to be an invaluable tool that enhances productivity and enjoyment in coding. In an age of ever-changing development tools, the continued popularity of Vim is a testament to its enduring value and utility.
41 |
--------------------------------------------------------------------------------
/src/app/blog/layout.tsx:
--------------------------------------------------------------------------------
1 | import Container from "@/components/Container";
2 | import { MainNav } from "@/components/main-nav";
3 |
4 | export default function Layout({ children }: { children: React.ReactNode }) {
5 | return (
6 | <>
7 |
25 |
26 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/src/app/privacy-policy/page.tsx:
--------------------------------------------------------------------------------
1 | import Container from "@/components/Container";
2 | import { getPrivacyPolicy } from "../blog/utils";
3 | import { MainNav } from "@/components/main-nav";
4 | import { CustomMDX } from "@/components/mdx";
5 | import { Metadata } from "next";
6 |
7 | export const metadata: Metadata = {
8 | title: "Privary Policy",
9 | description: "This page explains the Privacy Policy of the site.",
10 | };
11 |
12 | export default function Page() {
13 | let post = getPrivacyPolicy().find((post) => post.slug === "privacy-policy");
14 |
15 | return (
16 |
17 |
18 |
19 |
20 |
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/src/app/privacy-policy/privacy-policy.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Privacy Policy"
3 | publishedAt: "2024-06-19"
4 | summary: "Privacy Policy"
5 | category: "Privacy Policy"
6 | ---
7 |
8 | # Privacy Policy
9 |
10 | ### Welcome to Coding jitsu Blog!
11 |
12 | We take your privacy seriously. This Privacy Policy explains how we collect, use, and disclose information from and about you when you visit our website [Your Website URL] (the "Service").
13 |
14 | **1. Information We Collect**
15 |
16 | We only collect personal information from you if you choose to subscribe to our email list. When you subscribe, you may provide us with your email address.
17 |
18 | We may also collect non-personal information about your use of the Service, such as your browsing history, IP address, and device information. This information is collected through cookies and similar tracking technologies.
19 |
20 | **2. Use of Information**
21 |
22 | We will only use your email address to send you new blog posts and newsletters. We will not share your email address with any third-party companies for marketing purposes.
23 |
24 | **3. Cookies and Tracking Technologies**
25 |
26 | We use cookies and similar tracking technologies to collect and analyze non-personal information about your use of the Service. This information helps us improve the functionality and user experience of the Service.
27 |
28 | You can choose to disable cookies in your web browser settings. However, this may limit your ability to use certain features of the Service.
29 |
30 | **4. Your Choices**
31 |
32 | You can unsubscribe from our email list at any time by clicking the "unsubscribe" link at the bottom of any email we send you.
33 |
34 | **5. Data Retention**
35 |
36 | We will retain your email address for as long as you are subscribed to our email list. We will delete your email address from our records when you unsubscribe.
37 |
38 | **6. Security**
39 |
40 | We take reasonable steps to protect your information from unauthorized access, disclosure, alteration, or destruction. However, no website or internet transmission is completely secure. We cannot guarantee the security of your information.
41 |
42 | **7. Children's Privacy**
43 |
44 | Our Service is not directed to children under the age of 13. We do not knowingly collect personal information from children under 13. If you are a parent or guardian and you learn that your child has provided us with personal information, please contact us. We will delete such information from our records.
45 |
46 | **8. Changes to this Privacy Policy**
47 |
48 | We may revise this Privacy Policy at any time by posting the revised terms on the Service. You are expected to check this page periodically so you are aware of any changes, as they are binding on you.
49 |
50 | **9. Contact Us**
51 |
52 | If you have any questions about this Privacy Policy, please contact us at [Your Email Address].
53 |
--------------------------------------------------------------------------------
/src/app/robots.ts:
--------------------------------------------------------------------------------
1 | import { baseUrl } from "./sitemap";
2 |
3 | export default function robots() {
4 | return {
5 | rules: [
6 | {
7 | userAgent: "*",
8 | },
9 | ],
10 | sitemap: `${baseUrl}/sitemap.xml`,
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/src/app/rss/route.ts:
--------------------------------------------------------------------------------
1 | import { getBlogPosts } from "../blog/utils";
2 | import { baseUrl } from "../sitemap";
3 |
4 | export async function GET() {
5 | let allBlogs = getBlogPosts();
6 |
7 | const itemsXml = allBlogs
8 | .sort((a, b) => {
9 | if (new Date(a.metadata.publishedAt) > new Date(b.metadata.publishedAt)) {
10 | return -1;
11 | }
12 | return 1;
13 | })
14 | .map(
15 | (post) => `
16 | ${post.metadata.title}
17 | ${baseUrl}/blog/${post.metadata.category}/${post.slug}
18 | ${post.metadata.summary || ""}
19 | ${new Date(post.metadata.publishedAt).toUTCString()}
20 | `
21 | )
22 | .join("/n");
23 |
24 | const rssFeed = `
25 |
26 |
27 | Coding Jitsu
28 | ${baseUrl}
29 | This is my Technical Blog RSS feed
30 | ${itemsXml}
31 |
32 | `;
33 |
34 | return new Response(rssFeed, {
35 | headers: {
36 | "Content-Type": "text/xml",
37 | },
38 | });
39 | }
40 |
--------------------------------------------------------------------------------
/src/app/sitemap.ts:
--------------------------------------------------------------------------------
1 | import { POSTS } from "@/lib/constants";
2 | import { getBlogPosts } from "./blog/utils";
3 |
4 | export const baseUrl = "https://next-blog-cj.vercel.app";
5 |
6 | export default async function sitemap() {
7 | let blogs = getBlogPosts().map((post) => ({
8 | url: `${baseUrl}/blog/${post.metadata.category}/${post.slug}`,
9 | lastModified: post.metadata.publishedAt,
10 | }));
11 |
12 | let routes = POSTS.map((route) => ({
13 | url: `${baseUrl}${route.href}`,
14 | lastModified: new Date().toISOString().split("T")[0],
15 | }));
16 |
17 | return [...blogs, ...routes];
18 | }
19 |
--------------------------------------------------------------------------------
/src/app/terms-of-services/page.tsx:
--------------------------------------------------------------------------------
1 | import Container from "@/components/Container";
2 | import { getTermsOfServices } from "../blog/utils";
3 | import { MainNav } from "@/components/main-nav";
4 | import { CustomMDX } from "@/components/mdx";
5 | import { Metadata } from "next";
6 |
7 | export const metadata: Metadata = {
8 | title: "Terms Of Services",
9 | description: "This page explains the terms of use of the site.",
10 | };
11 |
12 | export default function Page() {
13 | let post = getTermsOfServices().find(
14 | (post) => post.slug === "terms-of-services"
15 | );
16 |
17 | return (
18 |
19 |
20 |
21 |
22 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/src/app/terms-of-services/terms-of-services.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Terms Of Services"
3 | publishedAt: "2024-06-19"
4 | summary: "Terms of Services"
5 | category: "Terms of Services"
6 | ---
7 |
8 | # Terms of Use
9 |
10 | ## Welcome to Coding Jitsu!
11 |
12 | These terms of use ("Terms") outline the rules and regulations for using our website [Your Website URL] (Coding Jitsu Blog") operated by [Your Name] ("we," "us," or "our").
13 |
14 | **By accessing or using the Service, you agree to be bound by these Terms. If you disagree with any part of the terms, then you may not access the Service.**
15 |
16 | **1. Use of Content**
17 |
18 | The content on the Service, including text, graphics, code, images, and other materials (the "Content"), is protected by copyright, trademarks, and other intellectual property laws. You may access and use the Content for your personal, non-commercial use only. You may not modify, copy, reproduce, republish, upload, post, transmit, or distribute any Content without our prior written consent.
19 |
20 | **2. User Conduct**
21 |
22 | You agree to use the Service in a lawful and respectful manner. You agree not to:
23 |
24 | - Use the Service for any illegal or unauthorized purpose.
25 |
26 | - Violate any international, federal, provincial, state, or local laws or regulations.
27 | - Infringe on our or any third party's intellectual property rights.
28 | - Transmit any harmful, offensive, threatening, abusive, defamatory, obscene, or harassing content.
29 | - Interfere with the normal operation of the Service or any computer systems connected to the Service.
30 | - Use the Service to spam or solicit others.
31 |
32 | **3. Disclaimer**
33 |
34 | The Content on the Service is provided "as is" and without warranties of any kind, express or implied. We disclaim all warranties, including, but not limited to, warranties of merchantability, fitness for a particular purpose, and non-infringement. We do not warrant that the Service will be uninterrupted, secure, or error-free.
35 |
36 | **4. Limitations of Liability**
37 |
38 | We will not be liable for any damages arising out of or related to your use of the Service, including, but not limited to, direct, indirect, incidental, consequential, or punitive damages.
39 |
40 | **5. Termination**
41 |
42 | We may terminate your access to the Service for any reason, at any time, and without notice.
43 |
44 | **6. Governing Law**
45 |
46 | These Terms shall be governed and construed in accordance with the laws of [Your State] without regard to its conflict of law provisions.
47 |
48 | **7. Changes to the Terms**
49 |
50 | We may revise these Terms at any time by posting the revised terms on the Service. You are expected to check this page periodically so you are aware of any changes, as they are binding on you.
51 |
52 | **8. Contact Us**
53 |
54 | If you have any questions about these Terms, please contact us at [Your Email Address].
55 |
56 | **Please note that this is a basic template and you may need to modify it to fit your specific needs. It is recommended that you consult with an attorney to ensure that your Terms of Use are compliant with all applicable laws.**
57 |
--------------------------------------------------------------------------------
/src/components/Breadcrumb.tsx:
--------------------------------------------------------------------------------
1 | import { Slash } from "lucide-react";
2 |
3 | import {
4 | Breadcrumb,
5 | BreadcrumbItem,
6 | BreadcrumbLink,
7 | BreadcrumbList,
8 | BreadcrumbPage,
9 | BreadcrumbSeparator,
10 | } from "@/components/ui/breadcrumb";
11 |
12 | export function BreadcrumbWithCustomSeparator({
13 | category,
14 | slug,
15 | }: {
16 | category: string;
17 | slug: string;
18 | }) {
19 | return (
20 |
21 |
22 |
23 | Home
24 |
25 |
26 |
27 |
28 |
29 | {category}
30 |
31 |
32 |
33 |
34 |
35 | {slug}
36 |
37 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/src/components/CardCategory.tsx:
--------------------------------------------------------------------------------
1 | import { formatDate } from "@/app/blog/utils";
2 | import {
3 | Card,
4 | CardContent,
5 | CardFooter,
6 | CardHeader,
7 | CardTitle,
8 | } from "./ui/card";
9 |
10 | export default function CardCategory({
11 | title,
12 | summary,
13 | date,
14 | }: {
15 | title: string;
16 | summary: string;
17 | date: string;
18 | }) {
19 | return (
20 |
21 |
22 | {title}
23 |
24 |
25 |