diff --git a/src/app/dashboard/utils/order.ts b/src/app/dashboard/utils/order.ts index 3c100bb..fc15784 100644 --- a/src/app/dashboard/utils/order.ts +++ b/src/app/dashboard/utils/order.ts @@ -1,5 +1,5 @@ import { ScrapCardData } from "@/types/scrapCard"; -import { sortByKorean, sortByDateDesc, type SortType } from "@/utils/sorting"; +import { sortByKorean, type SortType } from "@/utils/sorting"; export type { SortType }; @@ -11,7 +11,7 @@ export function sortCards( sortType: SortType ): ScrapCardData[] { if (sortType === "latest") { - return sortByDateDesc(cards, (card) => card.date); + return [...cards].reverse(); } return sortByKorean(cards, (card) => card.term); diff --git a/src/app/quiz/components/QuizResult.tsx b/src/app/quiz/components/QuizResult.tsx index 2db9ce9..a37dce4 100644 --- a/src/app/quiz/components/QuizResult.tsx +++ b/src/app/quiz/components/QuizResult.tsx @@ -27,7 +27,7 @@ export default function QuizResult({ onRetry, }: QuizResultProps) { const { user } = useAuthCore(); - const { toggleScrap, isScraped } = useScrap(); + const { addMultipleToScrap } = useScrap(); const { showToast } = useToast(); const [isRetrying, setIsRetrying] = useState(false); @@ -42,13 +42,8 @@ export default function QuizResult({ } try { - let scrapCount = 0; - for (const question of wrongQuestions) { - if (!isScraped(question.term.id)) { - await toggleScrap(question.term.id); - scrapCount++; - } - } + const termIds = wrongQuestions.map((q) => q.term.id); + const scrapCount = await addMultipleToScrap(termIds); showToast( scrapCount > 0 ? `틀린 문제 ${scrapCount}개를 스크랩했습니다!` diff --git a/src/contexts/auth/ScrapContext.tsx b/src/contexts/auth/ScrapContext.tsx index 1d71647..547592c 100644 --- a/src/contexts/auth/ScrapContext.tsx +++ b/src/contexts/auth/ScrapContext.tsx @@ -16,6 +16,7 @@ interface ScrapContextType { toggleScrap: ( termId: number ) => Promise<{ success: boolean; isScraped: boolean }>; + addMultipleToScrap: (termIds: number[]) => Promise; } const ScrapContext = createContext(null); @@ -78,11 +79,44 @@ export function ScrapProvider({ children }: { children: ReactNode }) { } }; + /** + * 여러 항목을 한 번에 스크랩에 추가 + */ + const addMultipleToScrap = async (termIds: number[]): Promise => { + if (!user || !userData) { + return 0; + } + + // 이미 스크랩된 항목 제외 + const newTermIds = termIds.filter((id) => !userData.scrapList.includes(id)); + + if (newTermIds.length === 0) { + return 0; + } + + const newScrapList = [...userData.scrapList, ...newTermIds]; + + try { + const userRef = doc(db, "users", user.uid); + await updateDoc(userRef, { + scrapList: newScrapList, + }); + + updateScrapList(newScrapList); + + return newTermIds.length; + } catch (error) { + console.error("다중 스크랩 추가 실패:", error); + throw error; + } + }; + return ( {children} diff --git a/src/lib/terms.ts b/src/lib/terms.ts index f840df9..d459609 100644 --- a/src/lib/terms.ts +++ b/src/lib/terms.ts @@ -151,5 +151,8 @@ export async function getRelatedTerms( relatedIds: number[] ): Promise { const index = await getTermsIndex(); - return index.filter((t) => relatedIds.includes(t.id)); + const indexMap = new Map(index.map((t) => [t.id, t])); + return relatedIds + .map((id) => indexMap.get(id)) + .filter(Boolean) as TermIndexItem[]; }