From 1fb0072fc79fd2b070a4820b8b30b54203a48870 Mon Sep 17 00:00:00 2001 From: NADAL Jean-Baptiste Date: Wed, 18 Feb 2026 12:52:15 +0100 Subject: [PATCH] [FEAT] We now have a functional APP --- AGENTS.md | 26 +++++++++ api/config/users.json | 5 ++ partitions/src/lib/api.ts | 7 ++- .../src/lib/components/PdfViewer.svelte | 38 +++++++++++-- partitions/src/routes/+layout.svelte | 3 - partitions/src/routes/scores/+page.svelte | 28 +++------ .../src/routes/scores/[id]/+page.svelte | 53 +++++++++++++----- .../routes/scores/[id]/[piece]/+page.svelte | 17 ++++-- .../[id]/[piece]/[instrument]/+page.svelte | 28 ++++++--- partitions/src/routes/test-icons/+page.svelte | 46 ++++++++------- partitions/static/icons/basson.png | Bin 0 -> 1927 bytes partitions/static/icons/clarinette.png | Bin 0 -> 1661 bytes partitions/static/icons/clarinette_basse.png | Bin 0 -> 6674 bytes partitions/static/icons/contrebasse.png | Bin 0 -> 2762 bytes partitions/static/icons/cor-anglais.jpg | Bin 0 -> 81186 bytes partitions/static/icons/cor.png | Bin 0 -> 3383 bytes partitions/static/icons/cornet.png | Bin 0 -> 2470 bytes partitions/static/icons/euphonium.png | Bin 0 -> 2616 bytes partitions/static/icons/flute.png | Bin 0 -> 1004 bytes partitions/static/icons/harpe.png | Bin 0 -> 2296 bytes partitions/static/icons/hautbois.png | Bin 0 -> 452 bytes partitions/static/icons/percussion.png | Bin 0 -> 3589 bytes partitions/static/icons/piccolo.png | Bin 0 -> 652 bytes partitions/static/icons/sax-alto.png | Bin 0 -> 3052 bytes partitions/static/icons/sax-barython.png | Bin 0 -> 3918 bytes partitions/static/icons/sax-soprano.png | Bin 0 -> 1476 bytes partitions/static/icons/sax-tenor.png | Bin 0 -> 2837 bytes partitions/static/icons/tronbonne.png | Bin 0 -> 1157 bytes partitions/static/icons/trumpet.png | Bin 0 -> 1759 bytes partitions/static/icons/tuba.png | Bin 0 -> 2616 bytes 30 files changed, 174 insertions(+), 77 deletions(-) create mode 100644 partitions/static/icons/basson.png create mode 100644 partitions/static/icons/clarinette.png create mode 100644 partitions/static/icons/clarinette_basse.png create mode 100644 partitions/static/icons/contrebasse.png create mode 100644 partitions/static/icons/cor-anglais.jpg create mode 100644 partitions/static/icons/cor.png create mode 100644 partitions/static/icons/cornet.png create mode 100644 partitions/static/icons/euphonium.png create mode 100644 partitions/static/icons/flute.png create mode 100644 partitions/static/icons/harpe.png create mode 100644 partitions/static/icons/hautbois.png create mode 100644 partitions/static/icons/percussion.png create mode 100644 partitions/static/icons/piccolo.png create mode 100644 partitions/static/icons/sax-alto.png create mode 100644 partitions/static/icons/sax-barython.png create mode 100644 partitions/static/icons/sax-soprano.png create mode 100644 partitions/static/icons/sax-tenor.png create mode 100644 partitions/static/icons/tronbonne.png create mode 100644 partitions/static/icons/trumpet.png create mode 100644 partitions/static/icons/tuba.png diff --git a/AGENTS.md b/AGENTS.md index 6412389..3abfbf3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -132,8 +132,34 @@ MySQL database connection configured in `api/config/database.php`: - Site targets French-speaking users - Production URL: `ohmj2.free.fr` +## Design Guidelines + +- **Style**: Clean, sober, and modern +- **Icons**: Use SVG icons instead of emojis for better consistency +- **Buttons**: Integrate related actions (view + download) in a single row with consistent styling +- **Hide unnecessary labels**: Don't show "Piece 1" or "Version 1" when there's only one +- **Visual hierarchy**: Use spacing, subtle borders, and hover effects for interactivity + ## Temporary Work Files - Use `_builds/` directory for temporary scripts and working files - Only `scripts/convert_final_v2.js` should be kept in the scripts folder (committed to git) - CSV output files belong in `_builds/` + +## Authentication + +- **Login**: Use `apiService.login('admin', 'password')` from frontend +- **API calls**: Include token in Authorization header: + ``` + Authorization: Bearer + ``` +- **Token format**: JWT (HS256) - see `api/lib/Auth.php` +- **Frontend**: Token stored in localStorage, auto-attached to API requests via axios interceptor +- **Test**: http://localhost:5173 - login with admin/password +- **API base URL**: http://localhost:8000/api/ + +## Current Tech Stack (2024) + +- **Frontend**: SvelteKit (NOT Vue.js 2) in `/partitions/` +- **Backend**: PHP API in `/api/` +- **Scores storage**: `/legacy/Scores/` (directory-based, not MySQL) diff --git a/api/config/users.json b/api/config/users.json index 15f03d1..51f9780 100644 --- a/api/config/users.json +++ b/api/config/users.json @@ -9,6 +9,11 @@ "username": "user", "password": "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi", "role": "user" + }, + { + "username": "ohmj", + "password": "$2y$10$qKjbai66h7sAY3ciIaO6z.ch1PwQweVCDtqWk85avk4sFcSBmTMBm", + "role": "user" } ] } diff --git a/partitions/src/lib/api.ts b/partitions/src/lib/api.ts index 83b663a..0430d20 100644 --- a/partitions/src/lib/api.ts +++ b/partitions/src/lib/api.ts @@ -86,8 +86,11 @@ export const apiService = { return response.data.score; }, - async getInstruments(scoreId: string): Promise { - const response = await api.get(`/scores/${scoreId}/instruments`); + async getInstruments(scoreId: string, pieceId?: number): Promise { + const url = pieceId + ? `/scores/${scoreId}/instruments?piece=${pieceId}` + : `/scores/${scoreId}/instruments`; + const response = await api.get(url); return response.data.instruments; }, diff --git a/partitions/src/lib/components/PdfViewer.svelte b/partitions/src/lib/components/PdfViewer.svelte index cb46b75..f51b40e 100644 --- a/partitions/src/lib/components/PdfViewer.svelte +++ b/partitions/src/lib/components/PdfViewer.svelte @@ -28,6 +28,7 @@ let loading = $state(true); let error = $state(''); let rendering = $state(false); + let isFullscreen = $state(false); async function loadPdf() { loading = true; @@ -102,8 +103,14 @@ renderPage(currentPage); } + function toggleFullscreen() { + isFullscreen = !isFullscreen; + } + function handleKeydown(e: KeyboardEvent) { - if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') { + if (e.key === 'Escape' && isFullscreen) { + isFullscreen = false; + } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') { prevPage(); } else if (e.key === 'ArrowRight' || e.key === 'ArrowDown') { nextPage(); @@ -129,8 +136,8 @@ }); -
-
+
+
{title} {#if totalPages > 0} @@ -143,7 +150,9 @@ class="px-2 py-1 bg-gray-700 hover:bg-gray-600 rounded text-sm" title="Zoom -" > - ➖ + + + {Math.round(scale * 100)}% +
@@ -172,7 +198,7 @@ {/if}
-
+
{/each} diff --git a/partitions/src/routes/test-icons/+page.svelte b/partitions/src/routes/test-icons/+page.svelte index 06d9003..fb296fc 100644 --- a/partitions/src/routes/test-icons/+page.svelte +++ b/partitions/src/routes/test-icons/+page.svelte @@ -1,25 +1,25 @@