diff --git a/src/api/constants/problems.ts b/src/api/constants/problems.ts new file mode 100644 index 00000000..bebf0440 --- /dev/null +++ b/src/api/constants/problems.ts @@ -0,0 +1,127 @@ +import type { Problem } from "../services/types"; + +export const problems: Problem[] = [ + { id: 128, title: "longest-consecutive-sequence", difficulty: "Med" }, + { id: 1, title: "two-sum", difficulty: "Easy" }, + { + id: 3, + title: "longest-substring-without-repeating-characters", + difficulty: "Med", + }, + { id: 5, title: "longest-palindromic-substring", difficulty: "Med" }, + { id: 133, title: "clone-graph", difficulty: "Med" }, + { id: 261, title: "graph-valid-tree", difficulty: "Med" }, + { id: 647, title: "palindromic-substrings", difficulty: "Med" }, + { id: 11, title: "container-with-most-water", difficulty: "Med" }, + { id: 139, title: "word-break", difficulty: "Med" }, + { id: 141, title: "linked-list-cycle", difficulty: "Easy" }, + { id: 268, title: "missing-number", difficulty: "Easy" }, + { id: 15, title: "3sum", difficulty: "Med" }, + { id: 143, title: "reorder-list", difficulty: "Med" }, + { id: 269, title: "alien-dictionary", difficulty: "Hard" }, + { id: 271, title: "encode-and-decode-strings", difficulty: "Med" }, + { id: 19, title: "remove-nth-node-from-end-of-list", difficulty: "Med" }, + { id: 20, title: "valid-parentheses", difficulty: "Easy" }, + { id: 21, title: "merge-two-sorted-lists", difficulty: "Easy" }, + { id: 23, title: "merge-k-sorted-lists", difficulty: "Hard" }, + { id: 152, title: "maximum-product-subarray", difficulty: "Med" }, + { + id: 153, + title: "find-minimum-in-rotated-sorted-array", + difficulty: "Med", + }, + { id: 33, title: "search-in-rotated-sorted-array", difficulty: "Med" }, + { id: 417, title: "pacific-atlantic-water-flow", difficulty: "Med" }, + { id: 39, title: "combination-sum", difficulty: "Med" }, + { id: 295, title: "find-median-from-data-stream", difficulty: "Hard" }, + { + id: 297, + title: "serialize-and-deserialize-binary-tree", + difficulty: "Hard", + }, + { + id: 424, + title: "longest-repeating-character-replacement", + difficulty: "Med", + }, + { id: 300, title: "longest-increasing-subsequence", difficulty: "Med" }, + { id: 48, title: "rotate-image", difficulty: "Med" }, + { id: 49, title: "group-anagrams", difficulty: "Med" }, + { id: 435, title: "non-overlapping-intervals", difficulty: "Med" }, + { id: 53, title: "maximum-subarray", difficulty: "Easy" }, + { id: 54, title: "spiral-matrix", difficulty: "Med" }, + { id: 55, title: "jump-game", difficulty: "Med" }, + { id: 56, title: "merge-intervals", difficulty: "Med" }, + { id: 57, title: "insert-interval", difficulty: "Hard" }, + { id: 572, title: "subtree-of-another-tree", difficulty: "Easy" }, + { id: 62, title: "unique-paths", difficulty: "Med" }, + { id: 190, title: "reverse-bits", difficulty: "Easy" }, + { id: 191, title: "number-of-1-bits", difficulty: "Easy" }, + { id: 322, title: "coin-change", difficulty: "Med" }, + { + id: 323, + title: "number-of-connected-components-in-an-undirected-graph", + difficulty: "Med", + }, + { id: 70, title: "climbing-stairs", difficulty: "Easy" }, + { id: 198, title: "house-robber", difficulty: "Med" }, + { id: 200, title: "number-of-islands", difficulty: "Med" }, + { id: 73, title: "set-matrix-zeroes", difficulty: "Med" }, + { id: 76, title: "minimum-window-substring", difficulty: "Hard" }, + { id: 206, title: "reverse-linked-list", difficulty: "Easy" }, + { id: 79, title: "word-search", difficulty: "Med" }, + { id: 207, title: "course-schedule", difficulty: "Med" }, + { id: 208, title: "implement-trie-prefix-tree", difficulty: "Med" }, + { id: 338, title: "counting-bits", difficulty: "Easy" }, + { + id: 211, + title: "design-add-and-search-words-data-structure", + difficulty: "Med", + }, + { id: 212, title: "word-search-ii", difficulty: "Hard" }, + { id: 213, title: "house-robber-ii", difficulty: "Med" }, + { id: 217, title: "contains-duplicate", difficulty: "Easy" }, + { id: 91, title: "decode-ways", difficulty: "Med" }, + { id: 347, title: "top-k-frequent-elements", difficulty: "Med" }, + { id: 253, title: "meeting-rooms-ii", difficulty: "Med" }, + { id: 98, title: "validate-binary-search-tree", difficulty: "Med" }, + { id: 226, title: "invert-binary-tree", difficulty: "Easy" }, + { id: 100, title: "same-tree", difficulty: "Easy" }, + { id: 1143, title: "longest-common-subsequence", difficulty: "Med" }, + { id: 102, title: "binary-tree-level-order-traversal", difficulty: "Med" }, + { id: 230, title: "kth-smallest-element-in-a-bst", difficulty: "Med" }, + { id: 104, title: "maximum-depth-of-binary-tree", difficulty: "Easy" }, + { + id: 105, + title: "construct-binary-tree-from-preorder-and-inorder-traversal", + difficulty: "Med", + }, + { + id: 235, + title: "lowest-common-ancestor-of-a-binary-search-tree", + difficulty: "Easy", + }, + { id: 238, title: "product-of-array-except-self", difficulty: "Med" }, + { id: 242, title: "valid-anagram", difficulty: "Easy" }, + { id: 371, title: "sum-of-two-integers", difficulty: "Med" }, + { id: 252, title: "meeting-rooms", difficulty: "Easy" }, + { id: 121, title: "best-time-to-buy-and-sell-stock", difficulty: "Easy" }, + { id: 124, title: "binary-tree-maximum-path-sum", difficulty: "Hard" }, + { id: 125, title: "valid-palindrome", difficulty: "Easy" }, +]; + +export const problemMap: Record = problems.reduce( + (map, problem) => { + map[problem.title] = problem; + return map; + }, + {} as Record, +); + +export const problemCounts = problems.reduce( + (acc, problem) => { + acc[problem.difficulty] += 1; + return acc; + }, + { Easy: 0, Med: 0, Hard: 0 }, +); diff --git a/src/api/services/process/processService.test.ts b/src/api/services/process/processService.test.ts index 248ce5f2..68c6cdcc 100644 --- a/src/api/services/process/processService.test.ts +++ b/src/api/services/process/processService.test.ts @@ -2,7 +2,7 @@ import { faker } from "@faker-js/faker"; import { expect, test } from "vitest"; import { mock } from "vitest-mock-extended"; -import { problems } from "../../../constants/problems"; +import { problems } from "../../constants/problems"; import type { Config } from "../../config/types"; import { Grade, MemberIdentity, Submission } from "../types"; import { createProcessService } from "./processService"; diff --git a/src/api/services/process/processService.ts b/src/api/services/process/processService.ts index 5cea736c..88a5bf70 100644 --- a/src/api/services/process/processService.ts +++ b/src/api/services/process/processService.ts @@ -1,4 +1,4 @@ -import { problemMap } from "../../../constants/problems"; +import { problemMap } from "../../constants/problems"; import type { Config } from "../../config/types"; import { Grade, diff --git a/src/api/services/types.ts b/src/api/services/types.ts index 2e973d22..ead7c6c2 100644 --- a/src/api/services/types.ts +++ b/src/api/services/types.ts @@ -22,9 +22,10 @@ export type Submission = { language: string; }; -export type Difficulty = "easy" | "medium" | "hard"; +export type Difficulty = "Easy" | "Med" | "Hard"; export type Problem = { + id: number; title: string; difficulty: Difficulty; }; diff --git a/src/components/Progress/Progress.module.css b/src/components/Progress/Progress.module.css index 73e67e87..13b03227 100644 --- a/src/components/Progress/Progress.module.css +++ b/src/components/Progress/Progress.module.css @@ -1,19 +1,25 @@ .progress { width: 80%; margin: 0 auto; - margin-top: 100px; + margin-top: 120px; + max-width: 1200px; +} + +h1 { + font-size: 24px; } .container { display: flex; justify-content: space-between; + margin-top: 30px; + gap: 20px; } -.profile { +.sideBar { width: 20%; } .problemList { - margin-top: 77px; - width: 80%; + width: 75%; } diff --git a/src/components/Progress/Progress.stories.tsx b/src/components/Progress/Progress.stories.tsx index 14847b5e..4c341e7b 100644 --- a/src/components/Progress/Progress.stories.tsx +++ b/src/components/Progress/Progress.stories.tsx @@ -1,10 +1,34 @@ import type { Meta, StoryObj } from "@storybook/react"; import Progress from "./Progress"; +import { http, HttpResponse } from "msw"; -const meta = { +const meta: Meta = { component: Progress, -} satisfies Meta; + parameters: { + query: { + member: "sunjae95", + }, + msw: { + handlers: [ + http.get("https://api.github.com/orgs/DaleStudy/teams", () => + HttpResponse.json([{ name: "leetcode02" }]), + ), + http.get( + "https://api.github.com/orgs/DaleStudy/teams/leetcode02/members", + () => + HttpResponse.json([ + { + login: "Sunjae95", + avatar_url: + "https://avatars.githubusercontent.com/u/63578094?v=4", + }, + ]), + ), + ], + }, + }, +}; export default meta; -export const Default: StoryObj = {}; +export const Default: StoryObj = {}; diff --git a/src/components/Progress/Progress.test.tsx b/src/components/Progress/Progress.test.tsx index 78c6e991..36964106 100644 --- a/src/components/Progress/Progress.test.tsx +++ b/src/components/Progress/Progress.test.tsx @@ -1,13 +1,37 @@ import { faker } from "@faker-js/faker"; +import { expect } from "vitest"; import { render, screen } from "@testing-library/react"; -import { expect, test, vi } from "vitest"; +import Progress from "./Progress"; import { mock } from "vitest-mock-extended"; -import { type Member, Grade } from "../../api/services/types"; import useMembers from "../../hooks/useMembers"; -import Progress from "./Progress"; +import { test, vi } from "vitest"; +import { type Member, Grade } from "../../api/services/types"; vi.mock("../../hooks/useMembers"); +test("render the site header", () => { + vi.mocked(useMembers).mockReturnValue( + mock({ + isLoading: false, + error: null, + members: [mockMember({ id: "sam" })], + totalCohorts: 3, // Add missing property + filter: { name: "", cohort: null }, // Add missing property + setFilter: vi.fn(), // Add mock function + }), + ); + + vi.stubGlobal("location", { + href: `http://example.com?member=sam`, + search: `?member=sam`, + }); + + render(); + + const header = screen.getByRole("banner"); + expect(header).toBeInTheDocument(); +}); + test("display error message if member is not found", () => { vi.mocked(useMembers).mockReturnValue( mock({ @@ -53,9 +77,9 @@ test("render page when query parameter is passed", async () => { mockedMember.id = mockedQueryParam; mockedMember.name = "soundmin"; mockedMember.solvedProblems = [ - { title: "Problem 1", difficulty: "easy" }, - { title: "Problem 2", difficulty: "medium" }, - { title: "Problem 3", difficulty: "easy" }, + { id: 31, title: "Problem 1", difficulty: "Easy" }, + { id: 52, title: "Problem 2", difficulty: "Med" }, + { id: 30, title: "Problem 3", difficulty: "Hard" }, ]; vi.mocked(useMembers).mockReturnValue( diff --git a/src/components/Progress/Progress.tsx b/src/components/Progress/Progress.tsx index bc11aff9..91dab93c 100644 --- a/src/components/Progress/Progress.tsx +++ b/src/components/Progress/Progress.tsx @@ -1,7 +1,13 @@ -import { getMembers } from "../../api/getMembers"; -import { problemCounts, problemMap } from "../../constants/problems"; import Sidebar from "../Sidebar/Sidebar"; -import Table from "../Table/Table"; +import Footer from "../Footer/Footer"; +import Header from "../Header/Header"; +import { Table } from "../Table/Table"; +import { getMembers } from "../../api/getMembers"; +import { + problems, + problemMap, + problemCounts, +} from "../../api/constants/problems"; import useMembers from "../../hooks/useMembers"; import styles from "./Progress.module.css"; @@ -19,9 +25,9 @@ export default function Progress() { const totalProblems = Object.values(problemMap).length; const { - easy: easyProblemsCount, - medium: mediumProblemsCount, - hard: hardProblemsCount, + Easy: easyProblemsCount, + Med: mediumProblemsCount, + Hard: hardProblemsCount, } = problemCounts; const solvedCounts = member.solvedProblems.reduce( @@ -30,13 +36,13 @@ export default function Progress() { acc.total += 1; return acc; }, - { easy: 0, medium: 0, hard: 0, total: 0 }, + { Easy: 0, Med: 0, Hard: 0, total: 0 }, ); const { - easy: easySolved, - medium: mediumSolved, - hard: hardSolved, + Easy: easySolved, + Med: mediumSolved, + Hard: hardSolved, total: totalSolved, } = solvedCounts; @@ -48,33 +54,12 @@ export default function Progress() { const profileUrl = member.profileUrl || "Logo.png"; - // To be updated, this will be replaced by the real data in a seperate pr. - const mockedProblems = [ - { - id: 1, - title: "Problem 1", - difficulty: "easy", - completed: true, - }, - { - id: 2, - title: "Problem 2", - difficulty: "medium", - completed: false, - }, - { - id: 3, - title: "Problem 3", - difficulty: "hard", - completed: true, - }, - ]; - return (
+

풀이 현황

-
+
- +
+ +
); } diff --git a/src/components/Table/Table.module.css b/src/components/Table/Table.module.css index 103ba561..23645859 100644 --- a/src/components/Table/Table.module.css +++ b/src/components/Table/Table.module.css @@ -34,6 +34,7 @@ tr:nth-child(even) { padding-left: 17px; text-align: left; width: 52%; + font-weight: var(--font-weight-regular); } /* Difficulty column */ @@ -43,6 +44,10 @@ tr:nth-child(even) { width: 25%; } +.difficultyData { + font-weight: var(--font-weight-medium); +} + .easy { color: #1cbaba; } diff --git a/src/components/Table/Table.stories.tsx b/src/components/Table/Table.stories.tsx index 8a30c657..f9dad7ca 100644 --- a/src/components/Table/Table.stories.tsx +++ b/src/components/Table/Table.stories.tsx @@ -1,39 +1,123 @@ import type { Meta, StoryObj } from "@storybook/react"; -import Table from "./Table"; +import { Table } from "./Table"; const meta: Meta = { component: Table, + args: { + problems: [ + { + id: 1, + title: "Two Sum", + difficulty: "Easy", + }, + { + id: 128, + title: "Longest Consecutive Sequence", + difficulty: "Med", + }, + { + id: 133, + title: "Clone Graph", + difficulty: "Med", + }, + { + id: 295, + title: "Find Median From Data Stream", + difficulty: "Hard", + }, + ], + solvedProblems: [ + { + id: 1, + title: "Two Sum", + difficulty: "Easy", + }, + { + id: 133, + title: "Clone Graph", + difficulty: "Med", + }, + ], + }, }; export default meta; -export const Default: StoryObj = { +export const Default: StoryObj = {}; + +export const AllCompleted: StoryObj = { + args: { + problems: [ + { + id: 1, + title: "Two Sum", + difficulty: "Easy", + }, + { + id: 128, + title: "Longest Consecutive Sequence", + difficulty: "Med", + }, + { + id: 133, + title: "Clone Graph", + difficulty: "Med", + }, + { + id: 295, + title: "Find Median From Data Stream", + difficulty: "Hard", + }, + ], + solvedProblems: [ + { + id: 1, + title: "Two Sum", + difficulty: "Easy", + }, + { + id: 128, + title: "Longest Consecutive Sequence", + difficulty: "Med", + }, + { + id: 133, + title: "Clone Graph", + difficulty: "Med", + }, + { + id: 295, + title: "Find Median From Data Stream", + difficulty: "Hard", + }, + ], + }, +}; + +export const NoCompleted: StoryObj = { args: { problems: [ { id: 1, title: "Two Sum", difficulty: "Easy", - completed: true, }, { id: 128, title: "Longest Consecutive Sequence", - difficulty: "Med.", - completed: false, + difficulty: "Med", }, { id: 133, title: "Clone Graph", - difficulty: "Med.", - completed: true, + difficulty: "Med", }, { id: 295, title: "Find Median From Data Stream", difficulty: "Hard", - completed: false, }, ], + solvedProblems: [], }, }; diff --git a/src/components/Table/Table.test.tsx b/src/components/Table/Table.test.tsx index b996c779..536fe63a 100644 --- a/src/components/Table/Table.test.tsx +++ b/src/components/Table/Table.test.tsx @@ -1,21 +1,30 @@ import { render, screen, within } from "@testing-library/react"; import { test, expect } from "vitest"; -import Table from "./Table"; +import { Table } from "./Table"; const problems = [ { id: 128, title: "Longest Consecutive Sequence", difficulty: "Med.", - completed: true, }, - { id: 1, title: "Two Sum", difficulty: "Easy", completed: true }, - { id: 257, title: "Binary Tree Paths", difficulty: "Easy", completed: false }, - { id: 133, title: "Clone Graph", difficulty: "Med.", completed: true }, + { id: 1, title: "Two Sum", difficulty: "Easy" }, + { id: 257, title: "Binary Tree Paths", difficulty: "Easy" }, + { id: 133, title: "Clone Graph", difficulty: "Med." }, +]; + +const solvedProblems = [ + { + id: 128, + title: "Longest Consecutive Sequence", + difficulty: "Med.", + }, + { id: 257, title: "Binary Tree Paths", difficulty: "Easy" }, + { id: 133, title: "Clone Graph", difficulty: "Med." }, ]; test("renders table headers", () => { - render(
); + render(
); expect( screen.getByRole("columnheader", { name: "Problem Title" }), ).toBeInTheDocument(); @@ -28,18 +37,22 @@ test("renders table headers", () => { }); test("renders number of problem rows", () => { - render(
); + render(
); const rows = screen.getAllByRole("row"); - expect(rows).toHaveLength(problems.length + 1); // +1 for the header row + expect(rows).toHaveLength(problems.length + 1); }); test("renders icon for completed/incomplete problems", () => { - render(
); - const rows = screen.getAllByRole("row").slice(1); // Exclude header row + render(
); + + const rows = screen.getAllByRole("row").slice(1); rows.forEach((row, index) => { - const { completed } = problems[index]; - const iconLabel = completed ? "Completed problem" : "Incomplete problem"; - expect(within(row).getByLabelText(iconLabel)).toBeInTheDocument(); + const problem = problems[index]; + const isCompleted = solvedProblems.some((p) => p.id === problem.id); + const iconLabel = isCompleted ? "Completed problem" : "Incomplete problem"; + + const icon = within(row).getByLabelText(iconLabel); + expect(icon).toBeInTheDocument(); }); }); diff --git a/src/components/Table/Table.tsx b/src/components/Table/Table.tsx index 84ff60df..1acf9845 100644 --- a/src/components/Table/Table.tsx +++ b/src/components/Table/Table.tsx @@ -1,67 +1,17 @@ import styles from "./Table.module.css"; -// temporary interface for now until we have data fetching hook interface Problem { id: number; title: string; difficulty: string; - completed: boolean; } interface TableProps { problems: Problem[]; + solvedProblems: Problem[]; } -function getTaskIcon(completed: boolean) { - if (completed) { - return ( - - ); - } else { - return ( - - ); - } -} - -function getDifficultyClass(difficulty: string) { - if (difficulty === "Easy") { - return styles.easy; - } else if (difficulty === "Med.") { - return styles.medium; - } else { - return styles.hard; - } -} - -function Table({ problems }: TableProps) { +export function Table({ problems, solvedProblems }: TableProps) { return (
@@ -91,20 +41,31 @@ function Table({ problems }: TableProps) { {problems.map((problem) => { - const problemIcon = getTaskIcon(problem.completed); + const isCompleted = solvedProblems.some( + (solved) => solved.id === problem.id, + ); + const problemIcon = getTaskIcon(isCompleted); const difficultyClass = getDifficultyClass(problem.difficulty); + const formattedTitle = problem.title.replace(/-/g, " "); + + // Add a period to "Med" only + const difficultyLabel = + problem.difficulty === "Med" + ? `${problem.difficulty}.` + : problem.difficulty; + return ( @@ -116,4 +77,51 @@ function Table({ problems }: TableProps) { ); } -export default Table; +function getTaskIcon(completed: boolean) { + if (completed) { + return ( + + ); + } else { + return ( + + ); + } +} + +function getDifficultyClass(difficulty: string) { + if (difficulty === "Easy") { + return styles.easy; + } else if (difficulty === "Med") { + return styles.medium; + } else { + return styles.hard; + } +} diff --git a/src/constants/problems.ts b/src/constants/problems.ts deleted file mode 100644 index 698781dc..00000000 --- a/src/constants/problems.ts +++ /dev/null @@ -1,107 +0,0 @@ -import type { Problem } from "../api/services/types"; - -export const problems: Problem[] = [ - { title: "3sum", difficulty: "medium" }, - { title: "alien-dictionary", difficulty: "hard" }, - { title: "best-time-to-buy-and-sell-stock", difficulty: "easy" }, - { title: "binary-tree-level-order-traversal", difficulty: "medium" }, - { title: "binary-tree-maximum-path-sum", difficulty: "hard" }, - { title: "climbing-stairs", difficulty: "easy" }, - { title: "clone-graph", difficulty: "medium" }, - { title: "coin-change", difficulty: "medium" }, - { title: "combination-sum", difficulty: "medium" }, - { - title: "construct-binary-tree-from-preorder-and-inorder-traversal", - difficulty: "medium", - }, - { title: "container-with-most-water", difficulty: "medium" }, - { title: "contains-duplicate", difficulty: "easy" }, - { title: "course-schedule", difficulty: "medium" }, - { title: "counting-bits", difficulty: "easy" }, - { title: "decode-ways", difficulty: "medium" }, - { title: "design-add-and-search-words-data-structure", difficulty: "medium" }, - { title: "encode-and-decode-strings", difficulty: "medium" }, - { title: "find-median-from-data-stream", difficulty: "hard" }, - { title: "find-minimum-in-rotated-sorted-array", difficulty: "medium" }, - { title: "group-anagrams", difficulty: "medium" }, - { title: "graph-valid-tree", difficulty: "medium" }, - { title: "house-robber", difficulty: "medium" }, - { title: "house-robber-ii", difficulty: "medium" }, - { title: "implement-trie-prefix-tree", difficulty: "medium" }, - { title: "insert-interval", difficulty: "hard" }, - { title: "invert-binary-tree", difficulty: "easy" }, - { title: "jump-game", difficulty: "medium" }, - { title: "kth-smallest-element-in-a-bst", difficulty: "medium" }, - { title: "linked-list-cycle", difficulty: "easy" }, - { title: "longest-common-subsequence", difficulty: "medium" }, - { title: "longest-consecutive-sequence", difficulty: "medium" }, - { title: "longest-increasing-subsequence", difficulty: "medium" }, - { title: "longest-palindromic-substring", difficulty: "medium" }, - { title: "longest-repeating-character-replacement", difficulty: "medium" }, - { - title: "longest-substring-without-repeating-characters", - difficulty: "medium", - }, - { - title: "lowest-common-ancestor-of-a-binary-search-tree", - difficulty: "easy", - }, - { title: "maximum-depth-of-binary-tree", difficulty: "easy" }, - { title: "maximum-product-subarray", difficulty: "medium" }, - { title: "maximum-subarray", difficulty: "easy" }, - { title: "meeting-rooms", difficulty: "easy" }, - { title: "meeting-rooms-ii", difficulty: "medium" }, - { title: "merge-intervals", difficulty: "medium" }, - { title: "merge-k-sorted-lists", difficulty: "hard" }, - { title: "merge-two-sorted-lists", difficulty: "easy" }, - { title: "minimum-window-substring", difficulty: "hard" }, - { title: "missing-number", difficulty: "easy" }, - { title: "non-overlapping-intervals", difficulty: "medium" }, - { title: "number-of-1-bits", difficulty: "easy" }, - { title: "number-of-islands", difficulty: "medium" }, - { - title: "number-of-connected-components-in-an-undirected-graph", - difficulty: "medium", - }, - { title: "pacific-atlantic-water-flow", difficulty: "medium" }, - { title: "palindromic-substrings", difficulty: "medium" }, - { title: "product-of-array-except-self", difficulty: "medium" }, - { title: "reorder-list", difficulty: "medium" }, - { title: "reverse-bits", difficulty: "easy" }, - { title: "reverse-linked-list", difficulty: "easy" }, - { title: "remove-nth-node-from-end-of-list", difficulty: "medium" }, - { title: "same-tree", difficulty: "easy" }, - { title: "search-in-rotated-sorted-array", difficulty: "medium" }, - { title: "serialize-and-deserialize-binary-tree", difficulty: "hard" }, - { title: "set-matrix-zeroes", difficulty: "medium" }, - { title: "spiral-matrix", difficulty: "medium" }, - { title: "subtree-of-another-tree", difficulty: "easy" }, - { title: "sum-of-two-integers", difficulty: "medium" }, - { title: "top-k-frequent-elements", difficulty: "medium" }, - { title: "two-sum", difficulty: "easy" }, - { title: "unique-paths", difficulty: "medium" }, - { title: "validate-binary-search-tree", difficulty: "medium" }, - { title: "valid-anagram", difficulty: "easy" }, - { title: "valid-palindrome", difficulty: "easy" }, - { title: "valid-parentheses", difficulty: "easy" }, - { title: "word-break", difficulty: "medium" }, - { title: "word-search", difficulty: "medium" }, - { title: "word-search-ii", difficulty: "hard" }, - { title: "rotate-image", difficulty: "medium" }, -]; - -export const problemMap: Record = problems.reduce( - (map, problem) => { - map[problem.title] = problem; - return map; - }, - {} as Record, -); - -export const problemCounts = problems.reduce( - (acc, problem) => { - acc[problem.difficulty] += 1; - return acc; - }, - { easy: 0, medium: 0, hard: 0 }, -); diff --git a/src/hooks/useMembers.test.ts b/src/hooks/useMembers.test.ts index 2749c409..0c01e862 100644 --- a/src/hooks/useMembers.test.ts +++ b/src/hooks/useMembers.test.ts @@ -4,7 +4,7 @@ import { faker } from "@faker-js/faker"; import { Grade, type Member } from "../api/services/types"; import useMembers from "./useMembers"; -import { problems } from "../constants/problems"; +import { problems } from "../api/constants/problems"; function createMockMember(custom: Partial = {}): Member { return {
- {problem.id}. {problem.title} + {problem.id}. {formattedTitle} - {problem.difficulty} + {difficultyLabel} {problemIcon}