Begin add MonParcours + Update css work

This commit is contained in:
Florian RICHER 2023-10-10 22:59:08 +02:00
parent 1e27d18cb3
commit f4dba8213d
21 changed files with 1499 additions and 36 deletions

1
.tool-versions Normal file
View file

@ -0,0 +1 @@
nodejs 19.9.0

1138
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

9
package.json Normal file
View file

@ -0,0 +1,9 @@
{
"devDependencies": {
"autoprefixer": "^10.4.16",
"postcss": "^8.4.31",
"postcss-import": "^15.1.0",
"postcss-nested": "^6.0.1",
"tailwindcss": "^3.3.3"
}
}

8
postcss.config.js Normal file
View file

@ -0,0 +1,8 @@
export default {
plugins: {
'postcss-import': {},
'postcss-nested': {},
tailwindcss: {},
autoprefixer: {},
}
}

View file

@ -9,9 +9,9 @@ pub fn Link(
children: Children
) -> impl IntoView {
view! {
<a class="flex gap-1 font-semibold italic" href={url} target="_blank">
<a class="link" href={url} target="_blank">
{ children() }
<i class="flex items-center"><Icon icon=Icon::from(FiExternalLink) class="scale-75" /></i>
<i><Icon icon=Icon::from(FiExternalLink) /></i>
</a>
}
}

View file

@ -1,17 +1,27 @@
mod tag;
pub use tag::Tag;
mod link;
pub use link::Link;
mod social_link;
pub use social_link::{SocialLinkContainer, SocialLink};
mod top_component;
pub use top_component::TopComponent;
mod project;
pub use project::{ProjectContainer, Project};
mod timeline;
pub use timeline::{Timeline};
pub use timeline::{Timeline, TimelineElement, TimelineLabel, TimelineCard, TimelineCardTag, TimelineCardContent, TimelineCardSummary};
mod mon_parcours;
pub use mon_parcours::{MonParcours};

View file

@ -0,0 +1,80 @@
use std::collections::HashMap;
use std::rc::Rc;
use leptos::*;
use super::{
Tag,
Timeline,
TimelineElement,
TimelineLabel,
TimelineCard,
TimelineCardSummary,
TimelineCardTag,
TimelineCardContent
};
// Lang
// const CPP_TAG = <Tag name="C++" url="https://isocpp.org/" />
//
// // Other
// const REACT_TAG = <Tag name="React" url="https://fr.legacy.reactjs.org/" />
// const SYMFONY_4_TAG = <Tag name="Symfony" url="https://symfony.com/" />
// const FLUTTER_TAG = <Tag name="Flutter" url="https://flutter.dev/" />
// const RUBY_ON_RAILS_TAG = <Tag name="Ruby on rails" url="https://rubyonrails.org/" />
// const HOTWIRED_TAG = <Tag name="Hotwired" url="https://hotwired.dev/" />
// const DOCKER_TAG = <Tag name="Docker" url="https://www.docker.com/" />
// const STEAM_TAG = <Tag name="Steam API" url="https://partner.steamgames.com/doc/sdk/api/example" />
// const GITLAB_CI_TAG = <Tag name="Gitlab CI" url="https://docs.gitlab.com/ee/ci/" />
// const UNITY_TAG = <Tag name="Unity 3D" url="https://unity.com/fr" />
// const WORDPRESS_TAG = <Tag name="Wordpress" url="https://wordpress.com/fr/" />
// const CORDOVA_TAG = <Tag name="Cordova" url="https://cordova.apache.org/" />
// const ELECTRON_TAG = <Tag name="Electron" url="https://www.electronjs.org/" />
// const LWJGL_TAG = <Tag name="LWJGL" url="https://www.lwjgl.org/" />
// const OPENGL_TAG = <Tag name="OpenGL" url="https://www.opengl.org/" />
// const VULKAN_TAG = <Tag name="Vulkan" url="https://www.vulkan.org/" />
// const MIDI_TAG = <Tag name="MIDI" url="https://fr.wikipedia.org/wiki/Musical_Instrument_Digital_Interface" />
// const REQUIREJS_TAG = <Tag name="RequireJS" url="https://requirejs.org/" />
// const WEBPACK_TAG = <Tag name="Webpack" url="https://webpack.js.org/" />
// const VITE_TAG = <Tag name="Vite" url="https://vitejs.dev/" />
// const MAVEN_TAG = <Tag name="Maven" url="https://maven.apache.org/" />
// const GRADLE_TAG = <Tag name="Gradle" url="https://gradle.org/" />
// const BABYLONJG_TAG = <Tag name="BabylonJS" url="https://www.babylonjs.com/" />
// const ROCKET_RS_TAG = <Tag name="Rocket" url="https://rocket.rs/" />
// const ACTIX_WEB_TAG = <Tag name="Actix Web" url="https://actix.rs/" />
#[component]
pub fn MonParcours() -> impl IntoView {
let tools = Rc::from(HashMap::from([
("Rust", "https://www.rust-lang.org/"),
("Java", "https://www.java.com/fr/"),
("C++", "https://isocpp.org/")
]));
let to_tag = |tools: &HashMap<&str, &str>, lang: &str| {
let url = tools.get(lang).unwrap_or(&"");
view! { <Tag url=url.to_string()>Rust</Tag> }
};
view! {
<div>
<Timeline>
<TimelineElement slot:elements>
<TimelineLabel slot:labels>r"2019 - Aujourdhui"</TimelineLabel>
<TimelineCard slot:cards>
<TimelineCardSummary slot:titles>
<TimelineCardTag slot:tags>{ to_tag(tools.as_ref(), "Rust") }</TimelineCardTag>
r"Développeur dapplication Web, Mobile et Système (CDI)"
</TimelineCardSummary>
<TimelineCardContent slot:cards>
<p>r"Développement dapplication Symfony, React, Flutter, Rust et Ruby on rails (6 et 7) pour des clients."</p><br />
<p>r"Je développe surtout des applications Flutter et Ruby on rails avec laide de Hotwired."</p><br />
<i>Unova France</i><br />
<i>11 Septembre 2019 - Toujours en CDI</i>
</TimelineCardContent>
</TimelineCard>
</TimelineElement>
</Timeline>
</div>
}
}

