Skip to content

Commit

Permalink
Feat(BookmarkProblem): 북마크에서 문제풀기 (#28)
Browse files Browse the repository at this point in the history
- 북마크에서 문제를 고르고 문제를 풀러 갈 수 있음
- 선택 문제가 100개 이상 시 선택 불가
- 전체 선택을 누를경우 100개 이상의 문제는 선택지에서 잘림
- 디자인 피드백 적용(pull request참고)
  • Loading branch information
godzz733 authored Jul 30, 2024
1 parent 7052357 commit 73e6953
Show file tree
Hide file tree
Showing 37 changed files with 845 additions and 514 deletions.
5 changes: 0 additions & 5 deletions src/api/apis/mainFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,5 @@ export const mainfetch = async <T>(
response = await fetch(url, { ...fetchOptions, headers });
}

if (!response.ok) {
const errorText = await response.text();
throw new Error(`Error: ${response.status} - ${errorText}`);
}

return response;
};
100 changes: 88 additions & 12 deletions src/app/bookmark/components/bookMarkMain.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";
import { mainfetch } from "@/src/api/apis/mainFetch";
import { NoHoverButton } from "@/src/components/elements/styledElements";
import { MiddleBoxColumn, NoHoverButton } from "@/src/components/elements/styledElements";
import { globalTheme } from "@/src/components/globalStyle";
import useBookmarks from "@/src/hooks/useBookmarks";
import useCertificateInfo from "@/src/hooks/useCertificateInfo";
Expand All @@ -11,8 +11,9 @@ import ExamChoice from "./examChoice";
import BookmarkProblemList from "./problemList";
import SubjectChoice from "./subjectChoice";

const MAX_SELECTED_PROBLEMS = 100;

