1
1
mirror of https://github.com/theoludwig/theoludwig.git synced 2025-05-29 22:37:44 +02:00

Compare commits

...

10 Commits

42 changed files with 1625 additions and 1486 deletions

View File

@ -1,5 +1,5 @@
{ {
"name": "Divlo", "name": "theoludwig",
"dockerComposeFile": "./docker-compose.yml", "dockerComposeFile": "./docker-compose.yml",
"service": "workspace", "service": "workspace",
"workspaceFolder": "/workspace", "workspaceFolder": "/workspace",

View File

@ -1,2 +1,2 @@
COMPOSE_PROJECT_NAME=divlo COMPOSE_PROJECT_NAME=theoludwig
PORT=3000 PORT=3000

View File

@ -60,7 +60,7 @@ representative at an online or offline event.
Instances of abusive, harassing, or otherwise unacceptable behavior may be Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at reported to the community leaders responsible for enforcement at
<contact@divlo.fr>. <contact@theoludwig.fr>.
All complaints will be reviewed and investigated promptly and fairly. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the All community leaders are obligated to respect the privacy and security of the

View File

@ -1,10 +1,10 @@
# 💡 Contributing # 💡 Contributing
Thanks a lot for your interest in contributing to **divlo.fr**! 🎉 Thanks a lot for your interest in contributing to **theoludwig.fr**! 🎉
## Code of Conduct ## Code of Conduct
**divlo.fr** adopted the [Contributor Covenant](https://www.contributor-covenant.org/) as its Code of Conduct, and we expect project participants to adhere to it. Please read [the full text](./CODE_OF_CONDUCT.md) so that you can understand what actions will and will not be tolerated. **theoludwig.fr** adopted the [Contributor Covenant](https://www.contributor-covenant.org/) as its Code of Conduct, and we expect project participants to adhere to it. Please read [the full text](./CODE_OF_CONDUCT.md) so that you can understand what actions will and will not be tolerated.
## Types of contributions ## Types of contributions
@ -15,13 +15,13 @@ Thanks a lot for your interest in contributing to **divlo.fr**! 🎉
## Pull Requests ## Pull Requests
- **Please first discuss** the change you wish to make via [issue](https://github.com/Divlo/Divlo/issues) before making a change. It might avoid a waste of your time. - **Please first discuss** the change you wish to make via [issue](https://github.com/theoludwig/theoludwig/issues) before making a change. It might avoid a waste of your time.
- Ensure your code respect linting. - Ensure your code respect linting.
- Make sure your **code passes the tests**. - Make sure your **code passes the tests**.
If you're adding new features to **divlo.fr**, please include tests. If you're adding new features to **theoludwig.fr**, please include tests.
## Commits ## Commits
@ -29,7 +29,7 @@ The commit message guidelines adheres to [Conventional Commits](https://www.conv
## Getting Started ## Getting Started
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/Divlo/Divlo) [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/theoludwig/theoludwig)
### Prerequisites ### Prerequisites
@ -40,10 +40,10 @@ The commit message guidelines adheres to [Conventional Commits](https://www.conv
```sh ```sh
# Clone the repository # Clone the repository
git clone https://github.com/Divlo/Divlo.git git clone git@github.com:theoludwig/theoludwig.git
# Go to the project root # Go to the project root
cd Divlo cd theoludwig
# Configure environment variables # Configure environment variables
cp .env.example .env cp .env.example .env
@ -68,4 +68,4 @@ docker compose up --build
### Services started ### Services started
- website: `http://127.0.0.1:3000` - `website`: <http://127.0.0.1:3000>

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) Divlo Copyright (c) Théo LUDWIG
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,18 +1,18 @@
<h1 align="center"><a href="https://divlo.fr/">Théo LUDWIG (Divlo)</a></h1> <h1 align="center"><a href="https://theoludwig.fr/">Théo LUDWIG</a></h1>
<p align="center"> <p align="center">
<strong>Developer Full Stack • Open-Source enthusiast</strong> <strong>Developer Full Stack • Open-Source enthusiast</strong>
</p> </p>
<p align="center"> <p align="center">
<a href="https://github.com/Divlo"><img alt="GitHub" src="https://img.shields.io/badge/-GitHub-5A5A5A?style=flat&labelColor=5A5A5A&logo=github&logoColor=white"/></a> <a href="https://github.com/theoludwig"><img alt="GitHub" src="https://img.shields.io/badge/-GitHub-5A5A5A?style=flat&labelColor=5A5A5A&logo=github&logoColor=white"/></a>
<a href="https://gitlab.com/Divlo"><img alt="GitLab" src="https://img.shields.io/badge/-GitLab-303030?style=flat&labelColor=303030&logo=gitlab&logoColor=white"/></a> <a href="https://gitlab.com/theoludwig"><img alt="GitLab" src="https://img.shields.io/badge/-GitLab-303030?style=flat&labelColor=303030&logo=gitlab&logoColor=white"/></a>
<a href="https://www.npmjs.com/~divlo"><img alt="npm" src="https://img.shields.io/badge/-npm-c4302b?style=flat&labelColor=c4302b&logo=npm&logoColor=white"/></a> <a href="https://www.npmjs.com/~theoludwig"><img alt="npm" src="https://img.shields.io/badge/-npm-c4302b?style=flat&labelColor=c4302b&logo=npm&logoColor=white"/></a>
<a href="https://twitter.com/Divlo_FR"><img alt="Twitter" src="https://img.shields.io/badge/-Twitter-1ca0f1?style=flat&labelColor=1ca0f1&logo=twitter&logoColor=white"/></a> <a href="https://twitter.com/theoludwig_"><img alt="Twitter" src="https://img.shields.io/badge/-Twitter-1ca0f1?style=flat&labelColor=1ca0f1&logo=twitter&logoColor=white"/></a>
<a href="https://www.youtube.com/channel/UCfEKQzI3c8vmZOrsTOi5spA"><img alt="YouTube" src="https://img.shields.io/badge/-YouTube-c4302b?style=flat&labelColor=c4302b&logo=youtube&logoColor=white"/></a> <a href="https://www.youtube.com/@theo_ludwig"><img alt="YouTube" src="https://img.shields.io/badge/-YouTube-c4302b?style=flat&labelColor=c4302b&logo=youtube&logoColor=white"/></a>
<a href="https://www.twitch.tv/divlo"><img alt="Twitch" src="https://img.shields.io/badge/-Twitch-9147FF?style=flat&labelColor=9147FF&logo=twitch&logoColor=white"/></a> <a href="https://www.twitch.tv/theoludwig"><img alt="Twitch" src="https://img.shields.io/badge/-Twitch-9147FF?style=flat&labelColor=9147FF&logo=twitch&logoColor=white"/></a>
<a href="https://www.divlo.fr"><img alt="Website" src="https://img.shields.io/badge/-Website-181818?style=flat&labelColor=181818&logo=Google-Chrome&logoColor=white"/></a> <a href="https://theoludwig.fr/"><img alt="Website" src="https://img.shields.io/badge/-Website-181818?style=flat&labelColor=181818&logo=Google-Chrome&logoColor=white"/></a>
<a href="mailto:contact@divlo.fr"><img alt="Email" src="https://img.shields.io/badge/-contact@divlo.fr-2F7EBE?style=flat&labelColor=2F7EBE&logo=minutemailer&logoColor=white"/></a> <a href="mailto:contact@theoludwig.fr"><img alt="Email" src="https://img.shields.io/badge/-contact@theoludwig.fr-2F7EBE?style=flat&labelColor=2F7EBE&logo=minutemailer&logoColor=white"/></a>
</p> </p>
<hr /> <hr />
@ -21,7 +21,7 @@
```json ```json
{ {
"name": "Théo LUDWIG (Divlo)", "name": "Théo LUDWIG",
"pronouns": "He/Him", "pronouns": "He/Him",
"birthDate": "31/03/2003", "birthDate": "31/03/2003",
"nationality": "Alsace, France", "nationality": "Alsace, France",
@ -40,6 +40,6 @@
## 📈 Statistics ## 📈 Statistics
<p align=center> <p align=center>
<img height=175 align="center" src="https://github-readme-stats.vercel.app/api?username=Divlo&show_icons=true&theme=dark" /> <img height=175 align="center" src="https://github-readme-stats.vercel.app/api?username=theoludwig&show_icons=true&theme=dark" />
<img height=175 align="center" src="https://github-readme-stats.vercel.app/api/top-langs/?username=Divlo&hide=html,css,javascript&langs_count=8&layout=compact&theme=dark" /> <img height=175 align="center" src="https://github-readme-stats.vercel.app/api/top-langs/?username=theoludwig&hide=html,css,javascript&langs_count=8&layout=compact&theme=dark" />
</p> </p>

View File

@ -11,7 +11,7 @@ export const Footer: React.FC<FooterProps> = (props) => {
const { version } = props const { version } = props
const versionLink = useMemo(() => { const versionLink = useMemo(() => {
return `https://github.com/Divlo/Divlo/releases/tag/v${version}` return `https://github.com/theoludwig/theoludwig/releases/tag/v${version}`
}, [version]) }, [version])
return ( return (
@ -21,7 +21,7 @@ export const Footer: React.FC<FooterProps> = (props) => {
href='/' href='/'
className='text-yellow hover:underline dark:text-yellow-dark' className='text-yellow hover:underline dark:text-yellow-dark'
> >
Théo LUDWIG (Divlo) Théo LUDWIG
</Link>{' '} </Link>{' '}
| {t('common:all-rights-reserved')} | {t('common:all-rights-reserved')}
</p> </p>

View File

@ -9,10 +9,10 @@ interface HeadProps {
export const Head: React.FC<HeadProps> = (props) => { export const Head: React.FC<HeadProps> = (props) => {
const { const {
title = 'Théo LUDWIG (Divlo)', title = 'Théo LUDWIG',
image = 'https://divlo.fr/images/icon-96x96.png', image = 'https://theoludwig.fr/images/icon-96x96.png',
description = 'Théo LUDWIG (Divlo) - Developer Full Stack • Passionate about High-Tech', description = 'Théo LUDWIG - Developer Full Stack • Passionate about High-Tech',
url = 'https://divlo.fr/' url = 'https://theoludwig.fr/'
} = props } = props
return ( return (
@ -40,12 +40,6 @@ export const Head: React.FC<HeadProps> = (props) => {
<meta name='twitter:description' content={description} /> <meta name='twitter:description' content={description} />
<meta name='twitter:title' content={title} /> <meta name='twitter:title' content={title} />
<meta name='twitter:image' content={image} /> <meta name='twitter:image' content={image} />
{/* Google Verification */}
<meta
name='google-site-verification'
content='j9CQEbSuYydXytr6gdkTfam_xX_pU97NSpVH3Bq-6f4'
/>
</NextHead> </NextHead>
) )
} }

View File

@ -19,12 +19,12 @@ export const Header: React.FC<HeaderProps> = (props) => {
quality={100} quality={100}
width={60} width={60}
height={60} height={60}
src='/images/divlo_icon_small.png' src='/images/icon_small.png'
alt='Divlo' alt='Théo LUDWIG'
priority priority
/> />
<strong className='ml-1 hidden font-headline font-semibold text-yellow dark:text-yellow-dark xs:block'> <strong className='ml-1 hidden font-headline font-semibold text-yellow dark:text-yellow-dark xs:block'>
Théo LUDWIG (Divlo) Théo LUDWIG
</strong> </strong>
</div> </div>
</Link> </Link>

View File

@ -12,22 +12,22 @@ export const OpenSource: React.FC = () => {
<Repository <Repository
name='nodejs/node' name='nodejs/node'
description='Node.js JavaScript runtime 🐢🚀' description='Node.js JavaScript runtime 🐢🚀'
href='https://github.com/nodejs/node/commits?author=Divlo' href='https://github.com/nodejs/node/commits?author=theoludwig'
/> />
<Repository <Repository
name='standard/standard' name='standard/standard'
description='🌟 JavaScript Style Guide, with linter & automatic code fixer' description='🌟 JavaScript Style Guide, with linter & automatic code fixer'
href='https://github.com/standard/standard/commits?author=Divlo' href='https://github.com/standard/standard/commits?author=theoludwig'
/> />
<Repository <Repository
name='nrwl/nx' name='nrwl/nx'
description='Smart, Extensible Build Framework' description='Smart, Extensible Build Framework'
href='https://github.com/nrwl/nx/commits?author=Divlo' href='https://github.com/nrwl/nx/commits?author=theoludwig'
/> />
<Repository <Repository
name='vercel/next.js' name='vercel/next.js'
description='The React Framework for Production' description='The React Framework for Production'
href='https://github.com/vercel/next.js/commits?author=Divlo' href='https://github.com/vercel/next.js/commits?author=theoludwig'
/> />
</div> </div>
</div> </div>

View File

@ -6,7 +6,7 @@ export const ProfileInformation: React.FC = () => {
return ( return (
<div className='mb-6 border-b-2 border-gray-600 pb-2 font-headline dark:border-gray-400'> <div className='mb-6 border-b-2 border-gray-600 pb-2 font-headline dark:border-gray-400'>
<h1 className='mb-2 text-4xl font-semibold text-yellow dark:text-yellow-dark'> <h1 className='mb-2 text-4xl font-semibold text-yellow dark:text-yellow-dark'>
Théo LUDWIG (Divlo) Théo LUDWIG
</h1> </h1>
<h2 className='mb-3 text-base'>{t('home:about.description')}</h2> <h2 className='mb-3 text-base'>{t('home:about.description')}</h2>
</div> </div>

View File

@ -1,7 +1,7 @@
import useTranslation from 'next-translate/useTranslation' import useTranslation from 'next-translate/useTranslation'
import { useMemo } from 'react' import { useMemo } from 'react'
import { DIVLO_BIRTH_DATE, DIVLO_BIRTH_DATE_STRING, getAge } from 'utils/getAge' import { BIRTH_DATE, BIRTH_DATE_STRING, getAge } from 'utils/getAge'
import { ProfileItem } from './ProfileItem' import { ProfileItem } from './ProfileItem'
@ -9,7 +9,7 @@ export const ProfileList: React.FC = () => {
const { t } = useTranslation('home') const { t } = useTranslation('home')
const age = useMemo(() => { const age = useMemo(() => {
return getAge(DIVLO_BIRTH_DATE) return getAge(BIRTH_DATE)
}, []) }, [])
return ( return (
@ -20,15 +20,13 @@ export const ProfileList: React.FC = () => {
/> />
<ProfileItem <ProfileItem
title={t('home:about.birth-date')} title={t('home:about.birth-date')}
value={`${DIVLO_BIRTH_DATE_STRING} (${age} ${t( value={`${BIRTH_DATE_STRING} (${age} ${t('home:about.years-old')})`}
'home:about.years-old'
)})`}
/> />
<ProfileItem title={t('home:about.nationality')} value='Alsace, France' /> <ProfileItem title={t('home:about.nationality')} value='Alsace, France' />
<ProfileItem <ProfileItem
title='Email' title='Email'
value='contact@divlo.fr' value='contact@theoludwig.fr'
link='mailto:contact@divlo.fr' link='mailto:contact@theoludwig.fr'
/> />
</ul> </ul>
) )

View File

@ -1,11 +1,11 @@
import Image from 'next/image' import Image from 'next/image'
import DivloLogo from 'public/images/divlo_logo.png' import Logo from 'public/images/logo.png'
export const ProfileLogo: React.FC = () => { export const ProfileLogo: React.FC = () => {
return ( return (
<div className='max-h-[370px] max-w-[370px] px-2 py-6'> <div className='max-h-[370px] max-w-[370px] px-2 py-6'>
<Image quality={100} src={DivloLogo} alt='Divlo' priority /> <Image quality={100} src={Logo} alt='Théo LUDWIG' priority />
</div> </div>
) )
} }

View File

@ -10,28 +10,34 @@ import { NPMIcon } from './SocialMediaIcons/NPMIcon'
export const SocialMediaList: React.FC = () => { export const SocialMediaList: React.FC = () => {
return ( return (
<ul className='social-media-list m-0 mt-2 list-none py-4 text-center'> <ul className='social-media-list m-0 mt-2 list-none py-4 text-center'>
<SocialMediaItem link='https://github.com/Divlo' ariaLabel='GitHub'> <SocialMediaItem link='https://github.com/theoludwig' ariaLabel='GitHub'>
<GitHubIcon /> <GitHubIcon />
</SocialMediaItem> </SocialMediaItem>
<SocialMediaItem link='https://gitlab.com/Divlo' ariaLabel='GitLab'> <SocialMediaItem link='https://gitlab.com/theoludwig' ariaLabel='GitLab'>
<GitLabIcon /> <GitLabIcon />
</SocialMediaItem> </SocialMediaItem>
<SocialMediaItem link='https://www.npmjs.com/~divlo' ariaLabel='NPM'> <SocialMediaItem link='https://www.npmjs.com/~theoludwig' ariaLabel='NPM'>
<NPMIcon /> <NPMIcon />
</SocialMediaItem> </SocialMediaItem>
<SocialMediaItem link='https://twitter.com/Divlo_FR' ariaLabel='Twitter'> <SocialMediaItem
link='https://twitter.com/theoludwig_'
ariaLabel='Twitter'
>
<TwitterIcon /> <TwitterIcon />
</SocialMediaItem> </SocialMediaItem>
<SocialMediaItem <SocialMediaItem
link='https://www.youtube.com/c/Divlo' link='https://www.youtube.com/@theo_ludwig'
ariaLabel='YouTube' ariaLabel='YouTube'
> >
<YouTubeIcon /> <YouTubeIcon />
</SocialMediaItem> </SocialMediaItem>
<SocialMediaItem link='https://www.twitch.tv/divlo' ariaLabel='Twitch'> <SocialMediaItem
link='https://www.twitch.tv/theoludwig'
ariaLabel='Twitch'
>
<TwitchIcon /> <TwitchIcon />
</SocialMediaItem> </SocialMediaItem>
<SocialMediaItem link='mailto:contact@divlo.fr' ariaLabel='Email'> <SocialMediaItem link='mailto:contact@theoludwig.fr' ariaLabel='Email'>
<EmailIcon /> <EmailIcon />
</SocialMediaItem> </SocialMediaItem>
</ul> </ul>

View File

@ -88,16 +88,12 @@ export const skills = {
}, },
'Visual Studio Code': { 'Visual Studio Code': {
link: 'https://code.visualstudio.com/', link: 'https://code.visualstudio.com/',
image: '/images/skills/Visual_Studio_Code.png' image: '/images/skills/VisualStudioCode.png'
}, },
Git: { Git: {
link: 'https://git-scm.com/', link: 'https://git-scm.com/',
image: '/images/skills/Git.png' image: '/images/skills/Git.png'
}, },
Hyper: {
link: 'https://hyper.is/',
image: '/images/skills/Hyper.svg'
},
Ubuntu: { Ubuntu: {
link: 'https://ubuntu.com/', link: 'https://ubuntu.com/',
image: '/images/skills/Ubuntu.png' image: '/images/skills/Ubuntu.png'

View File

@ -4,13 +4,13 @@ describe('<Footer />', () => {
it('should render with appropriate link tag version', () => { it('should render with appropriate link tag version', () => {
const version = '1.0.0' const version = '1.0.0'
cy.mount(<Footer version={version} />) cy.mount(<Footer version={version} />)
cy.contains('Divlo') cy.contains('Théo LUDWIG')
.get('[data-cy=version-link]') .get('[data-cy=version-link]')
.should('have.text', version) .should('have.text', version)
.should( .should(
'have.attr', 'have.attr',
'href', 'href',
`https://github.com/Divlo/Divlo/releases/tag/v${version}` `https://github.com/theoludwig/theoludwig/releases/tag/v${version}`
) )
}) })
}) })

View File

@ -38,7 +38,7 @@ describe('Common > Header', () => {
describe('Switch Language', () => { describe('Switch Language', () => {
it('should switch language from EN (default) to FR', () => { it('should switch language from EN (default) to FR', () => {
cy.get('h1').contains('Divlo') cy.get('h1').contains('Théo LUDWIG')
cy.get('[data-cy=language-flag-text]').contains('EN') cy.get('[data-cy=language-flag-text]').contains('EN')
cy.get('[data-cy=languages-list]').should('not.be.visible') cy.get('[data-cy=languages-list]').should('not.be.visible')
cy.get('[data-cy=language-click]').click() cy.get('[data-cy=language-click]').click()
@ -46,7 +46,7 @@ describe('Common > Header', () => {
cy.get('[data-cy=languages-list] > li:first-child').contains('FR').click() cy.get('[data-cy=languages-list] > li:first-child').contains('FR').click()
cy.get('[data-cy=languages-list]').should('not.be.visible') cy.get('[data-cy=languages-list]').should('not.be.visible')
cy.get('[data-cy=language-flag-text]').contains('FR') cy.get('[data-cy=language-flag-text]').contains('FR')
cy.get('h1').contains('Divlo') cy.get('h1').contains('Théo LUDWIG')
}) })
it('should close the language list menu when clicking outside', () => { it('should close the language list menu when clicking outside', () => {

View File

@ -3,7 +3,7 @@ describe('Page /blog/[slug]', () => {
cy.visit('/blog/hello-world') cy.visit('/blog/hello-world')
cy.get('[data-cy=language-flag-text]').should('not.exist') cy.get('[data-cy=language-flag-text]').should('not.exist')
cy.get('h1').should('have.text', '👋 Hello, world!') cy.get('h1').should('have.text', '👋 Hello, world!')
cy.get('.prose a').should('have.attr', 'target', '_blank') cy.get('.prose a:visible').should('have.attr', 'target', '_blank')
}) })
it("should redirect to /404 if the blog post doesn't exist", () => { it("should redirect to /404 if the blog post doesn't exist", () => {

View File

@ -1,7 +1,7 @@
services: services:
divlo: theoludwig:
container_name: ${COMPOSE_PROJECT_NAME} container_name: ${COMPOSE_PROJECT_NAME}
image: 'divlo' image: 'theoludwig'
build: build:
context: './' context: './'
ports: ports:

View File

@ -12,8 +12,8 @@
"modern-normalize": "2.0.0" "modern-normalize": "2.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "20.2.5", "@types/node": "20.3.1",
"date-and-time": "3.0.0", "date-and-time": "3.0.1",
"vite": "4.3.9", "vite": "4.3.9",
"vite-plugin-html": "3.2.0" "vite-plugin-html": "3.2.0"
} }
@ -483,15 +483,15 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.2.5", "version": "20.3.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz",
"integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==", "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==",
"dev": true "dev": true
}, },
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.8.2", "version": "8.9.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz",
"integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==",
"dev": true, "dev": true,
"bin": { "bin": {
"acorn": "bin/acorn" "acorn": "bin/acorn"
@ -682,9 +682,9 @@
} }
}, },
"node_modules/date-and-time": { "node_modules/date-and-time": {
"version": "3.0.0", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-3.0.0.tgz", "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-3.0.1.tgz",
"integrity": "sha512-uuzXp/mvv6jEMLiP5QzERSQPzHqYnv9i8NZ8BS5kYeB2sakv74EewQiCS4Ahxwq3In+9fYZhGztuDHRVzIOkFQ==", "integrity": "sha512-Az1hy3IPuh7LR4duPGlgkUzZXtjoWH8pd+XVLpLXMNd+DD48sRdcsWIPbqdHCXg4izb9lPzrKtqUXPXevS9g4Q==",
"dev": true "dev": true
}, },
"node_modules/dom-serializer": { "node_modules/dom-serializer": {
@ -753,12 +753,15 @@
} }
}, },
"node_modules/dotenv": { "node_modules/dotenv": {
"version": "16.0.3", "version": "16.3.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.0.tgz",
"integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", "integrity": "sha512-tHB+hmf8MRCkT3VVivGiG8kq9HiGTmQ3FzOKgztfpJQH1IWuZTOvKSJmHNnQPowecAmkCJhLrxdPhOr06LLqIQ==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">=12" "node": ">=12"
},
"funding": {
"url": "https://github.com/motdotla/dotenv?sponsor=1"
} }
}, },
"node_modules/dotenv-expand": { "node_modules/dotenv-expand": {
@ -1270,9 +1273,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "3.23.0", "version": "3.25.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.23.0.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.1.tgz",
"integrity": "sha512-h31UlwEi7FHihLe1zbk+3Q7z1k/84rb9BSwmBSr/XjOCEaBJ2YyedQDuM0t/kfOS0IxM+vk1/zI9XxYj9V+NJQ==", "integrity": "sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==",
"dev": true, "dev": true,
"bin": { "bin": {
"rollup": "dist/bin/rollup" "rollup": "dist/bin/rollup"
@ -1349,13 +1352,13 @@
} }
}, },
"node_modules/terser": { "node_modules/terser": {
"version": "5.17.6", "version": "5.18.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.17.6.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-5.18.0.tgz",
"integrity": "sha512-V8QHcs8YuyLkLHsJO5ucyff1ykrLVsR4dNnS//L5Y3NiSXpbK1J+WMVUs67eI0KTxs9JtHhgEQpXQVHlHI92DQ==", "integrity": "sha512-pdL757Ig5a0I+owA42l6tIuEycRuM7FPY4n62h44mRLRfnOxJkkOHd6i89dOpwZlpF6JXBwaAHF6yWzFrt+QyA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@jridgewell/source-map": "^0.3.2", "@jridgewell/source-map": "^0.3.3",
"acorn": "^8.5.0", "acorn": "^8.8.2",
"commander": "^2.20.0", "commander": "^2.20.0",
"source-map-support": "~0.5.20" "source-map-support": "~0.5.20"
}, },
@ -1385,9 +1388,9 @@
} }
}, },
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.5.2", "version": "2.5.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz",
"integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==", "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==",
"dev": true "dev": true
}, },
"node_modules/universalify": { "node_modules/universalify": {

View File

@ -13,8 +13,8 @@
"modern-normalize": "2.0.0" "modern-normalize": "2.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "20.2.5", "@types/node": "20.3.1",
"date-and-time": "3.0.0", "date-and-time": "3.0.1",
"vite": "4.3.9", "vite": "4.3.9",
"vite-plugin-html": "3.2.0" "vite-plugin-html": "3.2.0"
} }

View File

@ -1,5 +1,5 @@
import { DIVLO_BIRTH_DATE, getAge } from '../../utils/getAge.ts' import { BIRTH_DATE, getAge } from '../../utils/getAge.ts'
const yearOld = document.getElementById('year-old') const yearOld = document.getElementById('year-old')
yearOld.textContent = getAge(DIVLO_BIRTH_DATE).toString() yearOld.textContent = getAge(BIRTH_DATE).toString()

View File

@ -17,7 +17,7 @@
}, },
{ {
"title": "Open-Source enthusiast", "title": "Open-Source enthusiast",
"description": "For me, everyone should work, solve problems, build things and think together.<br/> The website is open-source on <a class='text-yellow dark:text-yellow-dark hover:underline' href='https://github.com/Divlo/Divlo' target='_blank' rel='noopener noreferrer'>GitHub</a>." "description": "For me, everyone should work, solve problems, build things and think together.<br/> The website is open-source on <a class='text-yellow dark:text-yellow-dark hover:underline' href='https://github.com/theoludwig/theoludwig' target='_blank' rel='noopener noreferrer'>GitHub</a>."
}, },
{ {
"title": "Passionate about High-Tech", "title": "Passionate about High-Tech",

View File

@ -17,7 +17,7 @@
}, },
{ {
"title": "Enthousiaste de l'Open-Source", "title": "Enthousiaste de l'Open-Source",
"description": "Pour moi, tout le monde devrait travailler, résoudre des problèmes, construire des choses et réfléchir ensemble. <br/> Le site est open-source sur <a class='text-yellow dark:text-yellow-dark hover:underline' href='https://github.com/Divlo/Divlo' target='_blank' rel='noopener noreferrer'>GitHub</a>." "description": "Pour moi, tout le monde devrait travailler, résoudre des problèmes, construire des choses et réfléchir ensemble. <br/> Le site est open-source sur <a class='text-yellow dark:text-yellow-dark hover:underline' href='https://github.com/theoludwig/theoludwig' target='_blank' rel='noopener noreferrer'>GitHub</a>."
}, },
{ {
"title": "Passionné de High-Tech", "title": "Passionné de High-Tech",

2750
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
{ {
"name": "divlo", "name": "theoludwig",
"version": "2.7.3", "version": "2.10.0",
"private": true, "private": true,
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/Divlo/Divlo" "url": "https://github.com/theoludwig/theoludwig"
}, },
"engines": { "engines": {
"node": ">=16.0.0", "node": ">=16.0.0",
@ -17,12 +17,12 @@
"lint:commit": "commitlint", "lint:commit": "commitlint",
"lint:editorconfig": "editorconfig-checker", "lint:editorconfig": "editorconfig-checker",
"lint:markdown": "markdownlint-cli2", "lint:markdown": "markdownlint-cli2",
"lint:eslint": "eslint \".\" --ignore-path \".gitignore\"", "lint:eslint": "eslint . --ignore-path .gitignore",
"lint:prettier": "prettier \".\" --check --ignore-path \".gitignore\"", "lint:prettier": "prettier . --check --ignore-path .gitignore",
"lint:staged": "lint-staged", "lint:staged": "lint-staged",
"test:unit": "cypress run --component", "test:unit": "cypress run --component",
"test:html-w3c-validator": "start-server-and-test \"start\" \"http://127.0.0.1:3000\" \"html-w3c-validator\"", "test:html-w3c-validator": "start-server-and-test \"start\" \"http://127.0.0.1:3000\" \"html-w3c-validator\"",
"test:e2e": "start-server-and-test \"start\" \"http://127.0.0.1:3000\" \"cypress run\"", "test:e2e": "start-server-and-test \"start\" http://127.0.0.1:3000 \"cypress run\"",
"test:dev": "start-server-and-test \"dev\" \"http://127.0.0.1:3000\" \"cypress open\"", "test:dev": "start-server-and-test \"dev\" \"http://127.0.0.1:3000\" \"cypress open\"",
"resume:build": "node ./jsonresume-theme-custom/build.js", "resume:build": "node ./jsonresume-theme-custom/build.js",
"release": "semantic-release", "release": "semantic-release",
@ -30,21 +30,21 @@
"postinstall": "husky install" "postinstall": "husky install"
}, },
"dependencies": { "dependencies": {
"@fontsource/montserrat": "5.0.1", "@fontsource/montserrat": "5.0.3",
"@fortawesome/fontawesome-svg-core": "6.4.0", "@fortawesome/fontawesome-svg-core": "6.4.0",
"@fortawesome/free-brands-svg-icons": "6.4.0", "@fortawesome/free-brands-svg-icons": "6.4.0",
"@fortawesome/free-solid-svg-icons": "6.4.0", "@fortawesome/free-solid-svg-icons": "6.4.0",
"@fortawesome/react-fontawesome": "0.2.0", "@fortawesome/react-fontawesome": "0.2.0",
"@giscus/react": "2.2.8", "@giscus/react": "2.2.8",
"clsx": "1.2.1", "clsx": "1.2.1",
"date-and-time": "3.0.0", "date-and-time": "3.0.1",
"gray-matter": "4.0.3", "gray-matter": "4.0.3",
"html-react-parser": "3.0.16", "html-react-parser": "4.0.0",
"katex": "0.16.7", "katex": "0.16.7",
"next": "13.4.4", "next": "13.4.6",
"next-mdx-remote": "4.4.1", "next-mdx-remote": "4.4.1",
"next-themes": "0.2.1", "next-themes": "0.2.1",
"next-translate": "2.0.5", "next-translate": "2.0.6",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"read-pkg": "8.0.0", "read-pkg": "8.0.0",
@ -60,22 +60,22 @@
"universal-cookie": "4.0.4" "universal-cookie": "4.0.4"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "17.6.3", "@commitlint/cli": "17.6.5",
"@commitlint/config-conventional": "17.6.3", "@commitlint/config-conventional": "17.6.5",
"@saithodev/semantic-release-backmerge": "3.2.0", "@saithodev/semantic-release-backmerge": "3.2.0",
"@semantic-release/git": "10.0.1", "@semantic-release/git": "10.0.1",
"@tailwindcss/typography": "0.5.9", "@tailwindcss/typography": "0.5.9",
"@tsconfig/strictest": "2.0.1", "@tsconfig/strictest": "2.0.1",
"@types/node": "20.2.5", "@types/node": "20.3.1",
"@types/react": "18.2.7", "@types/react": "18.2.12",
"@types/unist": "2.0.6", "@types/unist": "2.0.6",
"@typescript-eslint/eslint-plugin": "5.59.7", "@typescript-eslint/eslint-plugin": "5.59.11",
"autoprefixer": "10.4.14", "autoprefixer": "10.4.14",
"cypress": "12.13.0", "cypress": "12.14.0",
"editorconfig-checker": "5.0.1", "editorconfig-checker": "5.0.1",
"eslint": "8.41.0", "eslint": "8.42.0",
"eslint-config-conventions": "9.0.0", "eslint-config-conventions": "9.0.0",
"eslint-config-next": "13.4.4", "eslint-config-next": "13.4.6",
"eslint-config-prettier": "8.8.0", "eslint-config-prettier": "8.8.0",
"eslint-plugin-import": "2.27.5", "eslint-plugin-import": "2.27.5",
"eslint-plugin-prettier": "4.2.1", "eslint-plugin-prettier": "4.2.1",
@ -85,16 +85,16 @@
"husky": "8.0.3", "husky": "8.0.3",
"jsonresume-theme-custom": "file:./jsonresume-theme-custom", "jsonresume-theme-custom": "file:./jsonresume-theme-custom",
"lint-staged": "13.2.2", "lint-staged": "13.2.2",
"markdownlint-cli2": "0.7.1", "markdownlint-cli2": "0.8.1",
"markdownlint-rule-relative-links": "1.2.0", "markdownlint-rule-relative-links": "1.2.0",
"next-translate-plugin": "2.0.5", "next-translate-plugin": "2.0.5",
"postcss": "8.4.24", "postcss": "8.4.24",
"prettier": "2.8.8", "prettier": "2.8.8",
"prettier-plugin-tailwindcss": "0.3.0", "prettier-plugin-tailwindcss": "0.3.0",
"semantic-release": "21.0.2", "semantic-release": "21.0.5",
"start-server-and-test": "2.0.0", "start-server-and-test": "2.0.0",
"tailwindcss": "3.3.2", "tailwindcss": "3.3.2",
"typescript": "5.0.4", "typescript": "5.0.4",
"vercel": "30.0.0" "vercel": "30.2.2"
} }
} }

View File

@ -13,7 +13,7 @@ const Error404: NextPage<Error404Props> = (props) => {
return ( return (
<> <>
<Head title='404 | Théo LUDWIG (Divlo)' /> <Head title='404 | Théo LUDWIG' />
<ErrorPage <ErrorPage
statusCode={404} statusCode={404}
message={t('errors:not-found')} message={t('errors:not-found')}

View File

@ -13,7 +13,7 @@ const Error500: NextPage<Error500Props> = (props) => {
return ( return (
<> <>
<Head title='500 | Théo LUDWIG (Divlo)' /> <Head title='500 | Théo LUDWIG' />
<ErrorPage <ErrorPage
statusCode={500} statusCode={500}
message={t('errors:server-error')} message={t('errors:server-error')}

View File

@ -1,6 +1,9 @@
import type { GetStaticProps, GetStaticPaths, NextPage } from 'next' import type { GetStaticProps, GetStaticPaths, NextPage } from 'next'
import Link from 'next/link'
import Image from 'next/image' import Image from 'next/image'
import { MDXRemote } from 'next-mdx-remote' import { MDXRemote } from 'next-mdx-remote'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faLink } from '@fortawesome/free-solid-svg-icons'
import date from 'date-and-time' import date from 'date-and-time'
import Giscus from '@giscus/react' import Giscus from '@giscus/react'
import { useTheme } from 'next-themes' import { useTheme } from 'next-themes'
@ -17,6 +20,26 @@ interface BlogPostPageProps extends FooterProps {
post: Post post: Post
} }
const Heading = (
props: React.DetailedHTMLProps<
React.HTMLAttributes<HTMLHeadingElement>,
HTMLHeadingElement
>
): JSX.Element => {
const { children, id = '' } = props
return (
<h2 {...props} className='group'>
<Link
href={`#${id}`}
className='invisible !text-black group-hover:visible dark:!text-white'
>
<FontAwesomeIcon className='mr-2 inline h-4 w-4' icon={faLink} />
</Link>
{children}
</h2>
)
}
const BlogPostPage: NextPage<BlogPostPageProps> = (props) => { const BlogPostPage: NextPage<BlogPostPageProps> = (props) => {
const { version, post } = props const { version, post } = props
@ -25,7 +48,7 @@ const BlogPostPage: NextPage<BlogPostPageProps> = (props) => {
return ( return (
<> <>
<Head <Head
title={`${post.frontmatter.title} | Théo LUDWIG (Divlo)`} title={`${post.frontmatter.title} | Théo LUDWIG`}
description={post.frontmatter.description} description={post.frontmatter.description}
/> />
@ -42,6 +65,12 @@ const BlogPostPage: NextPage<BlogPostPageProps> = (props) => {
<MDXRemote <MDXRemote
{...post.source} {...post.source}
components={{ components={{
h1: Heading,
h2: Heading,
h3: Heading,
h4: Heading,
h5: Heading,
h6: Heading,
img: (properties) => { img: (properties) => {
const { src = '', alt = 'Blog Image' } = properties const { src = '', alt = 'Blog Image' } = properties
const source = src.replace('../public/', '/') const source = src.replace('../public/', '/')
@ -69,7 +98,7 @@ const BlogPostPage: NextPage<BlogPostPageProps> = (props) => {
/> />
<Giscus <Giscus
id='comments' id='comments'
repo='Divlo/Divlo' repo='theoludwig/theoludwig'
repoId='MDEwOlJlcG9zaXRvcnkzNTg5NDg1NDQ=' repoId='MDEwOlJlcG9zaXRvcnkzNTg5NDg1NDQ='
category='General' category='General'
categoryId='DIC_kwDOFWUewM4CQ_WK' categoryId='DIC_kwDOFWUewM4CQ_WK'

View File

@ -21,7 +21,7 @@ const BlogPage: NextPage<BlogPageProps> = (props) => {
return ( return (
<> <>
<Head title='Blog | Divlo' description={blogDescription} /> <Head title='Blog | Théo LUDWIG' description={blogDescription} />
<Header /> <Header />
<main className='flex flex-1 flex-col flex-wrap items-center'> <main className='flex flex-1 flex-col flex-wrap items-center'>

View File

@ -21,7 +21,7 @@ Git was originally authored by [Linus Torvalds](https://en.wikipedia.org/wiki/Li
Git allows: Git allows:
- to be able to work with several people on the same codebase. - to work with several people on the same codebase.
- track changes to know who did what and when. - track changes to know who did what and when.
- revert changes. - revert changes.
@ -122,6 +122,13 @@ git checkout <branch>
# Merge a branch into the current branch # Merge a branch into the current branch
git merge <branch> git merge <branch>
# Combine multiple commits of a branch into one for a merge
git merge --squash <branch>
# Change several past commits (interactive rebase)
# HEAD points to the current consulted commit.
git rebase --interactive HEAD~<number-of-commits>
# Delete a branch # Delete a branch
git branch --delete <branch> git branch --delete <branch>
git push <remote> --delete <branch> git push <remote> --delete <branch>
@ -132,14 +139,11 @@ git fetch --prune
# Revert a commit # Revert a commit
git revert <commit> git revert <commit>
# Change several past commits (interactive rebase)
# HEAD points to the current consulted commit.
git rebase --interactive HEAD~<number-of-commits>
# Reset the current branch, delete all commits since <branch> (without removing the changes) # Reset the current branch, delete all commits since <branch> (without removing the changes)
git reset --soft <branch> git reset --soft <branch>
# Apply the changes introduced by some existing commits # Apply the changes introduced by some existing commits
# (by first being on the branch where you want to apply the commit)
git cherry-pick <commit> git cherry-pick <commit>
``` ```

View File

@ -13,11 +13,11 @@ This blog is here to document my journey of learning computer science, explainin
The idea is that I will share my knowledge with you (readers), and hopefully help you to learn too. The idea is that I will share my knowledge with you (readers), and hopefully help you to learn too.
Keep in mind that I will not translate the posts in French, all the posts will be written in English, as I'm not a native English speaker, I will probably make mistakes, feel free to open pull requests on [GitHub](https://github.com/Divlo/Divlo) to correct them. 😊 Keep in mind that I will not translate the posts in French, all the posts will be written in English, as I'm not a native English speaker, I will probably make mistakes, feel free to open pull requests on [GitHub](https://github.com/theoludwig/theoludwig) to correct them. 😊
I plan to publish new posts when I have something new to share. There's no schedule, so stay tuned! I plan to publish new posts when I have something new to share. There's no schedule, so stay tuned!
To stay informed of new blog post and to ask questions, feel free to follow me on Twitter: [@Divlo_FR](https://twitter.com/Divlo_FR). To stay informed of new blog post and to ask questions, feel free to follow me on Twitter: [@theoludwig\_](https://twitter.com/theoludwig_).
## Project based learning ## Project based learning
@ -33,7 +33,7 @@ I learn something new, because it solved a "real life" problem I had encountered
In this section, I will explain what technologies I used to make this blog, and what are the technical choices I had to do. In this section, I will explain what technologies I used to make this blog, and what are the technical choices I had to do.
The code of this website is open source on [GitHub](https://github.com/Divlo/Divlo), so you can see the code and contribute to it. The code of this website is open source on [GitHub](https://github.com/theoludwig/theoludwig), so you can see the code and contribute to it.
### Technologies ### Technologies

View File

@ -333,11 +333,11 @@ def maximum_subarray_sum_linear(array: list[int]) -> int:
Problems solving is a very complicated and large topic, and also a very important skill to have as a software developer. Problems solving is a very complicated and large topic, and also a very important skill to have as a software developer.
To improve our problems solving skills, we can regularly practice with [programming challenges](https://github.com/Divlo/programming-challenges). To improve our problems solving skills, we can regularly practice with [programming challenges](https://github.com/theoludwig/programming-challenges).
## Sources ## Sources
- [Wikipedia - Competitive programming](https://en.wikipedia.org/wiki/Competitive_programming) - [Wikipedia - Competitive programming](https://en.wikipedia.org/wiki/Competitive_programming)
- [Frontend Masters - The Last Algorithms Course You'll Need](https://frontendmasters.com/courses/algorithms/) - [Frontend Masters - The Last Algorithms Course You'll Need](https://frontendmasters.com/courses/algorithms/)
- [Big-O Cheat Sheet](https://www.bigocheatsheet.com/) - [Big-O Cheat Sheet](https://www.bigocheatsheet.com/)
- [programming challenges](https://github.com/Divlo/programming-challenges) - [programming challenges](https://github.com/theoludwig/programming-challenges)

View File

@ -7,13 +7,13 @@ publishedOn: '2022-04-11T10:24:55.206Z'
Hello! 👋 Hello! 👋
After months of hard work, [Thream v1.0.0](https://www.thream.divlo.fr/) has been released! 🎉 After months of hard work, [Thream v1.0.0](https://thream.divlo.fr/) has been released! 🎉
[**Thream**](https://www.thream.divlo.fr/) is your open-source platform to stay close with your friends and communities, talk, chat, collaborate, share and have fun. [**Thream**](https://thream.divlo.fr/) is your open-source platform to stay close with your friends and communities, talk, chat, collaborate, share and have fun.
## Presentation ## Presentation
[**Thream**](https://www.thream.divlo.fr/) is a social network to stay close with your friends and communities to talk, chat, collaborate and share. [**Thream**](https://thream.divlo.fr/) is a social network to stay close with your friends and communities to talk, chat, collaborate and share.
The project is largely inspired by [Discord](https://discord.com), a proprietary instant messaging service, but differentiates itself by its **non-profit open source philosophy** and will integrate special features. The project is largely inspired by [Discord](https://discord.com), a proprietary instant messaging service, but differentiates itself by its **non-profit open source philosophy** and will integrate special features.
@ -23,11 +23,11 @@ The idea is that a user can create an account to authenticate with an email addr
![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://www.thream.divlo.fr/) is a website that works on any recent browser, accessible on [thream.divlo.fr](https://www.thream.divlo.fr/). [**Thream**](https://thream.divlo.fr/) is a website that works on any recent browser, accessible on [thream.divlo.fr](https://thream.divlo.fr/).
## History ## History
The idea for the project has existed since May 13, 2020, symbolized by a [publication on Twitter](https://twitter.com/Divlo_FR/status/1260638175246135296) by the creator: Divlo. The idea for the project has existed since May 13, 2020, symbolized by a [publication on Twitter](https://twitter.com/theoludwig_/status/1260638175246135296) by the creator: Théo LUDWIG.
The main goal is to put into **practice knowledge in web development** and computer science in general on a concrete project that can **easily evolve over time** where you can add many features. The main goal is to put into **practice knowledge in web development** and computer science in general on a concrete project that can **easily evolve over time** where you can add many features.
@ -116,4 +116,4 @@ The other interest of the project is that it is completely **open-source**, and
Feel free to give feebacks and suggestions to improve the project, and to report any bug you find. Feel free to give feebacks and suggestions to improve the project, and to report any bug you find.
**Thream** is available: [**thream.divlo.fr**](https://www.thream.divlo.fr/). **Thream** is available: [**thream.divlo.fr**](https://thream.divlo.fr/).

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 92 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.7 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -6,14 +6,14 @@
"basics": { "basics": {
"name": "Théo LUDWIG", "name": "Théo LUDWIG",
"label": "Développeur Full Stack • Étudiant", "label": "Développeur Full Stack • Étudiant",
"image": "https://divlo.fr/images/logo_orange.png", "image": "https://theoludwig.fr/images/logo_orange.png",
"email": "contact@divlo.fr", "email": "contact@theoludwig.fr",
"age": "31/03/2003", "age": "31/03/2003",
"location": { "location": {
"address": "Alsace, France" "address": "Alsace, France"
}, },
"url": "https://divlo.fr", "url": "https://theoludwig.fr",
"summary": "Je suis étudiant à l'université suivant la formation \"BUT Informatique\" et me forme en autodidacte dans l'informatique en suivant des formations en ligne. <br/> Je mets en pratique tout ce que j'apprends et réalise de nombreux projets (disponible sur <a href=\"https://divlo.fr\">divlo.fr</a>)." "summary": "Je suis étudiant à l'université suivant la formation \"BUT Informatique\" et me forme en autodidacte dans l'informatique en suivant des formations en ligne. <br/> Je mets en pratique tout ce que j'apprends et réalise de nombreux projets (disponible sur <a href=\"https://theoludwig.fr\">theoludwig.fr</a>)."
}, },
"education": [ "education": [
{ {

View File

@ -8,7 +8,19 @@
} }
.prose { .prose {
@apply !max-w-5xl text-gray dark:text-gray-300; @apply !max-w-5xl scroll-smooth text-gray dark:text-gray-300;
}
.prose p {
@apply text-justify;
}
.prose [id]::before {
content: '';
display: block;
height: 90px;
margin-top: -90px;
visibility: hidden;
} }
.prose a, .prose a,

View File

@ -1,11 +1,11 @@
export const DIVLO_BIRTH_DATE_DAY = '31' as const export const BIRTH_DATE_DAY = '31' as const
export const DIVLO_BIRTH_DATE_MONTH = '03' as const export const BIRTH_DATE_MONTH = '03' as const
export const DIVLO_BIRTH_DATE_YEAR = '2003' as const export const BIRTH_DATE_YEAR = '2003' as const
export const DIVLO_BIRTH_DATE_STRING = export const BIRTH_DATE_STRING =
`${DIVLO_BIRTH_DATE_DAY}/${DIVLO_BIRTH_DATE_MONTH}/${DIVLO_BIRTH_DATE_YEAR}` as const `${BIRTH_DATE_DAY}/${BIRTH_DATE_MONTH}/${BIRTH_DATE_YEAR}` as const
export const DIVLO_BIRTH_DATE_ISO_8601 = export const BIRTH_DATE_ISO_8601 =
`${DIVLO_BIRTH_DATE_YEAR}-${DIVLO_BIRTH_DATE_MONTH}-${DIVLO_BIRTH_DATE_DAY}` as const `${BIRTH_DATE_YEAR}-${BIRTH_DATE_MONTH}-${BIRTH_DATE_DAY}` as const
export const DIVLO_BIRTH_DATE = new Date(DIVLO_BIRTH_DATE_ISO_8601) export const BIRTH_DATE = new Date(BIRTH_DATE_ISO_8601)
/** /**
* Calculates the age of a person based on their birth date * Calculates the age of a person based on their birth date