generated from avior/template-web-astro
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
851ae7a528 | |||
f671a21d2f |
@ -1,4 +1,4 @@
|
||||
# This Dockerfile allows you to run Astro in a static container (no server side)
|
||||
# This Dockerfile allows you to run Astro in a static container using NGINX (no server side)
|
||||
|
||||
#########
|
||||
# Build #
|
||||
|
26
nginx.conf
26
nginx.conf
@ -9,6 +9,16 @@ http {
|
||||
listen 3000;
|
||||
listen [::]:3000;
|
||||
|
||||
# Redirect from non-www to www
|
||||
# if ($host ~ ^(?!www\.)(?<domain>.+)$) {
|
||||
# return 301 $scheme://www.$domain$request_uri;
|
||||
# }
|
||||
|
||||
# Redirect from www to non-www
|
||||
if ($host ~ ^www\.(?<domain>.+)$) {
|
||||
return 301 $scheme://$domain$request_uri;
|
||||
}
|
||||
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
@ -18,13 +28,23 @@ http {
|
||||
gzip on;
|
||||
gzip_min_length 1000;
|
||||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_types text/html text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
error_page 404 /404.html;
|
||||
error_page 500 502 503 504 /500.html;
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
|
||||
# Security headers (note: temporaly unvailable "prefetch-src 'self'; ")
|
||||
add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'none'; form-action 'self'; manifest-src 'self'; script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src data: 'self' https://img.shields.io; font-src 'self'; connect-src 'self'; base-uri 'self';";
|
||||
add_header X-Frame-Options "DENY";
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Content-Type-Options "nosniff";
|
||||
add_header Referrer-Policy "no-referrer";
|
||||
add_header Permissions-Policy "geolocation=(), microphone=(), interest-cohort=()";
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
|
||||
add_header X-Download-Options "noopen";
|
||||
|
||||
location / {
|
||||
try_files $uri $uri.html $uri/index.html /$uri /$uri/index.html /index.html;
|
||||
try_files $uri $uri.html $uri/index.html /$uri /$uri/index.html =404;
|
||||
}
|
||||
|
||||
# Plausible script
|
||||
|
8
package-lock.json
generated
8
package-lock.json
generated
@ -11,7 +11,7 @@
|
||||
"@dzeio/logger": "^3",
|
||||
"@dzeio/object-util": "^1",
|
||||
"@dzeio/url-manager": "^1",
|
||||
"@fontsource-variable/lexend": "^5.0.12",
|
||||
"@fontsource-variable/lexend": "^5.1.1",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"astro": "^3",
|
||||
"astro-seo": "^0.8.0",
|
||||
@ -947,9 +947,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@fontsource-variable/lexend": {
|
||||
"version": "5.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource-variable/lexend/-/lexend-5.0.12.tgz",
|
||||
"integrity": "sha512-ib0Fvf4MK+Cpjq3xp9F8Xf/uigo08lPqPK/dU6s2RQk2U+IVuKB2Fbhceql7LFxC80OYlEjN+CyOZbSzqsirRQ=="
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource-variable/lexend/-/lexend-5.1.1.tgz",
|
||||
"integrity": "sha512-ixzYkzPiJRBAxYPsjIUBLBjS1zXBMF75qQwoVyEPWOtt5uyEHdT8jTpbh/b4ibsnQvqEVb/CToifmEXJfvShag=="
|
||||
},
|
||||
"node_modules/@istanbuljs/schema": {
|
||||
"version": "0.1.3",
|
||||
|
@ -20,7 +20,7 @@
|
||||
"@dzeio/logger": "^3",
|
||||
"@dzeio/object-util": "^1",
|
||||
"@dzeio/url-manager": "^1",
|
||||
"@fontsource-variable/lexend": "^5.0.12",
|
||||
"@fontsource-variable/lexend": "^5.1.1",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"astro": "^3",
|
||||
"astro-seo": "^0.8.0",
|
||||
|
5
public/robots.txt
Normal file
5
public/robots.txt
Normal file
@ -0,0 +1,5 @@
|
||||
User-Agent: *
|
||||
Disallow:
|
||||
Disallow: /cv
|
||||
|
||||
Sitemap: https://avior.me/sitemap.xml
|
BIN
src/assets/pages/cv/me.jpg
Normal file
BIN
src/assets/pages/cv/me.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
@ -13,6 +13,7 @@ export interface Props extends Omit<astroHTML.JSX.ImgHTMLAttributes, 'src'> {
|
||||
srcDark?: ImageMetadata | string
|
||||
width?: number
|
||||
height?: number
|
||||
innerClass?: string
|
||||
}
|
||||
|
||||
type PictureResult = {
|
||||
@ -70,7 +71,7 @@ const props = objectOmit(Astro.props, 'src', 'srcDark', 'class')
|
||||
{res.light.formats.map((it) => (
|
||||
<source srcset={it.img.src} type={`image/${it.format}`} />
|
||||
))}
|
||||
<img src={res.light.src.src} />
|
||||
<img src={res.light.src.src} class={Astro.props.innerClass} />
|
||||
</picture>
|
||||
) || (
|
||||
<img {...props} class:list={[Astro.props.class, {'dark:hidden': res.dark}]} src={res.light.src as string} />
|
||||
@ -81,7 +82,7 @@ const props = objectOmit(Astro.props, 'src', 'srcDark', 'class')
|
||||
{res.dark.formats.map((it) => (
|
||||
<source srcset={it.img.src} type={`image/${it.format}`} />
|
||||
))}
|
||||
<img src={res.dark.src.src} />
|
||||
<img src={res.dark.src.src} class={Astro.props.innerClass} />
|
||||
</picture>
|
||||
) || (res.dark && (
|
||||
<img {...props} class:list={[Astro.props.class, 'hidden', 'dark:block']} src={res.dark.src as string} />
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
import Head, { type Props as HeadProps } from './Head.astro'
|
||||
|
||||
import '@fontsource-variable/lexend'
|
||||
|
||||
export interface Props extends HeadProps {}
|
||||
---
|
||||
|
||||
@ -13,3 +15,9 @@ export interface Props extends HeadProps {}
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style is:global>
|
||||
html {
|
||||
font-weight: 350;
|
||||
}
|
||||
</style>
|
||||
|
158
src/pages/cv.astro
Normal file
158
src/pages/cv.astro
Normal file
@ -0,0 +1,158 @@
|
||||
---
|
||||
import Base from 'layouts/Base.astro'
|
||||
import Picture from 'components/Picture.astro'
|
||||
import Me from 'assets/pages/cv/me.jpg'
|
||||
import { objectMap } from '@dzeio/object-util'
|
||||
|
||||
const skills = {
|
||||
'Langages': 'Typescript/JavaScript, Web (HTML/CSS), Kotlin, C++',
|
||||
'Frameworks': 'Astro, NextJS, Android (MVVM), PlatformIO',
|
||||
'Softwares': 'Git, VSCode, Zed',
|
||||
'Tertiaire': 'Gestion de projet, Encadrement de collaborateurs'
|
||||
} as const
|
||||
|
||||
const skillColor: Record<keyof typeof skills, string> = {
|
||||
'Langages': 'amber',
|
||||
'Frameworks': 'sky',
|
||||
'Softwares': 'teal',
|
||||
'Tertiaire': 'gray'
|
||||
}
|
||||
|
||||
const passions: Array<string> = [
|
||||
'Pokémon',
|
||||
'Tennis',
|
||||
'Programation'
|
||||
]
|
||||
|
||||
const jobs: Array<{
|
||||
company: string
|
||||
start: string
|
||||
end?: string
|
||||
projects: Array<{
|
||||
name: string
|
||||
client?: string
|
||||
description: string
|
||||
technics?: Array<string>
|
||||
}>
|
||||
}> = [{
|
||||
company: 'Aptatio',
|
||||
start: '2019-09-30',
|
||||
projects: [{
|
||||
name: 'Ifremer LOOP',
|
||||
client: 'Ifremer',
|
||||
description: 'Développement d’une application de gestion des réponses des appels à données et participations aux groupes internationaux',
|
||||
technics: [
|
||||
'Gestion de projet',
|
||||
'Conception de logiciel',
|
||||
'Développement de logiciel Web (Framework Astro & Typescript)'
|
||||
]
|
||||
}, {
|
||||
name: 'Gwaleen',
|
||||
client: 'Ifremer & Aptatio',
|
||||
description: 'Développement de plusieurs modules logiciel des Ichtyomètre éléctronique Gwaleen',
|
||||
technics: [
|
||||
'Création et maintenance d\'un Logiciel Android de Gestion de donnée provenant d\'Ichtyomètres Connecté (Kotlin)',
|
||||
'Conception et Création d\'un protocol de communication entre 2 appareil Android en bluetooth pour de la donnée Vidéo (Kotlin)',
|
||||
'Gestion et création du code embarqué dans les Ichtyomètres Gwaleen (C++)'
|
||||
]
|
||||
}, {
|
||||
name: 'ImmerCité',
|
||||
client: 'La cité des congrès de Nantes',
|
||||
description: 'Création d\'ImmerCité, un logiciel immersif pour la présentation d\'événements, primé au concours international des Cités des Congrès et lauréat du 1er prix Innovation Award à la conférence annuelle de l\'AIPC au Costa Rica.',
|
||||
technics: [
|
||||
'Conception de logiciel',
|
||||
'Développement de logiciel Web (Framework NextJS & Typescript)',
|
||||
'Création d\'un engine de gestion 2D pour le placement et l\'automatisation des objets dans les salles de la cité',
|
||||
'Gestion de la communication et synchronisation entre plusieurs ordinateurs (WebSocket & ExpressJS)',
|
||||
'Programation de la 3D dans Unity puis Godot (C#, GDScript)'
|
||||
]
|
||||
}, {
|
||||
name: 'Gestion de l\'infrastructure',
|
||||
description: 'Gestion de l\'infrastructure Réseau de l\'entreprise',
|
||||
technics: [
|
||||
'mise en place d\'un SSO (Single sign-on)',
|
||||
'Gestion de la donnée utilisateur/client',
|
||||
'Mise en ligne des logiciels Client',
|
||||
'Maintenance Préventive des serveurs'
|
||||
]
|
||||
}]
|
||||
}, {
|
||||
company: 'Auto-Entreprise',
|
||||
start: '2019-04-01',
|
||||
projects: [{
|
||||
name: 'TCGdex',
|
||||
description: 'Développement de TCGdex, une API open source multilingue (14 langues) pour le jeu de cartes Pokémon JCC, offrant des fonctionnalités avancées aux développeurs et amateurs du jeu.',
|
||||
technics: [
|
||||
'Récupération des données depuis une multitude de sources',
|
||||
'Création et maintenance d\'une API avec + de 4 Millions de requettes par mois',
|
||||
'Mise en place d\'outillages pour simplifier l\'usage de l\'API aux développeurs',
|
||||
'Maintenance et gestion d\'une communauté autour du jeux de carte Pokémon'
|
||||
]
|
||||
}]
|
||||
}]
|
||||
---
|
||||
|
||||
<Base>
|
||||
<main class="container py-8">
|
||||
<div class="flex gap-4">
|
||||
<div class="w-1/4 flex flex-col gap-4">
|
||||
<Picture src={Me} innerClass="rounded-xl" />
|
||||
<h1 class="font-bold text-5xl text-center">Florian Bouillon</h1>
|
||||
<div>
|
||||
<p>Compétences :</p>
|
||||
<div class="hidden bg-amber-300 bg-sky-300 bg-teal-300"></div>
|
||||
<ul class="pl-6 list-disc">
|
||||
{objectMap(skills, (it, key) => (
|
||||
<li>{key}: {it.split(',').map((it) => <span class:list={[`bg-${skillColor[key]}-300`, "inline-block px-2 py-1 m-1 text-black rounded-xl"]}>{it}</span>)}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p>Passions :</p>
|
||||
<ul class="pl-2 list-disc">
|
||||
{passions.map((it) => (
|
||||
<li>{it}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-3/4">
|
||||
<div class="">
|
||||
<h2 class="text-4xl font-bold">Expérience professionnel</h2>
|
||||
{jobs.map((company) => (
|
||||
<div class="mt-6">
|
||||
<div class="flex justify-between items-center">
|
||||
<h2 class="text-2xl font-semibold">{company.company}</h2>
|
||||
<div class="italic">{company.start} - {company.end ?? 'Aujourd\'hui'}</div>
|
||||
</div>
|
||||
<div class="pl-2">
|
||||
{company.projects.map((it, idx) => (
|
||||
<div>
|
||||
{idx > 0 && (
|
||||
<hr class="my-2 border-t-2 border-gray-500" />
|
||||
)}
|
||||
<div class="flex justify-between items-center">
|
||||
<p class="text-xl font-[550]">- {it.name}</p>
|
||||
{it.client && (
|
||||
<p>{it.client}</p>
|
||||
)}
|
||||
</div>
|
||||
<p class="mt-2 pl-4">{it.description}</p>
|
||||
{it.technics && (
|
||||
<div class="pl-4 mt-2">
|
||||
<p>Tâches:</p>
|
||||
<ul class="list-disc pl-6">
|
||||
{it.technics?.map((tech) => <li>{tech}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
@ -29,7 +29,7 @@ const clients = await Promise.all((await getCollection('clients')).map(async (it
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<div></div>
|
||||
<div class="prose dark:prose-invert max-w-none">
|
||||
<p class="font-semibold">Tâches :O :</p>
|
||||
<p class="font-semibold">Tâches :</p>
|
||||
</div>
|
||||
</div>
|
||||
{clients.map((client, index) => {
|
||||
|
@ -15,9 +15,7 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
fontFamily: {
|
||||
fontFamily: {
|
||||
sans: ["Lexend Variable", "Lexend", ...defaultTheme.fontFamily.sans],
|
||||
},
|
||||
sans: ["Lexend Variable", "Lexend", ...defaultTheme.fontFamily.sans],
|
||||
},
|
||||
extend: {
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user