diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..58aaa72 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + } +} diff --git a/app/app.vue b/app/app.vue index fa4ee3e..fea5e1f 100644 --- a/app/app.vue +++ b/app/app.vue @@ -4,3 +4,24 @@ + + + + \ No newline at end of file diff --git a/app/components/gameBox.vue b/app/components/atropos.vue similarity index 100% rename from app/components/gameBox.vue rename to app/components/atropos.vue diff --git a/app/components/boxItem.vue b/app/components/boxItem.vue new file mode 100644 index 0000000..ad0e27d --- /dev/null +++ b/app/components/boxItem.vue @@ -0,0 +1,263 @@ + + + + + \ No newline at end of file diff --git a/app/components/compilationBox.vue b/app/components/compilationBox.vue new file mode 100644 index 0000000..342c549 --- /dev/null +++ b/app/components/compilationBox.vue @@ -0,0 +1,338 @@ + + + + + + \ No newline at end of file diff --git a/app/pages/design.vue b/app/pages/design.vue index 2b2dadb..65aad4c 100644 --- a/app/pages/design.vue +++ b/app/pages/design.vue @@ -1,11 +1,17 @@ + + diff --git a/app/store/dataStore.ts b/app/store/dataStore.ts new file mode 100644 index 0000000..d6a0108 --- /dev/null +++ b/app/store/dataStore.ts @@ -0,0 +1,51 @@ +import type { Compilation, Artist, Track } from '~/../types/types' + +// stores/data.ts +import { defineStore } from 'pinia' + +export const useDataStore = defineStore('data', { + state: () => ({ + compilations: [] as Compilation[], // Store your compilation data here + artists: [] as Artist[], // Store artist data here + tracks: [] as Track[], // Store track data here + isLoaded: false, // Remember if data is already loaded + }), + + actions: { + async loadData() { + if (this.isLoaded) return // Avoid re-fetching if already loaded + + // Fetch your data once (e.g., from an API or local JSON) + const { data: compilations } = await useFetch('/api/compilations') + const { data: artists } = await useFetch('/api/artists') + const { data: tracks } = await useFetch('/api/tracks') + + // Set the data in the store + this.compilations = compilations.value + this.artists = artists.value + this.tracks = tracks.value + this.isLoaded = true + } + }, + + getters: { + // Obtenir tous les compilations + getAllCompilations: (state) => state.compilations, + getCompilationById: (state) => { + return (id: string) => { + return state.compilations.find(compilation => compilation.id === id) + } + }, + // Obtenir toutes les pistes d'une compilation donnée + getTracksByCompilationId: (state) => (compilationId: string) => { + return state.tracks.filter(track => track.compilationId === compilationId) + }, + // 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: string) => { + return state.tracks.filter(track => track.artistId === artistId) + }, + }, +}) diff --git a/app/utils/cssVars.js b/app/utils/cssVars.js new file mode 100644 index 0000000..771f110 --- /dev/null +++ b/app/utils/cssVars.js @@ -0,0 +1,6 @@ +// utils/cssVars.js +export function updateCssVar(name, value, el) { + // if (!import.meta.client) return; + const target = el?.$el || el || document.documentElement; + target.style.setProperty(name, value); +} diff --git a/eslint.config.mjs b/eslint.config.mjs index 934c3a1..f0f16dd 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,6 +1,21 @@ // @ts-check -import withNuxt from './.nuxt/eslint.config.mjs' +import withNuxt from "./.nuxt/eslint.config.mjs"; -export default withNuxt( - // Your custom configs here -) +export default withNuxt({ + rules: { + // Garde l'ordre correct : class avant @click + "vue/attributes-order": "error", + + // Contrôle du nombre d'attributs par ligne + "vue/max-attributes-per-line": [ + "error", + { + singleline: 3, // autorise jusqu’à 3 attributs sur une ligne + multiline: { + max: 1, // si retour à la ligne, 1 attr par ligne + allowFirstLine: false, + }, + }, + ], + }, +}); diff --git a/nuxt.config.ts b/nuxt.config.ts index e2f7854..6c69276 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -2,7 +2,7 @@ export default defineNuxtConfig({ compatibilityDate: '2025-07-15', devtools: { enabled: true }, - modules: ['@nuxt/eslint', '@nuxtjs/tailwindcss'], + modules: ['@nuxt/eslint', '@nuxtjs/tailwindcss', '@pinia/nuxt'], app: { head: { link: [ diff --git a/package.json b/package.json index 4644e67..f2196ad 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "build": "nuxt build", - "dev": "nuxt dev", + "dev": "nuxt dev --host", "generate": "nuxt generate", "preview": "nuxt preview", "postinstall": "nuxt prepare" @@ -12,11 +12,13 @@ "dependencies": { "@nuxt/eslint": "1.9.0", "@nuxtjs/tailwindcss": "6.14.0", + "@pinia/nuxt": "0.11.2", + "atropos": "^2.0.2", "eslint": "^9.33.0", "nuxt": "^4.0.3", + "pinia": "^3.0.3", "vue": "^3.5.18", - "vue-router": "^4.5.1", - "atropos": "^2.0.2" + "vue-router": "^4.5.1" }, "engines": { "pnpm": ">=10 <11" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 799984d..e7d4e94 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@nuxtjs/tailwindcss': specifier: 6.14.0 version: 6.14.0(magicast@0.3.5) + '@pinia/nuxt': + specifier: 0.11.2 + version: 0.11.2(magicast@0.3.5)(pinia@3.0.3(typescript@5.9.2)(vue@3.5.18(typescript@5.9.2))) atropos: specifier: ^2.0.2 version: 2.0.2 @@ -23,6 +26,9 @@ importers: nuxt: specifier: ^4.0.3 version: 4.0.3(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@24.3.0)(@vue/compiler-sfc@3.5.18)(db0@0.3.2)(eslint@9.33.0(jiti@2.5.1))(ioredis@5.7.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.46.3)(terser@5.43.1)(typescript@5.9.2)(vite@7.1.2(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(yaml@2.8.1))(yaml@2.8.1) + pinia: + specifier: ^3.0.3 + version: 3.0.3(typescript@5.9.2)(vue@3.5.18(typescript@5.9.2)) vue: specifier: ^3.5.18 version: 3.5.18(typescript@5.9.2) @@ -1142,6 +1148,11 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} + '@pinia/nuxt@0.11.2': + resolution: {integrity: sha512-CgvSWpbktxxWBV7ModhAcsExsQZqpPq6vMYEe9DexmmY6959ev8ukL4iFhr/qov2Nb9cQAWd7niFDnaWkN+FHg==} + peerDependencies: + pinia: ^3.0.3 + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -1608,6 +1619,9 @@ packages: '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + '@vue/devtools-api@7.7.7': + resolution: {integrity: sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==} + '@vue/devtools-core@7.7.7': resolution: {integrity: sha512-9z9TLbfC+AjAi1PQyWX+OErjIaJmdFlbDHcD+cAMYKY6Bh5VlsAtCeGyRMrXwIlMEQPukvnWt3gZBLwTAIMKzQ==} peerDependencies: @@ -3690,6 +3704,15 @@ packages: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} + pinia@3.0.3: + resolution: {integrity: sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==} + peerDependencies: + typescript: '>=4.4.4' + vue: ^2.7.0 || ^3.5.11 + peerDependenciesMeta: + typescript: + optional: true + pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} @@ -6106,6 +6129,13 @@ snapshots: '@parcel/watcher-win32-ia32': 2.5.1 '@parcel/watcher-win32-x64': 2.5.1 + '@pinia/nuxt@0.11.2(magicast@0.3.5)(pinia@3.0.3(typescript@5.9.2)(vue@3.5.18(typescript@5.9.2)))': + dependencies: + '@nuxt/kit': 3.18.1(magicast@0.3.5) + pinia: 3.0.3(typescript@5.9.2)(vue@3.5.18(typescript@5.9.2)) + transitivePeerDependencies: + - magicast + '@pkgjs/parseargs@0.11.0': optional: true @@ -6571,6 +6601,10 @@ snapshots: '@vue/devtools-api@6.6.4': {} + '@vue/devtools-api@7.7.7': + dependencies: + '@vue/devtools-kit': 7.7.7 + '@vue/devtools-core@7.7.7(vite@7.1.2(@types/node@24.3.0)(jiti@2.5.1)(terser@5.43.1)(yaml@2.8.1))(vue@3.5.18(typescript@5.9.2))': dependencies: '@vue/devtools-kit': 7.7.7 @@ -8923,6 +8957,13 @@ snapshots: pify@2.3.0: {} + pinia@3.0.3(typescript@5.9.2)(vue@3.5.18(typescript@5.9.2)): + dependencies: + '@vue/devtools-api': 7.7.7 + vue: 3.5.18(typescript@5.9.2) + optionalDependencies: + typescript: 5.9.2 + pirates@4.0.7: {} pkg-types@1.3.1: diff --git a/public/ES00A/cover.jpg b/public/ES00A/cover.jpg new file mode 100644 index 0000000..9d5297b Binary files /dev/null and b/public/ES00A/cover.jpg differ diff --git a/public/ES00A/title.svg b/public/ES00A/title.svg new file mode 100644 index 0000000..778c972 --- /dev/null +++ b/public/ES00A/title.svg @@ -0,0 +1,59 @@ + + + + + + + + + + zero + + diff --git a/public/ES00B/cover.jpg b/public/ES00B/cover.jpg new file mode 100644 index 0000000..e9b7bdf Binary files /dev/null and b/public/ES00B/cover.jpg differ diff --git a/public/ES00B/title.svg b/public/ES00B/title.svg new file mode 100644 index 0000000..4ef177f --- /dev/null +++ b/public/ES00B/title.svg @@ -0,0 +1,59 @@ + + + + + + + + + + zero + + diff --git a/public/ES01A/cover.jpg b/public/ES01A/cover.jpg new file mode 100644 index 0000000..bdb21bc Binary files /dev/null and b/public/ES01A/cover.jpg differ diff --git a/public/ES01A/number1.svg b/public/ES01A/number1.svg deleted file mode 100644 index 292c723..0000000 --- a/public/ES01A/number1.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - diff --git a/public/ES01A/title.svg b/public/ES01A/title.svg new file mode 100644 index 0000000..bc691f6 --- /dev/null +++ b/public/ES01A/title.svg @@ -0,0 +1,50 @@ + + + + + + + + + + diff --git a/public/ES01B/cover.jpg b/public/ES01B/cover.jpg new file mode 100644 index 0000000..036b8bd Binary files /dev/null and b/public/ES01B/cover.jpg differ diff --git a/public/ES01B/title.svg b/public/ES01B/title.svg new file mode 100644 index 0000000..e4818f2 --- /dev/null +++ b/public/ES01B/title.svg @@ -0,0 +1,50 @@ + + + + + + + + + + diff --git a/server/api/artists.ts b/server/api/artists.ts new file mode 100644 index 0000000..7e1e6d2 --- /dev/null +++ b/server/api/artists.ts @@ -0,0 +1,70 @@ +export default eventHandler(() => { + return [ + { + id: 0, + name: "L'efondras", + url: "https://leffondras.bandcamp.com/music", + coverId: "0024705317" + }, + { + id: 1, + name: "The kundalini genie", + url: "https://the-kundalini-genie.bandcamp.com", + coverId: "0012045550" + }, + { + id: 2, + name: "Fontaines D.C.", + url: "https://fontainesdc.bandcamp.com", + coverId: "0027327090" + }, + { + id: 3, + name: "Fontanarosa", + url: "https://fontanarosa.bandcamp.com", + coverId: "0035380235", + }, + { + id: 4, + name: "Johnny mafia", + url: "https://johnnymafia.bandcamp.com", + coverId: "0035009392", + }, + { + id: 5, + name: "New candys", + url: "https://newcandys.bandcamp.com", + coverId: "0033518637", + }, + { + id: 6, + name: "Magic shoppe", + url: "https://magicshoppe.bandcamp.com", + coverId: "0030748374" + }, + { + id: 7, + name: "Les jaguars", + url: "https://radiomartiko.bandcamp.com/album/surf-qu-b-cois", + coverId: "0016551336", + }, + { + id: 8, + name: "TRAAMS", + url: "https://traams.bandcamp.com", + coverId: "0028348410", + }, + { + id: 9, + name: "Blue orchid", + url: "https://blue-orchid.bandcamp.com", + coverId: "0034796193", + }, + { + id: 10, + name: "I love UFO", + url: "https://bruitblanc.bandcamp.com", + coverId: "a2203158939", + } + ] +}) diff --git a/server/api/compilations.ts b/server/api/compilations.ts new file mode 100644 index 0000000..90b6aea --- /dev/null +++ b/server/api/compilations.ts @@ -0,0 +1,36 @@ +export default eventHandler(() => { + return [ + { + id: 'ES00A', + name: 'zero', + duration: 2794, + description: 'Zero is for manifesto ... ;)', + colorFrom: '#ffffff', + colorTo: '#48959d', + }, + { + id: 'ES00B', + name: 'zero b-side', + duration: 2470, + description: 'Even Zero has a b-side', + colorFrom: '#0d01b9', + colorTo: '#3b7589', + }, + { + id: 'ES01A', + name: 'first', + duration: 3487, + description: '...', + colorFrom: '#c7b3aa', + colorTo: '#000100', + }, + { + id: 'ES01B', + name: 'first b-side', + duration: 3773, + description: '...', + colorFrom: '#f7dd01', + colorTo: '#010103', + } + ] +}) diff --git a/server/api/playlists/[id].ts b/server/api/playlists/[id].ts new file mode 100644 index 0000000..c72f80d --- /dev/null +++ b/server/api/playlists/[id].ts @@ -0,0 +1,23 @@ +import fs from 'fs' +import path from 'path' + +export default eventHandler(async (event) => { + const id = event.context.params?.id || '' + + const directoryPath = path.join(process.cwd(), 'media/files/music/' + id) // replace 'your-folder' with the folder you want to list + + try { + // Read the directory contents + const files = await fs.promises.readdir(directoryPath) + + return { + success: true, + files: files.filter(file => !file.startsWith('.')) // optional: exclude unwanted files + } + } catch (error) { + return { + success: false, + error: error.message + } + } +}) diff --git a/server/api/playlists/index.ts b/server/api/playlists/index.ts new file mode 100644 index 0000000..20ef77f --- /dev/null +++ b/server/api/playlists/index.ts @@ -0,0 +1,21 @@ +import fs from 'fs' +import path from 'path' + +export default eventHandler(async (event) => { + const directoryPath = path.join(process.cwd(), 'media/files/music') + + try { + // Read the directory contents + const files = await fs.promises.readdir(directoryPath) + + return { + success: true, + files: files.filter(file => !file.startsWith('.')).reverse() // exclude unwanted files + } + } catch (error) { + return { + success: false, + error: error.message + } + } +}) diff --git a/server/api/tracks.ts b/server/api/tracks.ts new file mode 100644 index 0000000..a7bb894 --- /dev/null +++ b/server/api/tracks.ts @@ -0,0 +1,224 @@ +export default eventHandler(() => { + return [ + { + id: 1, + compilationId: 'ES00A', + title: 'The grinding wheel', + artist: 0, + start: 0, + bpm: 0, + url: 'https://arakirecords.bandcamp.com/track/the-grinding-wheel', + coverId: 'a3236746052', + }, + { + id: 2, + compilationId: 'ES00A', + title: 'Bleach', + artist: 1, + start: 393, + bpm: 0, + url: 'https://the-kundalini-genie.bandcamp.com/track/bleach-2', + coverId: 'a1714786533', + }, + { + id: 3, + compilationId: 'ES00A', + title: 'Televised mind', + artist: 2, + start: 892, + bpm: 0, + url: 'https://fontainesdc.bandcamp.com/track/televised-mind', + coverId: 'a3772806156' + }, + { + id: 4, + compilationId: 'ES00A', + title: 'In it', + artist: 3, + start: 1138, + bpm: 0, + url: 'https://howlinbananarecords.bandcamp.com/track/in-it', + coverId: 'a1720372066', + }, + { + id: 5, + compilationId: 'ES00A', + title: 'Bad michel', + artist: 4, + start: 1245, + bpm: 0, + url: 'https://johnnymafia.bandcamp.com/track/bad-michel-3', + coverId: 'a0984622869', + }, + { + id: 6, + compilationId: 'ES00A', + title: 'Overall', + artist: 5, + start: 1394, + bpm: 0, + url: 'https://newcandys.bandcamp.com/track/overall', + coverId: 'a0559661270', + }, + { + id: 7, + compilationId: 'ES00A', + title: 'Blowup', + artist: 6, + start: 1674, + bpm: 0, + url: 'https://magicshoppe.bandcamp.com/track/blowup', + coverId: 'a1444895293', + }, + { + id: 8, + compilationId: 'ES00A', + title: 'Guitar jet', + artist: 7, + start: 1880, + bpm: 0, + url: 'https://radiomartiko.bandcamp.com/track/guitare-jet', + coverId: 'a1494681687', + }, + { + id: 9, + compilationId: 'ES00A', + title: 'Intercontinental radio waves', + artist: 8, + start: 2024, + bpm: 0, + url: 'https://traams.bandcamp.com/track/intercontinental-radio-waves', + coverId: 'a0046738552', + }, + { + id: 10, + compilationId: 'ES00A', + title: 'Here comes the sun', + artist: 9, + start: 2211, + bpm: 0, + url: 'https://blue-orchid.bandcamp.com/track/here-come-the-sun', + coverId: 'a4102567047', + }, + { + id: 11, + compilationId: 'ES00A', + title: 'Like in the movies', + artist: 10, + start: 2559, + bpm: 0, + url: 'https://bruitblanc.bandcamp.com/track/like-in-the-movies-2', + coverId: 'a2203158939', + }, + { + id: 21, + compilationId: 'ES00B', + title: 'Ce que révèle l\'éclipse', + artist: 0, + start: 0, + bpm: 0, + url: 'https://arakirecords.bandcamp.com/track/ce-que-r-v-le-l-clipse', + coverId: 'a3236746052', + }, + { + id: 22, + compilationId: 'ES00B', + title: 'Bleedin\' Gums Mushrool', + artist: 1, + start: 263, + bpm: 0, + url: 'https://the-kundalini-genie.bandcamp.com/track/bleedin-gums-mushroom', + coverId: 'a1714786533', + }, + { + id: 23, + compilationId: 'ES00B', + title: 'A lucid dream', + artist: 2, + start: 554, + bpm: 0, + url: 'https://fontainesdc.bandcamp.com/track/a-lucid-dream', + coverId: 'a3772806156', + }, + { + id: 24, + compilationId: 'ES00B', + title: 'Lights off', + artist: 3, + start: 781, + bpm: 0, + url: 'https://howlinbananarecords.bandcamp.com/track/lights-off', + coverId: 'a1720372066', + }, + { + id: 25, + compilationId: 'ES00B', + title: 'I\'m sentimental', + artist: 4, + start: 969, + bpm: 0, + url: 'https://johnnymafia.bandcamp.com/track/im-sentimental-2', + coverId: 'a2333676849', + }, + { + id: 26, + compilationId: 'ES00B', + title: 'Thrill or trip', + artist: 5, + start: 1128, + bpm: 0, + url: 'https://newcandys.bandcamp.com/track/thrill-or-trip', + coverId: 'a0559661270', + }, + { + id: 27, + compilationId: 'ES00B', + title: 'Redhead', + artist: 6, + start: 1303, + bpm: 0, + url: 'https://magicshoppe.bandcamp.com/track/redhead', + coverId: 'a0594426943', + }, + { + id: 28, + compilationId: 'ES00B', + title: 'Supersonic twist', + artist: 7, + start: 1584, + bpm: 0, + url: 'https://open.spotify.com/track/66voQIZAJ3zD3Eju2qtNjF', + coverId: 'a1494681687', + }, + { + id: 29, + compilationId: 'ES00B', + title: 'Flowers', + artist: 8, + start: 1749, + bpm: 0, + url: 'https://traams.bandcamp.com/track/flowers', + coverId: 'a3644668199', + }, + { + id: 30, + compilationId: 'ES00B', + title: 'The shade', + artist: 9, + start: 1924, + bpm: 0, + url: 'https://blue-orchid.bandcamp.com/track/the-shade', + coverId: 'a0804204790', + }, + { + id: 31, + compilationId: 'ES00B', + title: 'Like in the movies', + artist: 10, + start: 2185, + bpm: 0, + url: 'https://bruitblanc.bandcamp.com/track/like-in-the-movies', + coverId: 'a3647322740', + }, + ] +}) diff --git a/server/tsconfig.json b/server/tsconfig.json new file mode 100644 index 0000000..b9ed69c --- /dev/null +++ b/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/types/types.ts b/types/types.ts new file mode 100644 index 0000000..0c966e0 --- /dev/null +++ b/types/types.ts @@ -0,0 +1,28 @@ +// types.ts +export interface Compilation { + id: string + name: string + duration: number + tracks?: Track[] + description: string + colorFrom: string + colorTo: string +} + +export interface Artist { + id: number + name: string + url: string + coverId: string +} + +export interface Track { + id: string + compilationId: string + title: string + artistId: number + artist?: Artist + start: number + link: string + coverId: string +}