From 745e7e0889bf36d30dbd8a7ef283ba6823c4b764 Mon Sep 17 00:00:00 2001
From: Jungwoo
Date: Mon, 25 Sep 2023 14:55:01 +0900
Subject: [PATCH 01/23] =?UTF-8?q?refactor:=20=EC=A0=84=EC=B2=B4=20?=
=?UTF-8?q?=EC=84=A0=ED=83=9D=EC=9E=90=EB=A5=BC=20=EC=82=AC=EC=9A=A9?=
=?UTF-8?q?=ED=95=B4=20=ED=8F=B0=ED=8A=B8=EB=A5=BC=20=EC=A0=81=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/styles/GlobalStyle.tsx | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/client/src/styles/GlobalStyle.tsx b/client/src/styles/GlobalStyle.tsx
index ce3e6c0fd..255e09133 100644
--- a/client/src/styles/GlobalStyle.tsx
+++ b/client/src/styles/GlobalStyle.tsx
@@ -33,12 +33,17 @@ const GlobalStyle = createGlobalStyle`
* {
scrollbar-width: none;
+ font-family: 'Noto Sans KR', 'Noto Sans' , sans-serif;
&::-webkit-scrollbar {
display: none; /* 크롬, 사파리, 오페라, 엣지 */
}
}
+ body {
+ font-family: 'Noto Sans KR', 'Noto Sans' , sans-serif;
+ }
+
*, :after, :before {
box-sizing: inherit;
}
@@ -67,13 +72,14 @@ const GlobalStyle = createGlobalStyle`
@font-face {
font-family: 'Noto Sans KR';
src: url(${require('../assets/fonts/NotoSansKR-Regular.woff')}) format('woff');
+ unicode-range: U+0020-007E;
}
@font-face {
font-family: 'Noto Sans';
font-display: swap;
src: url(${require('../assets/fonts/NotoSans-Regular.woff')}) format('woff');
- unicode-range: U+0041-005A, U+0061-007A;
+ unicode-range: U+0020-007E;
}
:root {
@@ -91,11 +97,6 @@ const GlobalStyle = createGlobalStyle`
}
body {
- font-family: 'Noto Sans KR', 'Noto Sans' , sans-serif;
-
- button {
- border:none;
- }
}
input {
From 12d781f08c722f23914087807f19b1735ca2e43e Mon Sep 17 00:00:00 2001
From: Jungwoo
Date: Mon, 25 Sep 2023 14:55:53 +0900
Subject: [PATCH 02/23] =?UTF-8?q?refactor:=20=EC=9D=B8=EC=A6=9D/=EC=9D=B8?=
=?UTF-8?q?=EA=B0=80=20=ED=94=8C=EB=A1=9C=EC=9A=B0=EC=9D=98=20=EB=B2=84?=
=?UTF-8?q?=ED=8A=BC=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../components/signUpPage/signUpForm/SignUpForm.styles.ts | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/client/src/components/signUpPage/signUpForm/SignUpForm.styles.ts b/client/src/components/signUpPage/signUpForm/SignUpForm.styles.ts
index ff02e9d37..9dc8d429d 100644
--- a/client/src/components/signUpPage/signUpForm/SignUpForm.styles.ts
+++ b/client/src/components/signUpPage/signUpForm/SignUpForm.styles.ts
@@ -39,12 +39,16 @@ export const BoldText = styled.span`
`;
export const SubmitButton = styled.button`
+ ${({ theme }) => theme.fonts.button1};
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
width: 100%;
height: 3rem;
margin-top: 1rem;
- padding: 1rem;
+ padding: 2rem;
- ${({ theme }) => theme.fonts.button1};
color: ${({ theme }) => theme.colors.white};
background-color: ${({ theme }) => theme.colors.main_dark};
From 84777ac31e1f241671cdcc1adf0d202d9dd14da1 Mon Sep 17 00:00:00 2001
From: Jungwoo
Date: Tue, 26 Sep 2023 17:00:09 +0900
Subject: [PATCH 03/23] =?UTF-8?q?feat:=20Slider=20Compound=20=EC=BB=B4?=
=?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=9D=98=20=EB=BC=88=EB=8C=80=20?=
=?UTF-8?q?=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/components/_common/slider/Slider.tsx | 79 +++++++++++++++++++
1 file changed, 79 insertions(+)
create mode 100644 client/src/components/_common/slider/Slider.tsx
diff --git a/client/src/components/_common/slider/Slider.tsx b/client/src/components/_common/slider/Slider.tsx
new file mode 100644
index 000000000..bb4f72c8f
--- /dev/null
+++ b/client/src/components/_common/slider/Slider.tsx
@@ -0,0 +1,79 @@
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+import React, {
+ Dispatch,
+ PropsWithChildren,
+ SetStateAction,
+ createContext,
+ useContext,
+ useState,
+} from 'react';
+
+type SliderContextType = {
+ curIndex: number;
+ slideToPrevContent: () => void;
+ slideToNextContent: () => void;
+ setCurIndex: Dispatch>;
+ setContentLength: Dispatch>;
+};
+
+const SliderContext = createContext(null);
+
+const Slider = ({ children }: PropsWithChildren) => {
+ const [curIndex, setCurIndex] = useState(0);
+ const [contentLength, setContentLength] = useState(1);
+
+ const isFirstContentIndex = curIndex === 0;
+ const isLastContentIndex = curIndex === contentLength - 1;
+
+ const slideToPrevContent = () => {
+ setCurIndex((prev) => {
+ return isFirstContentIndex ? prev : prev - 1;
+ });
+ };
+
+ const slideToNextContent = () => {
+ setCurIndex((prev) => {
+ return isLastContentIndex ? prev : prev + 1;
+ });
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+const PrevButton = ({ children }: PropsWithChildren) => {
+ const { slideToPrevContent } = useContext(SliderContext)!;
+
+ return ;
+};
+
+const NextButton = ({ children }: PropsWithChildren) => {
+ const { slideToNextContent } = useContext(SliderContext)!;
+
+ return ;
+};
+
+const Contents = ({ children }: PropsWithChildren) => {
+ const { curIndex, setContentLength } = useContext(SliderContext)!;
+ const childrenArray = React.Children.toArray(children);
+ setContentLength(childrenArray.length);
+
+ return {childrenArray[curIndex]};
+};
+
+Slider.PrevButton = PrevButton;
+Slider.NextButton = NextButton;
+Slider.Contents = Contents;
+
+export default Slider;
From ae546f52a2ccae7fe4afbe650043c810f40a3294 Mon Sep 17 00:00:00 2001
From: sh981013s
Date: Tue, 26 Sep 2023 17:57:50 +0900
Subject: [PATCH 04/23] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?=
=?UTF-8?q?=EC=95=88=EB=90=98=EC=96=B4=20=EC=9E=88=EB=8A=94=20=EA=B8=B0?=
=?UTF-8?q?=EC=A4=80=EC=97=90=20accessToken=20=EA=B0=80=EC=A7=80=EA=B3=A0?=
=?UTF-8?q?=20=EC=9E=88=EB=8A=94=EC=A7=80=20=EC=B2=B4=ED=81=AC=ED=95=98?=
=?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/App.tsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/client/src/App.tsx b/client/src/App.tsx
index 42132db37..0bea35225 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -22,6 +22,7 @@ import useToast from '@hooks/_common/useToast';
import OAuthRedirect from './components/loginPage/OAuthRedirect';
import AsyncBoundary from './components/_common/errorBoundary/AsyncBoundary';
import SessionHandler from '@components/_common/sessionHandler/SessionHandler';
+import { getCookie } from '@utils/_common/cookies';
const GoalRoomDashboardPage = lazy(
() => import('@pages/goalRoomDashboardPage/GoalRoomDashboardPage')
@@ -36,9 +37,10 @@ const PrivateRouter = (props: PropsWithChildren) => {
const { userInfo } = useUserInfoContext();
const { triggerToast } = useToast();
const navigate = useNavigate();
+ const accessToken = getCookie('access_token');
useEffect(() => {
- if (userInfo.id === null) {
+ if (userInfo.id === null && !accessToken) {
navigate('/login');
triggerToast({ message: '로그인이 필요한 서비스입니다.' });
}
From 908b3e5f80fa52bf4da5112d5190caf2989fbba1 Mon Sep 17 00:00:00 2001
From: sh981013s
Date: Tue, 26 Sep 2023 18:00:26 +0900
Subject: [PATCH 05/23] =?UTF-8?q?feat:=20privateRouter=20=EA=B8=B0?=
=?UTF-8?q?=EC=A1=B4=20App=20=EC=97=90=EC=84=9C=20=EB=B6=84=EB=A6=AC=20?=
=?UTF-8?q?=ED=9B=84=20=EC=A0=81=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/App.tsx | 28 +++----------------
.../_common/privateRouter/PrivateRouter.tsx | 24 ++++++++++++++++
2 files changed, 28 insertions(+), 24 deletions(-)
create mode 100644 client/src/components/_common/privateRouter/PrivateRouter.tsx
diff --git a/client/src/App.tsx b/client/src/App.tsx
index 0bea35225..3ca656e84 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -1,5 +1,5 @@
-import { lazy, PropsWithChildren, Suspense, useEffect } from 'react';
-import { BrowserRouter, Route, Routes, useNavigate } from 'react-router-dom';
+import { lazy, Suspense } from 'react';
+import { BrowserRouter, Route, Routes } from 'react-router-dom';
import theme from '@styles/theme';
import GlobalStyle from '@styles/GlobalStyle';
import { ThemeProvider } from 'styled-components';
@@ -13,16 +13,13 @@ import RoadmapDetailPage from './pages/roadmapDetailPage/RoadmapDetailPage';
import RoadmapCreatePage from './pages/roadmapCreatePage/RoadmapCreatePage';
import ToastProvider from '@components/_common/toastProvider/ToastProvider';
import MyPage from '@pages/myPage/MyPage';
-import UserInfoProvider, {
- useUserInfoContext,
-} from './components/_providers/UserInfoProvider';
+import UserInfoProvider from './components/_providers/UserInfoProvider';
import RoadmapSearchResult from './components/roadmapListPage/roadmapSearch/RoadmapSearchResult';
import MainPage from '@pages/mainPage/MainPage';
-import useToast from '@hooks/_common/useToast';
import OAuthRedirect from './components/loginPage/OAuthRedirect';
import AsyncBoundary from './components/_common/errorBoundary/AsyncBoundary';
import SessionHandler from '@components/_common/sessionHandler/SessionHandler';
-import { getCookie } from '@utils/_common/cookies';
+import PrivateRouter from '@components/_common/privateRouter/PrivateRouter';
const GoalRoomDashboardPage = lazy(
() => import('@pages/goalRoomDashboardPage/GoalRoomDashboardPage')
@@ -32,23 +29,6 @@ const GoalRoomCreatePage = lazy(
() => import('@pages/goalRoomCreatePage/GoalRoomCreatePage')
);
-const PrivateRouter = (props: PropsWithChildren) => {
- const { children } = props;
- const { userInfo } = useUserInfoContext();
- const { triggerToast } = useToast();
- const navigate = useNavigate();
- const accessToken = getCookie('access_token');
-
- useEffect(() => {
- if (userInfo.id === null && !accessToken) {
- navigate('/login');
- triggerToast({ message: '로그인이 필요한 서비스입니다.' });
- }
- }, [userInfo.id, navigate]);
-
- return <>{children}>;
-};
-
const App = () => {
return (
diff --git a/client/src/components/_common/privateRouter/PrivateRouter.tsx b/client/src/components/_common/privateRouter/PrivateRouter.tsx
new file mode 100644
index 000000000..c02e0323d
--- /dev/null
+++ b/client/src/components/_common/privateRouter/PrivateRouter.tsx
@@ -0,0 +1,24 @@
+import { PropsWithChildren, useEffect } from 'react';
+import { useUserInfoContext } from '@components/_providers/UserInfoProvider';
+import useToast from '@hooks/_common/useToast';
+import { useNavigate } from 'react-router-dom';
+import { getCookie } from '@utils/_common/cookies';
+
+const PrivateRouter = (props: PropsWithChildren) => {
+ const { children } = props;
+ const { userInfo } = useUserInfoContext();
+ const { triggerToast } = useToast();
+ const navigate = useNavigate();
+ const accessToken = getCookie('access_token');
+
+ useEffect(() => {
+ if (userInfo.id === null && !accessToken) {
+ navigate('/login');
+ triggerToast({ message: '로그인이 필요한 서비스입니다.' });
+ }
+ }, [userInfo.id, navigate]);
+
+ return <>{children}>;
+};
+
+export default PrivateRouter;
From bb3d8bd07fef102c971f215dc7d3f0ebfcfb43f8 Mon Sep 17 00:00:00 2001
From: Jungwoo
Date: Thu, 28 Sep 2023 22:16:45 +0900
Subject: [PATCH 06/23] =?UTF-8?q?feat:=20Slider=EC=97=90=20=EA=B8=B0?=
=?UTF-8?q?=EB=B3=B8=20=EC=8A=A4=ED=83=80=EC=9D=BC=EC=9D=84=20=EC=A0=81?=
=?UTF-8?q?=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/components/_common/slider/Slider.tsx | 43 ++++++++++++++++---
.../_common/slider/Sliders.styles.ts | 23 ++++++++++
2 files changed, 61 insertions(+), 5 deletions(-)
create mode 100644 client/src/components/_common/slider/Sliders.styles.ts
diff --git a/client/src/components/_common/slider/Slider.tsx b/client/src/components/_common/slider/Slider.tsx
index bb4f72c8f..ef2409b92 100644
--- a/client/src/components/_common/slider/Slider.tsx
+++ b/client/src/components/_common/slider/Slider.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/no-array-index-key */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import React, {
Dispatch,
@@ -7,6 +8,7 @@ import React, {
useContext,
useState,
} from 'react';
+import * as S from './Sliders.styles';
type SliderContextType = {
curIndex: number;
@@ -47,7 +49,7 @@ const Slider = ({ children }: PropsWithChildren) => {
setContentLength,
}}
>
- {children}
+ {children}
);
};
@@ -55,21 +57,52 @@ const Slider = ({ children }: PropsWithChildren) => {
const PrevButton = ({ children }: PropsWithChildren) => {
const { slideToPrevContent } = useContext(SliderContext)!;
- return ;
+ if (!React.isValidElement(children)) {
+ throw new Error('React Element children이 필요합니다');
+ }
+
+ // React.isValidElement는 런타임에 대상이 유요한 React Element인지 확인하기 때문에 as 키워드를 사용한 타입 단언이 필요합니다
+ return React.cloneElement(children as React.ReactElement, {
+ onClick: slideToPrevContent,
+ style: {
+ position: 'absolute',
+ zIndex: 1,
+ ...children.props.style,
+ },
+ });
};
const NextButton = ({ children }: PropsWithChildren) => {
const { slideToNextContent } = useContext(SliderContext)!;
- return ;
+ if (!React.isValidElement(children)) {
+ throw new Error('React Element children이 필요합니다');
+ }
+
+ return React.cloneElement(children as React.ReactElement, {
+ onClick: slideToNextContent,
+ style: {
+ position: 'absolute',
+ zIndex: 1,
+ right: 0,
+ ...children.props.style,
+ },
+ });
};
const Contents = ({ children }: PropsWithChildren) => {
const { curIndex, setContentLength } = useContext(SliderContext)!;
- const childrenArray = React.Children.toArray(children);
+ // ReactElement이길 기대하지만 다른 타입이 오더라도(string 등) 정상적으로 동작합니다
+ const childrenArray = React.Children.toArray(children) as React.ReactElement[];
setContentLength(childrenArray.length);
- return {childrenArray[curIndex]};
+ return (
+
+ {childrenArray.map((child, index) => (
+ {child}
+ ))}
+
+ );
};
Slider.PrevButton = PrevButton;
diff --git a/client/src/components/_common/slider/Sliders.styles.ts b/client/src/components/_common/slider/Sliders.styles.ts
new file mode 100644
index 000000000..d09b67136
--- /dev/null
+++ b/client/src/components/_common/slider/Sliders.styles.ts
@@ -0,0 +1,23 @@
+import styled from 'styled-components';
+
+export const Slider = styled.div`
+ position: relative;
+
+ overflow: hidden;
+ display: flex;
+ align-items: center;
+
+ width: 100%;
+`;
+
+export const Contents = styled.article<{ curIndex: number; length: number }>`
+ transform: ${({ curIndex }) => `translateX(${-curIndex * 100}%)`};
+ display: flex;
+ width: ${({ length }) => `${length * 100}%`};
+ transition: transform 0.3s ease;
+`;
+
+export const Content = styled.div`
+ flex-shrink: 0;
+ width: 100%;
+`;
From 53ec1228556f46dee5cc97e7d586d8ea5f8b357f Mon Sep 17 00:00:00 2001
From: Jungwoo
Date: Fri, 29 Sep 2023 16:40:18 +0900
Subject: [PATCH 07/23] =?UTF-8?q?refactor:=20media=20desktop=EC=9D=98=20?=
=?UTF-8?q?=EC=A0=9C=EC=95=BD=EC=A1=B0=EA=B1=B4=EC=9D=84=20min-width?=
=?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/styles/media.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/src/styles/media.ts b/client/src/styles/media.ts
index 1efe3875d..1ea234e2f 100644
--- a/client/src/styles/media.ts
+++ b/client/src/styles/media.ts
@@ -30,7 +30,7 @@ const media = {
`,
desktop: (styles: TemplateStringsArray) => css`
- @media (max-width: ${BREAK_POINTS.DESKTOP}px) {
+ @media (min-width: ${BREAK_POINTS.DESKTOP}px) {
${styles}
}
`,
From b5c0d1537d351c147e62dc4d8fe90974d414ff81 Mon Sep 17 00:00:00 2001
From: Jungwoo
Date: Fri, 29 Sep 2023 16:54:25 +0900
Subject: [PATCH 08/23] =?UTF-8?q?refactor:=20css``=EB=A1=9C=20=EB=84=98?=
=?UTF-8?q?=EA=B8=B4=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EA=B5=AC=EB=AC=B8?=
=?UTF-8?q?=EC=9D=B4=20=EB=8F=99=EC=9E=91=ED=95=A0=20=EC=88=98=20=EC=9E=88?=
=?UTF-8?q?=EB=8F=84=EB=A1=9D=20=ED=83=80=EC=9E=85=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
client/src/styles/media.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/client/src/styles/media.ts b/client/src/styles/media.ts
index 1ea234e2f..6bb9ba128 100644
--- a/client/src/styles/media.ts
+++ b/client/src/styles/media.ts
@@ -1,4 +1,4 @@
-import { css } from 'styled-components';
+import { RuleSet, css } from 'styled-components';
import BREAK_POINTS from '@constants/_common/breakPoints';
/*
@@ -17,19 +17,19 @@ import BREAK_POINTS from '@constants/_common/breakPoints';
*/
const media = {
- mobile: (styles: TemplateStringsArray) => css`
+ mobile: (styles: TemplateStringsArray | RuleSet
+
+
본문
+ {roadmapInfo.content.content === ''
+ ? '로드맵에 대한 설명이 없어요🥲'
+ : roadmapInfo.content.content}
+
+
+ {showMoreButton && !isExpanded && (
+ <>
+
+ 더 보기
+ >
+ )}
+
+ );
+};
+
+export default Introduction;
From e01e873566b684429c242fd2be1cfa8adb86299a Mon Sep 17 00:00:00 2001
From: Jungwoo
Date: Sat, 30 Sep 2023 17:29:49 +0900
Subject: [PATCH 17/23] =?UTF-8?q?feat:=20NodeContent(=EA=B0=81=20=EB=85=B8?=
=?UTF-8?q?=EB=93=9C=20=EC=A0=95=EB=B3=B4=20Slider)=20=EC=BB=B4=ED=8F=AC?=
=?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../nodeContent/NodeContent.styles.ts | 92 +++++++++++++++++++
.../nodeContent/NodeContent.tsx | 38 ++++++++
2 files changed, 130 insertions(+)
create mode 100644 client/src/components/roadmapDetailPage/nodeContent/NodeContent.styles.ts
create mode 100644 client/src/components/roadmapDetailPage/nodeContent/NodeContent.tsx
diff --git a/client/src/components/roadmapDetailPage/nodeContent/NodeContent.styles.ts b/client/src/components/roadmapDetailPage/nodeContent/NodeContent.styles.ts
new file mode 100644
index 000000000..9db8597f8
--- /dev/null
+++ b/client/src/components/roadmapDetailPage/nodeContent/NodeContent.styles.ts
@@ -0,0 +1,92 @@
+import styled from 'styled-components';
+import media from '@styles/media';
+
+export const SliderContent = styled.div`
+ display: flex;
+ aspect-ratio: 5 / 3.5;
+ background-color: ${({ theme }) => theme.colors.gray100};
+ border-radius: 8px;
+
+ ${media.mobile`
+ flex-direction: column;
+ aspect-ratio: 0;
+ `}
+`;
+
+export const LeftContent = styled.div`
+ flex-shrink: 0;
+ width: 45%;
+
+ ${media.mobile`
+ display:none;
+ `}
+`;
+
+export const NodeImg = styled.img`
+ width: 100%;
+ height: 100%;
+ padding: 1.5rem;
+ object-fit: cover;
+`;
+
+export const NoImg = styled.div`
+ ${({ theme }) => theme.fonts.title_large}
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+
+ width: 100%;
+ height: 100%;
+`;
+
+export const Separator = styled.div`
+ display: flex;
+ flex-direction: column;
+ width: 0.2rem;
+ height: 100%;
+
+ & > div {
+ height: 50%;
+ }
+
+ & > div:last-child {
+ background-color: black;
+ }
+`;
+
+export const RightContent = styled.div`
+ ${({ theme }) => theme.fonts.h1}
+ overflow: scroll;
+ width: 55%;
+ padding: 1.5rem;
+ padding-top: 3rem;
+
+ ${media.mobile`
+ width: 100%;
+ height: 60rem;
+ padding-top: 1.5rem;
+ `}
+`;
+
+export const ContentTitle = styled.div`
+ ${({ theme }) => theme.fonts.title_large}
+ display: flex;
+ align-items: center;
+ margin-bottom: 1rem;
+`;
+
+export const Step = styled.div`
+ ${({ theme }) => theme.fonts.h2}
+ display: flex;
+ flex-shrink: 0;
+ align-items: center;
+ justify-content: center;
+
+ width: 3rem;
+ height: 3rem;
+ margin-right: 0.5rem;
+
+ border: 0.3rem solid black;
+ border-radius: 50%;
+`;
diff --git a/client/src/components/roadmapDetailPage/nodeContent/NodeContent.tsx b/client/src/components/roadmapDetailPage/nodeContent/NodeContent.tsx
new file mode 100644
index 000000000..f2ffb7e60
--- /dev/null
+++ b/client/src/components/roadmapDetailPage/nodeContent/NodeContent.tsx
@@ -0,0 +1,38 @@
+import type { NodeType } from '@myTypes/roadmap/internal';
+import * as S from './NodeContent.styles';
+import SVGIcon from '@components/icons/SVGIcon';
+
+type NodeContentProps = {
+ node: NodeType;
+ index: number;
+};
+
+const NodeContent = ({ node, index }: NodeContentProps) => {
+ return (
+
+
+ {node.imageUrls[0] ? (
+
+ ) : (
+
+
+ No Image
+
+ )}
+
+
+
+
+
+
+
+ {index + 1}
+ {node.title}
+
+ {node.description}
+
+
+ );
+};
+
+export default NodeContent;
From efe0c38d7169a70d7eb6482c48549a3f8f10bf78 Mon Sep 17 00:00:00 2001
From: Jungwoo
Date: Sat, 30 Sep 2023 17:30:31 +0900
Subject: [PATCH 18/23] =?UTF-8?q?feat:=20=EB=A1=9C=EB=93=9C=EB=A7=B5=20?=
=?UTF-8?q?=EB=94=94=ED=85=8C=EC=9D=BC=20=EC=BB=B4=ED=8F=AC=EB=84=8C?=
=?UTF-8?q?=ED=8A=B8=20UI=20=EA=B0=9C=ED=8E=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../roadmapDetail/RoadmapDetail.styles.ts | 41 ++-------
.../roadmapDetail/RoadmapDetail.tsx | 46 +++++-----
.../roadmapNodeList/RoadmapNodeList.tsx | 35 --------
.../roadmapNodeList/roadmapNodeList.styles.ts | 89 -------------------
4 files changed, 30 insertions(+), 181 deletions(-)
delete mode 100644 client/src/components/roadmapDetailPage/roadmapNodeList/RoadmapNodeList.tsx
delete mode 100644 client/src/components/roadmapDetailPage/roadmapNodeList/roadmapNodeList.styles.ts
diff --git a/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.styles.ts b/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.styles.ts
index f7ee43222..ce6785c43 100644
--- a/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.styles.ts
+++ b/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.styles.ts
@@ -1,42 +1,19 @@
-import media from '@styles/media';
import styled from 'styled-components';
export const RoadmapDetail = styled.div`
- position: relative;
- margin: 4rem 0;
- padding: 0 2rem;
-
- ${media.mobile`
- flex-direction: column;
- align-items: center;
- `}
+ padding: 2rem 0 4rem 0;
`;
-export const RoadmapBody = styled.p`
- ${({ theme }) => theme.fonts.button1}
- width: 50%;
- padding: 4rem 4rem;
- height: 35rem;
-
- overflow: scroll;
-
- border-radius: 18px;
- box-shadow: ${({ theme }) => theme.shadows.box};
-
- color: ${({ theme }) => theme.colors.gray300};
-
- ${media.mobile`
- padding: 4rem 4rem;
- `}
+export const RoadmapInfo = styled.div`
+ margin-bottom: 4rem;
+`;
- & > strong {
- ${({ theme }) => theme.fonts.h1};
- margin-bottom: 4rem;
- color: ${({ theme }) => theme.colors.main_dark};
- }
+export const Title = styled.div`
+ ${({ theme }) => theme.fonts.title_large};
+ margin-bottom: 2rem;
+ color: ${({ theme }) => theme.colors.main_dark};
`;
-export const PageOnTop = styled.div`
+export const Description = styled.div`
display: flex;
- justify-content: space-around;
`;
diff --git a/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.tsx b/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.tsx
index 94da78baa..76ee29aec 100644
--- a/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.tsx
+++ b/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.tsx
@@ -1,36 +1,32 @@
-import RoadmapItem from '../../_common/roadmapItem/RoadmapItem';
-import Button from '../../_common/button/Button';
import * as S from './RoadmapDetail.styles';
-import useValidParams from '@/hooks/_common/useValidParams';
-import { useNavigate } from 'react-router-dom';
-import { useRoadmapDetail } from '@/hooks/queries/roadmap';
-import RoadmapNodeList from '../roadmapNodeList/RoadmapNodeList';
+import useValidParams from '@hooks/_common/useValidParams';
+// import { useNavigate } from 'react-router-dom';
+import { useRoadmapDetail } from '@hooks/queries/roadmap';
+
+import Slider from '@components/_common/slider/Slider';
+import NodeContent from '../nodeContent/NodeContent';
+import ExtraInfo from '../extraInfo/ExtraInfo';
+import Introduction from '../introduction/Introduction';
const RoadmapDetail = () => {
const { id: roadmapId } = useValidParams<{ id: string }>();
- const navigate = useNavigate();
+ // const navigate = useNavigate();
const { roadmapInfo } = useRoadmapDetail(Number(roadmapId));
- const moveToGoalRoomCreatePage = () => {
- navigate(`/roadmap/${roadmapId}/goalroom-create`);
- };
-
return (
-
-
-
- 로드맵 설명
- {roadmapInfo.content.content === ''
- ? '로드맵에 대한 설명이 없어요🥲'
- : roadmapInfo.content.content}
-
-
-
-
+
+ {roadmapInfo.roadmapTitle}
+
+
+
+
+
+
+ {roadmapInfo.content.nodes.map((node, index) => (
+
+ ))}
+
);
};
diff --git a/client/src/components/roadmapDetailPage/roadmapNodeList/RoadmapNodeList.tsx b/client/src/components/roadmapDetailPage/roadmapNodeList/RoadmapNodeList.tsx
deleted file mode 100644
index 2f6ab88d6..000000000
--- a/client/src/components/roadmapDetailPage/roadmapNodeList/RoadmapNodeList.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { NodeType } from '@/myTypes/roadmap/internal';
-import * as S from './roadmapNodeList.styles';
-
-type RoadmapNodeListProps = {
- roadmapTitle: string;
- nodeInfo: NodeType[];
-};
-
-const RoadmapNodeList = ({ roadmapTitle, nodeInfo }: RoadmapNodeListProps) => {
- return (
-
-
- 🐘 {roadmapTitle}의 로드맵 🐘
-
- {nodeInfo.map((node, index) => {
- return (
-
- {index + 1}
-
- {node.title}
- {node.description}
-
- {node.imageUrls.map((nodeImage) => {
- return ;
- })}
-
-
-
- );
- })}
-
- );
-};
-
-export default RoadmapNodeList;
diff --git a/client/src/components/roadmapDetailPage/roadmapNodeList/roadmapNodeList.styles.ts b/client/src/components/roadmapDetailPage/roadmapNodeList/roadmapNodeList.styles.ts
deleted file mode 100644
index da3d3cd20..000000000
--- a/client/src/components/roadmapDetailPage/roadmapNodeList/roadmapNodeList.styles.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { styled } from 'styled-components';
-
-export const RoadmapNodeList = styled.div`
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: space-around;
-
- width: 100%;
- min-height: 30rem;
- margin-top: 3rem;
- padding: 2rem 0;
-
- border-radius: 12px;
- box-shadow: ${({ theme }) => theme.shadows.box};
-`;
-
-export const Title = styled.h1`
- ${({ theme }) => theme.fonts.nav_title}
- color: ${({ theme }) => theme.colors.gray300};
-
- & > strong {
- color: ${({ theme }) => theme.colors.main_dark};
- }
-`;
-
-export const NodeItemContainer = styled.article`
- display: flex;
- align-items: center;
- justify-content: space-around;
- margin-top: 2rem;
-`;
-
-export const NodeIndicator = styled.div`
- ${({ theme }) => theme.fonts.nav_title}
- position: relative;
- left: 2rem;
-
- display: flex;
- align-items: center;
- justify-content: center;
-
- width: 4rem;
- height: 4rem;
-
- color: ${({ theme }) => theme.colors.white};
-
- background-color: ${({ theme }) => theme.colors.main_dark};
- border-radius: 50%;
-`;
-
-export const NodeContent = styled.div`
- overflow-y: scroll;
- display: flex;
- flex-direction: column;
- align-items: center;
-
- width: 50rem;
- padding: 2rem 0;
-
- word-wrap: break-word;
- overflow-wrap: break-word;
- white-space: normal;
-
- border: 0.3rem solid ${({ theme }) => theme.colors.main_dark};
- border-radius: 24px;
-`;
-
-export const NodeTitle = styled.h2`
- ${({ theme }) => theme.fonts.h2}
- color: ${({ theme }) => theme.colors.black};
-`;
-
-export const NodeDescription = styled.div`
- ${({ theme }) => theme.fonts.description5}
- width: 40rem;
- color: ${({ theme }) => theme.colors.gray300};
- text-align: center;
-`;
-
-export const ImageWrapper = styled.div`
- display: flex;
-`;
-
-export const NodeImage = styled.img`
- width: 15rem;
- height: 20rem;
- object-fit: cover;
-`;
From 1e1a180a605eb467e91cdab518f38db5bce56dea Mon Sep 17 00:00:00 2001
From: NaveOWO <87578512+NaveOWO@users.noreply.github.com>
Date: Sat, 30 Sep 2023 23:32:05 +0900
Subject: [PATCH 19/23] =?UTF-8?q?[feat/CK-213]=20=EB=A1=9C=EB=93=9C?=
=?UTF-8?q?=EB=A7=B5=20=EA=B2=80=EC=83=89=20=EC=98=A4=EB=A5=98=EB=A5=BC=20?=
=?UTF-8?q?=ED=95=B4=EA=B2=B0=ED=95=9C=EB=8B=A4.=20(#172)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: enter키로 검색하는 로직 추가
* feat: no result 페이지 생성
* feat: 검색결과 초기화할 때 검색어 초기화로직 추가
* refactor: 검색바 form으로 변경
* refactor: 구조분해할당
---
.../roadmapList/RoadmapList.tsx | 4 +--
.../roadmapSearch/NoResult.tsx | 7 ++++++
.../roadmapSearch/RoadmapSearch.tsx | 14 ++++++++---
.../roadmapSearch/RoadmapSearchResult.tsx | 25 +++++++++++--------
.../roadmapSearch/roadmapSearch.styles.ts | 16 +++++++++++-
5 files changed, 48 insertions(+), 18 deletions(-)
create mode 100644 client/src/components/roadmapListPage/roadmapSearch/NoResult.tsx
diff --git a/client/src/components/roadmapListPage/roadmapList/RoadmapList.tsx b/client/src/components/roadmapListPage/roadmapList/RoadmapList.tsx
index 166299b20..221a65953 100644
--- a/client/src/components/roadmapListPage/roadmapList/RoadmapList.tsx
+++ b/client/src/components/roadmapListPage/roadmapList/RoadmapList.tsx
@@ -20,7 +20,7 @@ const RoadmapList = ({ selectedCategoryId }: RoadmapListProps) => {
});
const loadMoreRef = useInfiniteScroll({
- hasNextPage: roadmapListResponse?.hasNext,
+ hasNextPage: roadmapListResponse.hasNext,
fetchNextPage,
});
@@ -35,7 +35,7 @@ const RoadmapList = ({ selectedCategoryId }: RoadmapListProps) => {
{roadmapListResponse.responses.map((item) => (
))}
- {roadmapListResponse?.hasNext && }
+ {roadmapListResponse.hasNext && }
+
);
diff --git a/client/src/components/roadmapListPage/roadmapSearch/NoResult.tsx b/client/src/components/roadmapListPage/roadmapSearch/NoResult.tsx
new file mode 100644
index 000000000..45bcb5ef5
--- /dev/null
+++ b/client/src/components/roadmapListPage/roadmapSearch/NoResult.tsx
@@ -0,0 +1,7 @@
+import * as S from './roadmapSearch.styles';
+
+const NoResult = () => {
+ return 검색결과가 존재하지 않습니다. 😭;
+};
+
+export default NoResult;
diff --git a/client/src/components/roadmapListPage/roadmapSearch/RoadmapSearch.tsx b/client/src/components/roadmapListPage/roadmapSearch/RoadmapSearch.tsx
index 0a97e2943..635c02c44 100644
--- a/client/src/components/roadmapListPage/roadmapSearch/RoadmapSearch.tsx
+++ b/client/src/components/roadmapListPage/roadmapSearch/RoadmapSearch.tsx
@@ -1,6 +1,6 @@
import { SearchIcon } from '@/components/icons/svgIcons';
import { Select } from '@/components/roadmapCreatePage/selector/SelectBox';
-import { useRef, useState } from 'react';
+import { FormEvent, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import * as S from './roadmapSearch.styles';
@@ -24,11 +24,17 @@ const RoadmapSearch = () => {
}
};
- const searchRoadmap = () => {
+ const searchRoadmap = (e: FormEvent) => {
+ e.preventDefault();
+ if (searchWordRef.current?.value === '') return;
+
navigate(`/roadmap-list/${searchCategory}/${searchWordRef.current?.value}`);
};
const resetSearchResult = () => {
+ if (searchWordRef.current === null) return;
+
+ searchWordRef.current.value = '';
navigate('/roadmap-list');
};
@@ -52,7 +58,7 @@ const RoadmapSearch = () => {
(으)로 검색하기
-
+ ) => searchRoadmap(e)}>
{
ref={searchWordRef}
/>
-
+
diff --git a/client/src/components/roadmapListPage/roadmapSearch/RoadmapSearchResult.tsx b/client/src/components/roadmapListPage/roadmapSearch/RoadmapSearchResult.tsx
index 4382412b1..2f81bdc0a 100644
--- a/client/src/components/roadmapListPage/roadmapSearch/RoadmapSearchResult.tsx
+++ b/client/src/components/roadmapListPage/roadmapSearch/RoadmapSearchResult.tsx
@@ -4,34 +4,37 @@ import { useSearchRoadmapList } from '@/hooks/queries/roadmap';
import { useInfiniteScroll } from '@/hooks/_common/useInfiniteScroll';
import useValidParams from '@/hooks/_common/useValidParams';
import { useNavigate } from 'react-router-dom';
+import NoResult from './NoResult';
import * as S from './roadmapSearch.styles';
const RoadmapSearchResult = () => {
const { category, search } = useValidParams();
-
+ const navigate = useNavigate();
const { searchRoadmapListResponse, fetchNextPage } = useSearchRoadmapList({
category,
search,
});
+ const { hasNext, responses: roadmapList } = searchRoadmapListResponse;
const loadMoreRef = useInfiniteScroll({
- hasNextPage: searchRoadmapListResponse?.hasNext,
+ hasNextPage: hasNext,
fetchNextPage,
});
- const navigate = useNavigate();
-
const moveRoadmapCreatePage = () => {
navigate('/roadmap-create');
};
return (
-
- {searchRoadmapListResponse.responses.map((item) => (
-
- ))}
- {searchRoadmapListResponse?.hasNext && }
- +
-
+ <>
+ {roadmapList.length === 0 && }
+
+ {roadmapList.map((item) => (
+
+ ))}
+ {hasNext && }
+ +
+
+ >
);
};
diff --git a/client/src/components/roadmapListPage/roadmapSearch/roadmapSearch.styles.ts b/client/src/components/roadmapListPage/roadmapSearch/roadmapSearch.styles.ts
index b61f1a4b4..142b511af 100644
--- a/client/src/components/roadmapListPage/roadmapSearch/roadmapSearch.styles.ts
+++ b/client/src/components/roadmapListPage/roadmapSearch/roadmapSearch.styles.ts
@@ -92,7 +92,7 @@ export const CreateRoadmapButton = styled.button`
border-radius: 50%;
`;
-export const InputFlex = styled.div`
+export const InputFlex = styled.form`
display: flex;
align-items: flex-end;
`;
@@ -101,3 +101,17 @@ export const ResetSearchButton = styled.button`
${({ theme }) => theme.fonts.description3}
color: ${({ theme }) => theme.colors.main_dark};
`;
+
+export const NoResultWrapper = styled.h1`
+ ${({ theme }) => theme.fonts.title_large};
+ width: 100%;
+ height: 10rem;
+
+ text-align: center;
+
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ color: ${({ theme }) => theme.colors.main_dark};
+`;
From 552796fe5659a208c10da5c0d51089371e7fc432 Mon Sep 17 00:00:00 2001
From: Jungwoo
Date: Sun, 1 Oct 2023 00:09:57 +0900
Subject: [PATCH 20/23] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=83=9D?=
=?UTF-8?q?=EC=84=B1,=20=EC=A7=84=ED=96=89=EC=A4=91=EC=9D=B8=20=EB=AA=A8?=
=?UTF-8?q?=EC=9E=84=EB=B3=B4=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20=EA=B5=AC?=
=?UTF-8?q?=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../extraInfo/ExtraInfo.styles.ts | 4 ++
.../roadmapDetail/RoadmapDetail.styles.ts | 39 +++++++++++++++++--
.../roadmapDetail/RoadmapDetail.tsx | 13 ++++++-
3 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/client/src/components/roadmapDetailPage/extraInfo/ExtraInfo.styles.ts b/client/src/components/roadmapDetailPage/extraInfo/ExtraInfo.styles.ts
index 5485af792..98aa0449c 100644
--- a/client/src/components/roadmapDetailPage/extraInfo/ExtraInfo.styles.ts
+++ b/client/src/components/roadmapDetailPage/extraInfo/ExtraInfo.styles.ts
@@ -41,4 +41,8 @@ export const RecommendedRoadmapPeriod = styled.div`
export const Tags = styled.div`
color: ${({ theme }) => theme.colors.main_dark};
+
+ & > div {
+ text-align: end;
+ }
`;
diff --git a/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.styles.ts b/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.styles.ts
index ce6785c43..93c0b17ce 100644
--- a/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.styles.ts
+++ b/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.styles.ts
@@ -4,9 +4,7 @@ export const RoadmapDetail = styled.div`
padding: 2rem 0 4rem 0;
`;
-export const RoadmapInfo = styled.div`
- margin-bottom: 4rem;
-`;
+export const RoadmapInfo = styled.div``;
export const Title = styled.div`
${({ theme }) => theme.fonts.title_large};
@@ -17,3 +15,38 @@ export const Title = styled.div`
export const Description = styled.div`
display: flex;
`;
+
+export const ButtonsWrapper = styled.div`
+ position: relative;
+ width: 100%;
+`;
+
+export const Buttons = styled.div`
+ bottom: 3rem;
+
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+
+ margin: 2rem 0;
+
+ background-color: ${({ theme }) => theme.colors.main_dark};
+ border-radius: 8px;
+
+ & > div {
+ width: 0.2rem;
+ height: 5.5rem;
+ background-color: ${({ theme }) => theme.colors.white};
+ }
+`;
+
+export const Button = styled.button`
+ ${({ theme }) => theme.fonts.nav_text}
+ width: 50%;
+ height: 5.5rem;
+
+ color: ${({ theme }) => theme.colors.white};
+
+ background-color: ${({ theme }) => theme.colors.main_dark};
+ border-radius: 8px;
+`;
diff --git a/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.tsx b/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.tsx
index 76ee29aec..912425ee5 100644
--- a/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.tsx
+++ b/client/src/components/roadmapDetailPage/roadmapDetail/RoadmapDetail.tsx
@@ -1,6 +1,6 @@
import * as S from './RoadmapDetail.styles';
import useValidParams from '@hooks/_common/useValidParams';
-// import { useNavigate } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import { useRoadmapDetail } from '@hooks/queries/roadmap';
import Slider from '@components/_common/slider/Slider';
@@ -10,7 +10,7 @@ import Introduction from '../introduction/Introduction';
const RoadmapDetail = () => {
const { id: roadmapId } = useValidParams<{ id: string }>();
- // const navigate = useNavigate();
+ const navigate = useNavigate();
const { roadmapInfo } = useRoadmapDetail(Number(roadmapId));
return (
@@ -22,6 +22,15 @@ const RoadmapDetail = () => {
+
+ navigate(`/roadmap/${roadmapId}/goalroom-create`)}>
+ 모임 생성하기
+
+
+ navigate(`/roadmap/${roadmapId}/goalroom-list`)}>
+ 진행중인 모임보기
+
+
{roadmapInfo.content.nodes.map((node, index) => (
From 1619ac8573cec39c3a1a9d531344f5ede0c4941d Mon Sep 17 00:00:00 2001
From: Jungwoo
Date: Sun, 1 Oct 2023 00:34:45 +0900
Subject: [PATCH 21/23] =?UTF-8?q?chore:=20=EB=B6=88=ED=95=84=EC=9A=94?=
=?UTF-8?q?=ED=95=9C=20css=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../roadmapDetailPage/nodeContent/NodeContent.styles.ts | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/client/src/components/roadmapDetailPage/nodeContent/NodeContent.styles.ts b/client/src/components/roadmapDetailPage/nodeContent/NodeContent.styles.ts
index 9db8597f8..695e6a26b 100644
--- a/client/src/components/roadmapDetailPage/nodeContent/NodeContent.styles.ts
+++ b/client/src/components/roadmapDetailPage/nodeContent/NodeContent.styles.ts
@@ -8,17 +8,15 @@ export const SliderContent = styled.div`
border-radius: 8px;
${media.mobile`
- flex-direction: column;
aspect-ratio: 0;
`}
`;
export const LeftContent = styled.div`
- flex-shrink: 0;
width: 45%;
${media.mobile`
- display:none;
+ display: none;
`}
`;
From 11542954aedba0c8a315f58276a51f57c1c7d9b4 Mon Sep 17 00:00:00 2001
From: NaveOWO <87578512+NaveOWO@users.noreply.github.com>
Date: Sun, 1 Oct 2023 04:35:47 +0900
Subject: [PATCH 22/23] =?UTF-8?q?[feat/CK-212]=20=EB=A1=9C=EB=93=9C?=
=?UTF-8?q?=EB=A7=B5=20=EC=83=9D=EC=84=B1=ED=8E=98=EC=9D=B4=EC=A7=80=20?=
=?UTF-8?q?=EC=98=A4=EB=A5=98=EB=A5=BC=20=ED=95=B4=EA=B2=B0=ED=95=9C?=
=?UTF-8?q?=EB=8B=A4.=20(#171)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* fix: 400에러시에 요청이 다시 보내지지 않는 오류 해결
* refactor: 로드맵의 첫번째 노드 기본으로 노출
* fix: difficulty 요청이 잘못가는 오류 수정
* fix: tag무한생성 오류 해결
* fix: 중복되는 태그생성 오류 해결
* refactor: ref 예외처리 단순화
---
.../difficulty/Difficulty.tsx | 45 ++++++++++---------
.../roadmapCreateForm/RoadmapCreateForm.tsx | 8 ++++
.../components/roadmapCreatePage/tag/Tag.tsx | 17 +++++--
client/src/constants/roadmap/tag.ts | 2 +-
.../hooks/roadmap/useCollectRoadmapData.ts | 10 +++--
client/src/hooks/roadmap/useCreateTag.ts | 19 ++++++--
client/src/myTypes/roadmap/internal.ts | 13 +++++-
7 files changed, 82 insertions(+), 32 deletions(-)
diff --git a/client/src/components/roadmapCreatePage/difficulty/Difficulty.tsx b/client/src/components/roadmapCreatePage/difficulty/Difficulty.tsx
index 8e6dcdb88..c5b07ce0a 100644
--- a/client/src/components/roadmapCreatePage/difficulty/Difficulty.tsx
+++ b/client/src/components/roadmapCreatePage/difficulty/Difficulty.tsx
@@ -1,31 +1,32 @@
/* eslint-disable react/no-unused-prop-types */
import { useSelect } from '@/hooks/_common/useSelect';
+import { DifficultiesType, DifficultyKeyType } from '@/myTypes/roadmap/internal';
+import { getInvariantObjectKeys, invariantOf } from '@/utils/_common/invariantType';
import { useEffect } from 'react';
import { Select, SelectBox } from '../selector/SelectBox';
import * as S from './difficulty.styles';
-// 임시 더미데이터
-export type DummyDifficultyType = {
- [key: number]: string;
+const Difficulties: DifficultiesType = {
+ VERY_EASY: '매우쉬움',
+ EASY: '쉬움',
+ NORMAL: '보통',
+ DIFFICULT: '어려움',
+ VERY_DIFFICULT: '매우어려움',
};
-const DummyDifficulty: DummyDifficultyType = {
- 1: '매우쉬움',
- 2: '쉬움',
- 3: '보통',
- 4: '어려움',
- 5: '매우어려움',
+type DifficultyProps = {
+ getSelectedDifficulty: (difficulty: DifficultyKeyType | null) => void;
};
-type DifficultyType = {
- getSelectedDifficulty: (difficulty: keyof DummyDifficultyType | null) => void;
-};
-
-const Difficulty = ({ getSelectedDifficulty }: DifficultyType) => {
+const Difficulty = ({ getSelectedDifficulty }: DifficultyProps) => {
const { selectOption, selectedOption } = useSelect();
useEffect(() => {
- getSelectedDifficulty(selectedOption);
+ if (selectedOption === null) return;
+
+ getSelectedDifficulty(
+ getInvariantObjectKeys(invariantOf(Difficulties))[selectedOption]
+ );
}, [selectedOption]);
return (
@@ -46,7 +47,11 @@ const Difficulty = ({ getSelectedDifficulty }: DifficultyType) => {
{({ selectedId }: { selectedId: number | null }) => {
return (
- {selectedId === null ? '선택안함' : DummyDifficulty[selectedId]}
+ {selectedId === null
+ ? '선택안함'
+ : Difficulties[
+ getInvariantObjectKeys(invariantOf(Difficulties))[selectedId]
+ ]}
);
}}
@@ -55,14 +60,14 @@ const Difficulty = ({ getSelectedDifficulty }: DifficultyType) => {
- {Object.keys(DummyDifficulty).map((difficultyId) => {
+ {getInvariantObjectKeys(invariantOf(Difficulties)).map((difficulty, idx) => {
return (
-
+
-
+
- {DummyDifficulty[Number(difficultyId)]}
+ {Difficulties[difficulty]}
);
diff --git a/client/src/components/roadmapCreatePage/roadmapCreateForm/RoadmapCreateForm.tsx b/client/src/components/roadmapCreatePage/roadmapCreateForm/RoadmapCreateForm.tsx
index a84968ee7..2c11169b6 100644
--- a/client/src/components/roadmapCreatePage/roadmapCreateForm/RoadmapCreateForm.tsx
+++ b/client/src/components/roadmapCreatePage/roadmapCreateForm/RoadmapCreateForm.tsx
@@ -50,6 +50,14 @@ const RoadmapCreateForm = () => {
<>
+ {roadmapValue.roadmapNodes.length === 0 && (
+
+ )}
{roadmapValue.roadmapNodes.map((_, index) => {
return (
void;
};
const Tag = ({ getTags }: TagProps) => {
- const { tags, ref, addTagByButton, addTagByEnter, checkIsTagCountMax, deleteTag } =
- useCreateTag();
+ const {
+ tags,
+ ref,
+ addTagByButton,
+ addTagByEnter,
+ checkIsTagCountMax,
+ checkIsAddCountMax,
+ deleteTag,
+ } = useCreateTag();
useEffect(() => {
getTags(tags);
@@ -29,8 +36,10 @@ const Tag = ({ getTags }: TagProps) => {
>
))}
-
- {checkIsTagCountMax() && +}
+ {checkIsTagCountMax() && (
+
+ )}
+ {checkIsAddCountMax() && +}
);
diff --git a/client/src/constants/roadmap/tag.ts b/client/src/constants/roadmap/tag.ts
index 8c4b6e9f2..6662ea4e7 100644
--- a/client/src/constants/roadmap/tag.ts
+++ b/client/src/constants/roadmap/tag.ts
@@ -1,3 +1,3 @@
-export const TAG_LIMIT = 4;
+export const TAG_LIMIT = 5;
export const TAG_ITEM_MAX_LENGTH = 10;
diff --git a/client/src/hooks/roadmap/useCollectRoadmapData.ts b/client/src/hooks/roadmap/useCollectRoadmapData.ts
index 2bfed9fce..d5b1658f1 100644
--- a/client/src/hooks/roadmap/useCollectRoadmapData.ts
+++ b/client/src/hooks/roadmap/useCollectRoadmapData.ts
@@ -1,6 +1,9 @@
import { DummyCategoryType } from '@/components/roadmapCreatePage/category/Category';
-import { DummyDifficultyType } from '@/components/roadmapCreatePage/difficulty/Difficulty';
-import { NodeImagesType, RoadmapValueType } from '@/myTypes/roadmap/internal';
+import {
+ DifficultyKeyType,
+ NodeImagesType,
+ RoadmapValueType,
+} from '@/myTypes/roadmap/internal';
import { getInvariantObjectKeys, invariantOf } from '@/utils/_common/invariantType';
import { useEffect, useState } from 'react';
import { useCreateRoadmap } from '../queries/roadmap';
@@ -27,7 +30,7 @@ export const useCollectRoadmapData = () => {
}));
};
- const getSelectedDifficulty = (difficulty: keyof DummyDifficultyType | null) => {
+ const getSelectedDifficulty = (difficulty: DifficultyKeyType | null) => {
setRoadmapValue((prev) => ({
...prev,
difficulty,
@@ -106,6 +109,7 @@ export const useCollectRoadmapData = () => {
if (isSumbited) {
createRoadmap(formData);
}
+ setIsSubmited(false);
}, [isSumbited]);
return {
diff --git a/client/src/hooks/roadmap/useCreateTag.ts b/client/src/hooks/roadmap/useCreateTag.ts
index 913ec80c8..28ee13847 100644
--- a/client/src/hooks/roadmap/useCreateTag.ts
+++ b/client/src/hooks/roadmap/useCreateTag.ts
@@ -6,8 +6,9 @@ export const useCreateTag = () => {
const ref = useRef(null);
const getAddedTagText = () => {
- if (ref.current === null) return;
- if (ref.current.value === '') return;
+ if (!ref.current?.value) return;
+
+ if (tags.includes(ref.current.value)) return;
setTags((prev) => {
return [...prev, ref.current?.value as string];
@@ -31,6 +32,10 @@ export const useCreateTag = () => {
return tags.length < TAG_LIMIT;
};
+ const checkIsAddCountMax = () => {
+ return tags.length < TAG_LIMIT - 1;
+ };
+
const deleteTag = (e: React.MouseEvent) => {
e.preventDefault();
@@ -40,5 +45,13 @@ export const useCreateTag = () => {
return prev.filter((tag) => tag !== target.value);
});
};
- return { tags, ref, addTagByButton, addTagByEnter, checkIsTagCountMax, deleteTag };
+ return {
+ tags,
+ ref,
+ addTagByButton,
+ addTagByEnter,
+ checkIsTagCountMax,
+ checkIsAddCountMax,
+ deleteTag,
+ };
};
diff --git a/client/src/myTypes/roadmap/internal.ts b/client/src/myTypes/roadmap/internal.ts
index aeb9a0fbe..76aba525a 100644
--- a/client/src/myTypes/roadmap/internal.ts
+++ b/client/src/myTypes/roadmap/internal.ts
@@ -1,6 +1,17 @@
import { DIFFICULTY_ICON_NAME } from '@constants/roadmap/difficulty';
import { CategoriesInfo } from '@constants/roadmap/category';
+export type DifficultyKeyType =
+ | 'VERY_EASY'
+ | 'EASY'
+ | 'NORMAL'
+ | 'DIFFICULT'
+ | 'VERY_DIFFICULT';
+
+export type DifficultyValueType = '매우쉬움' | '쉬움' | '보통' | '어려움' | '매우어려움';
+
+export type DifficultiesType = { [key in DifficultyKeyType]: DifficultyValueType };
+
export type CategoryType = {
id: keyof typeof CategoriesInfo;
name: string;
@@ -64,7 +75,7 @@ export type RoadmapValueType = {
title: null | string;
introduction: null | string;
content: null | string;
- difficulty: null | number;
+ difficulty: null | DifficultyKeyType;
requiredPeriod: null | string;
roadmapTags: { name: string }[];
roadmapNodes: RoadmapNodes[];
From 0fa6668cb74e82efdcbe867871091616fafb43e5 Mon Sep 17 00:00:00 2001
From: Jungwoo
Date: Sun, 1 Oct 2023 12:56:56 +0900
Subject: [PATCH 23/23] =?UTF-8?q?refactor:=20=ED=83=80=EC=9E=85=20?=
=?UTF-8?q?=EC=BB=A8=EB=B2=A4=EC=85=98=20=EB=B0=98=EC=98=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../roadmapDetailPage/introduction/Introduction.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/client/src/components/roadmapDetailPage/introduction/Introduction.tsx b/client/src/components/roadmapDetailPage/introduction/Introduction.tsx
index 2fae32dd3..3069efacf 100644
--- a/client/src/components/roadmapDetailPage/introduction/Introduction.tsx
+++ b/client/src/components/roadmapDetailPage/introduction/Introduction.tsx
@@ -2,11 +2,11 @@ import { RoadmapDetailType } from '@myTypes/roadmap/internal';
import * as S from './Introduction.styles';
import { useEffect, useRef, useState } from 'react';
-type IntroductionType = {
+type IntroductionProps = {
roadmapInfo: RoadmapDetailType;
};
-const Introduction = ({ roadmapInfo }: IntroductionType) => {
+const Introduction = ({ roadmapInfo }: IntroductionProps) => {
const [isExpanded, setIsExpanded] = useState(false);
const [showMoreButton, setShowMoreButton] = useState(false);
const introRef = useRef(null);
@@ -21,7 +21,7 @@ const Introduction = ({ roadmapInfo }: IntroductionType) => {
}, []);
const toggleExpand = () => {
- setIsExpanded(!isExpanded);
+ setIsExpanded((prev) => !prev);
};
return (