feat: ajouter la gestion des contacts et des hobbies avec des ressources associées

This commit is contained in:
2025-11-14 18:13:14 +01:00
parent 025820a85d
commit d36ba22c9a
14 changed files with 321 additions and 23 deletions

View File

@@ -71,6 +71,20 @@ export default defineContentConfig({
endDate: z.string().optional(),
location: z.string()
})
}),
contact: defineCollection({
type: 'data',
source: 'contact.json',
schema: z.object({
body: z.array(z.object({
name: z.string(),
url: z.string().url()
}))
})
}),
hobbies: defineCollection({
type: 'page',
source: 'hobbies.md'
})
}
})

34
content/contact.json Normal file
View File

@@ -0,0 +1,34 @@
{
"body": [
{
"name": "Personal Email",
"icon": "i-ph-envelope-simple-duotone",
"value": "https://go.arthurdanjou.fr/mail-perso"
},
{
"name": "Professional Email",
"icon": "i-ph-envelope-simple-duotone",
"value": "https://go.arthurdanjou.fr/mail-pro"
},
{
"name": "LinkedIn",
"icon": "i-ph:linkedin-logo-duotone",
"value": "https://go.arthurdanjou.fr/linkedin"
},
{
"name": "GitHub",
"icon": "i-ph:github-logo-duotone",
"value": "https://go.arthurdanjou.fr/github"
},
{
"name": "Twitter",
"icon": "i-ph:x-logo-duotone",
"value": "https://go.arthurdanjou.fr/twitter"
},
{
"name": "Discord",
"icon": "i-ph:discord-logo-duotone",
"value": "https://go.arthurdanjou.fr/discord"
}
]
}

16
content/hobbies.md Normal file
View File

@@ -0,0 +1,16 @@
---
title: Balance and Drive: Beyond the Data
description: Exploring my passions outside of data science and machine learning engineering that fuel my creativity and performance.
---
While my passion for data science and machine learning engineering is at the core of what I do, I am convinced that personal balance is the key to performance and creativity. Outside of my technical projects, I nurture this balance through several key interests.
**Sports** are fundamental to my equilibrium. Playing rugby and volleyball has taught me the importance of collective strategy, communication, and physical commitment. Alongside this, as a long-time supporter of PSG in football, I appreciate the tactical analysis and performance management that occurs at the highest level.
**Music** is my creative outlet. It trains me to think differently and build harmonious solutions—a skill I readily apply to system design and modeling.
**Travel** provides me with an essential perspective. Having had the opportunity to discover highly diverse cultures since childhood (such as in Egypt, South Africa, Thailand, and the United States) has profoundly nurtured my curiosity and my ability to adapt to different ways of thinking. This is a flexibility I consider crucial in a constantly evolving field like AI.
Finally, as a **motorsport** enthusiast, particularly Formula 1, I am fascinated by the pursuit of pure performance, optimization under constraint, and real-time, data-driven strategy.
These passions are not just an escape; they reinforce my commitment, adaptability, and constant drive to progress. It is this balance that allows me to approach every new challenge, whether academic or technical, with motivation and energy.

View File

