From 96f3c6bcd94eda31101082702b9e1d99cd82764e Mon Sep 17 00:00:00 2001 From: joojjang Date: Tue, 15 Oct 2024 21:06:05 +0900 Subject: [PATCH 1/8] =?UTF-8?q?!HOTFIX:=20=EA=B8=80=EC=9E=90=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20(=EC=B1=8C=EB=A6=B0=EC=A7=80=20=EB=82=A0=EC=A7=9C?= =?UTF-8?q?=20=ED=8F=AC=EB=A7=B7=ED=8C=85,=20=EC=B1=8C=EB=A6=B0=EC=A7=80?= =?UTF-8?q?=20=EC=9D=B8=EC=A6=9D=20caution)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/challenge-list/components/contents/index.tsx | 7 ++++--- .../challenge-record/components/caution/index.tsx | 10 +++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/pages/challenge-list/components/contents/index.tsx b/src/pages/challenge-list/components/contents/index.tsx index b9e4f11..fa86280 100644 --- a/src/pages/challenge-list/components/contents/index.tsx +++ b/src/pages/challenge-list/components/contents/index.tsx @@ -1,5 +1,6 @@ import { useState } from 'react'; +import { formatDate } from '@/utils/formatters'; import { Box, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; @@ -29,7 +30,7 @@ const Contents = ({ onClick(id); }; - const date = `${startDate} ~ ${endDate}`; + const period = `${formatDate(startDate)} ~ ${formatDate(endDate)}`; return ( @@ -50,9 +51,9 @@ const Contents = ({ - 참여 가능 기간 + 챌린지 신청 가능 기간 - {date} + {period} ); diff --git a/src/pages/challenge-record/components/caution/index.tsx b/src/pages/challenge-record/components/caution/index.tsx index faa585d..c51a40f 100644 --- a/src/pages/challenge-record/components/caution/index.tsx +++ b/src/pages/challenge-record/components/caution/index.tsx @@ -13,14 +13,10 @@ const Caution = () => { listStylePosition='inside' fontSize='var(--font-size-xs)' > -
  • 모든 스탬프를 모으면 챌린지를 완수하게 됩니다.
  • +
  • 1일 인증 횟수에는 제한이 없습니다.
  • +
  • 모든 스탬프를 모으면 챌린지를 완료하게 됩니다.
  • - 스탬프는 하루 1개로 제한됩니다. (동일 챌린지를 하루에 여러 번 - 인증하더라도 1회만 인정됩니다.) -
  • -
  • - 명시된 횟수를 초과한 경우 챌린지 완수로 인정되나 추가 인증에 대한 - 스탬프나 포인트는 제공되지 않습니다. + 완료한 챌린지는 '완료한 챌린지 목록'에서 조회할 수 있습니다.
  • 사진 조작, 타인의 계정 이용 등의 부정 행위 적발 시 해당 계정은 강제 From 8a3eb85d4199e0dbf002444d186229466c18d9fc Mon Sep 17 00:00:00 2001 From: joojjang Date: Tue, 15 Oct 2024 21:27:08 +0900 Subject: [PATCH 2/8] =?UTF-8?q?!HOTFIX:(my-challenge):=20=EC=B1=8C?= =?UTF-8?q?=EB=A6=B0=EC=A7=80=20=EC=83=81=EC=84=B8=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=A7=81=ED=81=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/interface/apis/challenge/index.ts | 1 + .../components/challenge-list/index.tsx | 32 +++++++++++-------- src/pages/my-challenge/index.tsx | 10 +++--- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/interface/apis/challenge/index.ts b/src/interface/apis/challenge/index.ts index 1b6de75..b0cb667 100644 --- a/src/interface/apis/challenge/index.ts +++ b/src/interface/apis/challenge/index.ts @@ -1,4 +1,5 @@ export interface ChallengeData { + challengeGroupId: number; challengeId: number; title: string; successCount: number; diff --git a/src/pages/my-challenge/components/challenge-list/index.tsx b/src/pages/my-challenge/components/challenge-list/index.tsx index f6b70c6..ebaeaeb 100644 --- a/src/pages/my-challenge/components/challenge-list/index.tsx +++ b/src/pages/my-challenge/components/challenge-list/index.tsx @@ -1,4 +1,4 @@ -import { useNavigate } from 'react-router-dom'; +import { useNavigate, Link } from 'react-router-dom'; import * as S from './styles'; import NotChallenge from '@/assets/UserImage.svg'; @@ -11,15 +11,15 @@ import { Box, Image, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; type ChallengeListProps = { - challenges: ChallengeData[]; + challengeList: ChallengeData[]; }; -const ChallengeList = ({ challenges }: ChallengeListProps) => { +const ChallengeList = ({ challengeList }: ChallengeListProps) => { const navigate = useNavigate(); return ( <> - {challenges.length === 0 ? ( + {challengeList.length === 0 ? ( { ) : ( - {challenges.map((challenge, index) => ( + {challengeList.map((challenge, index) => ( { src={FinishStamp} /> - - {challenge.title} - + + {challenge.title} + + { sessionStorage.setItem('activeTab', '0'); // 선택 탭 초기화 - const [listChallenges, setListChallenges] = useState([]); + const [challengeList, setChallengeList] = useState([]); useEffect(() => { const fetchCurrentChallenges = async () => { try { - const challenges = await getCurrentChallengeList(0, 10); - setListChallenges(challenges.data.data); - console.log(challenges.data.data); + const response = await getCurrentChallengeList(0, 10); + setChallengeList(response.data.data); + console.log(response.data.data); } catch (error) { console.error('Error fetching challenges:', error); } @@ -35,7 +35,7 @@ const MyChallengePage = () => { 참여 중인 챌린지 - + From 3f377a9f2ef2edf95c85798bcbe269ec43051e44 Mon Sep 17 00:00:00 2001 From: joojjang Date: Tue, 15 Oct 2024 21:31:41 +0900 Subject: [PATCH 3/8] =?UTF-8?q?!HOTFIX(caution):=20css=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20-=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EB=93=A4?= =?UTF-8?q?=EC=97=AC=EC=93=B0=EA=B8=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/challenge-record/components/caution/index.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pages/challenge-record/components/caution/index.tsx b/src/pages/challenge-record/components/caution/index.tsx index c51a40f..81f0e9c 100644 --- a/src/pages/challenge-record/components/caution/index.tsx +++ b/src/pages/challenge-record/components/caution/index.tsx @@ -12,6 +12,12 @@ const Caution = () => { listStyleType='disc' listStylePosition='inside' fontSize='var(--font-size-xs)' + css={` + li { + padding-left: 1.4em; /* 들여쓰기 추가 */ + text-indent: -1.4em; /* 첫 줄은 들여쓰지 않음 */ + } + `} >
  • 1일 인증 횟수에는 제한이 없습니다.
  • 모든 스탬프를 모으면 챌린지를 완료하게 됩니다.
  • From dd749c87dd52a23ba91b98c0e22b6ba532342d16 Mon Sep 17 00:00:00 2001 From: joojjang Date: Tue, 15 Oct 2024 22:29:44 +0900 Subject: [PATCH 4/8] =?UTF-8?q?!HOTFIX(=EB=82=B4=20=EC=B1=8C=EB=A6=B0?= =?UTF-8?q?=EC=A7=80=20=ED=8E=98=EC=9D=B4=EC=A7=80,=20=EC=99=84=EB=A3=8C?= =?UTF-8?q?=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20=ED=8E=98=EC=9D=B4=EC=A7=80):?= =?UTF-8?q?=20=EB=B7=B0=ED=8F=AC=ED=8A=B8=20=EB=86=92=EC=9D=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95,=20=EA=B8=80=EC=9E=90=20=EC=A0=95=EB=A0=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/empty-state/index.tsx | 1 + src/pages/my-challenge-record/index.tsx | 15 +++++---------- src/pages/my-challenge/index.tsx | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/components/common/empty-state/index.tsx b/src/components/common/empty-state/index.tsx index 700f54b..fdecec8 100644 --- a/src/components/common/empty-state/index.tsx +++ b/src/components/common/empty-state/index.tsx @@ -30,5 +30,6 @@ const Wrapper = styled.div` .highlight { font-weight: 600; color: var(--color-green-03); + text-align: center; } `; diff --git a/src/pages/my-challenge-record/index.tsx b/src/pages/my-challenge-record/index.tsx index 9051c5d..a5fae94 100644 --- a/src/pages/my-challenge-record/index.tsx +++ b/src/pages/my-challenge-record/index.tsx @@ -4,6 +4,7 @@ import ListItem from './components/list-item'; import { useGetReview } from '@/apis/my-challenge-record/getReview.api'; import { ChallengeData } from '@/apis/my-challenge-record/getReview.response'; import EmptyState from '@/components/common/empty-state'; +import { NAVBAR_HEIGHT } from '@/components/features/layout/nav-bar'; import TopBar, { HEADER_HEIGHT } from '@/components/features/layout/top-bar'; import { Box, Spinner } from '@chakra-ui/react'; import styled from '@emotion/styled'; @@ -63,13 +64,8 @@ const MyChallengeRecord = () => { )) ) : ( - - - 완료한 챌린지가 존재하지 않습니다. - -
    - 어서 챌린지를 인증하여 스탬프를 채워보세요! -
    +

    완료한 챌린지가 존재하지 않습니다.

    +

    어서 챌린지를 인증하여 스탬프를 채워보세요!

    )} @@ -86,9 +82,8 @@ const MyChallengeRecord = () => { export default MyChallengeRecord; const MyChallengeRecordLayout = styled.div` - min-height: calc( - 100vh - ${HEADER_HEIGHT} - ); // 부모가 block이므로 해당 요소에 직접 높이 지정 + min-height: calc(100vh - ${HEADER_HEIGHT} - ${NAVBAR_HEIGHT}); + // 부모가 block이므로 해당 요소에 직접 높이 지정 display: flex; flex-direction: column; background-color: var(--color-green-06); diff --git a/src/pages/my-challenge/index.tsx b/src/pages/my-challenge/index.tsx index 1fb6e3b..45c0290 100644 --- a/src/pages/my-challenge/index.tsx +++ b/src/pages/my-challenge/index.tsx @@ -45,7 +45,7 @@ const MyChallengePage = () => { export default MyChallengePage; const MyChallengeLayout = styled(Box)` - min-height: calc(100vh - ${HEADER_HEIGHT}); + min-height: calc(100vh - ${HEADER_HEIGHT} - ${NAVBAR_HEIGHT}); display: flex; flex-direction: column; `; From 44fe461f885e7a7a7f6ec15cfb59149213f0f844 Mon Sep 17 00:00:00 2001 From: Dobbymin Date: Tue, 15 Oct 2024 23:18:58 +0900 Subject: [PATCH 5/8] =?UTF-8?q?Feat(challenge-completes):=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=ED=95=9C=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20api=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../challenge-completes.api.ts | 27 +++++++++++++++++++ .../challenge-completes.response.ts | 18 +++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/apis/challenge-completes/challenge-completes.api.ts create mode 100644 src/apis/challenge-completes/challenge-completes.response.ts diff --git a/src/apis/challenge-completes/challenge-completes.api.ts b/src/apis/challenge-completes/challenge-completes.api.ts new file mode 100644 index 0000000..0b956bf --- /dev/null +++ b/src/apis/challenge-completes/challenge-completes.api.ts @@ -0,0 +1,27 @@ +import { axiosClient } from '../AxiosClient'; +import { ChallengeCompletesResponse } from './challenge-completes.response'; +import { useQuery } from '@tanstack/react-query'; + +export const challengeCompletesPath = () => '/api/user/challenges/completes'; + +export const ChallengeCompletesQueryKey = [challengeCompletesPath()]; + +export const getChallengeCompletes = async ( + page: number, + size: number +): Promise => { + const response = await axiosClient.get(challengeCompletesPath(), { + params: { + page, + size, + }, + }); + return response.data; +}; + +export const useGetChallengeCompletes = (page: number, size: number) => { + return useQuery({ + queryKey: [ChallengeCompletesQueryKey, page, size], + queryFn: () => getChallengeCompletes(page, size), + }); +}; diff --git a/src/apis/challenge-completes/challenge-completes.response.ts b/src/apis/challenge-completes/challenge-completes.response.ts new file mode 100644 index 0000000..feec96c --- /dev/null +++ b/src/apis/challenge-completes/challenge-completes.response.ts @@ -0,0 +1,18 @@ +import ApiResponse from '../ApiResponse'; + +export type ChallengeData = { + id: number; + challengeGroupId: number; + title: string; + successDate: string; + category: 'HEALTH' | 'ECHO' | 'SHARE' | 'VOLUNTEER'; + reviewWritten: boolean; +}; + +export type ChallengeCompletes = { + totalPage: number; + hasNext: boolean; + data: ChallengeData[]; +}; + +export type ChallengeCompletesResponse = ApiResponse; From 22deb4986f484ea7b548b1dd15e198e0c4aa10fe Mon Sep 17 00:00:00 2001 From: Dobbymin Date: Tue, 15 Oct 2024 23:19:26 +0900 Subject: [PATCH 6/8] =?UTF-8?q?Fix(challenge-completes):=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=ED=95=9C=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20api=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/my-challenge-record/index.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/pages/my-challenge-record/index.tsx b/src/pages/my-challenge-record/index.tsx index 9051c5d..91243e1 100644 --- a/src/pages/my-challenge-record/index.tsx +++ b/src/pages/my-challenge-record/index.tsx @@ -1,8 +1,8 @@ import { useCallback, useEffect, useState } from 'react'; import ListItem from './components/list-item'; -import { useGetReview } from '@/apis/my-challenge-record/getReview.api'; -import { ChallengeData } from '@/apis/my-challenge-record/getReview.response'; +import { useGetChallengeCompletes } from '@/apis/challenge-completes/challenge-completes.api'; +import { ChallengeData } from '@/apis/challenge-completes/challenge-completes.response'; import EmptyState from '@/components/common/empty-state'; import TopBar, { HEADER_HEIGHT } from '@/components/features/layout/top-bar'; import { Box, Spinner } from '@chakra-ui/react'; @@ -11,7 +11,7 @@ import styled from '@emotion/styled'; const MyChallengeRecord = () => { const [page, setPage] = useState(0); const [allChallenges, setAllChallenges] = useState([]); - const { data, isLoading } = useGetReview(page, 20); + const { data, isLoading } = useGetChallengeCompletes(page, 20); const loadMoreChallenges = useCallback(() => { if (data?.data.hasNext && !isLoading) { @@ -54,11 +54,9 @@ const MyChallengeRecord = () => { {allChallenges.length > 0 ? ( allChallenges.map((challenge, index) => ( )) ) : ( From a4b4174a0001f75efb0c78e39d9a7d434bdcb2e6 Mon Sep 17 00:00:00 2001 From: Dobbymin Date: Tue, 15 Oct 2024 23:19:43 +0900 Subject: [PATCH 7/8] =?UTF-8?q?Fix(challenge-completes):=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../my-challenge-record/components/list-item.tsx | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/pages/my-challenge-record/components/list-item.tsx b/src/pages/my-challenge-record/components/list-item.tsx index 6da7be0..0d0523f 100644 --- a/src/pages/my-challenge-record/components/list-item.tsx +++ b/src/pages/my-challenge-record/components/list-item.tsx @@ -9,12 +9,10 @@ import styled from '@emotion/styled'; type Props = { challengeId: number; challengeTitle: string; - userNickname: string; - profileImageUrl?: string | null; }; -const ListItem = ({ challengeId, challengeTitle, profileImageUrl }: Props) => { - sessionStorage.setItem('activeTab', '0'); // 선택 탭 초기화 +const ListItem = ({ challengeId, challengeTitle }: Props) => { + sessionStorage.setItem('activeTab', '0'); const navigate = useNavigate(); @@ -51,11 +49,7 @@ const ListItem = ({ challengeId, challengeTitle, profileImageUrl }: Props) => { return ( - profile + profile handleChallengeClick(challengeId, challengeTitle)} From f274365de7ca1140bb0e154035db8367b35f2a92 Mon Sep 17 00:00:00 2001 From: joojjang Date: Tue, 15 Oct 2024 23:21:02 +0900 Subject: [PATCH 8/8] =?UTF-8?q?!HOTFIX(=EC=99=84=EB=A3=8C=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20list-item):=20=EC=9D=B8=EC=A6=9D=20?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D=20=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80,?= =?UTF-8?q?=20CTA=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=20?= =?UTF-8?q?=EB=A7=88=EC=A7=84=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/cta/index.tsx | 27 +++++++++++--- .../components/list-item.tsx | 37 +++++++++++-------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/components/common/cta/index.tsx b/src/components/common/cta/index.tsx index a54a961..c3c5ce8 100644 --- a/src/components/common/cta/index.tsx +++ b/src/components/common/cta/index.tsx @@ -1,15 +1,27 @@ import styled from '@emotion/styled'; type CTAProps = { + theme?: 'primary' | 'secondary'; label: string; display?: 'flex' | 'block'; disabled?: boolean; onClick: () => void; }; -const CTA = ({ label, display = 'flex', disabled, onClick }: CTAProps) => { +const CTA = ({ + theme = 'primary', + label, + display = 'flex', + disabled, + onClick, +}: CTAProps) => { return ( - + {label} ); @@ -20,13 +32,17 @@ export default CTA; export const CTA_CONTAINER_HEIGHT = '4rem'; const StyledCTA = styled.button<{ + theme: 'primary' | 'secondary'; display: 'flex' | 'block'; disabled?: boolean; }>` - border: none; + border: ${({ theme }) => + theme === 'primary' ? `none` : `1px solid var(--color-green-01)`}; border-radius: 10px; - background-color: var(--color-green-01); - color: var(--color-white); + background-color: ${({ theme }) => + theme === 'primary' ? `var(--color-green-01)` : `var(--color-white)`}; + color: ${({ theme }) => + theme === 'primary' ? `var(--color-white)` : `var(--color-green-01)`}; outline: none; ${({ display }) => @@ -42,7 +58,6 @@ const StyledCTA = styled.button<{ ${({ display }) => display === 'block' && ` - margin: 0 0 0 auto; padding: 6px 8px; font-size: var(--font-size-sm); font-weight: 600; diff --git a/src/pages/my-challenge-record/components/list-item.tsx b/src/pages/my-challenge-record/components/list-item.tsx index 6da7be0..7a1d2ae 100644 --- a/src/pages/my-challenge-record/components/list-item.tsx +++ b/src/pages/my-challenge-record/components/list-item.tsx @@ -1,9 +1,9 @@ -import { useNavigate } from 'react-router-dom'; +import { useNavigate, Link } from 'react-router-dom'; import ProfileImg from '@/assets/challenge/ZZAN-Green.png'; import CTA from '@/components/common/cta'; import { RouterPath } from '@/routes/path'; -import { Image } from '@chakra-ui/react'; +import { Box, Image, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; type Props = { @@ -18,7 +18,7 @@ const ListItem = ({ challengeId, challengeTitle, profileImageUrl }: Props) => { const navigate = useNavigate(); - const handleChallengeClick = ( + const handleViewRecord = ( challengeId: number, title: string, category?: string @@ -57,16 +57,22 @@ const ListItem = ({ challengeId, challengeTitle, profileImageUrl }: Props) => { width='1.5rem' /> - handleChallengeClick(challengeId, challengeTitle)} - > - {challengeTitle} - - handleReviewWrite(challengeId, challengeTitle)} - /> + + {challengeTitle} + + + handleViewRecord(challengeId, challengeTitle)} + /> + handleReviewWrite(challengeId, challengeTitle)} + /> + ); }; @@ -100,12 +106,11 @@ const ProfileContainer = styled.div` padding: 0.5rem; `; -const ChallengeTitle = styled.button` +const ChallengeTitle = styled(Text)` white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 600; font-size: 1rem; + flex: 1; `; - -const ReviewWriteButton = styled(CTA)``;