mirror of
https://github.com/theoludwig/theoludwig.git
synced 2026-08-25 09:21:33 +02:00
feat: init Curriculum Vitae
This commit is contained in:
16 files changed
+74
-21
No files matched your search
@@ -15,7 +15,6 @@ coverage
|
||||
out/
|
||||
dist/
|
||||
build/
|
||||
apps/website/public/curriculum-vitae/
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,26 @@
|
||||
import "@repo/config-tailwind/styles.css"
|
||||
import type { LocaleProps } from "@repo/i18n/config"
|
||||
import { Footer } from "@repo/ui/Layout/Footer"
|
||||
import { Header } from "@repo/ui/Layout/Header"
|
||||
import { ThemeProvider } from "@repo/ui/Layout/Header/SwitchTheme"
|
||||
import { VERSION } from "@repo/utils/constants"
|
||||
import { unstable_setRequestLocale } from "next-intl/server"
|
||||
|
||||
interface MainLayoutProps extends React.PropsWithChildren, LocaleProps {}
|
||||
|
||||
const MainLayout: React.FC<MainLayoutProps> = async (props) => {
|
||||
const { children, params } = props
|
||||
|
||||
// Enable static rendering
|
||||
unstable_setRequestLocale(params.locale)
|
||||
|
||||
return (
|
||||
<ThemeProvider>
|
||||
<Header />
|
||||
{children}
|
||||
<Footer version={VERSION} />
|
||||
</ThemeProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default MainLayout
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,21 @@
|
||||
import "@repo/config-tailwind/styles.css"
|
||||
import type { LocaleProps } from "@repo/i18n/config"
|
||||
import { ThemeProvider } from "@repo/ui/Layout/Header/SwitchTheme"
|
||||
import { unstable_setRequestLocale } from "next-intl/server"
|
||||
|
||||
interface CurriculumVitaeLayoutProps
|
||||
extends React.PropsWithChildren,
|
||||
LocaleProps {}
|
||||
|
||||
const CurriculumVitaeLayout: React.FC<CurriculumVitaeLayoutProps> = async (
|
||||
props,
|
||||
) => {
|
||||
const { children, params } = props
|
||||
|
||||
// Enable static rendering
|
||||
unstable_setRequestLocale(params.locale)
|
||||
|
||||
return <ThemeProvider forcedTheme="light">{children}</ThemeProvider>
|
||||
}
|
||||
|
||||
export default CurriculumVitaeLayout
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { LocaleProps } from "@repo/i18n/config"
|
||||
import { unstable_setRequestLocale } from "next-intl/server"
|
||||
|
||||
interface CurriculumVitaeProps extends LocaleProps {}
|
||||
|
||||
const CurriculumVitaePage: React.FC<CurriculumVitaeProps> = (props) => {
|
||||
const { params } = props
|
||||
|
||||
// Enable static rendering
|
||||
unstable_setRequestLocale(params.locale)
|
||||
|
||||
return (
|
||||
<main>
|
||||
<h1>CurriculumVitae</h1>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
export default CurriculumVitaePage
|
||||
@@ -1,10 +1,6 @@
|
||||
import "@repo/config-tailwind/styles.css"
|
||||
import type { Locale, LocaleProps } from "@repo/i18n/config"
|
||||
import { LOCALES } from "@repo/i18n/config"
|
||||
import { Footer } from "@repo/ui/Layout/Footer"
|
||||
import { Header } from "@repo/ui/Layout/Header"
|
||||
import { ThemeProvider } from "@repo/ui/Layout/Header/SwitchTheme"
|
||||
import { VERSION } from "@repo/utils/constants"
|
||||
import type { Metadata } from "next"
|
||||
import { NextIntlClientProvider } from "next-intl"
|
||||
import {
|
||||
@@ -59,11 +55,7 @@ export const generateStaticParams = (): Array<{ locale: Locale }> => {
|
||||
})
|
||||
}
|
||||
|
||||
interface LocaleLayoutProps extends React.PropsWithChildren {
|
||||
params: {
|
||||
locale: Locale
|
||||
}
|
||||
}
|
||||
interface LocaleLayoutProps extends React.PropsWithChildren, LocaleProps {}
|
||||
|
||||
const LocaleLayout: React.FC<LocaleLayoutProps> = async (props) => {
|
||||
const { children, params } = props
|
||||
@@ -76,13 +68,9 @@ const LocaleLayout: React.FC<LocaleLayoutProps> = async (props) => {
|
||||
return (
|
||||
<html lang={params.locale} suppressHydrationWarning>
|
||||
<body>
|
||||
<ThemeProvider>
|
||||
<NextIntlClientProvider messages={messages}>
|
||||
<Header />
|
||||
{children}
|
||||
<Footer version={VERSION} />
|
||||
</NextIntlClientProvider>
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
/*! modern-normalize v2.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */*,:before,:after{box-sizing:border-box}html{font-family:system-ui,Segoe UI,Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";line-height:1.15;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4}body{margin:0}hr{height:0;color:inherit}abbr[title]{text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}::-moz-focus-inner{border-style:none;padding:0}:-moz-focusring{outline:1px dotted ButtonText}:-moz-ui-invalid{box-shadow:none}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}body{font-family:Montserrat,Arial,"sans-serif";background:#f0f0f0;color:#333;line-height:1.42857143;font-size:14px}hr{margin-top:15px;margin-bottom:15px;border:0;border-top:1px solid #eee}p{margin:0}strong{font-weight:600}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}.link-disguise,.link-disguise:hover{color:inherit}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.clear-margin{margin:0}.relative{position:relative}.center-block{display:block;margin-right:auto;margin-left:auto}.text-center{text-align:center}.text-muted{color:#777}.text-uppercase{text-transform:uppercase}.list-unstyled{padding-left:0;list-style:none}.main{padding:5px}.title{font-weight:600}.profile-card-wrapper{position:relative}.card-wrapper{float:none!important;padding:5px}.profile-card-wrapper .profile-card{padding:10px}.card{background:#fff;border-radius:3px;padding:10px 0}.profile-pic{padding:10px 0}.profile-pic img{width:100px;height:100px;border-radius:50%;vertical-align:middle;border:0}.contact-details{display:flex;justify-content:center}.contact-details .detail{position:relative;min-height:1px;padding:10px}.social-links{line-height:2.5}.experience-description{margin-top:10px}.background-details .detail{display:table}.background-details .detail .icon,.background-details .detail .info{display:table-cell}.background-details .detail .icon{color:#707070}.background-details .detail .icon{min-width:45px;max-width:45px;text-align:center}.icon img{width:20px;height:20px}.background-details .detail .mobile-title{display:none}.card-nested{min-height:0;border-width:1px 0 0 0}.card-skills{position:relative}.labels{line-height:2}.space-top{margin-top:10px}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:600;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label-keyword{display:inline-block;font-size:.9em;padding:5px;border:1px solid #357ebd;margin-right:5px}.label-keyword p{margin:0}.section-separated{display:flex}
|
||||
@@ -1 +0,0 @@
|
||||
(function(){const o=document.createElement("link").relList;if(o&&o.supports&&o.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))r(e);new MutationObserver(e=>{for(const t of e)if(t.type==="childList")for(const c of t.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&r(c)}).observe(document,{childList:!0,subtree:!0});function s(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin==="use-credentials"?t.credentials="include":e.crossOrigin==="anonymous"?t.credentials="omit":t.credentials="same-origin",t}function r(e){if(e.ep)return;e.ep=!0;const t=s(e);fetch(e.href,t)}})();const i="31",l="03",u="2003",d=`${u}-${l}-${i}`,f=new Date(d),a=n=>{const o=new Date;let s=o.getFullYear()-n.getFullYear();const r=o.getMonth()-n.getMonth();return(r<0||r===0&&o.getDate()<n.getDate())&&s--,s},g=document.getElementById("year-old");g.textContent=a(f).toString();
|
||||
@@ -1 +0,0 @@
|
||||
<!doctype html><html lang="fr-FR"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>Théo LUDWIG</title><link rel="icon" type="image/webp" href="https://theoludwig.fr/images/logo_background.webp"/><script type="module" crossorigin src="/curriculum-vitae/index-C1jSdDgn.js"></script><link rel="stylesheet" crossorigin href="/curriculum-vitae/index-BFUlhOmZ.css"></head><body><div class="container-fluid"><div class="row main clearfix"><section class="col-md-3 card-wrapper profile-card-wrapper affix"><div class="card profile-card"><div class="profile-pic-container"><div class="profile-pic"><img class="media-object img-circle center-block" data-src="holder.js/100x100" alt="Théo LUDWIG" src="https://theoludwig.fr/images/logo_background.webp"/></div><div class="name-and-profession text-center"><h3><strong>Théo LUDWIG</strong></h3><h5 class="text-muted">Développeur Full Stack • Étudiant</h5><h5 class="text-muted">31/03/2003 (<span id="year-old"></span> ans)</h5><h5 class="text-muted">Alsace, France</h5></div></div><div class="contact-details clearfix"><div class="detail"><span class="info"><a class="link-disguise" href="mailto:contact@theoludwig.fr">contact@theoludwig.fr</a></span></div><div class="detail"><span class="info"><a class="link-disguise" href="https://theoludwig.fr">https://theoludwig.fr</a></span></div></div><hr/></div><div class="card background-card"><div class="background-details"><div class="detail" id="about"><div class="icon"><img src="data:image/svg+xml,%3c!--!%20Font%20Awesome%20Free%206.0.0%20by%20@fontawesome%20-%20https://fontawesome.com%20License%20-%20https://fontawesome.com/license/free%20(Icons:%20CC%20BY%204.0,%20Fonts:%20SIL%20OFL%201.1,%20Code:%20MIT%20License)%20Copyright%202022%20Fonticons,%20Inc.%20--%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20448%20512'%3e%3cpath%20d='M224%20256c70.7%200%20128-57.31%20128-128s-57.3-128-128-128C153.3%200%2096%2057.31%2096%20128S153.3%20256%20224%20256zM274.7%20304H173.3C77.61%20304%200%20381.6%200%20477.3c0%2019.14%2015.52%2034.67%2034.66%2034.67h378.7C432.5%20512%20448%20496.5%20448%20477.3C448%20381.6%20370.4%20304%20274.7%20304z'/%3e%3c/svg%3e" alt="user"/></div><div class="info"><h4 class="title text-uppercase">À propos</h4><div class="card card-nested"><div class="content mop-wrapper"><p>Je me demande constamment comment améliorer notre présent, afin de rendre notre futur meilleur, particulièrement grâce aux progrès de l'informatique.<br/>Ma priorité réside dans la création d'expériences utilisateurs (UX) intuitives, répondant aux besoins des utilisateurs de la manière la plus efficace que possible.</p></div></div></div></div><hr/><section class="section-separated"><div class="detail" id="education"><div class="icon"><img src="data:image/svg+xml,%3c!--!%20Font%20Awesome%20Free%206.0.0%20by%20@fontawesome%20-%20https://fontawesome.com%20License%20-%20https://fontawesome.com/license/free%20(Icons:%20CC%20BY%204.0,%20Fonts:%20SIL%20OFL%201.1,%20Code:%20MIT%20License)%20Copyright%202022%20Fonticons,%20Inc.%20--%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20640%20512'%3e%3cpath%20d='M623.1%20136.9l-282.7-101.2c-13.73-4.91-28.7-4.91-42.43%200L16.05%20136.9C6.438%20140.4%200%20149.6%200%20160s6.438%2019.65%2016.05%2023.09L76.07%20204.6c-11.89%2015.8-20.26%2034.16-24.55%2053.95C40.05%20263.4%2032%20274.8%2032%20288c0%209.953%204.814%2018.49%2011.94%2024.36l-24.83%20149C17.48%20471.1%2025%20480%2034.89%20480H93.11c9.887%200%2017.41-8.879%2015.78-18.63l-24.83-149C91.19%20306.5%2096%20297.1%2096%20288c0-10.29-5.174-19.03-12.72-24.89c4.252-17.76%2012.88-33.82%2024.94-47.03l190.6%2068.23c13.73%204.91%2028.7%204.91%2042.43%200l282.7-101.2C633.6%20179.6%20640%20170.4%20640%20160S633.6%20140.4%20623.1%20136.9zM351.1%20314.4C341.7%20318.1%20330.9%20320%20320%20320c-10.92%200-21.69-1.867-32-5.555L142.8%20262.5L128%20405.3C128%20446.6%20213.1%20480%20320%20480c105.1%200%20192-33.4%20192-74.67l-14.78-142.9L351.1%20314.4z'/%3e%3c/svg%3e" alt="graduation"/></div><div class="info"><h4 class="title text-uppercase">Formations</h4><div class="content"><ul class="list-unstyled clear-margin"><li class="card card-nested"><div class="content"><p class="clear-margin relative"><strong>Bachelor Universitaire de Technologie (BUT) Informatique</strong></p><p class="clear-margin relative"><strong>3ème année</strong></p><p class="text-muted clear-margin">IUT Robert Schuman à Illkirch-Graffenstaden</p><p class="text-muted clear-margin"><small>2023 - 2024</small></p><ul class="education-courses"><li>Développement Web en Node.js et React.js</li><li>Intégration/Déploiement Continue et Docker</li><li>Complexité Algorithmique Théorique et Pratique en C++</li><li>Base de données NoSQL (Redis, MongoDB, Cassandra)</li></ul></div></li><li class="card card-nested"><div class="content"><p class="clear-margin relative"><strong>Bachelor Universitaire de Technologie (BUT) InfLine truncated
|
||||
@@ -13,8 +13,8 @@ export const AboutDescription: React.FC<AboutDescriptionProps> = () => {
|
||||
{t.rich("home.about.description")}
|
||||
</Typography>
|
||||
|
||||
<Button href="/curriculum-vitae/index.html" variant="outline">
|
||||
Curriculum vitæ ({t("locales.fr-FR")})
|
||||
<Button href="/curriculum-vitae" variant="outline">
|
||||
Curriculum vitæ
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -11,16 +11,19 @@ export const THEMES = ["light", "dark"] as const
|
||||
export type Theme = (typeof THEMES)[number]
|
||||
export const THEME_DEFAULT = "dark" as Theme
|
||||
|
||||
export interface ThemeProviderProps extends React.PropsWithChildren {}
|
||||
export interface ThemeProviderProps extends React.PropsWithChildren {
|
||||
forcedTheme?: Theme
|
||||
}
|
||||
|
||||
export const ThemeProvider: React.FC<ThemeProviderProps> = (props) => {
|
||||
const { children } = props
|
||||
const { children, forcedTheme } = props
|
||||
|
||||
return (
|
||||
<NextThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme={THEME_DEFAULT}
|
||||
enableSystem={false}
|
||||
forcedTheme={forcedTheme}
|
||||
>
|
||||
{children}
|
||||
</NextThemeProvider>
|
||||
|
||||
Reference in new issue
Block a user