const BookMarkMain = () => {
const { certificateInfo, loading, error } = useCertificateInfo();
const [selectedExam, setSelectedExam] = useState<string>("전체 회차");
const [problems, setProblems] = useState<BookMarkProblem[]>([]);
const [selectedProblems, setSelectedProblems] = useState<number[]>([]);
Expand All @@ -22,7 +23,7 @@ const BookMarkMain = () => {
const [selectedSubjectsId, setSelectedSubjectsId] = useState<number[]>([]);
const [page, setPage] = useState<number>(0);
const [isProcessing, setIsProcessing] = useState(false);
const { bookmarkedProblems, totalPage } = useBookmarks({
const { bookmarkedProblems, totalPage, isCertified, certificateInfo, loading } = useBookmarks({
selectedExamId,
selectedSubjectsId,
page,
Expand All @@ -31,20 +32,64 @@ const BookMarkMain = () => {
setisModalOpen(prev => !prev);
};

const gotoStudyMode = () => {
// 공부 모드로 이동하는 함수
const gotoStudyMode = async () => {
if (selectedProblems.length === 0) {
return;
}
const getProblmes = async () => {
const problems = await mainfetch(
"/problems/set/query",
{
method: "POST",
body: {
problemIds: selectedProblems,
},
},
true
);
if (!problems.ok) {
new Error("문제를 불러오는데 실패했습니다.");
}
const data = await problems.json();
localStorage.setItem("bookmarkProblems", JSON.stringify(data));
};
await getProblmes();
const path = `/study/bookmark`;
window.location.href = path;
};
const gotoExamMode = () => {
// 시험 모드로 이동하는 함수
const gotoExamMode = async () => {
if (selectedProblems.length === 0) {
return;
}
const getProblmes = async () => {
const problems = await mainfetch(
"/problems/set/query",
{
method: "POST",
body: {
problemIds: selectedProblems,
},
},
true
);
if (!problems.ok) {
new Error("문제를 불러오는데 실패했습니다.");
}
const data = await problems.json();
localStorage.setItem("bookmarkProblems", JSON.stringify(data));
};
await getProblmes();
const path = `/exam/bookmark`;
window.location.href = path;
};

useEffect(() => {
setProblems(bookmarkedProblems);
}, [bookmarkedProblems]);

const selectProblem = (problemId: number) => {
if (selectedProblems.includes(problemId)) {
setSelectedProblems(selectedProblems.filter(id => id !== problemId));
} else {
} else if (selectedProblems.length < MAX_SELECTED_PROBLEMS) {
setSelectedProblems([...selectedProblems, problemId]);
}
};
Expand Down Expand Up @@ -84,7 +129,7 @@ const BookMarkMain = () => {

const selectAllProblems = () => {
const allProblems = problems.map(problem => problem.problemId);
setSelectedProblems(allProblems);
setSelectedProblems(allProblems.slice(0, MAX_SELECTED_PROBLEMS));
};

const deselectAllProblems = () => {
Expand Down Expand Up @@ -140,6 +185,37 @@ const BookMarkMain = () => {
return <div>로딩중...</div>;
}

if (!isCertified) {
window.location.href = "/mypage";
return (
<ThemeProvider theme={globalTheme}>
<Box
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: "100%",
height: "100%",
}}
>
<Typography
variant="h1"
fontSize="28px"
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
}}
>
먼저 자격증을 선택해주세요
</Typography>
</Box>
</ThemeProvider>
);
}

return (
<ThemeProvider theme={globalTheme}>
<Box
Expand Down Expand Up @@ -171,8 +247,8 @@ const BookMarkMain = () => {
borderLeft: "1px solid var(--c-gray2)",
}}
>
<Box sx={{ mb: 2 }}>
<Typography variant="h4" fontSize="28px" mb="51px">
<Box sx={{ mb: "40px" }}>
<Typography variant="h4" fontSize="28px" mb="40px">
북마크
</Typography>
<Box
Expand Down
4 changes: 4 additions & 0 deletions src/app/bookmark/components/bookMarkSize.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import { useMediaQuery, useTheme } from "@mui/material";

import BookMarkMain from "./bookMarkMain";
import MobileBookMarkMain from "./mobileBookMarkMain";
import { useEffect } from "react";

const BookMarkSize = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(960));
useEffect(() => {
localStorage.setItem("focusTap", "북마크");
});
return (
<>
<Appbar />
Expand Down
89 changes: 60 additions & 29 deletions src/app/bookmark/components/mobileBookMarkMain.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
"use client";
import { mainfetch } from "@/src/api/apis/mainFetch";
import { NoHoverButton } from "@/src/components/elements/styledElements";
import { globalTheme } from "@/src/components/globalStyle";
import useBookmarks from "@/src/hooks/useBookmarks";
import useCertificateInfo from "@/src/hooks/useCertificateInfo";
import {
Box,
Button,
Collapse,
Pagination,
SelectChangeEvent,
ThemeProvider,
Typography,
} from "@mui/material";
import { Box, Button, Collapse, SelectChangeEvent, ThemeProvider, Typography } from "@mui/material";
import { useEffect, useState } from "react";
import BookMarkModal from "./bookmarkModal";
import BookMarkSlider from "./bookMarkSlider";
import ExamChoice from "./examChoice";
import BookmarkProblemList from "./problemList";
import SubjectChoice from "./subjectChoice";
import BookMarkSlider from "./bookMarkSlider";
import { globalTheme } from "@/src/components/globalStyle";
import { NoHoverButton } from "@/src/components/elements/styledElements";
import useBookmarks from "@/src/hooks/useBookmarks";
import { mainfetch } from "@/src/api/apis/mainFetch";

const MAX_SELECTED_PROBLEMS = 100;

const MobileBookMarkMain = () => {
const [isSliderOpen, setIsSliderOpen] = useState(false);
const handleSliderOpen = () => {
Expand All @@ -43,11 +38,55 @@ const MobileBookMarkMain = () => {
setisModalOpen(prev => !prev);
};

const gotoStudyMode = () => {
// 공부 모드로 이동하는 함수
const gotoStudyMode = async () => {
if (selectedProblems.length === 0) {
return;
}
const getProblmes = async () => {
const problems = await mainfetch(
"/problems/set/query",
{
method: "POST",
body: {
problemIds: selectedProblems,
},
},
true
);
if (!problems.ok) {
new Error("문제를 불러오는데 실패했습니다.");
}
const data = await problems.json();
localStorage.setItem("bookmarkProblems", JSON.stringify(data));
};
await getProblmes();
const path = `/study/bookmark`;
window.location.href = path;
};
const gotoExamMode = () => {
// 시험 모드로 이동하는 함수
const gotoExamMode = async () => {
if (selectedProblems.length === 0) {
return;
}
const getProblmes = async () => {
const problems = await mainfetch(
"/problems/set/query",
{
method: "POST",
body: {
problemIds: selectedProblems,
},
},
true
);
if (!problems.ok) {
new Error("문제를 불러오는데 실패했습니다.");
}
const data = await problems.json();
localStorage.setItem("bookmarkProblems", JSON.stringify(data));
};
await getProblmes();
const path = `/exam/bookmark`;
window.location.href = path;
};

useEffect(() => {
Expand All @@ -56,7 +95,7 @@ const MobileBookMarkMain = () => {
const selectProblem = (problemId: number) => {
if (selectedProblems.includes(problemId)) {
setSelectedProblems(selectedProblems.filter(id => id !== problemId));
} else {
} else if (selectedProblems.length < MAX_SELECTED_PROBLEMS) {
setSelectedProblems([...selectedProblems, problemId]);
}
};
Expand Down Expand Up @@ -96,7 +135,7 @@ const MobileBookMarkMain = () => {

const selectAllProblems = () => {
const allProblems = problems.map(problem => problem.problemId);
setSelectedProblems(allProblems);
setSelectedProblems(allProblems.slice(0, MAX_SELECTED_PROBLEMS));
};

const deselectAllProblems = () => {
Expand Down Expand Up @@ -194,8 +233,6 @@ const MobileBookMarkMain = () => {
onClick={selectAllProblems}
sx={{
mr: 1,
borderRadius: "40px",
padding: "4px 12px",
}}
>
<Typography
Expand All @@ -209,13 +246,7 @@ const MobileBookMarkMain = () => {
전체 선택
</Typography>
</NoHoverButton>
<NoHoverButton
onClick={deselectAllProblems}
sx={{
borderRadius: "40px",
padding: "4px 12px",
}}
>
<NoHoverButton onClick={deselectAllProblems} sx={{}}>
<Typography
variant="body2"
fontSize={{
Expand Down
Loading

0 comments on commit 73e6953

Please sign in to comment.