From afe891831a84d2dbf6ad77cd1f7538828b027953 Mon Sep 17 00:00:00 2001 From: iOdiO89 <117376841+iOdiO89@users.noreply.github.com> Date: Tue, 25 Jun 2024 00:52:58 +0900 Subject: [PATCH 01/29] =?UTF-8?q?fix:=20=EB=82=B4=EA=B0=80=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=ED=95=9C=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/home/challenge.tsx | 21 +++++++++++++++------ components/home/challengeBox.tsx | 8 ++++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/components/home/challenge.tsx b/components/home/challenge.tsx index 3015706..29f068d 100644 --- a/components/home/challenge.tsx +++ b/components/home/challenge.tsx @@ -3,12 +3,17 @@ import FlexBox from "../Flexbox"; import { useRouter } from "next/router"; import { useAtom } from "jotai"; import { isAdminAtom } from "@/utils/atom"; +import { Challenge as ChallengeType } from "@/apis/challenge"; interface ChallengeProps { setIsModalVisible: React.Dispatch>; + challengeInfo: ChallengeType; } -const Challenge: NextPage = ({ setIsModalVisible }) => { +const Challenge: NextPage = ({ + setIsModalVisible, + challengeInfo, +}) => { const router = useRouter(); const [isAdmin] = useAtom(isAdminAtom); @@ -20,10 +25,14 @@ const Challenge: NextPage = ({ setIsModalVisible }) => { onClick={isAdmin ? null : () => router.push("/challenge")} > -
풍물패 두드림
-
12명 참여 중
+
{challengeInfo.name}
+
+ {challengeInfo.participantsNum}명 참여 중 +
-
서울시립도서관 4층 | 월 16시
+
+ {challengeInfo.location} | {challengeInfo.schedule} +
= ({ setIsModalVisible }) => { {!isAdmin && (
개인달성률
-
100%
+
{challengeInfo.attendanceRate}%
)}
전체달성률
-
100%
+
{challengeInfo.totalAttendanceRate}%
void; @@ -19,6 +20,8 @@ const HomeChallenge: NextPage = ({ onNotify }) => { const [isAdmin] = useAtom(isAdminAtom); const [isOpen, setIsOpen] = useState(false); + const { data: challengeInfo } = useGetMyChallengeList(); + return (
@@ -31,8 +34,9 @@ const HomeChallenge: NextPage = ({ onNotify }) => { > {isAdmin ? "새 프로그램 등록" : "참여 프로그램 추가"}
- - + {challengeInfo.result.map((info) => ( + + ))} Date: Tue, 25 Jun 2024 12:59:09 +0900 Subject: [PATCH 02/29] =?UTF-8?q?feat:=20/challenge/ads=20get=20API=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apis/challenge.ts | 15 ++++++++++++++- apis/client.ts | 6 +++++- apis/hooks/challenge.ts | 13 +++++++++++-- components/home/carousel.tsx | 23 ++++++++++++++++++----- components/home/popular.tsx | 34 ++++++++++++++++++++++++++++++---- 5 files changed, 78 insertions(+), 13 deletions(-) diff --git a/apis/challenge.ts b/apis/challenge.ts index 4eea8ac..48c7a21 100644 --- a/apis/challenge.ts +++ b/apis/challenge.ts @@ -13,9 +13,22 @@ export interface Challenge { attendanceRate: number; totalAttendanceRate: number; } +interface GetChallengeAdsResponse extends ResponseBody2 { + result: { + mostParticipatedChallenge: Challenge; + mostAttendancedChallenge: Challenge; + mostRecentlyStartedChallenge: Challenge; + }; +} + async function getMyChallengeList(): Promise { const { data } = await client.get(`/challenges`); return data; } -export { getMyChallengeList }; +async function getChallengeAds(): Promise { + const { data } = await client.get(`/challenges/ads`); + return data; +} + +export { getMyChallengeList, getChallengeAds }; diff --git a/apis/client.ts b/apis/client.ts index c3dbd5a..04a1d94 100644 --- a/apis/client.ts +++ b/apis/client.ts @@ -5,6 +5,10 @@ interface ResponseBody { code: number; message: string; } +interface ResponseBody2 { + isSuccess: boolean; + message: string; +} export const setTokenFromLocalStorage = (access_token: string) => { localStorage.setItem("access_token", access_token); @@ -49,4 +53,4 @@ client.interceptors.request.use( ); export default client; -export type { ResponseBody }; +export type { ResponseBody, ResponseBody2 }; diff --git a/apis/hooks/challenge.ts b/apis/hooks/challenge.ts index 0ab0369..4ac797d 100644 --- a/apis/hooks/challenge.ts +++ b/apis/hooks/challenge.ts @@ -1,4 +1,4 @@ -import { getMyChallengeList } from "../challenge"; +import { getChallengeAds, getMyChallengeList } from "../challenge"; import { useQuery } from "@tanstack/react-query"; function useGetMyChallengeList() { @@ -10,4 +10,13 @@ function useGetMyChallengeList() { return { data }; } -export { useGetMyChallengeList }; +function useGetChallengeAds() { + const { data } = useQuery({ + queryKey: ["getChallengeAds"], + queryFn: getChallengeAds, + }); + + return { data }; +} + +export { useGetMyChallengeList, useGetChallengeAds }; diff --git a/components/home/carousel.tsx b/components/home/carousel.tsx index 53e2f8e..f59c99d 100644 --- a/components/home/carousel.tsx +++ b/components/home/carousel.tsx @@ -1,19 +1,32 @@ import { NextPage } from "next"; import FlexBox from "../Flexbox"; -import { PopularChallenge } from "./popular"; +import PopularChallenge from "./popular"; import useEmblaCarousel from "embla-carousel-react"; import Autoplay from "embla-carousel-autoplay"; +import { useGetChallengeAds } from "@/apis/hooks/challenge"; -export const HomeCarousel: NextPage = () => { +const HomeCarousel: NextPage = () => { const [emblaRef] = useEmblaCarousel({ loop: true }, [Autoplay()]); + const { data } = useGetChallengeAds(); return (
- - - + + +
); }; + +export default HomeCarousel; diff --git a/components/home/popular.tsx b/components/home/popular.tsx index 280a64d..354c03b 100644 --- a/components/home/popular.tsx +++ b/components/home/popular.tsx @@ -2,15 +2,41 @@ import { NextPage } from "next"; import FlexBox from "../Flexbox"; import React from "react"; import useEmblaCarousel from "embla-carousel-react"; +import { Challenge } from "@/apis/challenge"; + +interface PopularChallengeProps { + challengeInfo: Challenge; + type: + | "mostParticipatedChallenge" + | "mostAttendancedChallenge" + | "mostRecentlyStartedChallenge"; +} + +export default function PopularChallenge({ + challengeInfo, + type, +}: PopularChallengeProps) { + const returnTitle = () => { + switch (type) { + case "mostAttendancedChallenge": + return "출석률이 가장 높은 챌린지 🔥"; + break; + case "mostParticipatedChallenge": + return "참여자가 가장 많은 챌린지 🔥"; + break; + case "mostRecentlyStartedChallenge": + return "가장 최근에 개설된 챌린지 🔥"; + break; + } + }; -export const PopularChallenge: NextPage = () => { return ( -
참여자가 가장 많은 챌린지 🔥
-
레전드 영화보기 챌린지
+
{returnTitle()}
+
{challengeInfo?.name}
); -}; +} From 49d76a4b5a711e5e0469ee453efe44d9f827267f Mon Sep 17 00:00:00 2001 From: iOdiO89 <117376841+iOdiO89@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:59:28 +0900 Subject: [PATCH 03/29] =?UTF-8?q?fix:=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20?= =?UTF-8?q?=EC=9D=B8=EC=A6=9D=20=EB=AA=A8=EB=8B=AC=20title=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/home/certifyModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/home/certifyModal.tsx b/components/home/certifyModal.tsx index 0e8bbba..22c3532 100644 --- a/components/home/certifyModal.tsx +++ b/components/home/certifyModal.tsx @@ -27,7 +27,7 @@ export default function CertifyModal({ return ( <> -
풍물패 두드림 챌린지 인증하기
+
챌린지 인증하기
setIsModalVisible(false)}>
From 6bb9879a96bd2d860da159f452e980ded7006edc Mon Sep 17 00:00:00 2001 From: iOdiO89 <117376841+iOdiO89@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:59:48 +0900 Subject: [PATCH 04/29] =?UTF-8?q?fix:=20=EC=B0=B8=EC=97=AC=20=EC=A4=91?= =?UTF-8?q?=EC=9D=B8=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?Key=20props=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/home/challengeBox.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/components/home/challengeBox.tsx b/components/home/challengeBox.tsx index 04493a1..aae9041 100644 --- a/components/home/challengeBox.tsx +++ b/components/home/challengeBox.tsx @@ -1,7 +1,7 @@ import { NextPage } from "next"; import FlexBox from "../Flexbox"; import Challenge from "./challenge"; -import { HomeCarousel } from "./carousel"; +import HomeCarousel from "./carousel"; import { useRouter } from "next/router"; import { isAdminAtom } from "@/utils/atom"; import { useAtom } from "jotai"; @@ -34,8 +34,12 @@ const HomeChallenge: NextPage = ({ onNotify }) => { > {isAdmin ? "새 프로그램 등록" : "참여 프로그램 추가"}
- {challengeInfo.result.map((info) => ( - + {challengeInfo?.result.map((info) => ( + ))} Date: Tue, 25 Jun 2024 17:44:33 +0900 Subject: [PATCH 05/29] =?UTF-8?q?feat:=20/challenges/participation=20&=20/?= =?UTF-8?q?challenges/particiation=20API=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apis/challenge.ts | 27 +++++++++++++++++++-- apis/hooks/challenge.ts | 40 +++++++++++++++++++++++++++++--- components/home/searchResult.tsx | 24 +++++++++++++++---- pages/challenge/join.tsx | 12 ++++++---- 4 files changed, 90 insertions(+), 13 deletions(-) diff --git a/apis/challenge.ts b/apis/challenge.ts index 48c7a21..3ea3c3b 100644 --- a/apis/challenge.ts +++ b/apis/challenge.ts @@ -1,4 +1,4 @@ -import client, { ResponseBody } from "./client"; +import client, { ResponseBody, ResponseBody2 } from "./client"; interface GetMyChallengeListResponse extends ResponseBody { result: Challenge[]; @@ -21,6 +21,10 @@ interface GetChallengeAdsResponse extends ResponseBody2 { }; } +interface getChallengeSearchResponse extends ResponseBody2 { + result: Challenge[]; +} + async function getMyChallengeList(): Promise { const { data } = await client.get(`/challenges`); return data; @@ -31,4 +35,23 @@ async function getChallengeAds(): Promise { return data; } -export { getMyChallengeList, getChallengeAds }; +async function getChallengeSearch( + keyword: string, +): Promise { + const { data } = await client.get(`/challenges/search?searchWord=${keyword}`); + return data; +} + +async function postNewChallenge(challengeIdx: number): Promise { + const { data } = await client.post(`/challenges/participation`, { + challengeIdx, + }); + return data; +} + +export { + getMyChallengeList, + getChallengeAds, + getChallengeSearch, + postNewChallenge, +}; diff --git a/apis/hooks/challenge.ts b/apis/hooks/challenge.ts index 4ac797d..0a48418 100644 --- a/apis/hooks/challenge.ts +++ b/apis/hooks/challenge.ts @@ -1,5 +1,10 @@ -import { getChallengeAds, getMyChallengeList } from "../challenge"; -import { useQuery } from "@tanstack/react-query"; +import { + getChallengeAds, + getChallengeSearch, + getMyChallengeList, + postNewChallenge, +} from "../challenge"; +import { useMutation, useQuery } from "@tanstack/react-query"; function useGetMyChallengeList() { const { data } = useQuery({ @@ -19,4 +24,33 @@ function useGetChallengeAds() { return { data }; } -export { useGetMyChallengeList, useGetChallengeAds }; +function useGetChallengeSearch(keyword: string) { + const { data } = useQuery({ + queryKey: ["getChallengeSearch", keyword], + queryFn: () => getChallengeSearch(keyword), + enabled: keyword.trim().length !== 0, + }); + + return { data }; +} + +function usePostNewChallenge( + challengeIdx: number, + challengeName: string, + notify: (title: string) => void, +) { + const { mutate } = useMutation({ + mutationKey: ["postNewChallenge", challengeIdx], + mutationFn: () => postNewChallenge(challengeIdx), + onSuccess: () => notify(challengeName), + }); + + return { mutate }; +} + +export { + useGetMyChallengeList, + useGetChallengeAds, + useGetChallengeSearch, + usePostNewChallenge, +}; diff --git a/components/home/searchResult.tsx b/components/home/searchResult.tsx index e17273d..eafaf19 100644 --- a/components/home/searchResult.tsx +++ b/components/home/searchResult.tsx @@ -1,15 +1,31 @@ +import { Challenge } from "@/apis/challenge"; import FlexBox from "../Flexbox"; +import { usePostNewChallenge } from "@/apis/hooks/challenge"; interface SearchResultProps { - onClick?: () => void; + notify: (title: string) => void; + challengeInfo: Challenge; } -export default function SearchResult({ onClick }: SearchResultProps) { +export default function SearchResult({ + notify, + challengeInfo, +}: SearchResultProps) { + const { mutate } = usePostNewChallenge( + challengeInfo.challengeIdx, + challengeInfo.name, + notify, + ); + + const onClick = () => mutate(); + return ( -
풍물패 두드림
-
서울시립도서관 4층 | 월 16시
+
{challengeInfo.name}
+
+ {challengeInfo.location} | {challengeInfo.schedule} +
참여 diff --git a/pages/challenge/join.tsx b/pages/challenge/join.tsx index 25f56db..79e869b 100644 --- a/pages/challenge/join.tsx +++ b/pages/challenge/join.tsx @@ -1,3 +1,4 @@ +import { useGetChallengeSearch } from "@/apis/hooks/challenge"; import Divider from "@/components/Divider"; import HeadFunction from "@/components/HeadFunction"; import NavBar from "@/components/NavBar"; @@ -12,8 +13,10 @@ import "react-toastify/dist/ReactToastify.css"; const JoinChallenge: NextPage = () => { const [keyword, setKeyword] = useState(""); - const notify = () => { - toast.success("(챌린지이름)에 성공적으로 참여하셨습니다.", { + const { data } = useGetChallengeSearch(keyword); + + const notify = (title: string) => { + toast.success(`${title}에 성공적으로 참여하셨습니다.`, { position: "bottom-center", icon: ({ theme, type }) => ( @@ -27,8 +30,9 @@ const JoinChallenge: NextPage = () => {
- - + {data?.result.map((info) => ( + + ))}
Date: Tue, 25 Jun 2024 17:46:50 +0900 Subject: [PATCH 06/29] =?UTF-8?q?fix:=20Next/Image=20=EB=8C=80=EC=8B=A0=20?= =?UTF-8?q?=EC=A7=81=EC=A0=91=20import=20=ED=95=B4=EC=84=9C=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/home/carousel.tsx | 2 +- components/mypage/profile.tsx | 3 ++- pages/challenge/join.tsx | 5 ++--- pages/index.tsx | 7 +++---- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/components/home/carousel.tsx b/components/home/carousel.tsx index f59c99d..422c7ef 100644 --- a/components/home/carousel.tsx +++ b/components/home/carousel.tsx @@ -10,7 +10,7 @@ const HomeCarousel: NextPage = () => { const { data } = useGetChallengeAds(); return ( -
+
서울복지관 관리자
- + ); } diff --git a/pages/challenge/join.tsx b/pages/challenge/join.tsx index 79e869b..8df79f1 100644 --- a/pages/challenge/join.tsx +++ b/pages/challenge/join.tsx @@ -9,6 +9,7 @@ import Image from "next/image"; import { useState } from "react"; import { toast, ToastContainer, Zoom } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; +import CheckIcon from "@/public/svgs/Check.svg"; const JoinChallenge: NextPage = () => { const [keyword, setKeyword] = useState(""); @@ -18,9 +19,7 @@ const JoinChallenge: NextPage = () => { const notify = (title: string) => { toast.success(`${title}에 성공적으로 참여하셨습니다.`, { position: "bottom-center", - icon: ({ theme, type }) => ( - - ), + icon: ({ theme, type }) => , }); }; diff --git a/pages/index.tsx b/pages/index.tsx index 881a1fe..d5b3001 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -2,21 +2,20 @@ import HeadFunction from "@/components/HeadFunction"; import { NextPage } from "next"; import NavBar from "@/components/NavBar"; import Challenge from "@/components/home/challenge"; -import { HomeCarousel } from "@/components/home/carousel"; +import HomeCarousel from "@/components/home/carousel"; import { HomeHeader } from "@/components/home/header"; import HomeChallenge from "@/components/home/challengeBox"; import FlexBox from "@/components/Flexbox"; import { ToastContainer, Zoom, toast } from "react-toastify"; import Image from "next/image"; import "react-toastify/dist/ReactToastify.css"; +import CheckIcon from "@/public/svgs/Check.svg"; const Home: NextPage = () => { const notify = (msg: string) => { toast.success(msg, { position: "bottom-center", - icon: ({ theme, type }) => ( - - ), + icon: ({ theme, type }) => , }); }; From 91f596e1e2456d85edbc47fd8baff6209ec58555 Mon Sep 17 00:00:00 2001 From: leejin_rho <52371699+leejin-rho@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:52:23 +0900 Subject: [PATCH 07/29] Update nextjs.yml --- .github/workflows/nextjs.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/nextjs.yml b/.github/workflows/nextjs.yml index 57b7d09..c9aab73 100644 --- a/.github/workflows/nextjs.yml +++ b/.github/workflows/nextjs.yml @@ -30,6 +30,10 @@ jobs: # Build job build: runs-on: ubuntu-latest + + env: + NEXT_PUBLIC_API_URL: ${{secrets.NEXT_PUBLIC_API_URL}} + steps: - name: Checkout uses: actions/checkout@v4 From bcd45cd09baa267db7b20bf1132d4100d274519b Mon Sep 17 00:00:00 2001 From: leejin_rho Date: Thu, 27 Jun 2024 14:09:09 +0900 Subject: [PATCH 08/29] =?UTF-8?q?fix:=20gitignore=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 581a22a..d76b553 100644 --- a/.gitignore +++ b/.gitignore @@ -13,8 +13,8 @@ /.next/ /out/ -# production -/build +# # production +# /build # misc .DS_Store From ee357e80c0ae805b341cafa44e34d6b63a015c35 Mon Sep 17 00:00:00 2001 From: leejin_rho <52371699+leejin-rho@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:25:29 +0900 Subject: [PATCH 09/29] Update nextjs.yml --- .github/workflows/nextjs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/nextjs.yml b/.github/workflows/nextjs.yml index c9aab73..2340a2e 100644 --- a/.github/workflows/nextjs.yml +++ b/.github/workflows/nextjs.yml @@ -87,6 +87,9 @@ jobs: uses: actions/upload-pages-artifact@v3 with: path: ./out + - name: Check environment variable + run: echo $NEXT_PUBLIC_API_URL + # Deployment job deploy: From a73895e7edc69b6e6defa81b761fe23738788496 Mon Sep 17 00:00:00 2001 From: leejin_rho Date: Thu, 27 Jun 2024 14:26:23 +0900 Subject: [PATCH 10/29] =?UTF-8?q?fix:=20next.config.js=20env=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next.config.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/next.config.js b/next.config.js index feae51b..7c6ec5f 100644 --- a/next.config.js +++ b/next.config.js @@ -16,6 +16,10 @@ const nextConfig = { styledComponents: true, }, output: "export", + + env: { + NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL, + }, }; module.exports = nextConfig; From ff37fee3e6fc391f9ffd15848e7a2612b9cd8bf3 Mon Sep 17 00:00:00 2001 From: leejin_rho <52371699+leejin-rho@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:40:37 +0900 Subject: [PATCH 11/29] Update nextjs.yml --- .github/workflows/nextjs.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nextjs.yml b/.github/workflows/nextjs.yml index 2340a2e..bc11cdd 100644 --- a/.github/workflows/nextjs.yml +++ b/.github/workflows/nextjs.yml @@ -79,6 +79,11 @@ jobs: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}- - name: Install dependencies run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }} + - name: Check environment variable + run: echo NEXT_PUBLIC_API_URL + - name: Create .env file + run: | + echo NEXT_PUBLIC_API_URL=${{ secrets.NEXT_PUBLIC_API_URL }} >> .env - name: Build with Next.js run: ${{ steps.detect-package-manager.outputs.runner }} next build - name: Export with Next.js @@ -87,8 +92,6 @@ jobs: uses: actions/upload-pages-artifact@v3 with: path: ./out - - name: Check environment variable - run: echo $NEXT_PUBLIC_API_URL # Deployment job From aa09ec085cff81f511427fa94de1bfe28b7ac0a8 Mon Sep 17 00:00:00 2001 From: iOdiO89 <117376841+iOdiO89@users.noreply.github.com> Date: Fri, 28 Jun 2024 18:13:51 +0900 Subject: [PATCH 12/29] =?UTF-8?q?fix:=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20?= =?UTF-8?q?=EA=B4=91=EA=B3=A0=20Undefined=20=EC=9D=BC=20=EB=95=8C=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EB=82=98=EC=A7=80=20=EC=95=8A=EA=B2=8C=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/home/carousel.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/home/carousel.tsx b/components/home/carousel.tsx index 422c7ef..dcd6c07 100644 --- a/components/home/carousel.tsx +++ b/components/home/carousel.tsx @@ -13,15 +13,15 @@ const HomeCarousel: NextPage = () => {
From b98ed30a2226baabe132c6625f469c072f4f40b0 Mon Sep 17 00:00:00 2001 From: iOdiO89 <117376841+iOdiO89@users.noreply.github.com> Date: Fri, 28 Jun 2024 18:14:15 +0900 Subject: [PATCH 13/29] =?UTF-8?q?fix:=20=EC=B1=8C=EB=A6=B0=EC=A7=80=20?= =?UTF-8?q?=EC=B0=B8=EC=97=AC=20=ED=9B=84=20=EB=AA=A9=EB=A1=9D=20=EC=9E=AC?= =?UTF-8?q?=EA=B2=80=EC=83=89=EB=90=98=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apis/hooks/challenge.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apis/hooks/challenge.ts b/apis/hooks/challenge.ts index 0a48418..3055a43 100644 --- a/apis/hooks/challenge.ts +++ b/apis/hooks/challenge.ts @@ -4,7 +4,7 @@ import { getMyChallengeList, postNewChallenge, } from "../challenge"; -import { useMutation, useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; function useGetMyChallengeList() { const { data } = useQuery({ @@ -39,10 +39,16 @@ function usePostNewChallenge( challengeName: string, notify: (title: string) => void, ) { + const queryClient = useQueryClient(); const { mutate } = useMutation({ mutationKey: ["postNewChallenge", challengeIdx], mutationFn: () => postNewChallenge(challengeIdx), - onSuccess: () => notify(challengeName), + onSuccess: () => { + notify(challengeName); + queryClient.invalidateQueries({ + queryKey: ["getChallengeSearch"], + }); + }, }); return { mutate }; From d1b7ac79ce7940d4984c912a761d580aa490e908 Mon Sep 17 00:00:00 2001 From: leejin_rho Date: Sun, 30 Jun 2024 18:00:45 +0900 Subject: [PATCH 14/29] =?UTF-8?q?fix:=20InfoCalendar=20UI=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 --- components/calendar/FilterBox.tsx | 13 ++++++-- components/calendar/InfoCalendar.tsx | 16 ++++++++-- pages/calendar.tsx | 44 +++++++++++++++++++++++++--- pages/login.tsx | 2 +- 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/components/calendar/FilterBox.tsx b/components/calendar/FilterBox.tsx index 40f728f..b0d1088 100644 --- a/components/calendar/FilterBox.tsx +++ b/components/calendar/FilterBox.tsx @@ -1,8 +1,17 @@ import FilterArrow from "@/public/svgs/FilterArrow.svg"; -const FilterBox = ({ filterName }) => { +const FilterBox = ({ + filterName, + onClick, +}: { + filterName: string; + onClick: () => void; +}) => { return ( -
+
{filterName}
diff --git a/components/calendar/InfoCalendar.tsx b/components/calendar/InfoCalendar.tsx index 381d1c5..e2f6dcc 100644 --- a/components/calendar/InfoCalendar.tsx +++ b/components/calendar/InfoCalendar.tsx @@ -80,7 +80,7 @@ export default function InfoCalendar() { }; return ( -
+
{ const date = new Date(); console.log(date); + + const [isDrop, setIsDrop] = useState({ + categoryDrop: false, + regionDrop: false, + }); + return (
- - + { + setIsDrop(!isDrop); + }} + /> + {isDrop ? ( +
    + {options.map((option, index) => ( +
  • {}} + > + {option} +
  • + ))} +
+ ) : null} + { + console.log("지역"); + }} + />
-
+
diff --git a/pages/login.tsx b/pages/login.tsx index 6543f99..dcfdb24 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -92,7 +92,7 @@ const Login: NextPage = () => { From ef75a707a9cfc6474afd170234221779704f96fa Mon Sep 17 00:00:00 2001 From: leejin_rho Date: Mon, 1 Jul 2024 16:23:19 +0900 Subject: [PATCH 15/29] =?UTF-8?q?feat:=20challengeDetail=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20calendar=20api=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apis/calendar.ts | 1 - apis/challenge.ts | 20 +++++- apis/hooks/challenge.ts | 12 +++- components/challenge/ChallengeCalendar.tsx | 39 +++++++---- pages/calendar.tsx | 77 ++++++++++++++-------- 5 files changed, 105 insertions(+), 44 deletions(-) diff --git a/apis/calendar.ts b/apis/calendar.ts index 19d1183..49181e3 100644 --- a/apis/calendar.ts +++ b/apis/calendar.ts @@ -48,6 +48,5 @@ export const getProgramDetail = async ( ): Promise => { // const response = await client.get(`/programs/${programIdx}`); const response = await client.get(`/programs/2`); - // console.log("calenderDetail", response.data.result); return response.data.result; }; diff --git a/apis/challenge.ts b/apis/challenge.ts index 4eea8ac..ff79fbf 100644 --- a/apis/challenge.ts +++ b/apis/challenge.ts @@ -18,4 +18,22 @@ async function getMyChallengeList(): Promise { return data; } -export { getMyChallengeList }; +type AttendanceDate = { + year: number; + month: number; + day: number; +}; + +export interface GetChallengeDetailBody { + attendanceDate: AttendanceDate; +} + +async function getChallengDetail(): Promise { + const response = await client.get( + `/challenges/attendance/2?year=2024&month=6`, + ); + // console.log("challengeData", response.data.result); + return response.data.result; +} + +export { getMyChallengeList, getChallengDetail }; diff --git a/apis/hooks/challenge.ts b/apis/hooks/challenge.ts index 0ab0369..80128a4 100644 --- a/apis/hooks/challenge.ts +++ b/apis/hooks/challenge.ts @@ -1,4 +1,4 @@ -import { getMyChallengeList } from "../challenge"; +import { getMyChallengeList, getChallengDetail } from "../challenge"; import { useQuery } from "@tanstack/react-query"; function useGetMyChallengeList() { @@ -10,4 +10,12 @@ function useGetMyChallengeList() { return { data }; } -export { useGetMyChallengeList }; +function useGetChallengeDetail() { + const { data } = useQuery({ + queryKey: ["getChallengeDetail"], + queryFn: getChallengDetail, + }); + return { data }; +} + +export { useGetMyChallengeList, useGetChallengeDetail }; diff --git a/components/challenge/ChallengeCalendar.tsx b/components/challenge/ChallengeCalendar.tsx index 0e78857..ccc5287 100644 --- a/components/challenge/ChallengeCalendar.tsx +++ b/components/challenge/ChallengeCalendar.tsx @@ -2,6 +2,8 @@ import Calendar from "react-calendar"; import { useState } from "react"; import styled from "styled-components"; import LogoMark from "@/public/svgs/LogoMark.svg"; +import { useGetChallengeDetail } from "@/apis/hooks/challenge"; +import { GetChallengeDetailBody } from "@/apis/challenge"; export default function ChallengeCalendar() { type DatePiece = Date | null; @@ -13,18 +15,29 @@ export default function ChallengeCalendar() { setClickedDate(clickedDate); }; - const customTileContent = ({ date, view }) => { - // if (view === 'month' && DatesList.some(d => d.getTime() === date.getTime())) { - - const customDate = new Date(2024, 5, 19); - if (view === "month" && date.getTime() === customDate.getTime()) { - return ( -
-
- + // API 관리 + const { data } = useGetChallengeDetail(); + + const customTileContent = ({ date, view }: { date: Date; view: string }) => { + if (Array.isArray(data) && view === "month") { + const matchedData = data.find((challenge: GetChallengeDetailBody) => { + const attendanceDate = new Date( + challenge.attendanceDate.year, + challenge.attendanceDate.month - 1, + challenge.attendanceDate.day, + ); + return attendanceDate.getTime() === date.getTime(); + }); + + if (matchedData) { + return ( +
+
+ +
-
- ); + ); + } } return null; }; @@ -158,8 +171,8 @@ const StyledCalendarWrapper = styled.div` /* 일 */ .react-calendar__tile { text-align: center; - width: 2.5rem; - height: 3.75rem; + width: 3.25rem; + height: 3.25rem; display: flex; flex-direction: column; justify-content: center; diff --git a/pages/calendar.tsx b/pages/calendar.tsx index d94862d..b071487 100644 --- a/pages/calendar.tsx +++ b/pages/calendar.tsx @@ -11,7 +11,8 @@ interface DropProps { regionDrop: boolean; } -const options = ["Option 1", "Option 2", "Option 3"]; +const categories = ["운동", "예술", "학술"]; +const locations = ["서울", "경기", "그 외"]; const CalendarPage: NextPage = () => { const date = new Date(); @@ -22,36 +23,58 @@ const CalendarPage: NextPage = () => { regionDrop: false, }); + const toggleDrop = (dropName: string) => { + setIsDrop((prev: DropProps) => ({ ...prev, [dropName]: !prev[dropName] })); + }; + return (
-
- { - setIsDrop(!isDrop); - }} - /> - {isDrop ? ( -
    - {options.map((option, index) => ( -
  • {}} - > - {option} -
  • - ))} -
- ) : null} - { - console.log("지역"); - }} - /> +
+
+ { + toggleDrop("categoryDrop"); + console.log("category"); + }} + /> + {isDrop.categoryDrop ? ( +
    + {categories.map((option, index) => ( +
  • {}} + > + {option} +
  • + ))} +
+ ) : null} +
+
+ { + setIsDrop({ ...isDrop, regionDrop: !isDrop.regionDrop }); + }} + /> + {isDrop.regionDrop ? ( +
    + {locations.map((option, index) => ( +
  • {}} + > + {option} +
  • + ))} +
+ ) : null} +
From aa897e94ec3d42424fa443229369270b4332c94d Mon Sep 17 00:00:00 2001 From: leejin_rho Date: Mon, 1 Jul 2024 16:29:36 +0900 Subject: [PATCH 16/29] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=98=A4=EB=A5=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/login.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/login.tsx b/pages/login.tsx index dcfdb24..6543f99 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -92,7 +92,7 @@ const Login: NextPage = () => { From 72767d6b95280d5a1e9f2e9632683a59f37c4aff Mon Sep 17 00:00:00 2001 From: iOdiO89 <117376841+iOdiO89@users.noreply.github.com> Date: Mon, 1 Jul 2024 21:31:41 +0900 Subject: [PATCH 17/29] =?UTF-8?q?fix:=20=ED=94=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EB=9E=A8=20=EB=93=B1=EB=A1=9D=EC=8B=9C=20=ED=83=9C=EA=B7=B8=20?= =?UTF-8?q?Dropdown=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/challenge/ChallengeInput.tsx | 23 ++++++++++++++---- package.json | 1 + pages/_app.tsx | 1 + styles/dropdown.css | 31 +++++++++++++++++++++++++ yarn.lock | 20 ++++++++++++++++ 5 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 styles/dropdown.css diff --git a/components/challenge/ChallengeInput.tsx b/components/challenge/ChallengeInput.tsx index b4abce2..2592b19 100644 --- a/components/challenge/ChallengeInput.tsx +++ b/components/challenge/ChallengeInput.tsx @@ -1,10 +1,15 @@ import FlexBox from "../Flexbox"; import TextInput, { TextInputProps } from "../Input"; import TextArea from "../TextArea"; +import Dropdown from "react-dropdown"; +import "react-dropdown/style.css"; + +const locationOptions = ["서울", "경기", "그 외"]; +const typeOptions = ["학술", "운동", "예술", "기타"]; interface ChallengeInputProps extends TextInputProps { title: string; - inputType: "text" | "calendar" | "textarea"; + inputType: "text" | "calendar" | "textarea" | "dropdown"; value2?: string; setValue2?: React.Dispatch>; } @@ -42,16 +47,24 @@ export default function ChallengeInput({ isError={false} type="date" /> - ~ + ~ ); break; + case "dropdown": + return ( + + + + + ); + break; default: return (