fix(frontend): export ui object, harmonize API signatures, and clean view switcher

This commit is contained in:
2026-10-07 13:13:45 +03:00
parent 718e9797eb
commit 640da1f27c
4 changed files with 138 additions and 147 deletions
+43 -11
View File
@@ -167,18 +167,34 @@ export const api = {
// SRS Spaced Repetition
srs: {
async getQueue(forceAll = false, tagFilter = null) {
let url = '/api/srs/queue?limit=50';
async getQueue(forceAllOrOptions = false, tagFilter = null) {
let forceAll = false;
let tag = tagFilter;
let limit = 50;
if (typeof forceAllOrOptions === 'object' && forceAllOrOptions !== null) {
forceAll = !!forceAllOrOptions.forceAll || !!forceAllOrOptions.force_all;
tag = forceAllOrOptions.tagFilter || forceAllOrOptions.tag || tag;
if (forceAllOrOptions.limit) limit = forceAllOrOptions.limit;
} else {
forceAll = !!forceAllOrOptions;
}
let url = `/api/srs/queue?limit=${limit}`;
if (forceAll) url += '&force_all=true';
if (tagFilter) url += `&tag=${encodeURIComponent(tagFilter)}`;
if (tag) url += `&tag=${encodeURIComponent(tag)}`;
const resp = await fetch(url);
return resp.ok ? await resp.json() : [];
return resp.ok ? await resp.json() : { cards: [], count: 0 };
},
async submitReview(cardId, rating) {
async submitReview(cardIdOrPayload, rating) {
let cardId = cardIdOrPayload;
let r = rating;
if (typeof cardIdOrPayload === 'object' && cardIdOrPayload !== null) {
cardId = cardIdOrPayload.card_id ?? cardIdOrPayload.id;
r = cardIdOrPayload.rating;
}
return await fetch('/api/srs/review', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ card_id: cardId, rating })
body: JSON.stringify({ card_id: cardId, rating: r })
});
}
},
@@ -194,15 +210,25 @@ export const api = {
if (resp.ok) return await resp.json();
throw new Error(`Failed to load listening exercise: ${resp.status}`);
},
async checkAnswer(scenarioId, userAnswer, story = '', idealAnswer = '') {
async checkAnswer(scenarioIdOrPayload, userAnswer = '', story = '', idealAnswer = '') {
let sId = scenarioIdOrPayload;
let uAns = userAnswer;
let st = story;
let idAns = idealAnswer;
if (typeof scenarioIdOrPayload === 'object' && scenarioIdOrPayload !== null) {
sId = scenarioIdOrPayload.scenario_id ?? scenarioIdOrPayload.id;
uAns = scenarioIdOrPayload.user_answer ?? scenarioIdOrPayload.answer ?? '';
st = scenarioIdOrPayload.story ?? '';
idAns = scenarioIdOrPayload.ideal_answer ?? scenarioIdOrPayload.idealAnswer ?? '';
}
const resp = await fetch('/api/listening/check', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
scenario_id: scenarioId,
user_answer: userAnswer,
story: story,
ideal_answer: idealAnswer
scenario_id: sId,
user_answer: uAns,
story: st,
ideal_answer: idAns
})
});
if (resp.ok) return await resp.json();
@@ -374,6 +400,9 @@ export const api = {
if (resp.ok) return await resp.json();
throw new Error(`Failed to complete unit: ${resp.status}`);
},
async recordCompletion(unitId, score, handwrittenLogged = false) {
return this.completeUnit(unitId, score, handwrittenLogged);
},
async toggleHandwritten(unitId, handwritten) {
const resp = await fetch('/api/grammar/handwritten', {
method: 'POST',
@@ -385,6 +414,9 @@ export const api = {
});
if (resp.ok) return await resp.json();
throw new Error(`Failed to update handwritten status: ${resp.status}`);
},
async updateHandwritten(unitId, handwritten) {
return this.toggleHandwritten(unitId, handwritten);
}
},