import type { Box, Artist, Track } from '~/../types/types' import { defineStore } from 'pinia' export const useDataStore = defineStore('data', { state: () => ({ boxes: [] as Box[], // Store your box data here artists: [] as Artist[], // Store artist data here tracks: [] as Track[], // Store track data here isLoaded: false, // Remember if data is already loaded isLoading: true }), actions: { async loadData() { if (this.isLoaded) return this.isLoading = true try { this.boxes = await $fetch('/api/boxes') this.artists = await $fetch('/api/artists') const compilationTracks = await $fetch('/api/tracks/compilation') const playlistTracks = await $fetch('/api/tracks/playlist') // Mapper les tracks pour remplacer l'artist avec un objet Artist cohérent const artistMap = new Map(this.artists.map((a) => [a.id, a])) const allTracks = [ ...(Array.isArray(compilationTracks) ? compilationTracks : []), ...(Array.isArray(playlistTracks) ? playlistTracks : []) ] this.tracks = allTracks.map((track) => { const a = track.artist as unknown let artistObj: Artist if (typeof a === 'number') { artistObj = artistMap.get(a) ?? { id: a, name: String(a), url: '', coverId: '' } } else if (typeof a === 'string') { artistObj = { id: 0, name: a, url: '', coverId: '' } } else if (a && typeof a === 'object' && 'id' in (a as any)) { const idVal = (a as any).id as number | undefined artistObj = idVal != null ? artistMap.get(idVal) ?? (a as Artist) : (a as Artist) } else { artistObj = { id: 0, name: '', url: '', coverId: '' } } return { ...track, artist: artistObj } }) this.isLoaded = true } finally { this.isLoading = false } }, setActiveSideByBoxId(boxId: string, side: 'A' | 'B') { const box = this.boxes.find((box) => box.id === boxId.replace(/[AB]$/, '')) if (box) { box.activeSide = side } }, getRandomPlaylistTrack() { if (this.tracks.length === 0) return null const randomIndex = Math.floor(Math.random() * this.tracks.length) return this.tracks[randomIndex] } }, getters: { // Obtenir toutes les boxes getBoxById: (state) => { return (id: string) => { return state.boxes.find((box) => box.id === id) } }, getTrackById: (state) => { return (id: string) => { return state.tracks.find((track) => track.id === id) } }, getTracksByboxId: (state) => (id: string, side?: 'A' | 'B') => { const box = state.boxes.find((box) => box.id === id) if (box?.type !== 'compilation' || !side) { return state.tracks.filter((track) => track.boxId === id) } return state.tracks.filter((track) => track.boxId === id && track.side === side) }, getActiveSideByBoxId: (state) => (id: string) => { const box = state.boxes.find((box) => box.id === id) return box?.activeSide }, // Filtrer les artistes selon certains critères getArtistById: (state) => (id: number) => state.artists.find((artist) => artist.id === id), // Obtenir toutes les pistes d'un artiste donné getTracksByArtistId: (state) => (artistId: number) => { return state.tracks.filter( (track) => typeof track.artist === 'object' && !!track.artist && 'id' in track.artist && (track.artist as Artist).id === artistId ) }, getFirstTrackOfBox() { return (box: Box) => { const tracks = this.getTracksByboxId(box.id, box.activeSide) .slice() .sort((a, b) => (a.order ?? 0) - (b.order ?? 0)) return tracks.length > 0 ? tracks[0] : null } }, getNextPlaylistTrack: (state) => { return (track: Track) => { const tracksInPlaylist = state.tracks .filter((t) => t.boxId === track.boxId) .sort((a, b) => (a.order ?? 0) - (b.order ?? 0)) const index = tracksInPlaylist.findIndex((t) => t.id === track.id) return index >= 0 && index < tracksInPlaylist.length - 1 ? tracksInPlaylist[index + 1] : null } }, getNextTrack: (state) => { return (track: Track) => { // Récupérer toutes les tracks de la même box et les trier par ordre const tracksInBox = state.tracks .filter((t) => t.boxId === track.boxId && t.side === track.side) .sort((a, b) => (a.order ?? 0) - (b.order ?? 0)) // Trouver l’index de la track courante const index = tracksInBox.findIndex((t) => t.id === track.id) // Retourner la track suivante ou null si c’est la dernière return index >= 0 && index < tracksInBox.length - 1 ? tracksInBox[index + 1] : null } }, getPrevTrack: (state) => { return (track: Track) => { const tracksInBox = state.tracks .filter((t) => t.boxId === track.boxId && t.side === track.side) .sort((a, b) => (a.order ?? 0) - (b.order ?? 0)) const index = tracksInBox.findIndex((t) => t.id === track.id) return index > 0 ? tracksInBox[index - 1] : null } }, getYearColor: () => (year: number) => { // Palette élargie avec des différences plus marquées const colorMap: Record = { // Années récentes - teintes froides et claires 2025: '#3a4a6c', // bleu-gris clair 2024: '#1e3a7a', // bleu vif 2023: '#1a4d5c', // bleu-vert émeraude 2022: '#3a4a6a', // bleu-gris moyen // Années 2020-2021 - transition 2021: '#3a2e6a', // bleu-violet 2020: '#2a467a', // bleu-gris chaud // Années 2010-2019 - teintes moyennes 2019: '#2a2a7a', // bleu nuit profond 2018: '#1e2a8a', // bleu roi 2017: '#1a5a6a', // bleu canard vif 2016: '#1a5a4a', // vert bleuté 2015: '#1a3a7a', // bleu marine 2014: '#4a1e7a', // violet profond 2013: '#1a5a4a', // vert émeraude 2012: '#1e3a9a', // bleu ciel profond // Années 2000-2011 - teintes chaudes et foncées 2011: '#1e293b', // slate-800 de base 2010: '#2a467a', // bleu-gris chaud 2009: '#3a4a6a', // bleu-gris moyen 2008: '#1a3a8a', // bleu nuit clair 2007: '#5a2a4a', // bordeaux 2006: '#5a1e6a', // violet profond 2005: '#3a1a7a', // bleu-violet foncé 2004: '#2a1a5a', // bleu nuit profond 2003: '#3a3a5a', // bleu-gris foncé 2002: '#1a5a4a', // vert foncé 2001: '#5a3a2a', // marron chaud 2000: '#3a3a5a' // bleu-gris foncé } return colorMap[year] || '#1e293b' // slate-800 par défaut } } })