From de2b4493987662c47e52e701e4141a4fbd816b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 14:59:40 +0900 Subject: [PATCH 01/15] =?UTF-8?q?feat:=20=EB=8C=80=ED=9A=8C=20=EC=84=B8?= =?UTF-8?q?=EB=B6=80=EC=A0=95=EB=B3=B4=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 대회 세부정보 페이지 컴포넌트인 CompetitionDetailPage컴포넌트 작성 - 이에 대한 라우팅 router.tsx에 작성 - 대회 종료 후 페이지 작성중(문제 이름을 클릭하면 문제 세부 정보 페이지로 이동) --- .../CompetitionDetail/ProblemList.tsx | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 frontend/src/components/CompetitionDetail/ProblemList.tsx diff --git a/frontend/src/components/CompetitionDetail/ProblemList.tsx b/frontend/src/components/CompetitionDetail/ProblemList.tsx new file mode 100644 index 0000000..db65f9e --- /dev/null +++ b/frontend/src/components/CompetitionDetail/ProblemList.tsx @@ -0,0 +1,37 @@ +import { useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; + +import { fetchCompetitionProblemList, ProblemInfo } from '@/apis/problems'; + +interface Props { + competitionId: number; +} + +export default function ProblemList(props: Props) { + const [problems, setProblems] = useState([]); + + useEffect(() => { + const fetchData = async () => { + try { + const result = await fetchCompetitionProblemList(props.competitionId); + setProblems(result); + } catch (error) { + console.error('Error fetching competition problems:', error); + } + }; + + fetchData(); + }, [props.competitionId]); + + return ( +
+ +
+ ); +} From 9dcc76b63038bf4a3b4d0338f188d0188b0fc8bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 15:01:19 +0900 Subject: [PATCH 02/15] =?UTF-8?q?feat:=20=EB=8C=80=ED=9A=8C=20=EC=84=B8?= =?UTF-8?q?=EB=B6=80=EC=A0=95=EB=B3=B4=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 대회 세부정보 페이지 컴포넌트인 CompetitionDetailPage컴포넌트 작성 - 이에 대한 라우팅 router.tsx에 작성 - 대회 종료 후 페이지 작성중(문제 이름을 클릭하면 문제 세부 정보 페이지로 이동) --- frontend/src/pages/CompetitionDetailPage.tsx | 15 +++++++++++++++ frontend/src/router.tsx | 5 +++++ 2 files changed, 20 insertions(+) create mode 100644 frontend/src/pages/CompetitionDetailPage.tsx diff --git a/frontend/src/pages/CompetitionDetailPage.tsx b/frontend/src/pages/CompetitionDetailPage.tsx new file mode 100644 index 0000000..1e5354a --- /dev/null +++ b/frontend/src/pages/CompetitionDetailPage.tsx @@ -0,0 +1,15 @@ +import { useParams } from 'react-router-dom'; + +import ProblemList from '@/components/CompetitionDetail/ProblemList'; + +export default function CompetitionDetailPage() { + const { id } = useParams<{ id: string }>(); + const competitionId: number = id ? parseInt(id, 10) : -1; + + return ( +
+ CompetitionDetailPage + +
+ ); +} diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx index be13f57..bdff5bd 100644 --- a/frontend/src/router.tsx +++ b/frontend/src/router.tsx @@ -7,6 +7,7 @@ import MainPage from '@/pages/MainPage'; import ProblemPage from '@/pages/ProblemPage'; import App from './App'; +import CompetitionDetailPage from './pages/CompetitionDetailPage'; const router = createBrowserRouter([ { @@ -30,6 +31,10 @@ const router = createBrowserRouter([ element: , }, { path: '/login', element: }, + { + path: '/contest/detail/:id', + element: , + }, ], }, ]); From d53e611de33c08cbea278e8d5c14808a93c76181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 18:17:55 +0900 Subject: [PATCH 03/15] =?UTF-8?q?refactor:=20=EC=9E=91=EC=84=B1=EB=90=9C?= =?UTF-8?q?=20=EB=AA=A8=EB=93=88=EC=9D=84=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95,=20list=EB=8C=80?= =?UTF-8?q?=EC=8B=A0=20table=EC=9D=84=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CompetitionDetail/ProblemList.tsx | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/frontend/src/components/CompetitionDetail/ProblemList.tsx b/frontend/src/components/CompetitionDetail/ProblemList.tsx index db65f9e..5fbb763 100644 --- a/frontend/src/components/CompetitionDetail/ProblemList.tsx +++ b/frontend/src/components/CompetitionDetail/ProblemList.tsx @@ -1,37 +1,34 @@ -import { useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; -import { fetchCompetitionProblemList, ProblemInfo } from '@/apis/problems'; +import { useCompetitionProblemList } from '@/hooks/problem'; interface Props { competitionId: number; } -export default function ProblemList(props: Props) { - const [problems, setProblems] = useState([]); - - useEffect(() => { - const fetchData = async () => { - try { - const result = await fetchCompetitionProblemList(props.competitionId); - setProblems(result); - } catch (error) { - console.error('Error fetching competition problems:', error); - } - }; - - fetchData(); - }, [props.competitionId]); +export default function ProblemList({ competitionId }: Props) { + const { problemList } = useCompetitionProblemList(competitionId); return (
-
    - {problems.map((problem) => ( -
  • - {problem.title} -
  • - ))} -
+ + + + + + + + + {problemList.map((problem) => ( + + + + + ))} + +
번호문제 제목
{problem.id} + {problem.title} +
); } From 09e7a4317e3a646ffa7e3f439512f899637a4193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 18:18:28 +0900 Subject: [PATCH 04/15] =?UTF-8?q?feat:=20=EB=8C=80=ED=9A=8C=20=EC=9E=85?= =?UTF-8?q?=EC=9E=A5=20=EB=B2=84=ED=8A=BC=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Buttons/EnterCompetitionButton.tsx | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx diff --git a/frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx b/frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx new file mode 100644 index 0000000..01b2cd0 --- /dev/null +++ b/frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx @@ -0,0 +1,20 @@ +import { useNavigate } from 'react-router-dom'; + +import useAuth from '@/hooks/login/useAuth'; + +export default function EnterCompetitionButton(props: { id: number }) { + const competitionLink = `/contest/${props.id}`; + const { isLoggedin } = useAuth(); + const navigate = useNavigate(); + + const handleNavigate = () => { + if (!isLoggedin) { + alert('로그인이 필요합니다.'); + navigate('/login'); + } else { + navigate(competitionLink); + } + }; + + return ; +} From f48297105137e872b2d2f989b143289f4caaa1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 18:19:08 +0900 Subject: [PATCH 05/15] =?UTF-8?q?feat:=20=EC=8B=9C=EA=B0=84=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EB=8C=80=ED=9A=8C=20=EC=84=B8=EB=B6=80?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EB=A1=9C=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B5=AC=EB=B6=84=20=EB=A1=9C=EC=A7=81=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CompetitionDetail/AfterCompetition.tsx | 36 ++++++++++++++++++ .../CompetitionDetail/BeforeCompetition.tsx | 3 ++ .../CompetitionDetail/DuringCompetition.tsx | 37 +++++++++++++++++++ frontend/src/pages/CompetitionDetailPage.tsx | 27 ++++++++++++-- 4 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 frontend/src/components/CompetitionDetail/AfterCompetition.tsx create mode 100644 frontend/src/components/CompetitionDetail/BeforeCompetition.tsx create mode 100644 frontend/src/components/CompetitionDetail/DuringCompetition.tsx diff --git a/frontend/src/components/CompetitionDetail/AfterCompetition.tsx b/frontend/src/components/CompetitionDetail/AfterCompetition.tsx new file mode 100644 index 0000000..d95a474 --- /dev/null +++ b/frontend/src/components/CompetitionDetail/AfterCompetition.tsx @@ -0,0 +1,36 @@ +import { css } from '@style/css'; + +import { CompetitionInfo } from '@/apis/competitions'; + +import ProblemList from './ProblemList'; + +interface Props { + competitionId: number; + competition: CompetitionInfo; +} + +export default function AfterCompetition({ competitionId, competition }: Props) { + return ( +
+ {competition.name} + 종료 + +
+ ); +} + +const containerStyle = css({ + alignItems: 'center', +}); + +const competitionNameStyle = css({ + fontSize: '18px', + fontWeight: 'bold', + color: 'black', + marginRight: '8px', +}); + +const statusTextStyle = css({ + fontSize: '12px', + color: 'gray', +}); diff --git a/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx b/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx new file mode 100644 index 0000000..7fedd48 --- /dev/null +++ b/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx @@ -0,0 +1,3 @@ +export default function BeforeCompetition() { + return
대회 시작 전입니다.
; +} diff --git a/frontend/src/components/CompetitionDetail/DuringCompetition.tsx b/frontend/src/components/CompetitionDetail/DuringCompetition.tsx new file mode 100644 index 0000000..b6c1409 --- /dev/null +++ b/frontend/src/components/CompetitionDetail/DuringCompetition.tsx @@ -0,0 +1,37 @@ +import { css } from '@style/css'; + +import { CompetitionInfo } from '@/apis/competitions'; + +import EnterCompetitionButton from './Buttons/EnterCompetitionButton'; + +interface Props { + competitionId: number; + competition: CompetitionInfo; +} + +export default function DuringCompetition({ competitionId, competition }: Props) { + return ( +
+ {competition.name} + 진행중 + +
+ ); +} + +const containerStyle = css({ + display: 'flex', + alignItems: 'center', +}); + +const competitionNameStyle = css({ + fontSize: '18px', + fontWeight: 'bold', + color: 'black', + marginRight: '8px', +}); + +const statusTextStyle = css({ + fontSize: '12px', + color: 'gray', +}); diff --git a/frontend/src/pages/CompetitionDetailPage.tsx b/frontend/src/pages/CompetitionDetailPage.tsx index 1e5354a..bab1443 100644 --- a/frontend/src/pages/CompetitionDetailPage.tsx +++ b/frontend/src/pages/CompetitionDetailPage.tsx @@ -1,15 +1,36 @@ import { useParams } from 'react-router-dom'; -import ProblemList from '@/components/CompetitionDetail/ProblemList'; +import AfterCompetition from '@/components/CompetitionDetail/AfterCompetition'; +import BeforeCompetition from '@/components/CompetitionDetail/BeforeCompetition'; +import DuringCompetition from '@/components/CompetitionDetail/DuringCompetition'; +import Header from '@/components/Header'; +import { useCompetition } from '@/hooks/competition'; export default function CompetitionDetailPage() { const { id } = useParams<{ id: string }>(); const competitionId: number = id ? parseInt(id, 10) : -1; + const { competition } = useCompetition(competitionId); + // 대회 상태에 따른 페이지를 구성하기 위해 현재 날짜, 시작 시간, 종료 시간을 가져옴 + const currentDate = new Date(); + const startsAt = new Date(competition?.startsAt || ''); + const endsAt = new Date(competition?.endsAt || ''); + + let content; + + if (currentDate < startsAt) { + content = ; + } else if (currentDate >= startsAt && currentDate <= endsAt) { + content = ; + } else { + content = ; + } + + // content = ; return (
- CompetitionDetailPage - +
+ {content}
); } From df0c94df43065a6192d29bb767e0e0f57517b171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 20:33:21 +0900 Subject: [PATCH 06/15] =?UTF-8?q?refactor:=20=EC=8B=9C=EA=B0=84=EC=97=90?= =?UTF-8?q?=20=EB=94=B0=EB=A5=B8=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=AC=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 대회 종료 전 하나의 컴포넌트로 구현했던 것을 대회 시작 전후로 나누었습니다. - 대회 시작 전에 페이지에 접속해 대회 시작 시간이 지난 경우, 대회 입장 버튼을 누르면 페이지 리렌더링이 되게 코드 수정 --- ...ompetition.tsx => AfterCompetitionEnd.tsx} | 2 +- .../CompetitionDetail/BeforeCompetition.tsx | 41 ++++++++++++++++++- .../Buttons/EnterCompetitionButton.tsx | 13 +++++- .../CompetitionDetail/DuringCompetition.tsx | 5 ++- frontend/src/pages/CompetitionDetailPage.tsx | 31 ++++++++++---- 5 files changed, 78 insertions(+), 14 deletions(-) rename frontend/src/components/CompetitionDetail/{AfterCompetition.tsx => AfterCompetitionEnd.tsx} (89%) diff --git a/frontend/src/components/CompetitionDetail/AfterCompetition.tsx b/frontend/src/components/CompetitionDetail/AfterCompetitionEnd.tsx similarity index 89% rename from frontend/src/components/CompetitionDetail/AfterCompetition.tsx rename to frontend/src/components/CompetitionDetail/AfterCompetitionEnd.tsx index d95a474..f455048 100644 --- a/frontend/src/components/CompetitionDetail/AfterCompetition.tsx +++ b/frontend/src/components/CompetitionDetail/AfterCompetitionEnd.tsx @@ -9,7 +9,7 @@ interface Props { competition: CompetitionInfo; } -export default function AfterCompetition({ competitionId, competition }: Props) { +export default function AfterCompetitionEnd({ competitionId, competition }: Props) { return (
{competition.name} diff --git a/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx b/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx index 7fedd48..7f6e05c 100644 --- a/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx +++ b/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx @@ -1,3 +1,40 @@ -export default function BeforeCompetition() { - return
대회 시작 전입니다.
; +import { css } from '@style/css'; + +import { CompetitionInfo } from '@/apis/competitions'; + +import JoinCompetitionButton from '../Main/Buttons/JoinCompetitionButton'; +import EnterCompetitionButton from './Buttons/EnterCompetitionButton'; + +interface Props { + competitionId: number; + competition: CompetitionInfo; + startsAt: Date; } + +export default function BeforeCompetition({ competitionId, competition, startsAt }: Props) { + return ( +
+ {competition.name} + 대회 시작 전 + + +
+ ); +} + +const containerStyle = css({ + display: 'flex', + alignItems: 'center', +}); + +const competitionNameStyle = css({ + fontSize: '18px', + fontWeight: 'bold', + color: 'black', + marginRight: '8px', +}); + +const statusTextStyle = css({ + fontSize: '12px', + color: 'gray', +}); diff --git a/frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx b/frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx index 01b2cd0..887765f 100644 --- a/frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx +++ b/frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx @@ -2,8 +2,14 @@ import { useNavigate } from 'react-router-dom'; import useAuth from '@/hooks/login/useAuth'; -export default function EnterCompetitionButton(props: { id: number }) { - const competitionLink = `/contest/${props.id}`; +interface Props { + id: number; + startsAt: Date; +} + +export default function EnterCompetitionButton({ id, startsAt }: Props) { + const currentTime = new Date(); + const competitionLink = `/contest/${id}`; const { isLoggedin } = useAuth(); const navigate = useNavigate(); @@ -11,6 +17,9 @@ export default function EnterCompetitionButton(props: { id: number }) { if (!isLoggedin) { alert('로그인이 필요합니다.'); navigate('/login'); + } else if (currentTime < startsAt) { + alert('아직 대회가 시작되지 않았습니다. 다시 시도해주세요'); + window.location.reload(); } else { navigate(competitionLink); } diff --git a/frontend/src/components/CompetitionDetail/DuringCompetition.tsx b/frontend/src/components/CompetitionDetail/DuringCompetition.tsx index b6c1409..22f6826 100644 --- a/frontend/src/components/CompetitionDetail/DuringCompetition.tsx +++ b/frontend/src/components/CompetitionDetail/DuringCompetition.tsx @@ -7,14 +7,15 @@ import EnterCompetitionButton from './Buttons/EnterCompetitionButton'; interface Props { competitionId: number; competition: CompetitionInfo; + startsAt: Date; } -export default function DuringCompetition({ competitionId, competition }: Props) { +export default function DuringCompetition({ competitionId, competition, startsAt }: Props) { return (
{competition.name} 진행중 - +
); } diff --git a/frontend/src/pages/CompetitionDetailPage.tsx b/frontend/src/pages/CompetitionDetailPage.tsx index bab1443..6eda39e 100644 --- a/frontend/src/pages/CompetitionDetailPage.tsx +++ b/frontend/src/pages/CompetitionDetailPage.tsx @@ -1,6 +1,6 @@ import { useParams } from 'react-router-dom'; -import AfterCompetition from '@/components/CompetitionDetail/AfterCompetition'; +import AfterCompetitionEnd from '@/components/CompetitionDetail/AfterCompetitionEnd'; import BeforeCompetition from '@/components/CompetitionDetail/BeforeCompetition'; import DuringCompetition from '@/components/CompetitionDetail/DuringCompetition'; import Header from '@/components/Header'; @@ -18,15 +18,32 @@ export default function CompetitionDetailPage() { let content; if (currentDate < startsAt) { - content = ; - } else if (currentDate >= startsAt && currentDate <= endsAt) { - content = ; + content = ( + + ); + } else if (currentDate < endsAt) { + content = ( + + ); } else { - content = ; + content = ; } - // content = ; - + content = ( + + ); return (
From 826df7ba6d4bacec651b4e32d42024b8ec53af1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 21:22:15 +0900 Subject: [PATCH 07/15] =?UTF-8?q?refactor:=20=EB=8C=80=ED=9A=8C=20?= =?UTF-8?q?=EC=84=B8=EB=B6=80=EC=A0=95=EB=B3=B4=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EC=97=90=EC=84=9C=20=EC=8B=9C=EA=B0=84=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=B6=84?= =?UTF-8?q?=EB=A5=98=20=EC=BD=94=EB=93=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=ED=99=94,=20=EC=A4=91=EB=B3=B5=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CompetitionDetail/AfterCompetitionEnd.tsx | 32 +++++++------ .../CompetitionDetail/BeforeCompetition.tsx | 41 ++++++++++------- .../CompetitionDetailContent.tsx | 31 +++++++++++++ .../CompetitionDetailInfo.tsx | 46 +++++++++++++++++++ .../CompetitionDetail/DuringCompetition.tsx | 34 +++++++------- frontend/src/pages/CompetitionDetailPage.tsx | 42 ++++------------- 6 files changed, 147 insertions(+), 79 deletions(-) create mode 100644 frontend/src/components/CompetitionDetail/CompetitionDetailContent.tsx create mode 100644 frontend/src/components/CompetitionDetail/CompetitionDetailInfo.tsx diff --git a/frontend/src/components/CompetitionDetail/AfterCompetitionEnd.tsx b/frontend/src/components/CompetitionDetail/AfterCompetitionEnd.tsx index f455048..9552ac6 100644 --- a/frontend/src/components/CompetitionDetail/AfterCompetitionEnd.tsx +++ b/frontend/src/components/CompetitionDetail/AfterCompetitionEnd.tsx @@ -2,35 +2,37 @@ import { css } from '@style/css'; import { CompetitionInfo } from '@/apis/competitions'; +import CompetitionDetailInfo from './CompetitionDetailInfo'; import ProblemList from './ProblemList'; interface Props { competitionId: number; competition: CompetitionInfo; + competitionSchedule: string; } -export default function AfterCompetitionEnd({ competitionId, competition }: Props) { +const AFTER_COMPETITION_TEXT = ' 종료'; + +export default function AfterCompetitionEnd({ + competitionId, + competition, + competitionSchedule, +}: Props) { return (
- {competition.name} - 종료 +
); } const containerStyle = css({ + justifyContent: 'space-between', alignItems: 'center', -}); - -const competitionNameStyle = css({ - fontSize: '18px', - fontWeight: 'bold', - color: 'black', - marginRight: '8px', -}); - -const statusTextStyle = css({ - fontSize: '12px', - color: 'gray', + padding: '16px', + border: '1px solid #ccc', }); diff --git a/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx b/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx index 7f6e05c..aa573c3 100644 --- a/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx +++ b/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx @@ -4,37 +4,46 @@ import { CompetitionInfo } from '@/apis/competitions'; import JoinCompetitionButton from '../Main/Buttons/JoinCompetitionButton'; import EnterCompetitionButton from './Buttons/EnterCompetitionButton'; +import CompetitionDetailInfo from './CompetitionDetailInfo'; interface Props { competitionId: number; competition: CompetitionInfo; startsAt: Date; + competitionSchedule: string; } -export default function BeforeCompetition({ competitionId, competition, startsAt }: Props) { +export default function BeforeCompetition({ + competitionId, + competition, + startsAt, + competitionSchedule, +}: Props) { + const BEFORE_COMPETITION_TEXT = ` 시작 전`; + return (
- {competition.name} - 대회 시작 전 - - + +
+ + +
); } const containerStyle = css({ - display: 'flex', + justifyContent: 'space-between', alignItems: 'center', + padding: '16px', + border: '1px solid #ccc', }); -const competitionNameStyle = css({ - fontSize: '18px', - fontWeight: 'bold', - color: 'black', - marginRight: '8px', -}); - -const statusTextStyle = css({ - fontSize: '12px', - color: 'gray', +const buttonContainerStyle = css({ + display: 'flex', + gap: '16px', }); diff --git a/frontend/src/components/CompetitionDetail/CompetitionDetailContent.tsx b/frontend/src/components/CompetitionDetail/CompetitionDetailContent.tsx new file mode 100644 index 0000000..0e3b1f0 --- /dev/null +++ b/frontend/src/components/CompetitionDetail/CompetitionDetailContent.tsx @@ -0,0 +1,31 @@ +// CompetitionDetailContent.js +import { CompetitionInfo } from '@/apis/competitions'; +import AfterCompetitionEnd from '@/components/CompetitionDetail/AfterCompetitionEnd'; +import BeforeCompetition from '@/components/CompetitionDetail/BeforeCompetition'; +import DuringCompetition from '@/components/CompetitionDetail/DuringCompetition'; + +interface Props { + competitionId: number; + competition: CompetitionInfo; + startsAt: Date; + endsAt: Date; + competitionSchedule: string; +} + +export function CompetitionDetailContent({ + competitionId, + competition, + startsAt, + endsAt, + competitionSchedule, +}: Props) { + const currentDate = new Date(); + + if (currentDate < startsAt) { + return ; + } else if (currentDate < endsAt) { + return ; + } else { + return ; + } +} diff --git a/frontend/src/components/CompetitionDetail/CompetitionDetailInfo.tsx b/frontend/src/components/CompetitionDetail/CompetitionDetailInfo.tsx new file mode 100644 index 0000000..92582d8 --- /dev/null +++ b/frontend/src/components/CompetitionDetail/CompetitionDetailInfo.tsx @@ -0,0 +1,46 @@ +import { css } from '@style/css'; + +import { CompetitionInfo } from '@/apis/competitions'; + +interface Props { + competition: CompetitionInfo; + text: string; + competitionSchedule: string; +} + +export default function CompetitionDetailInfo({ competition, text, competitionSchedule }: Props) { + return ( +
+
+ {competition.name} + {text} +
+ {competitionSchedule} +
{competition.detail}
+
+ ); +} + +const infoContainerStyle = css({ + display: 'flex', + flexDirection: 'column', +}); + +const competitionNameStyle = css({ + fontSize: '18px', + fontWeight: 'bold', + color: 'black', + marginBottom: '8px', +}); + +const statusTextStyle = css({ + fontSize: '12px', + color: 'gray', + marginBottom: '8px', +}); + +const additionalTextStyle = css({ + fontSize: '14px', + color: 'black', + marginBottom: '8px', +}); diff --git a/frontend/src/components/CompetitionDetail/DuringCompetition.tsx b/frontend/src/components/CompetitionDetail/DuringCompetition.tsx index 22f6826..86743eb 100644 --- a/frontend/src/components/CompetitionDetail/DuringCompetition.tsx +++ b/frontend/src/components/CompetitionDetail/DuringCompetition.tsx @@ -3,36 +3,38 @@ import { css } from '@style/css'; import { CompetitionInfo } from '@/apis/competitions'; import EnterCompetitionButton from './Buttons/EnterCompetitionButton'; +import CompetitionDetailInfo from './CompetitionDetailInfo'; interface Props { competitionId: number; competition: CompetitionInfo; startsAt: Date; + competitionSchedule: string; } -export default function DuringCompetition({ competitionId, competition, startsAt }: Props) { +const DURING_COMPETITION_TEXT = ' 진행중'; + +export default function DuringCompetition({ + competitionId, + competition, + startsAt, + competitionSchedule, +}: Props) { return (
- {competition.name} - 진행중 +
); } const containerStyle = css({ - display: 'flex', + justifyContent: 'space-between', alignItems: 'center', -}); - -const competitionNameStyle = css({ - fontSize: '18px', - fontWeight: 'bold', - color: 'black', - marginRight: '8px', -}); - -const statusTextStyle = css({ - fontSize: '12px', - color: 'gray', + padding: '16px', + border: '1px solid #ccc', }); diff --git a/frontend/src/pages/CompetitionDetailPage.tsx b/frontend/src/pages/CompetitionDetailPage.tsx index 6eda39e..2cb3ffc 100644 --- a/frontend/src/pages/CompetitionDetailPage.tsx +++ b/frontend/src/pages/CompetitionDetailPage.tsx @@ -1,8 +1,6 @@ import { useParams } from 'react-router-dom'; -import AfterCompetitionEnd from '@/components/CompetitionDetail/AfterCompetitionEnd'; -import BeforeCompetition from '@/components/CompetitionDetail/BeforeCompetition'; -import DuringCompetition from '@/components/CompetitionDetail/DuringCompetition'; +import { CompetitionDetailContent } from '@/components/CompetitionDetail/CompetitionDetailContent'; import Header from '@/components/Header'; import { useCompetition } from '@/hooks/competition'; @@ -11,43 +9,23 @@ export default function CompetitionDetailPage() { const competitionId: number = id ? parseInt(id, 10) : -1; const { competition } = useCompetition(competitionId); // 대회 상태에 따른 페이지를 구성하기 위해 현재 날짜, 시작 시간, 종료 시간을 가져옴 - const currentDate = new Date(); const startsAt = new Date(competition?.startsAt || ''); const endsAt = new Date(competition?.endsAt || ''); + const formattedStartsAt = startsAt.toLocaleString(); + const formattedEndsAt = endsAt.toLocaleString(); - let content; + const competitionSchedule = `시작: ${formattedStartsAt} 종료: ${formattedEndsAt}`; - if (currentDate < startsAt) { - content = ( - - ); - } else if (currentDate < endsAt) { - content = ( - +
+ - ); - } else { - content = ; - } - - content = ( - - ); - return ( -
-
- {content}
); } From 16e8c11913918fe9c6a0115f59c76babdc0f3d20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 21:38:44 +0900 Subject: [PATCH 08/15] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20css=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/ContestPage.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/frontend/src/pages/ContestPage.tsx b/frontend/src/pages/ContestPage.tsx index fe55a8f..abb5e05 100644 --- a/frontend/src/pages/ContestPage.tsx +++ b/frontend/src/pages/ContestPage.tsx @@ -82,15 +82,13 @@ export default function ContestPage() { submitSolution(form); } - const { endsAt } = competition; function handleOpenModal() { modal.open(); } - + const problems = problemList.map((problem) => problem.id); - return (
@@ -160,8 +158,3 @@ const problemTitleStyle = css({ const execButtonStyle = css({ color: 'black', }); - -const rowStyle = css({ - display: 'flex', - justifyContent: 'space-between', -}); From 1e0f8b7c89d6e10da2854acd9453336c7a0cdec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 22:54:27 +0900 Subject: [PATCH 09/15] =?UTF-8?q?refactor:=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EB=AA=85=20=ED=86=B5=EC=9D=BC=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{AfterCompetitionEnd.tsx => AfterCompetition.tsx} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename frontend/src/components/CompetitionDetail/{AfterCompetitionEnd.tsx => AfterCompetition.tsx} (94%) diff --git a/frontend/src/components/CompetitionDetail/AfterCompetitionEnd.tsx b/frontend/src/components/CompetitionDetail/AfterCompetition.tsx similarity index 94% rename from frontend/src/components/CompetitionDetail/AfterCompetitionEnd.tsx rename to frontend/src/components/CompetitionDetail/AfterCompetition.tsx index 9552ac6..3be0e66 100644 --- a/frontend/src/components/CompetitionDetail/AfterCompetitionEnd.tsx +++ b/frontend/src/components/CompetitionDetail/AfterCompetition.tsx @@ -13,7 +13,7 @@ interface Props { const AFTER_COMPETITION_TEXT = ' 종료'; -export default function AfterCompetitionEnd({ +export default function AfterCompetition({ competitionId, competition, competitionSchedule, From f8439ef06ee315cde2dac69979cd0233faab7ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 22:55:15 +0900 Subject: [PATCH 10/15] =?UTF-8?q?update:=20=EB=81=9D=EB=82=9C=20=EB=8C=80?= =?UTF-8?q?=ED=9A=8C=EB=8A=94=20=EC=9E=85=EC=9E=A5=20=EB=AA=BB=20=ED=95=98?= =?UTF-8?q?=EA=B2=8C=20=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CompetitionDetail/Buttons/EnterCompetitionButton.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx b/frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx index 887765f..0512dba 100644 --- a/frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx +++ b/frontend/src/components/CompetitionDetail/Buttons/EnterCompetitionButton.tsx @@ -5,21 +5,26 @@ import useAuth from '@/hooks/login/useAuth'; interface Props { id: number; startsAt: Date; + endsAt: Date; } -export default function EnterCompetitionButton({ id, startsAt }: Props) { - const currentTime = new Date(); +export default function EnterCompetitionButton({ id, startsAt, endsAt }: Props) { const competitionLink = `/contest/${id}`; const { isLoggedin } = useAuth(); const navigate = useNavigate(); const handleNavigate = () => { + const currentTime = new Date(); + if (!isLoggedin) { alert('로그인이 필요합니다.'); navigate('/login'); } else if (currentTime < startsAt) { alert('아직 대회가 시작되지 않았습니다. 다시 시도해주세요'); window.location.reload(); + } else if (currentTime >= endsAt) { + alert('해당 대회는 종료되었습니다.'); + window.location.reload(); } else { navigate(competitionLink); } From 15235b872a2cd9a610b8d73b20415bc239102821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 22:56:07 +0900 Subject: [PATCH 11/15] =?UTF-8?q?feat:=20=ED=95=9C=EA=B5=AD=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EA=B8=B0=EC=A4=80=2024=EC=8B=9C=20=ED=91=9C?= =?UTF-8?q?=EA=B8=B0=EB=B2=95=EC=9C=BC=EB=A1=9C=20=EB=82=A0=EC=A7=9C?= =?UTF-8?q?=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/utils/date/index.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontend/src/utils/date/index.ts b/frontend/src/utils/date/index.ts index 96ed403..1e4e4a6 100644 --- a/frontend/src/utils/date/index.ts +++ b/frontend/src/utils/date/index.ts @@ -31,3 +31,14 @@ export const formatMilliSecond = (ms: number, form: string) => { } return ''; }; + +export const formatKoreanDateTime = (date: Date) => { + return date.toLocaleString('ko-KR', { + year: 'numeric', + month: 'numeric', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + hour12: false, + }); +}; From 3c7f46fe8230bb9241a8d33b8a4a21c0ea44b5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Tue, 28 Nov 2023 22:56:49 +0900 Subject: [PATCH 12/15] =?UTF-8?q?refactor:=20=EB=8C=80=ED=9A=8C=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EB=B0=8F=20=EC=A2=85=EB=A3=8C=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=EC=9D=84=2012=EC=8B=9C=20=ED=91=9C=EA=B8=B0=EB=B2=95?= =?UTF-8?q?=EC=97=90=EC=84=9C=2024=EC=8B=9C=20=ED=91=9C=EA=B8=B0=EB=B2=95?= =?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 --- .../CompetitionDetail/BeforeCompetition.tsx | 4 +++- .../CompetitionDetailContent.tsx | 16 ++++++++++++---- .../CompetitionDetail/DuringCompetition.tsx | 4 +++- frontend/src/pages/CompetitionDetailPage.tsx | 5 +++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx b/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx index aa573c3..a129b0a 100644 --- a/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx +++ b/frontend/src/components/CompetitionDetail/BeforeCompetition.tsx @@ -10,6 +10,7 @@ interface Props { competitionId: number; competition: CompetitionInfo; startsAt: Date; + endsAt: Date; competitionSchedule: string; } @@ -17,6 +18,7 @@ export default function BeforeCompetition({ competitionId, competition, startsAt, + endsAt, competitionSchedule, }: Props) { const BEFORE_COMPETITION_TEXT = ` 시작 전`; @@ -30,7 +32,7 @@ export default function BeforeCompetition({ />
- +
); diff --git a/frontend/src/components/CompetitionDetail/CompetitionDetailContent.tsx b/frontend/src/components/CompetitionDetail/CompetitionDetailContent.tsx index 0e3b1f0..da83829 100644 --- a/frontend/src/components/CompetitionDetail/CompetitionDetailContent.tsx +++ b/frontend/src/components/CompetitionDetail/CompetitionDetailContent.tsx @@ -1,6 +1,6 @@ // CompetitionDetailContent.js import { CompetitionInfo } from '@/apis/competitions'; -import AfterCompetitionEnd from '@/components/CompetitionDetail/AfterCompetitionEnd'; +import AfterCompetition from '@/components/CompetitionDetail/AfterCompetition'; import BeforeCompetition from '@/components/CompetitionDetail/BeforeCompetition'; import DuringCompetition from '@/components/CompetitionDetail/DuringCompetition'; @@ -22,10 +22,18 @@ export function CompetitionDetailContent({ const currentDate = new Date(); if (currentDate < startsAt) { - return ; + return ( + + ); } else if (currentDate < endsAt) { - return ; + return ( + + ); } else { - return ; + return ; } } diff --git a/frontend/src/components/CompetitionDetail/DuringCompetition.tsx b/frontend/src/components/CompetitionDetail/DuringCompetition.tsx index 86743eb..5fbbcd6 100644 --- a/frontend/src/components/CompetitionDetail/DuringCompetition.tsx +++ b/frontend/src/components/CompetitionDetail/DuringCompetition.tsx @@ -9,6 +9,7 @@ interface Props { competitionId: number; competition: CompetitionInfo; startsAt: Date; + endsAt: Date; competitionSchedule: string; } @@ -18,6 +19,7 @@ export default function DuringCompetition({ competitionId, competition, startsAt, + endsAt, competitionSchedule, }: Props) { return ( @@ -27,7 +29,7 @@ export default function DuringCompetition({ text={DURING_COMPETITION_TEXT} competitionSchedule={competitionSchedule} /> - +
); } diff --git a/frontend/src/pages/CompetitionDetailPage.tsx b/frontend/src/pages/CompetitionDetailPage.tsx index 2cb3ffc..cdcee0d 100644 --- a/frontend/src/pages/CompetitionDetailPage.tsx +++ b/frontend/src/pages/CompetitionDetailPage.tsx @@ -3,6 +3,7 @@ import { useParams } from 'react-router-dom'; import { CompetitionDetailContent } from '@/components/CompetitionDetail/CompetitionDetailContent'; import Header from '@/components/Header'; import { useCompetition } from '@/hooks/competition'; +import { formatKoreanDateTime } from '@/utils/date'; export default function CompetitionDetailPage() { const { id } = useParams<{ id: string }>(); @@ -11,8 +12,8 @@ export default function CompetitionDetailPage() { // 대회 상태에 따른 페이지를 구성하기 위해 현재 날짜, 시작 시간, 종료 시간을 가져옴 const startsAt = new Date(competition?.startsAt || ''); const endsAt = new Date(competition?.endsAt || ''); - const formattedStartsAt = startsAt.toLocaleString(); - const formattedEndsAt = endsAt.toLocaleString(); + const formattedStartsAt = formatKoreanDateTime(startsAt); + const formattedEndsAt = formatKoreanDateTime(endsAt); const competitionSchedule = `시작: ${formattedStartsAt} 종료: ${formattedEndsAt}`; From 7dc0fb304e1616f9f8821e4a6de8c4d4518288f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:44:47 +0900 Subject: [PATCH 13/15] =?UTF-8?q?feat:=20formatKoreanDateTime=EC=9D=B4=20'?= =?UTF-8?q?yyyy.mm.dd.=20hh:mm'=EC=9D=84=20=EB=B0=9B=EC=95=84=EB=8F=84=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/utils/date/index.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/frontend/src/utils/date/index.ts b/frontend/src/utils/date/index.ts index 1e4e4a6..3541ad1 100644 --- a/frontend/src/utils/date/index.ts +++ b/frontend/src/utils/date/index.ts @@ -32,13 +32,18 @@ export const formatMilliSecond = (ms: number, form: string) => { return ''; }; -export const formatKoreanDateTime = (date: Date) => { - return date.toLocaleString('ko-KR', { - year: 'numeric', - month: 'numeric', - day: 'numeric', - hour: 'numeric', - minute: 'numeric', - hour12: false, - }); +export const formatKoreanDateTime = (dateString: string | number | Date) => { + const date = new Date(dateString); + if (isNaN(date.getTime())) { + // Invalid date, handle error or return default value + return 'Invalid Date'; + } + + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + + return `${year}. ${month}. ${day}. ${hours}:${minutes}`; }; From a9243a36f72dff0d6697bfa3049ba8e7938eadf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:02:38 +0900 Subject: [PATCH 14/15] =?UTF-8?q?refactor:=20formatDate=ED=95=A8=EC=88=98?= =?UTF-8?q?=20=ED=99=95=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/utils/date/index.ts | 34 +++++++++++++++++++------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/frontend/src/utils/date/index.ts b/frontend/src/utils/date/index.ts index 3541ad1..0658dc0 100644 --- a/frontend/src/utils/date/index.ts +++ b/frontend/src/utils/date/index.ts @@ -16,6 +16,17 @@ export const formatDate = (date: Date, form: string) => { return date.toISOString().slice(0, 'YYYY-MM-DDThh:mm'.length); } + if (form === 'YYYY. MM. DD. hh:mm') { + return date.toLocaleString('ko-KR', { + year: 'numeric', + month: 'numeric', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + hour12: false, + }); + } + return ''; }; @@ -32,18 +43,13 @@ export const formatMilliSecond = (ms: number, form: string) => { return ''; }; -export const formatKoreanDateTime = (dateString: string | number | Date) => { - const date = new Date(dateString); - if (isNaN(date.getTime())) { - // Invalid date, handle error or return default value - return 'Invalid Date'; - } - - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const day = String(date.getDate()).padStart(2, '0'); - const hours = String(date.getHours()).padStart(2, '0'); - const minutes = String(date.getMinutes()).padStart(2, '0'); - - return `${year}. ${month}. ${day}. ${hours}:${minutes}`; +export const formatKoreanDateTime = (date: Date) => { + return date.toLocaleString('ko-KR', { + year: 'numeric', + month: 'numeric', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + hour12: false, + }); }; From 82231ee7961062c1cb8b52af9a28a6162e745d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=9A=B0=EC=B0=AC?= <132538081+dmdmdkdkr@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:09:04 +0900 Subject: [PATCH 15/15] =?UTF-8?q?refactor:=20formatDate=ED=95=A8=EC=88=98?= =?UTF-8?q?=20=ED=99=95=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/CompetitionDetailPage.tsx | 6 +++--- frontend/src/utils/date/index.ts | 11 ----------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/frontend/src/pages/CompetitionDetailPage.tsx b/frontend/src/pages/CompetitionDetailPage.tsx index cdcee0d..8a4ad72 100644 --- a/frontend/src/pages/CompetitionDetailPage.tsx +++ b/frontend/src/pages/CompetitionDetailPage.tsx @@ -3,7 +3,7 @@ import { useParams } from 'react-router-dom'; import { CompetitionDetailContent } from '@/components/CompetitionDetail/CompetitionDetailContent'; import Header from '@/components/Header'; import { useCompetition } from '@/hooks/competition'; -import { formatKoreanDateTime } from '@/utils/date'; +import { formatDate } from '@/utils/date'; export default function CompetitionDetailPage() { const { id } = useParams<{ id: string }>(); @@ -12,8 +12,8 @@ export default function CompetitionDetailPage() { // 대회 상태에 따른 페이지를 구성하기 위해 현재 날짜, 시작 시간, 종료 시간을 가져옴 const startsAt = new Date(competition?.startsAt || ''); const endsAt = new Date(competition?.endsAt || ''); - const formattedStartsAt = formatKoreanDateTime(startsAt); - const formattedEndsAt = formatKoreanDateTime(endsAt); + const formattedStartsAt = formatDate(startsAt, 'YYYY. MM. DD. hh:mm'); + const formattedEndsAt = formatDate(endsAt, 'YYYY. MM. DD. hh:mm'); const competitionSchedule = `시작: ${formattedStartsAt} 종료: ${formattedEndsAt}`; diff --git a/frontend/src/utils/date/index.ts b/frontend/src/utils/date/index.ts index 0658dc0..8b01e7a 100644 --- a/frontend/src/utils/date/index.ts +++ b/frontend/src/utils/date/index.ts @@ -42,14 +42,3 @@ export const formatMilliSecond = (ms: number, form: string) => { } return ''; }; - -export const formatKoreanDateTime = (date: Date) => { - return date.toLocaleString('ko-KR', { - year: 'numeric', - month: 'numeric', - day: 'numeric', - hour: 'numeric', - minute: 'numeric', - hour12: false, - }); -};