Style rework #35
4 changed files with 196 additions and 78 deletions
|
@ -23,12 +23,8 @@ async fn page(req: HttpRequest, config: web::Data<Config>) -> impl Responder {
|
||||||
#[derive(Content, Debug)]
|
#[derive(Content, Debug)]
|
||||||
struct PortfolioTemplate<'a> {
|
struct PortfolioTemplate<'a> {
|
||||||
navbar: NavBar,
|
navbar: NavBar,
|
||||||
bots_app: Option<Vec<File>>,
|
location_apps: Option<&'a str>,
|
||||||
bots_loc: Option<String>,
|
apps: Option<Vec<File>>,
|
||||||
persos_app: Option<Vec<File>>,
|
|
||||||
persos_loc: Option<String>,
|
|
||||||
univ_content: Option<String>,
|
|
||||||
univ_loc: Option<String>,
|
|
||||||
err_msg: &'a str,
|
err_msg: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,37 +33,16 @@ fn build_page(config: Config, url: String) -> String {
|
||||||
let projects_dir = "data/projects";
|
let projects_dir = "data/projects";
|
||||||
let ext = ".md";
|
let ext = ".md";
|
||||||
|
|
||||||
// Get bots apps
|
// Get apps
|
||||||
let bots_apps_loc = format!("{projects_dir}/bots");
|
let apps = glob(&format!("{projects_dir}/*{ext}"))
|
||||||
let bots_apps = glob(&format!("{bots_apps_loc}/*{ext}"))
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|e| read_file(&e.unwrap().to_string_lossy()).unwrap())
|
.map(|e| read_file(&e.unwrap().to_string_lossy()).unwrap())
|
||||||
.collect::<Vec<File>>();
|
.collect::<Vec<File>>();
|
||||||
|
|
||||||
// Get perso apps
|
let bots_app = if apps.is_empty() {
|
||||||
let perso_apps_loc = format!("{projects_dir}/perso");
|
(None, Some(projects_dir))
|
||||||
let perso_apps = glob(&format!("{perso_apps_loc}/*{ext}"))
|
|
||||||
.unwrap()
|
|
||||||
.map(|e| read_file(&e.unwrap().to_string_lossy()).unwrap())
|
|
||||||
.collect::<Vec<File>>();
|
|
||||||
|
|
||||||
let univ_loc = format!("{projects_dir}/univ{ext}");
|
|
||||||
|
|
||||||
let (bots_app, bots_loc) = if bots_apps.is_empty() {
|
|
||||||
(None, Some(bots_apps_loc))
|
|
||||||
} else {
|
} else {
|
||||||
(Some(bots_apps), None)
|
(Some(apps), None)
|
||||||
};
|
|
||||||
|
|
||||||
let (persos_app, persos_loc) = if perso_apps.is_empty() {
|
|
||||||
(None, Some(perso_apps_loc))
|
|
||||||
} else {
|
|
||||||
(Some(perso_apps), None)
|
|
||||||
};
|
|
||||||
|
|
||||||
let (univ_content, univ_loc) = match read_file(&univ_loc) {
|
|
||||||
Some(data) => (Some(data.content), None),
|
|
||||||
_ => (None, Some(univ_loc)),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config.tmpl.render(
|
config.tmpl.render(
|
||||||
|
@ -77,12 +52,8 @@ fn build_page(config: Config, url: String) -> String {
|
||||||
portfolio: true,
|
portfolio: true,
|
||||||
..NavBar::default()
|
..NavBar::default()
|
||||||
},
|
},
|
||||||
bots_app,
|
apps: bots_app.0,
|
||||||
bots_loc,
|
location_apps: bots_app.1,
|
||||||
persos_app,
|
|
||||||
persos_loc,
|
|
||||||
univ_content,
|
|
||||||
univ_loc,
|
|
||||||
err_msg: "is empty",
|
err_msg: "is empty",
|
||||||
},
|
},
|
||||||
Infos {
|
Infos {
|
||||||
|
|
71
static/css/langages.css
Normal file
71
static/css/langages.css
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
:root {
|
||||||
|
--lang-size-dot: 0.8em;
|
||||||
|
--lang-margin-text: 3px;
|
||||||
|
--lang-font-size: calc(var(--font-size) * 0.65);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dot */
|
||||||
|
p[data-lang]::before {
|
||||||
|
content: "";
|
||||||
|
|
||||||
|
height: var(--lang-size-dot);
|
||||||
|
width: var(--lang-size-dot);
|
||||||
|
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text */
|
||||||
|
p[data-lang]::after {
|
||||||
|
margin-left: var(--lang-margin-text);
|
||||||
|
font-size: var(--lang-font-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Langages definition */
|
||||||
|
p[data-lang="ts"]::before {
|
||||||
|
background-color: #3178c6;
|
||||||
|
}
|
||||||
|
|
||||||
|
p[data-lang="ts"]::after {
|
||||||
|
content: "TypeScript";
|
||||||
|
}
|
||||||
|
|
||||||
|
p[data-lang="rust"]::before {
|
||||||
|
background-color: #dea584;
|
||||||
|
}
|
||||||
|
|
||||||
|
p[data-lang="rust"]::after {
|
||||||
|
content: "Rust";
|
||||||
|
}
|
||||||
|
|
||||||
|
p[data-lang="py"]::before {
|
||||||
|
background-color: #3572a5;
|
||||||
|
}
|
||||||
|
|
||||||
|
p[data-lang="py"]::after {
|
||||||
|
content: "Python";
|
||||||
|
}
|
||||||
|
|
||||||
|
p[data-lang="ocaml"]::before {
|
||||||
|
background-color: #ef7a08;
|
||||||
|
}
|
||||||
|
|
||||||
|
p[data-lang="ocaml"]::after {
|
||||||
|
content: "OCaml";
|
||||||
|
}
|
||||||
|
|
||||||
|
p[data-lang="js"]::before {
|
||||||
|
background-color: #e3d357;
|
||||||
|
}
|
||||||
|
|
||||||
|
p[data-lang="js"]::after {
|
||||||
|
content: "JavaScript";
|
||||||
|
}
|
||||||
|
|
||||||
|
p[data-lang="c"]::before {
|
||||||
|
background-color: #555555;
|
||||||
|
}
|
||||||
|
|
||||||
|
p[data-lang="c"]::after {
|
||||||
|
content: "C";
|
||||||
|
}
|
84
static/css/portfolio.css
Normal file
84
static/css/portfolio.css
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
--extreme: white;
|
||||||
|
--card-hover: #bbbbbb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--extreme: black;
|
||||||
|
--card-hover: #0c1014;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--border-color: #6e6e6f;
|
||||||
|
--font-size-card: calc(var(--font-size) * 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List */
|
||||||
|
main ul {
|
||||||
|
padding: 0;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* breakpoint */
|
||||||
|
@media only screen and (max-width: 640px) {
|
||||||
|
main ul {
|
||||||
|
grid-template-columns: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card */
|
||||||
|
main li {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
|
||||||
|
|
||||||
|
background: color-mix(in srgb, var(--background) 90%, var(--extreme));
|
||||||
|
border: 1px solid
|
||||||
|
color-mix(in srgb, var(--background) 50%, var(--border-color));
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
padding: 10px;
|
||||||
|
margin-block: 10px;
|
||||||
|
margin-inline: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hover Card */
|
||||||
|
main li:hover {
|
||||||
|
background-color: color-mix(in srgb, var(--background) 40%, var(--extreme));
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Element */
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Element title */
|
||||||
|
div h3 {
|
||||||
|
margin-block: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Element description */
|
||||||
|
span {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Element text */
|
||||||
|
div p,
|
||||||
|
div a {
|
||||||
|
font-size: var(--font-size-card);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Element langage */
|
||||||
|
p[data-lang] {
|
||||||
|
margin: 0;
|
||||||
|
}
|
|
@ -2,52 +2,44 @@
|
||||||
<html class="index" lang="fr">
|
<html class="index" lang="fr">
|
||||||
<head dir="ltr">
|
<head dir="ltr">
|
||||||
{{>head.html}}
|
{{>head.html}}
|
||||||
|
<link rel="stylesheet" href="/css/portfolio.css" />
|
||||||
|
<link rel="stylesheet" href="/css/langages.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>{{>navbar.html}}</header>
|
<header>{{>navbar.html}}</header>
|
||||||
{{#data}}
|
|
||||||
<main>
|
<main>
|
||||||
<h1 id="title">Projets qui me tiennent à coeur</h1>
|
{{#data}}
|
||||||
<div id="content">
|
<h1>Portfolio</h1>
|
||||||
<h2 class="subtitle">Bots</h2>
|
<p>
|
||||||
<div class="subcontent">
|
Je programme depuis 2018 et j'ai appris une multitude de langages
|
||||||
{{#bots_app}} {{#metadata}} {{#info}}
|
depuis. Étant passionné de logiciels libres depuis ma licence
|
||||||
<h3 class="subsubtitle">
|
d'informatique à Paris 8, je publie tout sur des forges publiques.
|
||||||
<a target="_blank" href="{{link}} ">{{title}}</a>
|
</p>
|
||||||
</h3>
|
|
||||||
{{/info}} {{/metadata}}
|
|
||||||
<div class="subcontent">{{&content}}</div>
|
|
||||||
{{/bots_app}} {{^bots_app}}
|
|
||||||
<p>{{bots_loc}} {{err_msg}}</p>
|
|
||||||
{{/bots_app}}
|
|
||||||
<br />
|
|
||||||
</div>
|
|
||||||
<h2 class="subtitle">
|
|
||||||
<a target="_blank" href="https://git.mylloon.fr/Paris8"
|
|
||||||
>Projet de l'université</a
|
|
||||||
>
|
|
||||||
</h2>
|
|
||||||
<div class="subcontent">
|
|
||||||
{{&univ_content}} {{^univ_content}}
|
|
||||||
<p>{{univ_loc}} {{err_msg}}</p>
|
|
||||||
{{/univ_content}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2 class="subtitle">Projets perso</h2>
|
{{#location_apps}}
|
||||||
<div class="subcontent">
|
<!-- Error message -->
|
||||||
{{#persos_app}} {{#metadata}} {{#info}}
|
<p>{{location_apps}} {{err_msg}}</p>
|
||||||
<h3 class="subsubtitle">
|
{{/location_apps}} {{^location_apps}}
|
||||||
<a target="_blank" href="{{link}} ">{{title}}</a>
|
|
||||||
</h3>
|
<h2>Projets</h2>
|
||||||
|
<ul>
|
||||||
|
{{#apps}}
|
||||||
|
<li>
|
||||||
|
{{#metadata}} {{#info}}
|
||||||
|
<div
|
||||||
|
onclick="window.open('{{link}}', '_blank', 'noreferrer');"
|
||||||
|
title="{{title}} "
|
||||||
|
>
|
||||||
|
<h3>{{title}}</h3>
|
||||||
|
<span>{{&content}}</span> {{#language}}
|
||||||
|
<p data-lang="{{language}}"></p>
|
||||||
|
{{/language}}
|
||||||
|
</div>
|
||||||
{{/info}} {{/metadata}}
|
{{/info}} {{/metadata}}
|
||||||
<div class="subcontent">{{&content}}</div>
|
</li>
|
||||||
{{/persos_app}} {{^persos_app}}
|
{{/apps}}
|
||||||
<p>{{persos_loc}} {{err_msg}}</p>
|
</ul>
|
||||||
{{/persos_app}}
|
{{/location_apps}} {{/data}}
|
||||||
<br />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
{{/data}} {{>footer.html}}
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue