feat(exam): 4-button nav + overflow menu + resizable + tag auto — 7G.2

This commit is contained in:
reloop
2026-04-12 07:14:32 +09:00
parent 47a70f226b
commit 7c5cdf4c64
3 changed files with 701 additions and 235 deletions

View File

@@ -81,6 +81,8 @@ export class StudyLogsService {
update: {},
});
const tagCache = new Map<string, { id: number }>();
const problemById = new Map(problemSet.problems.map((problem) => [problem.id, problem]));
const seenProblemIds = new Set<number>();
let correct = 0;
@@ -137,8 +139,29 @@ export class StudyLogsService {
if (derivedResult === 'correct') correct += 1;
if (derivedResult === 'incorrect') incorrect += 1;
const tagName = normalizeTagName(problem.topic, problemSet.subjectName);
let tag = tagCache.get(tagName);
if (!tag) {
tag = await tx.tag.upsert({
where: {
subjectId_name: {
subjectId: subject.id,
name: tagName,
},
},
create: {
subjectId: subject.id,
name: tagName,
},
update: {},
select: { id: true },
});
tagCache.set(tagName, tag);
}
const created = await this.createInTransaction(tx, userId, user, {
subjectId: subject.id,
tagId: tag.id,
problemId: problem.id,
title: `${problemSet.title} ${problem.number}`,
difficulty: problem.difficulty,
@@ -351,3 +374,16 @@ function defaultSubjectColor(subjectName: string): string {
return colorMap[subjectName] ?? '#6366f1';
}
function normalizeTagName(
topic: string | null | undefined,
subjectName: string,
): string {
const trimmedTopic = topic?.trim();
if (trimmedTopic) return trimmedTopic;
const trimmedSubject = subjectName.trim();
if (trimmedSubject) return trimmedSubject;
return '미분류';
}

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@ import {
BookBookmark, Function as FunctionIcon, Dna, ClockCounterClockwise, PencilSimple, Archive,
Users, ChalkboardTeacher, Sliders, FilePdf, MoonStars, Devices, Keyboard, Brain, Funnel,
MagnifyingGlass, DownloadSimple, CalendarBlank, CalendarCheck, BellRinging, Bell, Sparkle,
Minus, DotsThree, Translate, BookOpenText, SkipForward, Info, SignOut, Camera, Crown,
Minus, DotsThree, DotsThreeVertical, Translate, BookOpenText, SkipForward, Info, SignOut, Camera, Crown,
Export, Gear, ArrowRight, type IconProps as PhIconProps, type IconWeight,
Scales, Feather, Clock, Flag, CheckSquare, Circle, ArrowLeft, User, Books,
} from '@phosphor-icons/react';
@@ -63,6 +63,7 @@ const ICON_MAP = {
'sparkle': Sparkle,
'minus': Minus,
'dots-three': DotsThree,
'dots-three-vertical': DotsThreeVertical,
'translate': Translate,
'book-open-text': BookOpenText,
'skip': SkipForward,