import { defineStore } from 'pinia' export type HeroType = 'recruteur' | 'client' | 'dev' export interface ProgressionState { sessionId: string hero: HeroType | null currentPath: string visitedSections: string[] completionPercent: number easterEggsFound: string[] challengeCompleted: boolean contactUnlocked: boolean narratorStage: number choices: Record consentGiven: boolean | null } const SECTIONS = ['projets', 'competences', 'temoignages', 'parcours'] as const /** * Storage conditionnel : ne persiste que si consentGiven === true. * La lecture est toujours autorisée (pour restaurer une session existante). */ const conditionalStorage: Storage = { get length() { return import.meta.client ? localStorage.length : 0 }, key(index: number) { return import.meta.client ? localStorage.key(index) : null }, getItem(key: string) { if (import.meta.client) { return localStorage.getItem(key) } return null }, setItem(key: string, value: string) { if (import.meta.client) { try { const parsed = JSON.parse(value) if (parsed.consentGiven === true) { localStorage.setItem(key, value) } } catch { // Si parsing échoue, ne pas persister } } }, removeItem(key: string) { if (import.meta.client) { localStorage.removeItem(key) } }, clear() { if (import.meta.client) { localStorage.clear() } }, } export const useProgressionStore = defineStore('progression', { state: (): ProgressionState => ({ sessionId: '', hero: null, currentPath: 'start', visitedSections: [], completionPercent: 0, easterEggsFound: [], challengeCompleted: false, contactUnlocked: false, narratorStage: 1, choices: {}, consentGiven: null, }), getters: { hasVisited: (state) => (section: string) => state.visitedSections.includes(section), isContactUnlocked: (state) => state.visitedSections.length >= 2 || state.contactUnlocked, progressPercent: (state) => Math.round((state.visitedSections.length / SECTIONS.length) * 100), hasExistingProgress: (state) => state.visitedSections.length > 0 || state.hero !== null, }, actions: { initSession() { if (!this.sessionId && import.meta.client) { this.sessionId = crypto.randomUUID() } }, setHero(hero: HeroType) { this.hero = hero this.initSession() }, visitSection(section: string) { if (!this.visitedSections.includes(section)) { this.visitedSections.push(section) this.completionPercent = this.progressPercent if (this.visitedSections.length >= 2) { this.contactUnlocked = true } } }, findEasterEgg(slug: string) { if (!this.easterEggsFound.includes(slug)) { this.easterEggsFound.push(slug) } }, completeChallenge() { this.challengeCompleted = true }, unlockContact() { this.contactUnlocked = true }, updateNarratorStage(stage: number) { if (stage >= 1 && stage <= 5) { this.narratorStage = stage } }, makeChoice(choiceId: string, value: string) { this.choices[choiceId] = value }, setConsent(given: boolean) { this.consentGiven = given if (given) { this.initSession() } else if (import.meta.client) { // Si refus, supprimer les données stockées localStorage.removeItem('skycel-progression') } }, }, persist: { key: 'skycel-progression', storage: conditionalStorage, }, })