mirror of
				https://github.com/theoludwig/theoludwig.git
				synced 2025-10-14 20:23:25 +02:00 
			
		
		
		
	feat: init Curriculum Vitae
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -15,7 +15,6 @@ coverage | ||||
| out/ | ||||
| dist/ | ||||
| build/ | ||||
| apps/website/public/curriculum-vitae/ | ||||
|  | ||||
| # misc | ||||
| .DS_Store | ||||
|   | ||||
							
								
								
									
										26
									
								
								apps/website/app/[locale]/(main)/layout.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								apps/website/app/[locale]/(main)/layout.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
							
								
								
									
										21
									
								
								apps/website/app/[locale]/curriculum-vitae/layout.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								apps/website/app/[locale]/curriculum-vitae/layout.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
							
								
								
									
										19
									
								
								apps/website/app/[locale]/curriculum-vitae/page.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								apps/website/app/[locale]/curriculum-vitae/page.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -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> | ||||
|         <NextIntlClientProvider messages={messages}> | ||||
|           {children} | ||||
|         </NextIntlClientProvider> | ||||
|       </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(); | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -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