- Add GET /skills/{slug}/projects endpoint with level progression
- Install @headlessui/vue for accessible modal
- Create SkillProjectsModal with Dialog component:
- Focus trap and keyboard navigation (automatic)
- Fade + scale transitions with backdrop blur
- prefers-reduced-motion support
- Create ProjectListItem with thumbnail and level display
- Integrate modal in competences.vue page
- Add translations for related projects UI
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
40 lines
939 B
TypeScript
40 lines
939 B
TypeScript
import type { Skill } from '~/types/skill'
|
|
|
|
export interface SkillProject {
|
|
id: number
|
|
slug: string
|
|
title: string
|
|
short_description: string
|
|
image: string
|
|
date_completed: string | null
|
|
level_before: number
|
|
level_after: number
|
|
level_description: string | null
|
|
}
|
|
|
|
interface SkillProjectsResponse {
|
|
data: {
|
|
skill: Pick<Skill, 'id' | 'slug' | 'name' | 'description' | 'level' | 'max_level'>
|
|
projects: SkillProject[]
|
|
}
|
|
meta: { lang: string }
|
|
}
|
|
|
|
export function useFetchSkillProjects(slug: Ref<string | null>) {
|
|
const config = useRuntimeConfig()
|
|
const { locale } = useI18n()
|
|
|
|
return useFetch<SkillProjectsResponse>(
|
|
() => slug.value ? `/skills/${slug.value}/projects` : '',
|
|
{
|
|
baseURL: config.public.apiUrl as string,
|
|
headers: {
|
|
'X-API-Key': config.public.apiKey as string,
|
|
'Accept-Language': locale.value,
|
|
},
|
|
immediate: false,
|
|
watch: false,
|
|
},
|
|
)
|
|
}
|