diff --git a/frontend/src/pages/CustomQuizPage.css b/frontend/src/pages/CustomQuizPage.css index 400ff80..22b40e1 100644 --- a/frontend/src/pages/CustomQuizPage.css +++ b/frontend/src/pages/CustomQuizPage.css @@ -46,3 +46,9 @@ details[open] > .custom-test-branch .custom-test-chevron { transform: rotate(45d .custom-test-adaptive input:checked + .custom-test-switch { background: var(--primary); } .custom-test-adaptive input:checked + .custom-test-switch span { transform: translateX(17px); } .custom-test-branch { display: flex; align-items: center; } +.custom-test-main { gap: 0; } +.custom-test-settings > p, .custom-test-settings > .custom-test-share { margin: 0; } +.custom-test-actions { display: flex; gap: 10px; align-items: center; margin-top: 12px; } +.custom-test-actions .btn-primary { flex: 1; background: var(--primary); color: var(--primary-fg); font-weight: 600; padding: 10px 16px; } +.custom-test-main > p { margin: 8px 0 0; } +.custom-test-main > .custom-test-share { margin-top: 8px; } diff --git a/frontend/src/pages/CustomQuizPage.jsx b/frontend/src/pages/CustomQuizPage.jsx index fe5a6f2..3cd2669 100644 --- a/frontend/src/pages/CustomQuizPage.jsx +++ b/frontend/src/pages/CustomQuizPage.jsx @@ -150,9 +150,11 @@ export default function CustomQuizPage() { {ready && available === 0 &&

No questions match these filters.

} {ready && !validCount && available > 0 &&

Choose 1–{Math.min(200, available)} questions.

} {countError &&

{countError}

} - +
+ + +
{error &&

{error}

} - diff --git a/frontend/src/pages/QuestionBankPage.css b/frontend/src/pages/QuestionBankPage.css index 778db25..df82ed9 100644 --- a/frontend/src/pages/QuestionBankPage.css +++ b/frontend/src/pages/QuestionBankPage.css @@ -5,3 +5,19 @@ .category-editor-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.45); z-index: 1100; display: flex; align-items: center; justify-content: center; padding: 16px; } .category-editor-card { background: var(--card-bg); border-radius: 12px; padding: 18px; width: 100%; max-width: 420px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); } .category-editor-card select { width: 100%; padding: 7px 12px; border: 1px solid var(--border); border-radius: 8px; font-size: .875rem; background: var(--input-bg); color: var(--text); } +.bank-layout { display: grid; grid-template-columns: 280px 1fr; gap: 16px; align-items: start; } +.bank-filters { padding: 14px; } +.bank-filters h2 { margin: 0 0 8px; font-size: 1rem; } +.bank-filters h3 { margin: 14px 0 6px; font-size: .82rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); } +.bank-state-buttons { display: flex; flex-wrap: wrap; gap: 6px; } +.bank-difficulty { display: flex; flex-direction: column; gap: 4px; font-size: .82rem; margin-top: 10px; } +.bank-category-list { display: flex; flex-direction: column; gap: 2px; max-height: 50vh; overflow-y: auto; } +.bank-category-row { display: flex; align-items: center; gap: 4px; } +.bank-category-chip { flex: 1; text-align: left; background: none; border: none; border-radius: 6px; padding: 6px 8px; font-size: .82rem; color: var(--text); cursor: pointer; } +.bank-category-chip:hover { background: var(--option-hover, #f8fafc); } +.bank-category-chip.active { background: var(--option-sel-bg, #eff6ff); color: var(--primary); font-weight: 600; } +.bank-main { min-width: 0; } +@media (max-width: 820px) { + .bank-layout { grid-template-columns: 1fr; } + .bank-category-list { max-height: none; } +} diff --git a/frontend/src/pages/QuestionBankPage.jsx b/frontend/src/pages/QuestionBankPage.jsx index e4e7676..5fa7551 100644 --- a/frontend/src/pages/QuestionBankPage.jsx +++ b/frontend/src/pages/QuestionBankPage.jsx @@ -649,6 +649,7 @@ export default function QuestionBankPage() { const [loading, setLoading] = useState(false) const [categories, setCategories] = useState([]) const [searchQuery, setSearchQuery] = useState('') + const [difficulty, setDifficulty] = useState('') const [searchMode, setSearchMode] = useState('hybrid') const [filterCatIds, setFilterCatIds] = useState([]) const [showUncategorized, setShowUncategorized] = useState(false) @@ -715,7 +716,7 @@ export default function QuestionBankPage() { clearTimeout(debounceRef.current) debounceRef.current = setTimeout(() => loadQuestions(searchQuery, 0, filterCatIds, showUncategorized, showFavorites, searchMode, pageSize, selectedTagIds), 300) return () => clearTimeout(debounceRef.current) - }, [searchQuery, catIdsKey, showUncategorized, showFavorites, showMyQuestions, searchMode, pageSize, tagIdsKey]) + }, [searchQuery, catIdsKey, showUncategorized, showFavorites, showMyQuestions, searchMode, pageSize, tagIdsKey, difficulty]) const toggleTag = (tagId) => { setSelectedTagIds(prev => { @@ -737,6 +738,7 @@ export default function QuestionBankPage() { try { const params = {} if (searchQuery.trim()) params.q = searchQuery.trim() + if (difficulty) params.difficulty = difficulty if (filterCatIds.length > 0) params.category_ids = filterCatIds.join(',') if (showUncategorized) params.uncategorized = true if (showFavorites) params.favorites_only = true @@ -1011,33 +1013,44 @@ export default function QuestionBankPage() { )} - {/* Category filter chips */} -
- Filter: - - - - - {categories.map(cat => { - const isActive = filterCatIds.includes(cat.id) - return ( -
- - {isModerator && } - {isModerator && } -
- ) - })} - {/* Active tag chips — shown inline with categories */} + {/* Filter side box (AMBOSS-style) */} +
+
+ {(tags.subjects?.length > 0 || tags.diseases?.length > 0 || tags.keywords?.length > 0) && ( +
+ + {showTags && } +
+ )} + - {/* Tag browser — collapsible */} - {(tags.subjects?.length > 0 || tags.diseases?.length > 0 || tags.keywords?.length > 0) && ( -
- - {showTags && } -
- )} + {/* Main column */} +
{/* AI question classification is intentionally not exposed in the UI; it remains available through the command line/Celery interface only. */} @@ -1217,6 +1231,8 @@ export default function QuestionBankPage() {
)} +
+ ) }