mirror of
https://github.com/ArthurDanjou/artsite.git
synced 2026-01-14 15:54:13 +01:00
Fix old resume, add contact popover, filter tags and more
This commit is contained in:
@@ -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"
|
||||
/>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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') }}
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
|
||||
|
||||
@@ -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
BIN
public/Resume2025.pdf
Normal file
Binary file not shown.
25
types.ts
25
types.ts
@@ -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',
|
||||
},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user