diff --git a/backend/src/db.rs b/backend/src/db.rs index 8d58a36..e862252 100644 --- a/backend/src/db.rs +++ b/backend/src/db.rs @@ -85,4 +85,10 @@ pub struct AllTags { pub icon: Option, pub type_icon: Option, pub color: Option +} + +#[derive(Deserialize, Serialize)] +pub struct SimpleProject { + pub project_id: Option, + pub title: Option } \ No newline at end of file diff --git a/backend/src/main.rs b/backend/src/main.rs index e8501db..25c2b1a 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -10,7 +10,10 @@ use std::net::SocketAddr; use tower_http::cors::CorsLayer; mod db; -use db::{Education, Experience, Info, Languages, ProgrammingLanguages, Project, Softwares, Tags, AllTags}; +use db::{ + AllTags, Education, Experience, Info, Languages, ProgrammingLanguages, Project, SimpleProject, + Softwares, Tags, +}; #[tokio::main] async fn main() -> Result<()> { @@ -30,6 +33,14 @@ async fn main() -> Result<()> { .route("/skills/:id", get(skills)) .route("/tags/:info_id/:project_id", get(tags)) .route("/tags/:id", get(alltags)) + .route( + "/getproject_programming/:programming_id", + get(getproject_programming), + ) + .route( + "/getproject_software/:software_id", + get(getproject_software), + ) .with_state(pool) .layer(CorsLayer::very_permissive()); @@ -166,3 +177,41 @@ async fn alltags(Path(info_id): Path, State(pool): State) -> Json, + State(pool): State, +) -> Json> { + let datas = sqlx::query_as!( + SimpleProject, + "SELECT project_id, title + FROM public.project p + JOIN public.project_tags pt ON p.id = pt.project_id + WHERE pt.programming_languages_id = $1 + ", + programming_id + ) + .fetch_all(&pool) + .await + .unwrap_or(vec![]); + Json(datas) +} + +async fn getproject_software( + Path(software_id): Path, + State(pool): State, +) -> Json> { + let datas = sqlx::query_as!( + SimpleProject, + "SELECT project_id, title + FROM public.project p + JOIN public.project_tags pt ON p.id = pt.project_id + WHERE pt.softwares_id = $1 + ", + software_id + ) + .fetch_all(&pool) + .await + .unwrap_or(vec![]); + Json(datas) +} diff --git a/frontend/src/lib/components/pill.svelte b/frontend/src/lib/components/pill.svelte index 4d58cc6..18784d5 100644 --- a/frontend/src/lib/components/pill.svelte +++ b/frontend/src/lib/components/pill.svelte @@ -9,9 +9,15 @@ export let color = "#000000"; export let type_icon = "mdi"; export let shadow_color = null; + export let show_tooltip = false; + export let tooltip_data = []; const white = shouldColorBeWhite(color.slice(1)); let style; + let pill_arrow; + let pill_tooltip; + let main_pill; + if (shadow_color === null) { style = `background-color: ${color}; box-shadow: 0px 8px 18px -1px ${color}60;`; @@ -19,12 +25,47 @@ style = `background-color: ${color}; box-shadow: 0px 8px 18px -1px ${shadow_color}60;`; } + + function showingTooltip(visible) { + if (visible && tooltip_data.length > 0) { + pill_tooltip.style.visibility = "visible"; + pill_arrow.style.visibility = "visible"; + // adjusting top + pill_tooltip.style.top = `${ + main_pill.offsetTop - pill_tooltip.offsetHeight - 17 + }px`; + if (white) { + pill_tooltip.style.boxShadow = `0px 8px 18px -1px ${color}60`; + pill_arrow.style.filter = `drop-shadow(0px 8px 18px ${color}40)`; + } else { + pill_tooltip.style.boxShadow = `0px 8px 18px -1px #261C2C30`; + pill_arrow.style.filter = `drop-shadow(0px 8px 18px #261C2C20)`; + } + } else { + pill_tooltip.style.visibility = "hidden"; + pill_arrow.style.visibility = "hidden"; + } + }
true} + on:mouseover={() => showingTooltip(true)} + on:mouseleave={() => showingTooltip(false)} + role="link" + tabindex="0" + bind:this={main_pill} > + {#if show_tooltip === true} +
+
+ {#each tooltip_data as td} +

{td.title}

+ {/each} +
+ {/if} {#if type_icon === "simpleicons"}
- {#each cv.skills.programming_languages as pilldata} - + {#each cv.skills.programming_languages as pilldata, index (index)} + {/each}
- {#each cv.skills.softwares as pilldata} - + {#each cv.skills.softwares as pilldata, index (index)} + {/each}