Fix old resume, add contact popover, filter tags and more

This commit is contained in:
2025-02-06 16:59:45 +01:00
parent b37cbd11cf
commit 3bb7911c77
8 changed files with 98 additions and 114 deletions

View File

@@ -1,26 +1,5 @@
<script setup lang="ts">
const socials = [
{
icon: 'x-logo-duotone',
label: 'Twitter',
link: 'https://twitter.com/ArthurDanj',
},
{
icon: 'github-logo-duotone',
label: 'GitHub',
link: 'https://github.com/ArthurDanjou',
},
{
icon: 'linkedin-logo-duotone',
label: 'LinkedIn',
link: 'https://www.linkedin.com/in/arthurdanjou/',
},
{
icon: 'discord-logo-duotone',
label: 'Discord',
link: 'https://discordapp.com/users/179635349100691456',
},
]
import { socials } from '~~/types'
const { t } = useI18n({
useScope: 'local',
@@ -43,8 +22,8 @@ const { t } = useI18n({
<HomeLink
v-for="social in socials.sort((a, b) => a.label.localeCompare(b.label))"
:key="social.label"
:href="social.link"
:icon="`i-ph:${social.icon}`"
:to="social.to"
:icon="social.icon"
:label="social.label"
target="_blank"
/>

View File

@@ -1,4 +1,6 @@
<script setup lang="ts">
import { socials } from '~~/types'
const colorMode = useColorMode()
const isDark = ref(colorMode.value === 'dark')
watch(isDark, () => {
@@ -40,7 +42,7 @@ const navs = [
es: 'currículum',
},
icon: 'address-book-duotone',
to: '/Resume2024.pdf',
to: '/Resume2025.pdf',
target: '_blank',
},
]
@@ -81,6 +83,15 @@ defineShortcuts({
c: () => openContactDrawer.value = !openContactDrawer.value,
backspace: () => router.back(),
})
const socialsList = [
{
label: 'Email',
icon: 'i-ph:envelope-duotone',
to: 'mailto:arthurdanjou@outlook.fr',
},
...socials,
]
</script>
<template>
@@ -110,16 +121,20 @@ defineShortcuts({
</UTooltip>
<USeparator orientation="vertical" class="h-6" />
<UDrawer
v-model:open="openContactDrawer"
should-scale-background
:title="t('contact.title')"
<UTooltip
:kbds="['C']"
:text="t('contact.button')"
:delay-duration="4"
class="cursor-pointer"
>
<UTooltip
:kbds="['C']"
:text="t('contact.button')"
:delay-duration="4"
class="cursor-pointer"
<UDropdownMenu
v-model:open="openContactDrawer"
:items="socialsList"
:content="{
align: 'center',
side: 'bottom',
sideOffset: 8,
}"
>
<UButton
icon="i-ph-mailbox-duotone"
@@ -128,16 +143,8 @@ defineShortcuts({
variant="ghost"
@click="openContactDrawer = true"
/>
</UTooltip>
<template #body>
<div class="w-full flex my-16">
<div>
Hey
</div>
</div>
</template>
</UDrawer>
</UDropdownMenu>
</UTooltip>
<USeparator orientation="vertical" class="h-6" />
<ClientOnly>
<UTooltip

View File

@@ -7,16 +7,18 @@ const { t } = useI18n({
<template>
<div class="flex items-center gap-2 mt-4">
<div class="flex items-center">
<UTooltip text="It's me 👋">
<div class="flex items-center w-12 h-12">
<UAvatar
alt="Avatar"
class="hover:rotate-[360deg] duration-500 transform-gpu"
size="md"
src="/favicon.png"
/>
</div>
</UTooltip>
<ClientOnly>
<UTooltip text="It's me 👋">
<div class="flex items-center w-12 h-12">
<UAvatar
alt="Avatar"
class="hover:rotate-[360deg] duration-500 transform-gpu"
size="md"
src="/favicon.png"
/>
</div>
</UTooltip>
</ClientOnly>
</div>
<p class="not-prose">
{{ t('quote') }}

View File

@@ -108,19 +108,19 @@ async function handleLike() {
{{ post.description }}
</p>
</div>
<div class="flex justify-end sticky top-0">
<div v-if="post.body.toc && post.body.toc.links.length > 0" class="flex justify-end sticky top-0 z-50">
<UPopover
mode="hover"
:content="{
align: 'start',
side: 'right',
align: 'end',
side: 'bottom',
sideOffset: 8,
}"
>
<UButton
:label="t('toc')"
color="neutral"
variant="soft"
variant="solid"
class="mt-2"
/>

View File

@@ -10,28 +10,27 @@ useSeoMeta({
description: t('description'),
})
const tagFilter = ref<string | undefined>(undefined)
const tagFilter = ref<string[]>([])
const { data: writings, refresh } = await useAsyncData('all-portfolio', () => queryCollection('portfolio')
.order('publishedAt', 'DESC')
.where('tags', 'LIKE', tagFilter.value ? `%${tagFilter.value}%` : '%')
.all())
const { data: writings, refresh } = await useAsyncData('all-portfolio', async () => {
const writings = await queryCollection('portfolio')
.order('publishedAt', 'DESC')
.all()
return writings.filter((writing) => {
if (tagFilter.value.length === 0)
return true
return writing.tags.some(tag => tagFilter.value.includes(tag.toLowerCase()))
})
})
watch(tagFilter, async () => await refresh())
const tags: Array<{ label: string, icon: string } & Tag> = [
{
label: 'All',
icon: 'i-ph-books-duotone',
color: 'black',
translation: 'tags.all',
},
...TAGS.filter(tag => tag.title).sort((a, b) => a.label.localeCompare(b.label)),
const tags: Array<Tag> = [
...TAGS.sort((a, b) => a.label.localeCompare(b.label)),
]
function updateTag(payload: number | string) {
const tag = tags[Number(payload)]
tagFilter.value = tag?.label.toLowerCase() === 'all' ? undefined : tag?.label.toLowerCase()
function updateTag(payload: Tag[]) {
tagFilter.value = payload.map(tag => tag.label.toLowerCase())
}
</script>
@@ -49,11 +48,17 @@ function updateTag(payload: number | string) {
icon="i-ph-warning-duotone"
variant="outline"
/>
<UTabs :items="tags" color="neutral" size="md" variant="pill" @update:model-value="updateTag">
<template #default="{ item }">
<span class="truncate">{{ t(item.translation) }}</span>
</template>
</UTabs>
<div class="flex justify-end sticky top-4 z-50">
<USelectMenu
:placeholder="t('tags')"
:items="tags"
multiple
color="neutral"
:highlight-on-hover="true"
class="w-full md:w-1/3"
@update:model-value="updateTag"
/>
</div>
<ul class="grid grid-cols-1 gap-4">
<NuxtLink
v-for="(writing, id) in writings"
@@ -113,17 +118,7 @@ function updateTag(payload: number | string) {
"title": "Translations alert!",
"description": "Due to time constraints, all article translations will be available only in English. Thank you for your understanding."
},
"tags": {
"article": "Articles",
"all": "Library",
"project": "Projects",
"r": "R",
"python": "Python",
"data": "Data",
"ai": "AI",
"maths": "Maths",
"web": "Web"
}
"tags": "Select tags to filter"
},
"fr": {
"title": "Écrits sur ma vie, le développement, mes projets et mes passions.",
@@ -132,17 +127,7 @@ function updateTag(payload: number | string) {
"title": "Attentions aux traductions!",
"description": "Par soucis de temps, toutes les traductions des articles seront disponibles uniquement en anglais. Merci de votre compréhension."
},
"tags": {
"article": "Articles",
"all": "Bibliothèque",
"project": "Projets",
"r": "R",
"python": "Python",
"data": "Data",
"ai": "AI",
"maths": "Maths",
"web": "Web"
}
"tags": "Sélectionner des tags pour filtrer"
},
"es": {
"title": "Escritos sobre mi vida, el desarrollo, mis proyectos y mis pasiones.",
@@ -151,17 +136,7 @@ function updateTag(payload: number | string) {
"title": "Cuidado con las traducciones !",
"description": "Por problema de tiempo, los artículos están solo disponibles en ingles. Gracias por vuestra comprensión."
},
"tags": {
"article": "Artículos",
"all": "Biblioteca",
"project": "Proyectos",
"r": "R",
"python": "Python",
"data": "Datos",
"ai": "IA",
"maths": "Mates",
"web": "Web"
}
"tags": "Seleccionar etiquetas para filtrar"
}
}
</i18n>

Binary file not shown.

BIN
public/Resume2025.pdf Normal file

Binary file not shown.

View File

@@ -59,14 +59,12 @@ export const TAGS: Array<Tag> = [
label: 'Article',
icon: 'i-ph-pencil-line-duotone',
color: 'red',
title: 'Articles',
translation: 'tags.article',
},
{
label: 'Project',
icon: 'i-ph-briefcase-duotone',
color: 'blue',
title: 'Projects',
translation: 'tags.project',
},
{
@@ -106,3 +104,26 @@ export const TAGS: Array<Tag> = [
translation: 'tags.maths',
},
]
export const socials = [
{
icon: 'i-ph:x-logo-duotone',
label: 'Twitter',
to: 'https://twitter.com/ArthurDanj',
},
{
icon: 'i-ph:github-logo-duotone',
label: 'GitHub',
to: 'https://github.com/ArthurDanjou',
},
{
icon: 'i-ph:linkedin-logo-duotone',
label: 'LinkedIn',
to: 'https://www.linkedin.com/in/arthurdanjou/',
},
{
icon: 'i-ph:discord-logo-duotone',
label: 'Discord',
to: 'https://discordapp.com/users/179635349100691456',
},
]