Frontend: Tweaked CSS for mobile devices (less than 1200px of width). Tweaked some text sizes and icons, fixed languages issues. Added a little notification for pills that are linked to a project with the number assigned.

This commit is contained in:
Yohan Boujon 2024-02-10 22:09:57 +01:00
parent b0072f3f44
commit 50b39a745b
17 changed files with 130 additions and 73 deletions

View file

@ -13,6 +13,6 @@
</div> </div>
<div class="flag-text"> <div class="flag-text">
<p>{lang}</p> <p>{lang}</p>
<p><span class="flag-bold">Level: </span>{level}</p> <p>{level}</p>
</div> </div>
</div> </div>

View file

@ -38,6 +38,7 @@
let pill_tooltip; let pill_tooltip;
let main_pill; let main_pill;
let pill_hitbox; let pill_hitbox;
let pill_notification;
// constants and variables // constants and variables
let innerWidth; let innerWidth;
@ -115,9 +116,18 @@
} }
} }
function calculateNotification() {
// 19 is arbitrary, based on the pill-notification width (which is around 25.6 px) minus a constant
pill_notification.style.left = `${
main_pill.offsetLeft + main_pill.clientWidth - 19
}px`;
pill_notification.style.top = `${main_pill.offsetTop}px`;
}
onMount(async () => { onMount(async () => {
calculateOffsetUp(); calculateOffsetUp();
calculateHitbox(); calculateHitbox();
calculateNotification();
}); });
</script> </script>
@ -128,6 +138,7 @@
calculateOffsetUp(); calculateOffsetUp();
calculateHitbox(); calculateHitbox();
calculateOutOfBounds(); calculateOutOfBounds();
calculateNotification();
}} }}
/> />
@ -151,17 +162,26 @@
<div> <div>
<span>{td.title}</span> <span>{td.title}</span>
{#if td.project_id != null} {#if td.project_id != null}
<div class="pill-last"> <div class="pill-last">
<button <button
class="pill-view" class="pill-view"
on:click={() => showPopup(true, td.project_id)} on:click={() => showPopup(true, td.project_id)}
><SvgIcon size="20" path={mdiPlus} type="mdi" /></button ><SvgIcon size="20" path={mdiPlus} type="mdi" /></button
> >
</div> </div>
{/if} {/if}
</div> </div>
{/each} {/each}
</div> </div>
<div
class={white
? "pill-notification pill-white"
: "pill-notification pill-black"}
{style}
bind:this={pill_notification}
>
{tooltip_data.length}
</div>
{/if} {/if}
{#if type_icon === "simpleicons"} {#if type_icon === "simpleicons"}
<img <img

View file

@ -1,12 +1,18 @@
<script> <script>
import { onMount } from "svelte"; import { onMount } from "svelte";
import SvgIcon from "@jamescoyle/svelte-icon"; import SvgIcon from "@jamescoyle/svelte-icon";
import { mdiCalendarRange, mdiPlus, mdiAccount, mdiSchool } from "@mdi/js"; import {
mdiCalendarRange,
mdiBookOpenVariant,
mdiAccount,
mdiSchool,
} from "@mdi/js";
import "$lib/css/slide.css"; import "$lib/css/slide.css";
import { formatMonth } from "$lib/js/date.js"; import { formatMonth } from "$lib/js/date.js";
import { showPopup, popupDatas } from "$lib/js/popup.js"; import { showPopup, popupDatas } from "$lib/js/popup.js";
export let active = false; export let active = false;
export let text;
export let data; export let data;
export let max = 0; export let max = 0;
export let actualnum = 0; export let actualnum = 0;
@ -64,9 +70,9 @@
</div> </div>
<div class="slide-button-container"> <div class="slide-button-container">
<button class="slide-button" on:click={() => showPopup(true, data.id)}> <button class="slide-button" on:click={() => showPopup(true, data.id)}>
<SvgIcon size="20" path={mdiPlus} type="mdi" /> <SvgIcon size="20" path={mdiBookOpenVariant} type="mdi" />
More</button <p class="slide-aftericon slide-button-text">{text.projects_read}</p>
> </button>
</div> </div>
</div> </div>
</div> </div>

View file

@ -8,6 +8,6 @@
</script> </script>
<div class="section-container"> <div class="section-container">
<SvgIcon size="60" path={icon} type="mdi" /> <SvgIcon size="45" path={icon} type="mdi" />
<h1 class="section-h1">{title}</h1> <h1 class="section-h1">{title}</h1>
</div> </div>

View file

@ -14,6 +14,7 @@
// Exported values // Exported values
export let data = []; export let data = [];
export let text = null;
export let type; export let type;
export let timeline = false; export let timeline = false;
export let reverse = false; export let reverse = false;
@ -220,12 +221,14 @@
active={index == slideshow_index ? true : false} active={index == slideshow_index ? true : false}
max={data.length} max={data.length}
actualnum={index + 1} actualnum={index + 1}
{text}
/> />
{:else} {:else}
<svelte:component <svelte:component
this={type} this={type}
data={selected_data} data={selected_data}
active={index == slideshow_index ? true : false} active={index == slideshow_index ? true : false}
{text}
/> />
{/if} {/if}
{/each} {/each}

View file

@ -8,6 +8,6 @@
</script> </script>
<div class="subsection-container"> <div class="subsection-container">
<SvgIcon size="40" path={icon} type="mdi" /> <SvgIcon size="30" path={icon} type="mdi" />
<h1 class="section-h2">{title}</h1> <h1 class="section-h2">{title}</h1>
</div> </div>

View file

@ -7,16 +7,7 @@
#topbar { #topbar {
display: none; display: none;
} }
}
@media screen and (max-width: 1200px) {
.container-cv {
display: flex;
flex-direction: column;
}
}
@media screen and (min-width: 1000px) {
.name { .name {
text-align: center; text-align: center;
text-shadow: -15px 5px 20px #00000030; text-shadow: -15px 5px 20px #00000030;
@ -89,7 +80,13 @@
} }
} }
@media screen and (max-width: 1000px) { @media screen and (max-width: 1200px) {
.container-cv {
display: flex;
flex-direction: column;
}
#topbar { #topbar {
width: 100%; width: 100%;
position: fixed; position: fixed;
@ -167,6 +164,10 @@
font-size: 1.5rem; font-size: 1.5rem;
font-weight: 100; font-weight: 100;
transition: all .3s ease 0s; transition: all .3s ease 0s;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
} }
.name { .name {
@ -191,7 +192,7 @@
.footer>div { .footer>div {
padding-top: 2rem; padding-top: 2rem;
padding-bottom: 2rem; padding-bottom: 1rem;
} }
.footer-mobile-btn { .footer-mobile-btn {

View file

@ -1,4 +1,4 @@
@media screen and (min-width: 1000px) { @media screen and (min-width: 1200px) {
.flag-main { .flag-main {
display: flex; display: flex;
border-radius: 0.4rem; border-radius: 0.4rem;
@ -12,13 +12,9 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.flag-text p {
margin: 0.5rem;
}
} }
@media screen and (max-width: 1000px) { @media screen and (max-width: 1200px) {
.flag-main { .flag-main {
display: flex; display: flex;
border-radius: 0.4rem; border-radius: 0.4rem;
@ -28,7 +24,6 @@
margin-top: 1rem; margin-top: 1rem;
padding: 1rem; padding: 1rem;
transition: all .3s ease 0s; transition: all .3s ease 0s;
justify-content: center;
align-items: center; align-items: center;
width: 100%; width: 100%;
} }
@ -37,11 +32,11 @@
margin-left: 10vw !important; margin-left: 10vw !important;
margin-right: 10vw; margin-right: 10vw;
} }
}
.flag-text p { .flag-text p {
margin: 0.5rem; margin: 0.5rem;
font-size: 1.25rem; font-size: 1.25rem;
}
} }
.flag-img { .flag-img {

View file

@ -127,7 +127,7 @@ li {
border-right: none; border-right: none;
} }
@media screen and (min-width: 1000px) { @media screen and (min-width: 1200px) {
.markdown img { .markdown img {
max-height: 16rem; max-height: 16rem;
max-width: 40dvh; max-width: 40dvh;
@ -137,7 +137,7 @@ li {
} }
} }
@media screen and (max-width: 1000px) { @media screen and (max-width: 1200px) {
.markdown img { .markdown img {
max-width: 76dvw; max-width: 76dvw;
max-height: 100%; max-height: 100%;

View file

@ -141,3 +141,14 @@
transform: translateY(2.2rem); transform: translateY(2.2rem);
border-bottom: 20px solid var(--color-background); border-bottom: 20px solid var(--color-background);
} }
.pill-notification {
border-radius: 50%;
width: 1.6rem;
height: 1.6rem;
justify-content: center;
align-items: center;
display: flex;
position: absolute;
box-shadow: 0px 8px 18px -1px #011e3164 !important;
}

View file

@ -1,4 +1,4 @@
@media screen and (min-width: 1000px) @media screen and (min-width: 1200px)
{ {
.section-container { .section-container {
margin-top: 3rem; margin-top: 3rem;
@ -23,6 +23,7 @@
.section-h1 { .section-h1 {
margin-left: 2rem; margin-left: 2rem;
font-size: 2.5rem; font-size: 2.5rem;
font-family: 'Gabarito', sans-serif !important;
} }
.section-h2 { .section-h2 {
@ -32,7 +33,7 @@
} }
} }
@media screen and (max-width: 1000px) @media screen and (max-width: 1200px)
{ {
.section-container { .section-container {
margin-top: 2rem; margin-top: 2rem;
@ -58,6 +59,7 @@
.section-h1 { .section-h1 {
margin-left: 0.5rem; margin-left: 0.5rem;
font-size: clamp(1.5rem, 8vh, 2.5rem); font-size: clamp(1.5rem, 8vh, 2.5rem);
font-family: 'Gabarito', sans-serif !important;
} }
.section-h2 { .section-h2 {

View file

@ -1,9 +1,7 @@
@media screen and (max-width: 1000px) { @media screen and (max-width: 1200px) {
.sc-description-little { .sc-description-little {
margin-left: 6dvh !important;
margin-left: 3rem !important; margin-right: 6dvh !important;
margin-right: 3rem !important;
} }
} }

View file

@ -1,4 +1,4 @@
@media screen and (min-width: 1000px) { @media screen and (min-width: 1200px) {
.slide-container { .slide-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -42,6 +42,7 @@
font-weight: 600; font-weight: 600;
font-size: 2rem; font-size: 2rem;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
margin-top: 0;
} }
/* Any Subtitle */ /* Any Subtitle */
@ -113,14 +114,14 @@
transition: all .3s ease 0s; transition: all .3s ease 0s;
} }
/* Date text */ /* Date text */
.slide-date { .slide-date {
color: var(--color-special); color: var(--color-special);
font-weight: 700; font-weight: 700;
} }
} }
@media screen and (max-width: 1000px) { @media screen and (max-width: 1200px) {
.slide-container { .slide-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -169,6 +170,7 @@
font-weight: 600; font-weight: 600;
font-size: 1.8rem; font-size: 1.8rem;
margin-bottom: 0; margin-bottom: 0;
margin-top: 0;
} }
/* Any Subtitle */ /* Any Subtitle */
@ -241,12 +243,16 @@
transition: all .3s ease 0s; transition: all .3s ease 0s;
} }
/* Date text */ /* Date text */
.slide-date { .slide-date {
color: var(--color-special); color: var(--color-special);
font-weight: 700; font-weight: 700;
font-size: 1.25rem; font-size: 1.25rem;
} }
.slide-overflow-title {
font-size: clamp(1rem, 2vh, 1.9rem);
}
} }
.slide-overflow { .slide-overflow {
@ -325,4 +331,11 @@
font-family: 'Urbanist', sans-serif; font-family: 'Urbanist', sans-serif;
font-weight: 700; font-weight: 700;
box-shadow: 0px 8px 18px -1px #261C2C60; box-shadow: 0px 8px 18px -1px #261C2C60;
padding-top: 0.8rem;
padding-bottom: 0.8rem;
}
.slide-button-text {
margin-top: 0.4rem;
margin-bottom: 0.4rem;
} }

View file

@ -5,7 +5,7 @@
position: relative; position: relative;
} }
@media screen and (min-width: 1000px) { @media screen and (min-width: 1200px) {
.slideshow_btn { .slideshow_btn {
z-index: 2; z-index: 2;
position: absolute; position: absolute;
@ -40,7 +40,7 @@
} }
} }
@media screen and (max-width: 1000px) { @media screen and (max-width: 1200px) {
.slideshow_btn { .slideshow_btn {
z-index: 2; z-index: 2;
position: absolute; position: absolute;

View file

@ -1,6 +1,6 @@
{ {
"education": "Education", "education": "Education",
"experience": "Experience", "experience": "Experiences",
"projects": "Projects", "projects": "Projects",
"skills": "Skills", "skills": "Skills",
"programming_languages": "Programming Languages", "programming_languages": "Programming Languages",
@ -14,7 +14,7 @@
"lang": "Language", "lang": "Language",
"madewith": "Made with", "madewith": "Made with",
"usingsvelte": "using Svelte", "usingsvelte": "using Svelte",
"copyright": "All rights reserved, Yohan Boujon", "copyright": "All rights reserved Yohan Boujon",
"github": "Github Repo", "github": "Github Repo",
"popup_school": "School", "popup_school": "School",
@ -26,6 +26,8 @@
"popup_dl_arc": "Download Archive", "popup_dl_arc": "Download Archive",
"popup_dl_rep": "See Report", "popup_dl_rep": "See Report",
"projects_read": "Read more",
"backend": "This backend", "backend": "This backend",
"frontend": "This website" "frontend": "This website"
} }

View file

@ -1,6 +1,6 @@
{ {
"education": "Éducation", "education": "Formation",
"experience": "Expérience", "experience": "Expériences",
"projects": "Projets", "projects": "Projets",
"skills": "Compétences", "skills": "Compétences",
"programming_languages": "Langages de programmation", "programming_languages": "Langages de programmation",
@ -14,7 +14,7 @@
"lang": "Langage", "lang": "Langage",
"madewith": "Fait avec", "madewith": "Fait avec",
"usingsvelte": "à l'aide de Svelte", "usingsvelte": "à l'aide de Svelte",
"copyright": "Tous droits réservés, Yohan Boujon", "copyright": "Tous droits réservés Yohan Boujon",
"github": "Lien Github", "github": "Lien Github",
"popup_school": "École", "popup_school": "École",
@ -26,6 +26,8 @@
"popup_dl_arc": "Archive ZIP", "popup_dl_arc": "Archive ZIP",
"popup_dl_rep": "Voir le Rapport", "popup_dl_rep": "Voir le Rapport",
"projects_read": "Lire plus",
"backend": "Ce serveur", "backend": "Ce serveur",
"frontend": "Ce site web" "frontend": "Ce site web"
} }

View file

@ -88,6 +88,11 @@
mobileTopBar(); mobileTopBar();
} }
}} }}
on:resize={() => {
if (innerWidth < 1200) {
mobileTopBar();
}
}}
/> />
{#if data.status == 0} {#if data.status == 0}
@ -102,7 +107,7 @@
<Sidebar info={cv.info} {footer} {containerCv} {text} /> <Sidebar info={cv.info} {footer} {containerCv} {text} />
{/if} {/if}
<!-- MOBILE TOP BAR --> <!-- MOBILE TOP BAR -->
{#if innerWidth < 1000} {#if innerWidth < 1200}
<div id="topbar" bind:this={topbar}> <div id="topbar" bind:this={topbar}>
<button <button
class={scrollY <= 53 class={scrollY <= 53
@ -115,14 +120,12 @@
<SvgIcon size="23" path={mdiAccount} type="mdi" /> <SvgIcon size="23" path={mdiAccount} type="mdi" />
{/if} {/if}
</button> </button>
<button <button
class={scrollY <= 53 ? "none" : "topbar-button"} class={scrollY <= 53 ? "none" : "topbar-button"}
on:click={() => (window.location.href = `/lang=${otherlang}`)} on:click={() => (window.location.href = `/lang=${otherlang}`)}
> >
<span class={`fi fi-${flag} flag-little`}></span> <span class={`fi fi-${flag} flag-little`}></span>
</button> </button>
<h1 class={scrollY <= 53 ? "topbar-name" : "topbar-name-little"}> <h1 class={scrollY <= 53 ? "topbar-name" : "topbar-name-little"}>
{cv.info.full_name} {cv.info.full_name}
</h1> </h1>
@ -131,7 +134,7 @@
{/if} {/if}
<!-- MAIN DIV (RIGHT: desktop/CENTER: mobile) --> <!-- MAIN DIV (RIGHT: desktop/CENTER: mobile) -->
<div class="main"> <div class="main">
{#if innerWidth >= 1000} {#if innerWidth >= 1200}
<div class="lang-btn-container"> <div class="lang-btn-container">
<button <button
class="footer-btn lang-btn" class="footer-btn lang-btn"
@ -143,7 +146,7 @@
</div> </div>
<h1 class="name">{cv.info.full_name}</h1> <h1 class="name">{cv.info.full_name}</h1>
{/if} {/if}
<h2 class="name">{cv.info.title}</h2> <h2 class="name">{@html cv.info.title}</h2>
<Section icon={mdiSchool} title={text.education} /> <Section icon={mdiSchool} title={text.education} />
<SlideShow <SlideShow
data={cv.education} data={cv.education}
@ -163,6 +166,7 @@
data={cv.skills.project} data={cv.skills.project}
type={Projects} type={Projects}
show_max_index={true} show_max_index={true}
{text}
/> />
<Section icon={mdiPencil} title={text.skills} /> <Section icon={mdiPencil} title={text.skills} />
<SubSection icon={mdiXml} title={text.programming_languages} /> <SubSection icon={mdiXml} title={text.programming_languages} />
@ -212,7 +216,7 @@
<!-- Footer --> <!-- Footer -->
<div class="footer" bind:this={footer}> <div class="footer" bind:this={footer}>
<!-- Footer desktop --> <!-- Footer desktop -->
{#if innerWidth >= 1000} {#if innerWidth >= 1200}
<div /> <div />
<div class="footer-text"> <div class="footer-text">
<p> <p>
@ -220,7 +224,7 @@
<SvgIcon size="20" path={mdiHeart} type="mdi" /> <SvgIcon size="20" path={mdiHeart} type="mdi" />
{text.usingsvelte} {text.usingsvelte}
</p> </p>
<p>{text.copyright}{new Date().getFullYear()}</p> <p>{new Date().getFullYear()}{text.copyright}</p>
</div> </div>
<div class="footer-btn-container"> <div class="footer-btn-container">
<a <a
@ -245,7 +249,7 @@
<SvgIcon size="20" path={mdiHeart} type="mdi" /> <SvgIcon size="20" path={mdiHeart} type="mdi" />
{text.usingsvelte} {text.usingsvelte}
</p> </p>
<p>{text.copyright}{new Date().getFullYear()}</p> <p>{new Date().getFullYear()}{text.copyright}</p>
</div> </div>
<div class="footer-mobile-btn"> <div class="footer-mobile-btn">
<div class="footer-btn-container"> <div class="footer-btn-container">