diff --git a/src/constants/Result.ts b/src/constants/Result.ts
new file mode 100644
index 0000000..6963a86
--- /dev/null
+++ b/src/constants/Result.ts
@@ -0,0 +1,83 @@
+export const GetResult = (score: number) => {
+ if (0 <= score && score < 50) {
+ return ResultLow[Math.floor(Math.random() * ResultLow.length)];
+ } else if (50 <= score && score < 80) {
+ return ResultMid[Math.floor(Math.random() * ResultMid.length)];
+ } else if (80 <= score && score < 100) {
+ return ResultHigh[Math.floor(Math.random() * ResultHigh.length)];
+ }
+};
+
+export const ResultLow = [
+ {
+ img: "/img/test-1.png",
+ title: "아니요 뚱인데요",
+ author: "뚱이",
+ },
+ {
+ img: "/img/test-2.png",
+ title: "상상력만 발휘하면 뭐든 할 수 있다구",
+ author: "스폰지밥",
+ },
+ {
+ img: "/img/test-3.png",
+ title: "노는 게 제일 좋아, 친구들 모여라",
+ author: "뽀로로",
+ },
+ {
+ img: "/img/test-4.png",
+ title: "왜 사람들은 보이는 것 너머에 또 보아야 할 것이 있다는 걸 알지 못하지?",
+ author: "슈렉",
+ },
+ {
+ img: "/img/test-5.png",
+ title: "사랑은 많이 양보하는 거야. 그래야 너가 사랑하는 사람을 행복하게 만들 수 있거든",
+ author: "곰돌이 푸",
+ },
+];
+
+export const ResultMid = [
+ {
+ img: "/img/test-6.png",
+ title: "불가능한 경우를 제외하고 남은 것은 아무리 이상하고 믿기지 않더라도 사실이기 마련이야",
+ author: "셜록",
+ },
+ {
+ img: "/img/test-7.png",
+ title: "넌 대단한 마법사야, 난 책과 지혜고요",
+ author: "헤르미온느",
+ },
+ {
+ img: "/img/test-8.png",
+ title: "영웅은 태어나지 않아, 다만 만들어질 뿐이지",
+ author: "아이언맨",
+ },
+];
+
+export const ResultHigh = [
+ {
+ img: "/img/test-9.png",
+ title: "가격이 잘못 매겨진 기회를 찾아라. 그게 바로 투자다. 어떤 기회가 가격이 잘못 매겨진 것인지 충분히 알아야 한다. 그게 가치투자다",
+ author: "찰리멍거",
+ },
+ {
+ img: "/img/test-10.png",
+ title: "포트폴리오를 분산시키세요. 한 번에 모든 것을 거는 것은 위험합니다",
+ author: "레이 달리오",
+ },
+ {
+ img: "/img/test-11.png",
+ title: "공부 없이 투자하는 것은 카드를 보지 않고 포커를 치는 것과 같다",
+ author: "피터 린치",
+ },
+ {
+ img: "/img/test-12.png",
+ title: "잭팟을 터트렸다고 말하는 사람들을 부러워해선 안된다",
+ author: "워렌버핏",
+ },
+ {
+ img: "/img/test-13.png",
+ title: "영리한 투자자의 고전적 정의는 모두가 팔고 있는 약세장에 매수해서 모두가 사고 있는 강세장에서 매도하는 사람이다",
+ author: "벤자민 그레이엄",
+ },
+];
diff --git a/src/interfaces/display/LabelContainer.module.scss b/src/interfaces/display/LabelContainer.module.scss
index 120362e..be7863d 100644
--- a/src/interfaces/display/LabelContainer.module.scss
+++ b/src/interfaces/display/LabelContainer.module.scss
@@ -26,3 +26,14 @@
line-height: 26px;
}
}
+
+@include mobile {
+ .label_container {
+ p {
+ font-size: 14px;
+ }
+ div {
+ font-size: 14px;
+ }
+ }
+}
diff --git a/src/interfaces/forms/RadioButton.module.scss b/src/interfaces/forms/RadioButton.module.scss
index b834ffb..4f93133 100644
--- a/src/interfaces/forms/RadioButton.module.scss
+++ b/src/interfaces/forms/RadioButton.module.scss
@@ -3,8 +3,8 @@
.radio_btn {
position: relative;
- width: 25px;
- height: 25px;
+ width: 24px;
+ height: 24px;
font-family: "SCDream";
@@ -37,8 +37,9 @@
p {
@include vertical-center;
- margin: 0px 5px;
+ margin: 0px 10px;
font-family: "SCDream";
- font-size: 16px;
+ font-size: 16px !important;
+ vertical-align: middle;
}
}
diff --git a/src/interfaces/forms/RadioButton.tsx b/src/interfaces/forms/RadioButton.tsx
index fb226e5..e4f0914 100644
--- a/src/interfaces/forms/RadioButton.tsx
+++ b/src/interfaces/forms/RadioButton.tsx
@@ -7,25 +7,27 @@ import styles from "./RadioButton.module.scss";
export interface IRadioButton {
name: string;
+ value: string;
}
export interface IRadioOption {
name: string;
+ value: string;
label: string;
}
-export const RadioButton = forwardRef
(({ name }, ref) => {
+export const RadioButton = forwardRef(({ name, value }, ref) => {
return (
<>
-
+
>
);
});
-export const RadioOption = forwardRef(({ name, label }, ref) => {
+export const RadioOption = forwardRef(({ name, label, value }, ref) => {
return (
);
diff --git a/src/layouts/TestLayout.module.scss b/src/layouts/TestLayout.module.scss
index a5b192a..c3fbcb9 100644
--- a/src/layouts/TestLayout.module.scss
+++ b/src/layouts/TestLayout.module.scss
@@ -1,7 +1,10 @@
@import "@/styles/utils.scss";
.test_page {
- @include vertical-center;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
width: 100%;
}
diff --git a/src/pages/test-page/QuestionPage.module.scss b/src/pages/test-page/QuestionPage.module.scss
index ca796e5..6584df2 100644
--- a/src/pages/test-page/QuestionPage.module.scss
+++ b/src/pages/test-page/QuestionPage.module.scss
@@ -1,6 +1,8 @@
@import "@/styles/utils";
.question_page {
+ margin: 100px 0px;
+
.title {
text-align: center;
h1 {
@@ -18,7 +20,7 @@
}
.breadcrumb_wrapper {
- margin: 30px 0px;
+ margin: 30px auto;
}
.btn {
@@ -42,4 +44,23 @@
}
@include mobile {
+ .question_page {
+ margin: 50px 0px;
+ .title {
+ h1 {
+ font-size: 40px;
+ }
+ p {
+ font-size: 14px;
+ }
+ }
+ .btn {
+ width: 160px;
+ height: 50px;
+ font-size: 18px;
+ }
+ }
+ .breadcrumb_wrapper {
+ padding: 0px 20px;
+ }
}
diff --git a/src/pages/test-page/QuestionPage.tsx b/src/pages/test-page/QuestionPage.tsx
index 4a365fb..d3ab396 100644
--- a/src/pages/test-page/QuestionPage.tsx
+++ b/src/pages/test-page/QuestionPage.tsx
@@ -6,23 +6,46 @@ import { Question } from "../../components/test-page/Question";
import { questions, questionsPerPage } from "../../constants/Questions";
+import { useDispatch } from "react-redux";
+
import styles from "./QuestionPage.module.scss";
-import { useSelector } from "react-redux";
-import { RootState } from "../../store/store";
+import { Dispatch } from "@reduxjs/toolkit";
+import { UserQuestionActions } from "../../store/user-question-slice";
export default function QuestionPage() {
- const { submittedAnswer } = useSelector((state: RootState) => state.UserQuestion);
-
+ const dispatch: Dispatch = useDispatch();
const navigate = useNavigate();
const [page, setPage] = useState(1);
const onNextBtnClick = () => {
- console.log(page * questionsPerPage, submittedAnswer.length);
- if (page * questionsPerPage !== submittedAnswer.length) {
+ if (document.querySelectorAll(`input[type=radio]:checked`).length !== 5) {
alert("아직 풀지 않은 문항이 있습니다!");
return;
}
+ const startIdx = (page - 1) * questionsPerPage;
+ const endIdx = startIdx + questionsPerPage;
+
+ let pageScore = 0;
+
+ for (let i = startIdx + 1; i < endIdx + 1; i++) {
+ const selectedOption = document.querySelector(`input[name=question-option-${i}]:checked`);
+
+ if (selectedOption) {
+ if (selectedOption.value === questions[i - 1].answer) {
+ pageScore += 1;
+ }
+ }
+ }
+
+ dispatch(UserQuestionActions.setScore({ index: page, score: pageScore }));
+
+ // Clear selected options on the current page
+ for (let i = startIdx + 1; i < endIdx + 1; i++) {
+ const options = document.querySelectorAll(`input[name=question-option-${i}]:checked`);
+ options.forEach((option) => (option.checked = false));
+ }
+
window.scrollTo(0, 0);
if (page === questions.length / questionsPerPage) navigate("/test/result");
else setPage((page) => page + 1);
diff --git a/src/pages/test-page/ResultDetailPage.module.scss b/src/pages/test-page/ResultDetailPage.module.scss
index 0c20bb4..f72c6b7 100644
--- a/src/pages/test-page/ResultDetailPage.module.scss
+++ b/src/pages/test-page/ResultDetailPage.module.scss
@@ -18,3 +18,12 @@
width: inherit;
height: auto;
}
+
+@include mobile {
+ .pros_cons_item {
+ flex-direction: column;
+ div {
+ width: 100% !important;
+ }
+ }
+}
diff --git a/src/pages/test-page/ResultDetailPage.tsx b/src/pages/test-page/ResultDetailPage.tsx
index e2f2c52..d6d9e26 100644
--- a/src/pages/test-page/ResultDetailPage.tsx
+++ b/src/pages/test-page/ResultDetailPage.tsx
@@ -1,8 +1,10 @@
+import domtoimage from "dom-to-image";
+
import { LabelContainer } from "../../interfaces/display/LabelContainer";
import { AvatarSection } from "../../components/test-page/AvatarSection";
-import { ShareSection, ShareItem } from "../../components/test-page/ShareSection";
+import { ShareContainer, ShareItem } from "../../components/test-page/ShareContainer";
import { ProsConsContainer } from "../../components/test-page/ProsConsContainer";
-import { LectureRedirectCard } from "../../components/test-page/LectureRedirectCard";
+import { LectureRedirectCard, LectureRedirectLink } from "../../components/test-page/LectureRedirectCard";
import resultPageStyle from "./ResultPage.module.scss";
import styles from "./ResultDetailPage.module.scss";
@@ -14,15 +16,38 @@ import shareFb from "@/assets/share-fb.png";
import shareLink from "@/assets/share-link.png";
import lectureImg from "@/assets/lecture.png";
+import { useSelector } from "react-redux";
+import { RootState } from "../../store/store";
+import { shareKakaoLink } from "../../utils/ShareKakaoLink";
+
+import { GetResult } from "../../constants/Result";
export default function ResultDetailPage() {
+ const { score } = useSelector((state: RootState) => state.UserQuestion);
+ const result = GetResult(score.reduce((prev, next) => prev + next) / 6);
+
+ const GetCategory = (index: number) => {
+ switch (index) {
+ case 0:
+ return "경제기초";
+ case 1:
+ return "은행상품";
+ case 2:
+ return "카드와 신용";
+ case 3:
+ return "세금";
+ case 4:
+ return "보험";
+ case 5:
+ return "투자";
+ default:
+ return "";
+ }
+ };
+
return (
-
+
@@ -38,24 +63,54 @@ export default function ResultDetailPage() {
-
-
-
-
-
-
-
+
+ {
+ // eslint-disable-next-line, @typescript-eslint/no-unsafe-call
+ domtoimage.toJpeg(document.querySelector(`.${styles.result_page}`) as Node, { quality: 0.95 }).then(function (dataUrl) {
+ const link = document.createElement("a");
+ link.download = "금융역량테스트 결과.jpeg";
+
+ link.href = dataUrl;
+ link.click();
+ });
+ }}
+ />
+ {
+ console.log("click");
+ shareKakaoLink("공유하기", "http://localhost:3000/test");
+ }}
+ />
+ alert("서비스 준비중입니다")} />
+ alert("서비스 준비중입니다")} />
+ {
+ window.navigator.clipboard.writeText("https://stocodi.com/test").then(() => {
+ alert("링크가 클립보드에 복사되었습니다");
+ });
+ }}
+ />
+
);
}
diff --git a/src/pages/test-page/ResultPage.module.scss b/src/pages/test-page/ResultPage.module.scss
index 43d3c0f..59c92e2 100644
--- a/src/pages/test-page/ResultPage.module.scss
+++ b/src/pages/test-page/ResultPage.module.scss
@@ -4,8 +4,6 @@
width: 100%;
max-width: 600px;
- margin: 0px auto;
-
a {
display: block;
@@ -28,3 +26,15 @@
padding: 30px 0px;
background-color: #fafbfd;
}
+
+@include mobile {
+ .result_page {
+ a {
+ font-size: 16px;
+ }
+ }
+
+ .result_section {
+ padding: 20px;
+ }
+}
diff --git a/src/pages/test-page/ResultPage.tsx b/src/pages/test-page/ResultPage.tsx
index 46deab4..5e7f863 100644
--- a/src/pages/test-page/ResultPage.tsx
+++ b/src/pages/test-page/ResultPage.tsx
@@ -1,9 +1,12 @@
-import { useEffect, useState } from "react";
+import domtoimage from "dom-to-image";
+
import { Link } from "react-router-dom";
import { AvatarSection } from "../../components/test-page/AvatarSection";
import { ResultGrid, ResultGridItem, ResultSummary } from "../../components/test-page/ResultSummary";
-import { ShareItem, ShareSection } from "../../components/test-page/ShareSection";
+import { ShareContainer, ShareItem } from "../../components/test-page/ShareContainer";
+
+import { shareKakaoLink } from "../../utils/ShareKakaoLink";
import { faArrowRight } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -22,56 +25,35 @@ import shareKakao from "@/assets/share-kakao.png";
import shareIG from "@/assets/share-ig.png";
import shareFb from "@/assets/share-fb.png";
import shareLink from "@/assets/share-link.png";
+import { useSelector } from "react-redux";
+import { RootState } from "../../store/store";
+import { useEffect } from "react";
+import { PostRequest } from "../../api/Request";
-export interface IScore {
- type_basic: number;
- type_bank: number;
- type_credit: number;
- type_tax: number;
- type_insurance: number;
- type_investment: number;
-}
+import { GetResult } from "../../constants/Result";
export default function ResultPage() {
- const [score, setScore] = useState({
- type_basic: 0,
- type_bank: 0,
- type_credit: 0,
- type_tax: 0,
- type_insurance: 0,
- type_investment: 0,
- });
+ const { score } = useSelector((state: RootState) => state.UserQuestion);
+ const result = GetResult(score.reduce((prev, next) => prev + next) / 6);
useEffect(() => {
- // 문제 채점 로직
- setScore({
- type_basic: 0,
- type_bank: 0,
- type_credit: 0,
- type_tax: 0,
- type_insurance: 0,
- type_investment: 0,
- });
- }, [score]);
+ PostRequest("/statistics/end", {});
+ });
return (
-
+
-
+ prev + next) / 6).toFixed(1)} />
-
-
-
-
-
-
+
+
+
+
+
+
@@ -80,13 +62,39 @@ export default function ResultPage() {
-
-
-
-
-
-
-
+
+ {
+ domtoimage.toJpeg(document.querySelector(`.${styles.result_page}`) as Node, { quality: 0.95 }).then(function (dataUrl) {
+ const link = document.createElement("a");
+ link.download = "금융역량테스트 결과.jpeg";
+ link.href = dataUrl;
+ link.click();
+ });
+ }}
+ />
+ {
+ console.log("click");
+ shareKakaoLink("공유하기", "http://localhost:3000/test");
+ }}
+ />
+ alert("서비스 준비중입니다")} />
+ alert("서비스 준비중입니다")} />
+ {
+ window.navigator.clipboard.writeText("https://stocodi.com/test").then(() => {
+ alert("링크가 클립보드에 복사되었습니다");
+ });
+ }}
+ />
+
);
}
diff --git a/src/pages/test-page/TestPage.module.scss b/src/pages/test-page/TestPage.module.scss
index 0c17051..3636119 100644
--- a/src/pages/test-page/TestPage.module.scss
+++ b/src/pages/test-page/TestPage.module.scss
@@ -51,11 +51,16 @@
text-align: center;
h2 {
- font-family: "Tendra";
+ margin: 5px 0px;
+ font-family: "SCDream";
+ font-weight: normal;
+ font-size: 16px;
}
h1 {
+ margin: 5px 0px;
font-size: 3.5rem;
- font-family: "SCDream";
+ font-size: 60px;
+ font-family: "Tenada";
}
}
@@ -66,12 +71,13 @@
gap: 3px;
width: 100%;
- height: 100%;
place-items: center center;
place-content: center center;
- margin: 30px auto;
+ align-items: flex-start;
+
+ margin: 20px auto;
div {
width: 100%;
@@ -79,10 +85,14 @@
@include place-center;
- line-height: 1;
- font-family: "Tenada";
- font-size: 3.5rem;
- color: #fff;
+ span {
+ position: relative;
+ top: 4px;
+
+ font-family: "Tenada";
+ font-size: 3.5rem;
+ color: #fff;
+ }
background-color: #404040;
}
@@ -108,22 +118,30 @@
padding: 20px 0px;
h2 {
- font-family: "Tendra";
- font-size: 1.2rem;
+ font-family: "SCDream";
+ font-size: 12px;
}
h1 {
font-size: 2.5rem;
- font-family: "SCDream";
+ font-family: "Tenada";
}
}
.grid {
width: auto;
height: auto;
+
+ grid-template-columns: repeat(3, 80px);
+ grid-template-rows: repeat(3, 80px);
gap: 0px;
+
+ margin: 0px auto;
+
div {
width: 90%;
height: 90%;
- font-size: 3rem;
+ span {
+ font-size: 3rem;
+ }
}
.img_grid {
width: 90%;
diff --git a/src/pages/test-page/TestPage.tsx b/src/pages/test-page/TestPage.tsx
index 23bc344..4c3fd0c 100644
--- a/src/pages/test-page/TestPage.tsx
+++ b/src/pages/test-page/TestPage.tsx
@@ -2,6 +2,7 @@ import { useNavigate } from "react-router-dom";
import { Button } from "../../interfaces/forms/Button";
import styles from "./TestPage.module.scss";
+import { PostRequest } from "../../api/Request";
export default function TestPage() {
const navigate = useNavigate();
@@ -14,23 +15,45 @@ export default function TestPage() {
금융역량테스트
-
나
-
의
+
+ 나
+
+
+ 의
+
-
금
+
+ 금
+
-
융
-
점
-
수
-
는
+
+ 융
+
+
+ 점
+
+
+ 수
+
+
+ 는
+