Skip to content

Commit e68cd7c

Browse files
committed
QuizContext: Keep just the last answer, not the entire history
1 parent 84d2435 commit e68cd7c

4 files changed

Lines changed: 78 additions & 116 deletions

File tree

api/quiz.ts

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ export const postFileAnswer = async (
170170

171171
export type CorrectAnswers = { questionId: string, answer: string }[];
172172

173-
export const getAnswers = async ({ accessToken, bookId, group }: {
173+
export const getLastAnswers = async ({ accessToken, bookId, group }: {
174174
accessToken: string;
175175
bookId: number;
176176
group: string | undefined | null;
@@ -179,37 +179,46 @@ export const getAnswers = async ({ accessToken, bookId, group }: {
179179
const answers = [
180180
...(
181181
await db.all(`
182-
SELECT answers.answer, q.questionId, isCorrect, points
183-
FROM answers
184-
JOIN questions q ON answers.questionId = q.id
185-
LEFT JOIN groups g ON answers.groupId = g.id
186-
WHERE userId = ? AND bookId = ? AND g.name IS ? AND q.type NOT LIKE 'upload%'
187-
ORDER BY answers.createdAt`,
182+
SELECT answer, questionId, isCorrect, points, nAttempts FROM (
183+
SELECT a.answer, q.questionId, a.isCorrect, a.points,
184+
ROW_NUMBER() OVER (PARTITION BY a.questionId ORDER BY a.createdAt DESC) AS rn,
185+
COUNT(*) OVER (PARTITION BY a.questionId) AS nAttempts
186+
FROM answers a
187+
JOIN questions q ON a.questionId = q.id
188+
LEFT JOIN groups g ON a.groupId = g.id
189+
WHERE a.userId = ? AND a.bookId = ? AND g.name IS ? AND q.type NOT LIKE 'upload%'
190+
) t
191+
WHERE rn = 1;`,
188192
[userId, bookId, group ?? null]
189-
)).map(({answer, questionId, isCorrect, points}) => ({
193+
)).map(({answer, questionId, isCorrect, points, nAttempts}) => ({
190194
type: "value",
191195
answer,
192196
questionId,
193197
points,
198+
nAttempts,
194199
// DB stores 0 and 1 even if the column is declared as BOOLEAN
195200
isCorrect: isCorrect === null ? undefined : !!isCorrect,
196-
}) as AnswerValue & {questionId: string}),
201+
}) as AnswerValue & {questionId: string, nAttempts: number}),
197202
...(
198203
await db.all(`
199-
SELECT q.questionId, group_concat(u.filename, "\n") as files
200-
FROM answers
201-
JOIN questions q ON answers.questionId = q.id
202-
LEFT JOIN groups g ON answers.groupId = g.id
203-
LEFT JOIN uploads u ON u.answerId = answers.id
204-
WHERE userId = ? AND bookId = ? AND g.name IS ? AND q.type LIKE 'upload%'
205-
GROUP BY answers.id
206-
ORDER BY answers.createdAt`,
204+
SELECT questionId, group_concat(u.filename, "\n") as files, 1 as nAttempts FROM (
205+
SELECT q.questionId, a.id as answerId,
206+
ROW_NUMBER() OVER (PARTITION BY a.questionId ORDER BY a.createdAt DESC) AS rn
207+
FROM answers a
208+
JOIN questions q ON a.questionId = q.id
209+
LEFT JOIN groups g ON a.groupId = g.id
210+
WHERE userId = ? AND bookId = ? AND g.name IS ? AND q.type LIKE 'upload%'
211+
) t
212+
JOIN uploads u ON u.answerId = t.answerId
213+
WHERE rn = 1
214+
GROUP BY t.answerId;`,
207215
[userId, bookId, group ?? null]
208-
)).map(({files, questionId}) => ({
216+
)).map(({files, questionId, nAttempts}) => ({
209217
type: "files",
210218
questionId,
219+
nAttempts,
211220
files: files ? files.split("\n") : [],
212-
}) as AnswerFile & {questionId: string})
221+
}) as AnswerFile & {questionId: string, nAttempts: number})
213222
];
214223

215224
const correctAnswers =

components/Book/Book.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import { usePathname } from "next/navigation";
55
import Image from "../Image";
66
import { toast } from "react-toastify";
77

8-
import { AnswersInBook, CorrectAnswers, getAnswers, getAnswersInBook } from "@/api/quiz";
8+
import { AnswersInBook, CorrectAnswers, getLastAnswers, getAnswersInBook } from "@/api/quiz";
99
import { BookProps, getPublicCollection } from "@/api/book";
1010
import { isAdminFor } from "@/api/user";
1111

1212
import { logger } from "@/utils/logger";
1313
import { getT, IntlContextProvider } from "@/i18n";
1414
import { UserContext } from "@/context/UserContextProvider";
15-
import { AnswerWithQuestionId, QuizContextProvider } from "@/context/QuizContextProvider";
15+
import { AnswerState, QuizContextProvider } from "@/context/QuizContextProvider";
1616
import Layout from "../Layout/Layout";
1717

1818
import Login from "../Login";
@@ -34,7 +34,7 @@ export const Book = (
3434
const [ isAdmin, setIsAdmin ] = useState<boolean>(false);
3535
const [answers, setAnswers] =
3636
useState<"pending" | null | {
37-
answers: AnswerWithQuestionId[],
37+
answers: AnswerState[],
3838
correctAnswers: CorrectAnswers}>("pending");
3939
const hasGroups = useMemo(() => frontmatter.groups.length > 0, [frontmatter]);
4040
const [groupRequired, setGroupRequired] = useState<boolean | null>(null);
@@ -56,7 +56,7 @@ export const Book = (
5656
) {
5757
return;
5858
}
59-
getAnswers({ accessToken: user.accessToken, bookId, group: userGroup})
59+
getLastAnswers({ accessToken: user.accessToken, bookId, group: userGroup})
6060
.then((response) => {
6161
logger("Quiz answers fetched:", response);
6262
setAnswers(response);

0 commit comments

Comments
 (0)