View file

@ -5,7 +5,7 @@ pub fn ProjectContainer(
children: Children
) -> impl IntoView {
view! {
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 mt-3">
<div class="project_list">
{ children() }
</div>
}
@ -20,9 +20,9 @@ pub fn Project(
url: Option<String>
) -> impl IntoView {
view! {
<a href=url target="_blank" class="rounded-lg p-5 flex flex-col items-center gap-2 bg-primary/10 dark:bg-dark_primary/10 shadow-md shadow-primary/5 dark:shadow-dark_primary/5 hover:bg-primary/20 hover:dark:bg-dark_primary/20 hover:shadow-md hover:shadow-primary/10 hover:dark:shadow-dark_primary/10">
{ image_src.map(|src| view! { <img src=src class="h-1/2"/> }) }
<div class="flex flex-col justify-center h-full"><p>{ children() }</p></div>
<a href=url target="_blank">
{ image_src.map(|src| view! { <img src=src/> }) }
<div><p>{ children() }</p></div>
</a>
}
}

View file

@ -6,7 +6,7 @@ pub fn SocialLinkContainer(
children: Children
) -> impl IntoView {
view! {
<div class="flex gap-5 justify-center flex-wrap my-5">
<div class="social_links">
{ children() }
</div>
}
@ -20,9 +20,9 @@ pub fn SocialLink(
icon: Icon,
) -> impl IntoView {
view! {
<a href=url target="_blank">
<Icon icon=icon class="mx-auto scale-150 mb-1" />
<span class="text-sm">{ children() }</span>
<a class="social_link" href=url target="_blank">
<Icon icon=icon />
<span>{ children() }</span>
</a>
}
}

View file

@ -7,7 +7,7 @@ pub fn Tag(
children: Children
) -> impl IntoView {
view! {
<a class="rounded-lg px-3 py-1 font-normal text-sm bg-primary dark:bg-dark_primary text-on_primary dark:text-dark_on_primary" href=url target="_blank">
<a class="tag" href=url target="_blank">
{children()}
</a>
}

View file

@ -4,11 +4,11 @@ use leptos_icons::*;
#[component]
pub fn Timeline(
#[prop(default=vec![])] elements: Vec<TimelineElement>,
#[prop(default = vec![])] elements: Vec<TimelineElement>,
) -> impl IntoView {
view! {
<div class="w-full px-5">
<ul class="list-none py-5 px-0 relative w-full max-w-5xl mx-auto before:top-0 before:bottom-0 before:left-0 before:md:left-1/2 before:absolute before:content-[\"\"] before:w-2 before:bg-primary/10 before:dark:bg-dark_primary/10 before:shadow-md before:shadow-primary/5 before:dark:shadow-dark_primary/5">
<div class="timeline">
<ul>
{ elements.collect_view() }
</ul>
</div>
@ -16,11 +16,11 @@ pub fn Timeline(
}
#[slot]
pub struct TimelineElementLabel {
pub struct TimelineLabel {
children: ChildrenFn,
}
impl IntoView for TimelineElementLabel {
impl IntoView for TimelineLabel {
fn into_view(self) -> View {
let view = view! { <>{ (self.children)() }</> };
view.into_view()
@ -29,8 +29,8 @@ impl IntoView for TimelineElementLabel {
#[slot]
pub struct TimelineElement {
#[prop(default=vec![])] labels: Vec<TimelineElementLabel>,
#[prop(default=vec![])] cards: Vec<TimelineCard>,
#[prop(default = vec![])] labels: Vec<TimelineLabel>,
#[prop(default = vec![])] cards: Vec<TimelineCard>,
}
impl IntoView for TimelineElement {
@ -62,9 +62,25 @@ impl IntoView for TimelineCardContent {
}
#[slot]
pub struct TimelineCardSummary {
pub struct TimelineCardTag {
children: ChildrenFn,
}
impl IntoView for TimelineCardTag {
fn into_view(self) -> View {
let view = view! {
<>
{ (self.children)() }
</>
};
view.into_view()
}
}
#[slot]
pub struct TimelineCardSummary {
#[prop(default = vec![])] tags: Vec<TimelineCardTag>,
children: ChildrenFn,
tags: ChildrenFn,
}
impl IntoView for TimelineCardSummary {
@ -75,7 +91,7 @@ impl IntoView for TimelineCardSummary {
{
view! {
<div class="flex flex-wrap gap-2 mt-2">
{ (self.tags)() }
{ self.tags.collect_view() }
</div>
}
}
@ -87,13 +103,13 @@ impl IntoView for TimelineCardSummary {
#[slot]
pub struct TimelineCard {
#[prop(default=vec![])] titles: Vec<TimelineCardSummary>,
#[prop(default=vec![])] cards: Vec<TimelineCardContent>,
#[prop(default = vec![])] titles: Vec<TimelineCardSummary>,
#[prop(default = vec![])] cards: Vec<TimelineCardContent>,
}
impl IntoView for TimelineCard {
fn into_view(self) -> View {
let view = view! {
let view = view! {
<details>
<summary>
{ self.titles.collect_view() }

View file

@ -7,14 +7,14 @@ use super::*;
#[component]
pub fn TopComponent() -> impl IntoView {
view! {
<div class="min-h-screen w-full flex flex-col md:flex-row items-center gap-5 relative">
<div class="flex-1 p-10 justify-center items-center">
<img src="https://devemyhg.lycee-darchicourt.net/wp-content/uploads/2018/01/No-picture.png" alt="Ma photo" class="mx-auto rounded-lg" />
<div class="top_component">
<div class="top_component__image">
<img src="https://devemyhg.lycee-darchicourt.net/wp-content/uploads/2018/01/No-picture.png" alt="Ma photo" />
</div>
<div class="flex-1 p-10 flex flex-col gap-3">
<h1 class="font-bold text-3xl">Florian RICHER</h1>
<h4 class="font-semibold text-xl">"Développeur d´application Web et Mobile"</h4>
<p class="font-normal text-base">
<div class="top_component__presentation">
<h1>Florian RICHER</h1>
<h4>"Développeur d´application Web et Mobile"</h4>
<p>
r#"
Découvrez mon parcours en développement, ma passion précoce pour la programmation a débuté avec la
création d'applications 3D utilisant OpenGL et s'est étendue à la maîtrise de diverses technologies,

View file

@ -24,6 +24,7 @@ fn Home() -> impl IntoView {
view! {
<main class="m-0 p-0 bg-surface dark:bg-dark_surface text-on_surface dark:text-dark_on_surface">
<components::TopComponent/>
<components::MonParcours/>
</main>
}
}

13
style/link.css Normal file
View file

@ -0,0 +1,13 @@
@layer components {
.link {
@apply flex gap-1 font-semibold italic;
& > i {
@apply flex items-center;
& > svg {
@apply scale-75;
}
}
}
}

View file

@ -1,3 +1,9 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import './link.css';
@import './social_links.css';
@import './tag.css';
@import './timeline.css';
@import './top_component.css';

24
style/project.css Normal file
View file

@ -0,0 +1,24 @@
@layer components {
.project_list {
@apply grid grid-cols-1 gap-4 md:grid-cols-2 mt-3;
& > a {
@apply rounded-lg p-5 flex flex-col items-center gap-2;
@apply bg-primary/10 dark:bg-dark_primary/10;
@apply shadow-md shadow-primary/5 dark:shadow-dark_primary/5;
&:hover {
@apply bg-primary/20 dark:bg-dark_primary/20;
@apply shadow-md shadow-primary/10 dark:shadow-dark_primary/10;
}
& > img {
@apply h-1/2;
}
& > div {
@apply flex flex-col justify-center h-full;
}
}
}
}

15
style/social_links.css Normal file
View file

@ -0,0 +1,15 @@
@layer components {
.social_links {
@apply flex gap-5 justify-center flex-wrap my-5;
& > .social_link {
& > svg {
@apply mx-auto scale-150 mb-1;
}
& > span {
@apply text-sm;
}
}
}
}

6
style/tag.css Normal file
View file

@ -0,0 +1,6 @@
@layer components {
.tag {
@apply rounded-lg px-3 py-1 font-normal text-sm;
@apply bg-primary dark:bg-dark_primary text-on_primary dark:text-dark_on_primary;
}
}

102
style/timeline.css Normal file
View file

@ -0,0 +1,102 @@
@layer components {
.timeline {
@apply w-full px-5;
& > ul {
@apply list-none py-5 px-0 relative w-full max-w-5xl mx-auto;
/* Draw center line */
&:before {
@apply top-0 bottom-0 left-0 md:left-1/2 absolute content-[""] w-2;
@apply bg-primary/10 dark:bg-dark_primary/10;
@apply shadow-md shadow-primary/5 dark:shadow-dark_primary/5;
}
}
}
.timeline-element {
@apply relative flex flex-col md:flex-row justify-between;
/* Place point in center line */
&:before {
@apply content-[""] w-6 h-6 rounded-[50%] absolute top-5 left-0 md:left-1/2 -ml-2 z-50;
@apply bg-primary/10 dark:bg-dark_primary/10;
@apply shadow-md shadow-primary/5 dark:shadow-dark_primary/5;
}
&:nth-child(even) {
@apply md:flex-row-reverse;
.timeline-element__category {
@apply md:flex-row-reverse;
}
}
.timeline-element__info, .timeline-element__category {
@apply relative w-4/5 md:w-2/5 left-[10%] md:left-0;
@apply text-on_surface dark:text-dark_on_surface;
}
.timeline-element__category {
@apply top-5 flex md:justify-end mb-12;
}
.timeline-element__info {
& > details {
@apply mb-12 rounded-xl overflow-hidden relative;
@apply bg-primary/10 dark:bg-dark_primary/10;
@apply shadow-md shadow-primary/5 dark:shadow-dark_primary/5;
& > summary, & > div {
@apply p-5;
}
& > summary {
@apply relative block select-none cursor-pointer outline-none p-5 pr-10 font-semibold;
&:hover {
@apply bg-primary/20 dark:bg-dark_primary/20;
}
i {
@apply absolute right-5 h-full top-0 flex items-center;
& > svg {
@apply scale-125;
transition: transform 300ms ease;
}
}
}
&[open] {
& > summary {
& > i > svg {
@apply -rotate-180;
}
& ~ * {
animation: toggle 0.4s ease-in-out;
}
}
}
}
}
}
@keyframes toggle {
0% {
font-size: 0;
opacity: 0;
}
90% {
font-size: 1rem;
opacity: 0;
}
100% {
font-size: 1rem;
opacity: 1;
}
}
}

34
style/top_component.css Normal file
View file

@ -0,0 +1,34 @@
@layer components {
.top_component {
@apply min-h-screen w-full flex flex-col md:flex-row items-center gap-5 relative;
& > div {
@apply flex-1 p-10;
}
& > .top_component__image {
@apply flex justify-center items-center;
& > img {
@apply mx-auto rounded-lg;
}
}
& > .top_component__presentation {
@apply flex flex-col gap-3;
& > h1 {
@apply font-bold text-3xl;
}
& > h4 {
@apply font-semibold text-xl;
}
& > p {
@apply font-normal text-base;
}
}
}
}

View file

@ -1,7 +1,7 @@
/** @type {import('tailwindcss').Config} */
export default {
content: {
files: ["*.html", "./src/**/*.rs"],
files: ["*.html", "./src/**/*.rs", "./style/*.css"],
},
theme: {
extend: {