Backend: Some tweaks for project ids, ordering the tags. Frontend: Added full support for tags.

This commit is contained in:
Yohan Boujon 2024-01-28 18:34:05 +01:00
parent 7d829cc22f
commit 1a3297199f
9 changed files with 61 additions and 28 deletions

View file

@ -38,6 +38,7 @@ pub struct Experience {
#[derive(Deserialize, Serialize)]
pub struct Project {
pub id: Option<i32>,
pub date_done: Option<NaiveDate>,
pub title: Option<String>,
pub description: Option<String>,

View file

@ -83,7 +83,7 @@ async fn skills(
)> {
let project = sqlx::query_as!(
Project,
"SELECT date_done, title, description, github_link, picture_name, type_project FROM public.project WHERE project.info_id = $1 ORDER BY date_done DESC",
"SELECT id, date_done, title, description, github_link, picture_name, type_project FROM public.project WHERE project.info_id = $1 ORDER BY date_done DESC",
id
)
.fetch_all(&pool)
@ -155,7 +155,8 @@ async fn alltags(Path(info_id): Path<i32>, State(pool): State<PgPool>) -> Json<V
SELECT project_id, software, icon, type_icon, color
FROM public.softwares s
JOIN public.project_tags pt ON s.id = pt.softwares_id
WHERE pt.info_id = $1;
WHERE pt.info_id = $1
ORDER BY project_id;
",
info_id

View file

@ -1,29 +1,39 @@
<script>
import SvgIcon from "@jamescoyle/svelte-icon";
import "$lib/css/pill.css";
import { mdiHelp } from "@mdi/js";
import { shouldColorBeWhite } from "$lib/js/color.js";
import SvgIcon from "@jamescoyle/svelte-icon";
import "$lib/css/pill.css";
import { mdiHelp } from "@mdi/js";
import { shouldColorBeWhite } from "$lib/js/color.js";
export let name = "Unknown";
export let icon = mdiHelp;
export let color = "#000000";
export let type_icon = "mdi";
export let name = "Unknown";
export let icon = mdiHelp;
export let color = "#000000";
export let type_icon = "mdi";
export let shadow_color = null;
const white = shouldColorBeWhite(color.slice(1));
const style = `background-color: ${color};
const white = shouldColorBeWhite(color.slice(1));
let style;
if (shadow_color === null) {
style = `background-color: ${color};
box-shadow: 0px 8px 18px -1px ${color}60;`;
} else {
style = `background-color: ${color};
box-shadow: 0px 8px 18px -1px ${shadow_color}60;`;
}
</script>
<div class={white ? "pill-container pill-white" : "pill-container pill-black"} {style}>
{#if type_icon === "simpleicons"}
<img
height="20"
width="20"
src="https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/{icon}.svg"
alt={name}
/>
{:else}
<SvgIcon type="mdi" path={icon} size="20" />
{/if}
<p>{name}</p>
<div
class={white ? "pill-container pill-white" : "pill-container pill-black"}
{style}
>
{#if type_icon === "simpleicons"}
<img
height="20"
width="20"
src="https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/{icon}.svg"
alt={name}
/>
{:else}
<SvgIcon type="mdi" path={icon} size="20" />
{/if}
<p>{name}</p>
</div>

View file

@ -3,6 +3,7 @@
import "$lib/css/project-popup.css";
import "$lib/css/slide.css";
import Pill from "$lib/components/pill.svelte";
import { showPopup, popupDatas } from "$lib/js/popup.js";
import SvgIcon from "@jamescoyle/svelte-icon";
import {
@ -16,7 +17,7 @@
mdiLink,
mdiTag,
mdiBookMultiple,
mdiDownload
mdiDownload,
} from "@mdi/js";
// Variables
@ -25,11 +26,13 @@
let active = false;
// Informations
export let tags;
let title = "Title";
let date = "Date";
let type_project = "Type of project";
let picture;
let description = "Description";
let id = 0;
async function popupShowed(data) {
/**
@ -45,6 +48,7 @@
type_project = data.type_project;
picture = (await import(`/src/lib/img/${data.picture_name}`)).default;
description = data.description;
id = data.id;
// Active set to true after the await to avoid conflict when clicking outside while the popup hasn't showed yet.
active = true;
}
@ -140,6 +144,19 @@
<SvgIcon size="35" path={mdiTag} type="mdi" />
<p class="slide-subtitle slide-aftericon">Tags</p>
</div>
<div class="project-popup-link-container">
{#each tags as tag}
{#if tag.project_id === id}
<Pill
name={tag.lang}
type_icon={tag.type_icon}
icon={tag.icon}
color="#F8F1F1"
shadow_color="#261C2C"
/>
{/if}
{/each}
</div>
</div>
<!-- Text -->
<div>

View file

@ -17,6 +17,7 @@
const project_type = data.type_project;
let picture;
const popDataObject = {
id: data.id,
title: data.title,
date: issued_date,
type_project: data.type_project,

View file

@ -11,6 +11,7 @@
align-items: center;
font-family: 'Urbanist', sans-serif;
font-weight: 700;
cursor: default;
}
.pill-white {

View file

@ -12,8 +12,9 @@ export function processData(data) {
const experiences = arrangeById(data.experience);
const education = arrangeById(data.education);
const skills = data.skills;
const tags = data.tags;
return {info, experiences, education, skills};
return {info, experiences, education, skills, tags};
} else {
return null; // Indicates an error
}

View file

@ -18,7 +18,7 @@ export async function load(context) {
}
const infos = [];
const dataToGather = ['info', 'education', 'experience', 'skills/1'];
const dataToGather = ['info', 'education', 'experience', 'skills/1', 'tags/1'];
for (const url of dataToGather) {
const res = await fetchData(url);
if (res.status == 0) {
@ -41,5 +41,6 @@ export async function load(context) {
softwares: infos[3][2],
languages: infos[3][3],
},
tags: infos[4],
};
}

View file

@ -76,7 +76,7 @@
<svelte:window bind:scrollY bind:innerHeight bind:innerWidth on:scroll={sidebarScrollingHandler} on:resize={mobileCheck} />
{#if data.status == 0}
<ProjectsPopup/>
<ProjectsPopup tags={cv.tags} />
<div class="container-cv">
<!-- SIDEBAR DIV (LEFT) -->
<div class="sidebar" bind:this={sidebar}>