Refactor code structure for improved readability and maintainability

This commit is contained in:
2025-10-03 17:37:34 +02:00
parent dbebcd23a5
commit 6c5b561d49
11 changed files with 155 additions and 118 deletions

View File

@@ -28,7 +28,7 @@ const head = useLocaleHead()
<ChatCommandPalette <ChatCommandPalette
v-motion v-motion
:active="messages.length > 0" :active="messages.length > 0"
:mode="route.path.includes('/projects') || route.path.includes('/writings') || route.path.includes('/canva') ? 'work' : 'chat'" :mode="route.path.includes('/projects') || route.path.includes('/writings') ? 'work' : 'chat'"
:initial="{ :initial="{
opacity: 0, opacity: 0,
y: 200, y: 200,

View File

@@ -5,7 +5,7 @@ const { t } = useI18n()
<template> <template>
<UCard class="mt-8 shadow-sm bg-white dark:bg-neutral-900"> <UCard class="mt-8 shadow-sm bg-white dark:bg-neutral-900">
<NuxtImg <NuxtImg
src="/arthur pro.webp" src="/arthur-pro.webp"
alt="Arthur Danjou" alt="Arthur Danjou"
class="w-24 h-24 rounded-full float-left mr-4 mb-4" class="w-24 h-24 rounded-full float-left mr-4 mb-4"
/> />

View File

@@ -10,7 +10,7 @@
<div class="m-1 md:max-w-2/3 shadow-sm rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden relative z-10"> <div class="m-1 md:max-w-2/3 shadow-sm rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden relative z-10">
<NuxtImg class="rounded-xl" src="/location.png" /> <NuxtImg class="rounded-xl" src="/location.png" />
<div class="size-12 rounded-full border-2 border-sky-500 absolute z-50 top-2/5 -translate-y-1/2 left-1/5 -translate-x-1/2 animate-bounce"> <div class="size-12 rounded-full border-2 border-sky-500 absolute z-50 top-2/5 -translate-y-1/2 left-1/5 -translate-x-1/2 animate-bounce">
<NuxtImg src="/arthur pro.webp" class="rounded-full" alt="Location of Arthur" /> <NuxtImg src="/arthur-pro.webp" class="rounded-full" alt="Location of Arthur" />
</div> </div>
</div> </div>
</section> </section>

View File

@@ -1,4 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useDateFormat } from '#imports'
const route = useRoute() const route = useRoute()
const { data: project } = await useAsyncData(`projects/${route.params.slug}`, () => const { data: project } = await useAsyncData(`projects/${route.params.slug}`, () =>
queryCollection('projects').path(`/projects/${route.params.slug}`).first()) queryCollection('projects').path(`/projects/${route.params.slug}`).first())
@@ -17,6 +19,8 @@ useSeoMeta({
}) })
const { t } = useI18n() const { t } = useI18n()
useSeoMeta(project.value.seo || {})
</script> </script>
<template> <template>

View File

@@ -1,4 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useDateFormat } from '#imports'
const route = useRoute() const route = useRoute()
const { data: writing } = await useAsyncData(`writings/${route.params.slug}`, () => const { data: writing } = await useAsyncData(`writings/${route.params.slug}`, () =>
queryCollection('writings').path(`/writings/${route.params.slug}`).first()) queryCollection('writings').path(`/writings/${route.params.slug}`).first())
@@ -10,13 +12,9 @@ if (!writing.value) {
}) })
} }
useSeoMeta({
title: writing.value?.title,
description: writing.value?.description,
author: 'Arthur Danjou',
})
const { t } = useI18n() const { t } = useI18n()
useSeoMeta(writing.value.seo || {})
</script> </script>
<template> <template>

View File

