From d665a98c7db83fcc4b7d88c81f423829610dfc13 Mon Sep 17 00:00:00 2001 From: orfelorfel23 Date: Sun, 26 Apr 2026 12:30:48 +0200 Subject: [PATCH] Implement balanced row grouping for question navigator without horizontal scroll --- public/js/app.js | 53 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/public/js/app.js b/public/js/app.js index cbc6660..7a03aee 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1175,19 +1175,46 @@ function WettkampfQuizPage({ params, navigate }) {
- {/* Question navigator */} -
- {questions.map((question, i) => { - const a = answers[question.id]; - const isAnswered = a && a.selected && a.selected.length > 0 && a.selected[0] !== ''; - const isCurrent = i === index; - const style = {}; - let cls = 'w-9 h-9 flex-shrink-0 rounded-lg text-sm font-bold transition-all '; - if (isCurrent) { cls += 'text-white ring-2'; style.backgroundColor = '#f59e0b'; style.boxShadow = '0 0 0 2px #fcd34d'; } - else if (isAnswered) { cls += 'text-white'; style.backgroundColor = accentColor; } - else cls += 'bg-gray-700 text-gray-400 hover:bg-gray-600'; - return ; - })} +
+ {(() => { + const N = questions.length; + if (N === 0) return null; + const R = Math.ceil(N / 20); + const chunks = []; + const baseSize = Math.floor(N / R); + let remainder = N % R; + let startIndex = 0; + for (let i = 0; i < R; i++) { + const chunkSize = baseSize + (remainder > 0 ? 1 : 0); + remainder--; + const chunk = []; + for (let j = 0; j < chunkSize; j++) { + chunk.push({ q: questions[startIndex + j], origIndex: startIndex + j }); + } + chunks.push(chunk); + startIndex += chunkSize; + } + return ( +
+ {chunks.map((chunk, rowIdx) => ( +
+ {chunk.map(({ q, origIndex }) => { + const a = answers[q.id]; + const isAnswered = a && a.selected && a.selected.length > 0 && a.selected[0] !== ''; + const isCurrent = origIndex === index; + const style = {}; + // w-7 allows for more questions per row on smaller screens + let cls = 'w-7 h-7 sm:w-8 sm:h-8 md:w-9 md:h-9 rounded-md sm:rounded-lg text-xs sm:text-sm font-bold transition-all flex items-center justify-center shrink-0 '; + if (isCurrent) { cls += 'text-white ring-2'; style.backgroundColor = '#f59e0b'; style.boxShadow = '0 0 0 2px #fcd34d'; } + else if (isAnswered) { cls += 'text-white'; style.backgroundColor = accentColor; } + else cls += 'bg-gray-700 text-gray-400 hover:bg-gray-600'; + return ; + })} +
+ ))} +
+ ); + })()}
{/* Status */}