1
1
mirror of https://github.com/theoludwig/theoludwig.git synced 2024-11-08 22:31:30 +01:00

refactor: blog directory

This commit is contained in:
Théo LUDWIG 2023-08-01 17:44:08 +02:00
parent 2e0138194c
commit 56520830e9
Signed by: theoludwig
GPG Key ID: ADFE5A563D718F3B
15 changed files with 86 additions and 79 deletions

View File

@ -17,9 +17,9 @@ import { getHighlighter } from 'shiki'
import 'katex/dist/katex.min.css'
import { remarkSyntaxHighlightingPlugin } from '@/utils/remarkSyntaxHighlightingPlugin'
import { getPostBySlug } from '@/utils/blog'
import { BlogPostComments } from '@/components/BlogPostComments'
import { remarkSyntaxHighlightingPlugin } from '@/blog/remarkSyntaxHighlightingPlugin'
import { getBlogPostBySlug } from '@/blog/blog'
import { BlogPostComments } from '@/blog/BlogPostComments'
import { getTheme } from '@/theme/theme.server'
const Heading = (
@ -51,12 +51,12 @@ interface BlogPostPageProps {
export const generateMetadata = async (
props: BlogPostPageProps
): Promise<Metadata> => {
const post = await getPostBySlug(props.params.slug)
if (post == null || !post.frontmatter.isPublished) {
const blogPost = await getBlogPostBySlug(props.params.slug)
if (blogPost == null || !blogPost.frontmatter.isPublished) {
return notFound()
}
const title = `${post.frontmatter.title} | Théo LUDWIG`
const description = post.frontmatter.description
const title = `${blogPost.frontmatter.title} | Théo LUDWIG`
const description = blogPost.frontmatter.description
return {
title,
description,
@ -74,8 +74,8 @@ export const generateMetadata = async (
const BlogPostPage = async (props: BlogPostPageProps): Promise<JSX.Element> => {
const { params } = props
const post = await getPostBySlug(params.slug)
if (post == null || !post.frontmatter.isPublished) {
const blogPost = await getBlogPostBySlug(params.slug)
if (blogPost == null || !blogPost.frontmatter.isPublished) {
return notFound()
}
@ -89,15 +89,18 @@ const BlogPostPage = async (props: BlogPostPageProps): Promise<JSX.Element> => {
return (
<main className='break-wrap-words flex flex-1 flex-col flex-wrap items-center'>
<div className='my-10 flex flex-col items-center text-center'>
<h1 className='text-3xl font-semibold'>{post.frontmatter.title}</h1>
<h1 className='text-3xl font-semibold'>{blogPost.frontmatter.title}</h1>
<p className='mt-2' data-cy='blog-post-date'>
{date.format(new Date(post.frontmatter.publishedOn), 'DD/MM/YYYY')}
{date.format(
new Date(blogPost.frontmatter.publishedOn),
'DD/MM/YYYY'
)}
</p>
</div>
<div className='prose mb-10'>
<div className='px-8'>
<MDXRemote
source={post.content}
source={blogPost.content}
options={{
mdxOptions: {
remarkPlugins: [
@ -121,7 +124,7 @@ const BlogPostPage = async (props: BlogPostPageProps): Promise<JSX.Element> => {
h6: Heading,
img: (properties) => {
const { src = '', alt = 'Blog Image' } = properties
const source = src.replace('../public/', '/')
const source = src.replace('../../public/', '/')
return (
<span className='flex flex-col items-center justify-center'>
<Image

View File

@ -1,7 +1,7 @@
import { Suspense } from 'react'
import type { Metadata } from 'next'
import { BlogPosts } from '@/components/BlogPosts'
import { BlogPosts } from '@/blog/BlogPosts'
import { Loader } from '@/components/Loader/Loader'
const title = 'Blog | Théo LUDWIG'

View File

@ -2,10 +2,10 @@ import Link from 'next/link'
import date from 'date-and-time'
import { ShadowContainer } from '@/components/design/ShadowContainer'
import { getPosts } from '@/utils/blog'
import { getBlogPosts } from '@/blog/blog'
export const BlogPosts = async (): Promise<JSX.Element> => {
const posts = await getPosts()
const posts = await getBlogPosts()
return (
<div className='flex w-full items-center justify-center p-8'>

View File

@ -4,7 +4,7 @@ import path from 'node:path'
import { cache } from 'react'
import matter from 'gray-matter'
export const POSTS_PATH = path.join(process.cwd(), 'posts')
export const POSTS_PATH = path.join(process.cwd(), 'blog', 'posts')
export interface FrontMatter {
title: string
@ -19,7 +19,7 @@ export interface Post {
content: string
}
export const getPosts = cache(async (): Promise<Post[]> => {
export const getBlogPosts = cache(async (): Promise<Post[]> => {
const posts = await fs.promises.readdir(POSTS_PATH)
const postsWithTime = await Promise.all(
posts.map(async (postFilename) => {
@ -54,9 +54,9 @@ export const getPosts = cache(async (): Promise<Post[]> => {
return postsWithTimeSorted
})
export const getPostBySlug = cache(
export const getBlogPostBySlug = cache(
async (slug: string): Promise<Post | undefined> => {
const posts = await getPosts()
const posts = await getBlogPosts()
const post = posts.find((post) => {
return post.slug === slug
})

View File

@ -216,7 +216,7 @@ $$
#### Complexity Classes (from fastest to slowest)
![Big O Notation](../public/images/posts/programming-challenges/big-o-chart-notations.webp)
![Big O Notation](../../public/images/posts/programming-challenges/big-o-chart-notations.webp)
Here is a list of classes of functions that are commonly encountered when analyzing the running time of an algorithm.

View File

@ -21,7 +21,7 @@ The source code is available on [GitHub](https://github.com/Thream).
The idea is that a user can create an account to authenticate with an email address, and a password, or directly use an account from another platform (currently supported: Google, GitHub, Discord). Once the user is authenticated, he/she can create and join "guilds", in other words communities, in order to discuss with other people in several channels to group discussions talking about the same subject.
![The Thream app on a community page](../public/images/posts/thream-v1-0-0/thream-ui.png)
![The Thream app on a community page](../../public/images/posts/thream-v1-0-0/thream-ui.png)
[**Thream**](https://thream.theoludwig.fr/) is a website that works on any recent browser, accessible on [thream.theoludwig.fr](https://thream.theoludwig.fr/).
@ -33,7 +33,7 @@ The main goal is to put into **practice knowledge in web development** and compu
The development of the project begins under the name of **SocialProject**, on August 20, 2020.
![SocialProject](../public/images/posts/thream-v1-0-0/social-project.jpg)
![SocialProject](../../public/images/posts/thream-v1-0-0/social-project.jpg)
When I started the project, I had little knowledge of database design, real-time management or the architecture of such a large <abbr title="Information Technology">IT</abbr> project, so this will be accompanied by many technical problems, to which we will need to find appropriate solutions.
@ -53,7 +53,7 @@ Since the project is mainly developed during free time (mainly on weekends), the
- The **client** part, called **frontend**, what **the user sees on the screen**, such as forms, buttons and all the **graphic elements** with which the user can interact from a browser.
![HTTP Communication Schema](../public/images/posts/thream-v1-0-0/http-communication.png)
![HTTP Communication Schema](../../public/images/posts/thream-v1-0-0/http-communication.png)
This design allows the separation between the client and the server, as long as they both structure their communication according to the <abbr title="Representational state transfer">REST</abbr> architectural guidelines, using the <abbr title="Hypertext Transfer Protocol">HTTP</abbr> protocol, they will be able to communicate with each other, which makes it possible to work independently on the backend and on the frontend using different technologies and skills, really useful in teamwork.

102
package-lock.json generated
View File

@ -48,10 +48,10 @@
"@tsconfig/strictest": "2.0.1",
"@types/negotiator": "0.6.1",
"@types/node": "20.4.5",
"@types/react": "18.2.17",
"@types/react": "18.2.18",
"@types/unist": "3.0.0",
"@typescript-eslint/eslint-plugin": "6.2.0",
"@typescript-eslint/parser": "6.2.0",
"@typescript-eslint/eslint-plugin": "6.2.1",
"@typescript-eslint/parser": "6.2.1",
"autoprefixer": "10.4.14",
"curriculum-vitae": "file:./curriculum-vitae",
"cypress": "12.17.2",
@ -2497,9 +2497,9 @@
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
},
"node_modules/@types/react": {
"version": "18.2.17",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.17.tgz",
"integrity": "sha512-u+e7OlgPPh+aryjOm5UJMX32OvB2E3QASOAqVMY6Ahs90djagxwv2ya0IctglNbNTexC12qCSMZG47KPfy1hAA==",
"version": "18.2.18",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.18.tgz",
"integrity": "sha512-da4NTSeBv/P34xoZPhtcLkmZuJ+oYaCxHmyHzwaDQo9RQPBeXV+06gEk2FpqEcsX9XrnNLvRpVh6bdavDSjtiQ==",
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@ -2550,16 +2550,16 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.0.tgz",
"integrity": "sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz",
"integrity": "sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.5.1",
"@typescript-eslint/scope-manager": "6.2.0",
"@typescript-eslint/type-utils": "6.2.0",
"@typescript-eslint/utils": "6.2.0",
"@typescript-eslint/visitor-keys": "6.2.0",
"@typescript-eslint/scope-manager": "6.2.1",
"@typescript-eslint/type-utils": "6.2.1",
"@typescript-eslint/utils": "6.2.1",
"@typescript-eslint/visitor-keys": "6.2.1",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.4",
@ -2601,15 +2601,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.0.tgz",
"integrity": "sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.1.tgz",
"integrity": "sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "6.2.0",
"@typescript-eslint/types": "6.2.0",
"@typescript-eslint/typescript-estree": "6.2.0",
"@typescript-eslint/visitor-keys": "6.2.0",
"@typescript-eslint/scope-manager": "6.2.1",
"@typescript-eslint/types": "6.2.1",
"@typescript-eslint/typescript-estree": "6.2.1",
"@typescript-eslint/visitor-keys": "6.2.1",
"debug": "^4.3.4"
},
"engines": {
@ -2629,13 +2629,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz",
"integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz",
"integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.2.0",
"@typescript-eslint/visitor-keys": "6.2.0"
"@typescript-eslint/types": "6.2.1",
"@typescript-eslint/visitor-keys": "6.2.1"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
@ -2646,13 +2646,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.0.tgz",
"integrity": "sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz",
"integrity": "sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "6.2.0",
"@typescript-eslint/utils": "6.2.0",
"@typescript-eslint/typescript-estree": "6.2.1",
"@typescript-eslint/utils": "6.2.1",
"debug": "^4.3.4",
"ts-api-utils": "^1.0.1"
},
@ -2673,9 +2673,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz",
"integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz",
"integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==",
"dev": true,
"engines": {
"node": "^16.0.0 || >=18.0.0"
@ -2686,13 +2686,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz",
"integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz",
"integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.2.0",
"@typescript-eslint/visitor-keys": "6.2.0",
"@typescript-eslint/types": "6.2.1",
"@typescript-eslint/visitor-keys": "6.2.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@ -2728,17 +2728,17 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.0.tgz",
"integrity": "sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.1.tgz",
"integrity": "sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
"@typescript-eslint/scope-manager": "6.2.0",
"@typescript-eslint/types": "6.2.0",
"@typescript-eslint/typescript-estree": "6.2.0",
"@typescript-eslint/scope-manager": "6.2.1",
"@typescript-eslint/types": "6.2.1",
"@typescript-eslint/typescript-estree": "6.2.1",
"semver": "^7.5.4"
},
"engines": {
@ -2768,12 +2768,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz",
"integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz",
"integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.2.0",
"@typescript-eslint/types": "6.2.1",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
@ -5157,9 +5157,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.4.477",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.477.tgz",
"integrity": "sha512-shUVy6Eawp33dFBFIoYbIwLHrX0IZ857AlH9ug2o4rvbWmpaCUdBpQ5Zw39HRrfzAFm4APJE9V+E2A/WB0YqJw==",
"version": "1.4.479",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.479.tgz",
"integrity": "sha512-ABv1nHMIR8I5n3O3Een0gr6i0mfM+YcTZqjHy3pAYaOjgFG+BMquuKrSyfYf5CbEkLr9uM05RA3pOk4udNB/aQ==",
"dev": true
},
"node_modules/emoji-regex": {

View File

@ -68,10 +68,10 @@
"@tsconfig/strictest": "2.0.1",
"@types/negotiator": "0.6.1",
"@types/node": "20.4.5",
"@types/react": "18.2.17",
"@types/react": "18.2.18",
"@types/unist": "3.0.0",
"@typescript-eslint/eslint-plugin": "6.2.0",
"@typescript-eslint/parser": "6.2.0",
"@typescript-eslint/eslint-plugin": "6.2.1",
"@typescript-eslint/parser": "6.2.1",
"autoprefixer": "10.4.14",
"curriculum-vitae": "file:./curriculum-vitae",
"cypress": "12.17.2",

View File

@ -1,6 +1,10 @@
/** @type {import('tailwindcss').Config} */
const tailwindConfig = {
content: ['./app/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
content: [
'./app/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
'./blog/**/*.{js,ts,jsx,tsx}'
],
darkMode: 'class',
theme: {
extend: {