@@ -1,104 +1,111 @@
import { defineCollection, z } from '@nuxt/content' import { defineCollection, defineContentConfig, z } from '@nuxt/content'
import { asSeoCollection } from '@nuxtjs/seo/content'
export const collections = { export default defineContentConfig({
projects: defineCollection({ collections: {
type: 'page', projects: defineCollection(
source: 'projects/*.md', asSeoCollection({
schema: z.object({ type: 'page',
slug: z.string(), source: 'projects/*.md',
title: z.string(), schema: z.object({
description: z.string(), slug: z.string(),
publishedAt: z.string(), title: z.string(),
readingTime: z.number().optional(), description: z.string(),
tags: z.array(z.string()), publishedAt: z.string(),
cover: z.string(), readingTime: z.number().optional(),
favorite: z.boolean().optional(), tags: z.array(z.string()),
canva: z.object({ cover: z.string(),
height: z.number().default(270), favorite: z.boolean().optional(),
width: z.number().default(480),
}),
}),
}),
writings: defineCollection({
type: 'page',
source: 'writings/*.md',
schema: z.object({
slug: z.string(),
title: z.string(),
description: z.string(),
publishedAt: z.string(),
readingTime: z.number(),
cover: z.string().optional(),
tags: z.array(z.string()),
canva: z.object({
height: z.number().default(270),
width: z.number().default(480),
}),
}),
}),
usesCategories: defineCollection({
type: 'data',
source: 'uses/categories/*.json',
schema: z.object({
slug: z.string(),
name: z.object({
en: z.string(),
fr: z.string(),
es: z.string(),
}),
}),
}),
uses: defineCollection({
type: 'data',
source: 'uses/*.json',
schema: z.object({
name: z.string(),
description: z.object({
en: z.string(),
fr: z.string(),
es: z.string(),
}),
category: z.string(),
}),
}),
skills: defineCollection({
type: 'data',
source: 'skills.json',
schema: z.object({
body: z.array(z.object({
id: z.string(),
name: z.object({
en: z.string(),
fr: z.string(),
es: z.string(),
}), }),
items: z.array(z.object({ }),
),
writings: defineCollection(
asSeoCollection({
type: 'page',
source: 'writings/*.md',
schema: z.object({
slug: z.string(),
title: z.string(),
description: z.string(),
publishedAt: z.string(),
readingTime: z.number(),
cover: z.string().optional(),
tags: z.array(z.string()),
}),
}),
),
usesCategories: defineCollection(
asSeoCollection({
type: 'data',
source: 'uses/categories/*.json',
schema: z.object({
slug: z.string(),
name: z.object({
en: z.string(),
fr: z.string(),
es: z.string(),
}),
}),
}),
),
uses: defineCollection(
asSeoCollection({
type: 'data',
source: 'uses/*.json',
schema: z.object({
name: z.string(), name: z.string(),
icon: z.string(), description: z.object({
})), en: z.string(),
})), fr: z.string(),
}), es: z.string(),
}), }),
experiences: defineCollection({ category: z.string(),
type: 'data', }),
source: 'experiences/*.json',
schema: z.object({
title: z.object({
en: z.string(),
fr: z.string(),
es: z.string(),
}), }),
company: z.string(), ),
companyUrl: z.string().url().optional(), skills: defineCollection(
startDate: z.string(), asSeoCollection({
endDate: z.string().optional(), type: 'data',
location: z.string(), source: 'skills.json',
description: z.object({ schema: z.object({
en: z.string(), body: z.array(z.object({
fr: z.string(), id: z.string(),
es: z.string(), name: z.object({
en: z.string(),
fr: z.string(),
es: z.string(),
}),
items: z.array(z.object({
name: z.string(),
icon: z.string(),
})),
})),
}),
}), }),
tags: z.array(z.string()), ),
}), experiences: defineCollection(
}), asSeoCollection({
} type: 'data',
source: 'experiences/*.json',
schema: z.object({
title: z.object({
en: z.string(),
fr: z.string(),
es: z.string(),
}),
company: z.string(),
companyUrl: z.string().url().optional(),
startDate: z.string(),
endDate: z.string().optional(),
location: z.string(),
description: z.object({
en: z.string(),
fr: z.string(),
es: z.string(),
}),
tags: z.array(z.string()),
}),
}),
),
},
})

View File