@@ -12,8 +12,21 @@ export default defineNuxtConfig({
runtimeConfig: {
public: {
helloText: 'Hello from the Edge 👋'
},
discord: {
userId: '',
id: '',
token: ''
},
wakatime: {
userId: '',
coding: '',
editors: '',
languages: '',
os: ''
}
},
future: { compatibilityVersion: 4 },
compatibilityDate: '2025-11-12',

View File

@@ -0,0 +1,4 @@
export default defineEventHandler(async (event) => {
const { discord } = useRuntimeConfig(event)
return await $fetch(`https://api.lanyard.rest/v1/users/${discord.userId}`)
})

10
server/api/contact.get.ts Normal file
View File

@@ -0,0 +1,10 @@
import { queryCollection } from '@nuxt/content/server'
export default defineCachedEventHandler(async (event) => {
return await queryCollection(event, 'contact')
.where('extension', '=', 'json')
.first()
}, {
name: 'contact-list',
maxAge: 3600 // 1 hour
})

View File

@@ -1,11 +1,9 @@
import { queryCollection } from '@nuxt/content/server'
export default defineCachedEventHandler(async (event) => {
return {
body: await queryCollection(event, 'education')
return await queryCollection(event, 'education')
.where('extension', '=', 'md')
.all()
}
}, {
name: 'educations-list',
maxAge: 3600 // 1 hour

View File

@@ -1,11 +1,9 @@
import { queryCollection } from '@nuxt/content/server'
export default defineCachedEventHandler(async (event) => {
return {
body: await queryCollection(event, 'experiences')
return await queryCollection(event, 'experiences')
.where('extension', '=', 'md')
.all()
}
}, {
name: 'experiences-list',
maxAge: 3600 // 1 hour

View File

@@ -0,0 +1,8 @@
import { queryCollection } from '@nuxt/content/server'
export default defineCachedEventHandler(async (event) => {
return await queryCollection(event, 'hobbies').first()
}, {
name: 'hobbies-list',
maxAge: 3600 // 1 hour
})

View File

@@ -1,11 +1,9 @@
import { queryCollection } from '@nuxt/content/server'
export default defineCachedEventHandler(async (event) => {
return {
body: await queryCollection(event, 'projects')
return await queryCollection(event, 'projects')
.where('extension', '=', 'md')
.all()
}
}, {
name: 'projects-list',
maxAge: 3600 // 1 hour

View File

@@ -1,11 +1,9 @@
import { queryCollection } from '@nuxt/content/server'
export default defineCachedEventHandler(async (event) => {
return {
body: await queryCollection(event, 'skills')
return await queryCollection(event, 'skills')
.where('extension', '=', 'json')
.all()
}
.first()
}, {
name: 'skills-list',
maxAge: 3600 // 1 hour

View File

@@ -15,9 +15,7 @@ export default defineCachedEventHandler(async (event) => {
})
}
return {
body: uses_by_categories
}
return uses_by_categories
}, {
name: 'uses-list',
maxAge: 3600 // 1 hour

View File

@@ -0,0 +1,57 @@
import type { H3Event } from 'h3'
const cachedWakatimeCoding = defineCachedFunction(async (event: H3Event) => {
const config = useRuntimeConfig(event)
return await $fetch(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.coding}.json`)
}, {
maxAge: 24 * 60 * 60,
name: 'wakatime',
getKey: () => 'coding'
})
const cachedWakatimeEditors = defineCachedFunction(async (event: H3Event) => {
const config = useRuntimeConfig(event)
return await $fetch(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.editors}.json`)
}, {
maxAge: 24 * 60 * 60,
name: 'wakatime',
getKey: () => 'editors'
})
const cachedWakatimeOs = defineCachedFunction(async (event: H3Event) => {
const config = useRuntimeConfig(event)
return await $fetch(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.os}.json`)
}, {
maxAge: 24 * 60 * 60,
name: 'wakatime',
getKey: () => 'os'
})
const cachedWakatimeLanguages = defineCachedFunction(async (event: H3Event) => {
const config = useRuntimeConfig(event)
return await $fetch(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.languages}.json`)
}, {
maxAge: 24 * 60 * 60,
name: 'wakatime',
getKey: () => 'languages'
})
export default defineEventHandler(async (event) => {
const [coding, editors, os, languages] = await Promise.all([
cachedWakatimeCoding(event),
cachedWakatimeEditors(event),
cachedWakatimeOs(event),
cachedWakatimeLanguages(event)
])
return {
coding,
editors,
os,
languages
}
})

View File

@@ -104,6 +104,82 @@ function createServer() {
}
)
server.registerResource(
'artmcp-activity',
'resource://artmcp/activity',
{
title: 'ArtMCP Activity',
description: 'Get realtime activity of Arthur Danjou'
},
async (uri) => {
const result = await $fetch('/api/activity')
return {
contents: [{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify(result, null, 2)
}]
}
}
)
server.registerResource(
'artmcp-wakatime',
'resource://artmcp/wakatime',
{
title: 'ArtMCP Wakatime',
description: 'Get Wakatime statistics of Arthur Danjou'
},
async (uri) => {
const result = await $fetch('/api/wakatime')
return {
contents: [{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify(result, null, 2)
}]
}
}
)
server.registerResource(
'artmcp-contact',
'resource://artmcp/contact',
{
title: 'ArtMCP Contact',
description: 'Get Contact Information of Arthur Danjou'
},
async (uri) => {
const result = await $fetch('/api/contact')
return {
contents: [{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify(result, null, 2)
}]
}
}
)
server.registerResource(
'artmcp-contact',
'resource://artmcp/hobbies',
{
title: 'ArtMCP Hobbies',
description: 'Get Hobbies Information of Arthur Danjou'
},
async (uri) => {
const result = await $fetch('/api/hobbies')
return {
contents: [{
uri: uri.href,
mimeType: 'application/json',
text: JSON.stringify(result, null, 2)
}]
}
}
)
// Tools
server.registerTool(
'get_resume_link',
@@ -148,6 +224,82 @@ function createServer() {
}
)
server.registerPrompt(
'artmcp-activity',
{
title: 'Get Realtime Activity of Arthur Danjou',
description: 'Get Realtime Activity of Arthur Danjou'
},
async () => {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: `Provide me the realtime activity of Arthur Danjou.`
}
}]
}
}
)
server.registerPrompt(
'artmcp-wakatime',
{
title: 'Get Stats of Arthur Danjou',
description: 'Get Stats of Arthur Danjou powered by Wakatime'
},
async () => {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: `Provide me the stats of Arthur Danjou powered by Wakatime.`
}
}]
}
}
)
server.registerPrompt(
'artmcp-contact',
{
title: 'Get Contact Information of Arthur Danjou',
description: 'Get Contact Information of Arthur Danjou'
},
async () => {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: `How can I contact Arthur Danjou?`
}
}]
}
}
)
server.registerPrompt(
'artmcp-hobbies',
{
title: 'Get Hobbies Information of Arthur Danjou',
description: 'Get Hobbies Information of Arthur Danjou'
},
async () => {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: `What are the hobbies, interests and passions of Arthur Danjou?`
}
}]
}
}
)
return server
}