Files
Portfolio-Game/frontend/app/composables/useFetchEasterEggs.ts
skycel 7e87a341a2 feat(epic-4): chemins narratifs, easter eggs, challenge et contact
Epic 4: Chemins Narratifs, Challenge & Contact

Stories implementees:
- 4.1: Composant ChoiceCards pour choix narratifs binaires
- 4.2: Sequence d'intro narrative avec Le Bug
- 4.3: Chemins narratifs differencies avec useNarrativePath
- 4.4: Table easter_eggs et systeme de detection (API + composable)
- 4.5: Easter eggs UI (popup, notification, collection)
- 4.6: Page challenge avec puzzle de code
- 4.7: Page revelation "Monde de Code"
- 4.8: Page contact avec formulaire et stats

Fichiers crees:
- Frontend: ChoiceCards, IntroSequence, ZoneEndChoice, EasterEggPopup,
  CodePuzzle, ChallengeSuccess, CodeWorld, et pages intro/challenge/revelation
- API: EasterEggController, Model, Migration, Seeder

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 13:35:12 +01:00

84 lines
2.0 KiB
TypeScript

export type TriggerType = 'click' | 'hover' | 'konami' | 'scroll' | 'sequence'
export type RewardType = 'snippet' | 'anecdote' | 'image' | 'badge'
export interface EasterEggMeta {
slug: string
location: string
trigger_type: TriggerType
difficulty: number
}
export interface EasterEggReward {
slug: string
reward_type: RewardType
reward: string
difficulty: number
}
interface EasterEggListResponse {
data: EasterEggMeta[]
meta: { total: number }
}
interface EasterEggValidateResponse {
data: EasterEggReward
}
export function useFetchEasterEggs() {
const config = useRuntimeConfig()
const { locale } = useI18n()
// Cache des easter eggs disponibles
const availableEasterEggs = ref<EasterEggMeta[]>([])
const isLoaded = ref(false)
async function fetchList(): Promise<EasterEggMeta[]> {
if (isLoaded.value) return availableEasterEggs.value
try {
const response = await $fetch<EasterEggListResponse>('/easter-eggs', {
baseURL: config.public.apiUrl as string,
headers: {
'X-API-Key': config.public.apiKey as string,
},
})
availableEasterEggs.value = response.data
isLoaded.value = true
return response.data
} catch {
return []
}
}
async function validate(slug: string): Promise<EasterEggReward | null> {
try {
const response = await $fetch<EasterEggValidateResponse>(`/easter-eggs/${slug}/validate`, {
method: 'POST',
baseURL: config.public.apiUrl as string,
headers: {
'X-API-Key': config.public.apiKey as string,
'Accept-Language': locale.value,
},
})
return response.data
} catch {
return null
}
}
function getByLocation(location: string): EasterEggMeta[] {
return availableEasterEggs.value.filter(
e => e.location === location || e.location === 'global'
)
}
return {
availableEasterEggs: readonly(availableEasterEggs),
isLoaded: readonly(isLoaded),
fetchList,
validate,
getByLocation,
}
}