@@ -230,9 +230,6 @@
}, },
"top": "Go to top" "top": "Go to top"
}, },
"canva": {
"title": "Loading the canva ..."
},
"writings": { "writings": {
"description": "All my reflections on programming, mathematics, the conception of artificial intelligence, etc., are put in chronological order.", "description": "All my reflections on programming, mathematics, the conception of artificial intelligence, etc., are put in chronological order.",
"title": "Writings on math, artificial intelligence, development, and my passions.", "title": "Writings on math, artificial intelligence, development, and my passions.",

View File

@@ -233,9 +233,6 @@
"top": "Ir arriba" "top": "Ir arriba"
}, },
"alert": "Por falta de tiempo, no tuve tiempo para traducir este contenido al francés. Gracias por su comprensión.", "alert": "Por falta de tiempo, no tuve tiempo para traducir este contenido al francés. Gracias por su comprensión.",
"canva": {
"title": "Cargando el lienzo ..."
},
"writings": { "writings": {
"description": "Todas mis reflexiones sobre programación, matemáticas, la concepción de la inteligencia artificial, etc., están organizadas en orden cronológico.", "description": "Todas mis reflexiones sobre programación, matemáticas, la concepción de la inteligencia artificial, etc., están organizadas en orden cronológico.",
"title": "Escritos sobre matemáticas, inteligencia artificial, desarrollo y mis pasiones.", "title": "Escritos sobre matemáticas, inteligencia artificial, desarrollo y mis pasiones.",

View File

@@ -231,9 +231,6 @@
}, },
"top": "Remonter en haut" "top": "Remonter en haut"
}, },
"canva": {
"title": "Chargement du canva..."
},
"writings": { "writings": {
"description": "Toutes mes réflexions sur la programmation, les mathématiques, la conception de l'intelligence artificielle, etc., sont mises en ordre chronologique.", "description": "Toutes mes réflexions sur la programmation, les mathématiques, la conception de l'intelligence artificielle, etc., sont mises en ordre chronologique.",
"title": "Écrits sur les maths, l'intelligence artificielle, le développement et mes passions.", "title": "Écrits sur les maths, l'intelligence artificielle, le développement et mes passions.",

View File

@@ -1,3 +1,5 @@
import { definePerson } from 'nuxt-schema-org/schema'
export default defineNuxtConfig({ export default defineNuxtConfig({
compatibilityDate: '2025-07-20', compatibilityDate: '2025-07-20',
@@ -19,6 +21,7 @@ export default defineNuxtConfig({
// Nuxt Modules // Nuxt Modules
modules: [ modules: [
'@nuxt/ui', '@nuxt/ui',
'@nuxtjs/seo',
'@nuxt/content', '@nuxt/content',
'@vueuse/nuxt', '@vueuse/nuxt',
'@nuxtjs/google-fonts', '@nuxtjs/google-fonts',
@@ -26,9 +29,43 @@ export default defineNuxtConfig({
'@vueuse/motion/nuxt', '@vueuse/motion/nuxt',
'@pinia/nuxt', '@pinia/nuxt',
'@nuxtjs/i18n', '@nuxtjs/i18n',
'@nuxtjs/seo',
], ],
ogImage: {
enabled: false,
},
linkChecker: {
enabled: false,
},
site: {
url: 'https://arthurdanjou.fr',
name: 'Developer enjoying Artificial Intelligence and Machine Learning. Mathematics Student at Paris Dauphine-PSL University specialised in Statistics and Data Science.',
},
schemaOrg: {
identity: definePerson({
// Basic Information, if applicable
name: 'Arthur Danjou',
givenName: 'Arthur',
familyName: 'Danjou',
// Profile Information, if applicable
image: '/arthur-pro.webp',
description: 'AI researcher and technical author specializing in machine learning and neural networks',
jobTitle: 'Principal AI Researcher',
// Contact & Social, if applicable
email: 'arthurdanjou@outlook.fr',
url: 'https://go.arthurdanjou.fr/website',
sameAs: [
'https://go.arthurdanjou.fr/twitter',
'https://go.arthurdanjou.fr/github',
'https://go.arthurdanjou.fr/linkedin',
],
}),
},
// Nuxt Content // Nuxt Content
content: { content: {
preview: { preview: {

View File

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB