From adf2d670bf8f944c76fbd084987352ad99b10d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Mon, 11 Mar 2024 20:31:00 +0900 Subject: [PATCH 01/18] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20:=20#492=20-=20?= =?UTF-8?q?=EB=B0=9C=EC=9E=90=EC=B7=A8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/footprints/index.scss | 0 src/app/footprints/page.tsx | 5 +++++ 2 files changed, 5 insertions(+) create mode 100644 src/app/footprints/index.scss create mode 100644 src/app/footprints/page.tsx diff --git a/src/app/footprints/index.scss b/src/app/footprints/index.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/footprints/page.tsx b/src/app/footprints/page.tsx new file mode 100644 index 00000000..893a8048 --- /dev/null +++ b/src/app/footprints/page.tsx @@ -0,0 +1,5 @@ +'use client'; + +export default function FootPrintsPage() { + return
; +} From 7281ae2a39a002dfc2b67109d7220438fd35ff12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Tue, 26 Mar 2024 20:22:43 +0900 Subject: [PATCH 02/18] =?UTF-8?q?=E2=9C=A8=20:=20#492=20-=20=EB=B0=9C?= =?UTF-8?q?=EC=9E=90=EC=B7=A8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=95=98?= =?UTF-8?q?=EC=9C=84=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B0=8F=20state=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AllFootPrints/AllFootPrints.tsx | 5 +++ .../_Components/AllFootPrints/index.scss | 0 .../FootPrintFilter/FootPrintFilter.tsx | 41 +++++++++++++++++++ .../_Components/FootPrintFilter/index.scss | 0 .../FootPrintList/FootPrintList.tsx | 13 ++++++ .../_Components/FootPrintList/index.scss | 0 .../_Components/FootPrintTab/FootPrintTab.tsx | 11 +++++ .../_Components/FootPrintTab/index.scss | 0 .../_Components/MyFootPrints/MyFootPrints.tsx | 25 +++++++++++ .../_Components/MyFootPrints/index.scss | 0 src/app/footprints/page.tsx | 25 ++++++++++- 11 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 src/app/footprints/_Components/AllFootPrints/AllFootPrints.tsx create mode 100644 src/app/footprints/_Components/AllFootPrints/index.scss create mode 100644 src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx create mode 100644 src/app/footprints/_Components/FootPrintFilter/index.scss create mode 100644 src/app/footprints/_Components/FootPrintList/FootPrintList.tsx create mode 100644 src/app/footprints/_Components/FootPrintList/index.scss create mode 100644 src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx create mode 100644 src/app/footprints/_Components/FootPrintTab/index.scss create mode 100644 src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx create mode 100644 src/app/footprints/_Components/MyFootPrints/index.scss diff --git a/src/app/footprints/_Components/AllFootPrints/AllFootPrints.tsx b/src/app/footprints/_Components/AllFootPrints/AllFootPrints.tsx new file mode 100644 index 00000000..b5cc0fee --- /dev/null +++ b/src/app/footprints/_Components/AllFootPrints/AllFootPrints.tsx @@ -0,0 +1,5 @@ +import React from 'react'; + +export default function AllFootPrints() { + return
; +} diff --git a/src/app/footprints/_Components/AllFootPrints/index.scss b/src/app/footprints/_Components/AllFootPrints/index.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx new file mode 100644 index 00000000..e7f0d61a --- /dev/null +++ b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { planType } from '../MyFootPrints/MyFootPrints'; + +interface FootPrintFilterProps { + year: number; + setYear: (year: number) => void; + setPlan: (plan: planType) => void; +} + +export default function FootPrintFilter({ + year, + setYear, + setPlan, +}: FootPrintFilterProps) { + // TODO: + // 1. props로 받은 year값을 기본값으로 year-DropDown의 selectedValue로 설정 + // 2. year에 해당하는 모든 계획 리스트 state를 보유한다. + // 3. 모든 계획 리스트 state를 plan-DropDown의 options로 넣어준다. + // 4. 검색 버튼을 클릭 시, + // year-DropDown의 selectedValue 값으로 setYear() 호출 + // plan-DropDown의 selectedValue 값으로 setPlan() 호출 + + // 자체 state + // year에 해당하는 모든 계획 리스트 state + // const [selectedYear, setSelectedYear] = useState(2024); + // const [selectedPlan, setSelectedPlan] = useState({ + // planId: -1, + // planTitle: '모든 계획', + // }); + + // useEffect로 year이 바뀔 때마다, selectedPlan의 값은 "모든 계획" + return ( +
{ + setYear(year); + setPlan({ planId: -1, planTitle: '1' }); + }}> + {year} +
+ ); +} diff --git a/src/app/footprints/_Components/FootPrintFilter/index.scss b/src/app/footprints/_Components/FootPrintFilter/index.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx new file mode 100644 index 00000000..aae2d9f7 --- /dev/null +++ b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { planType } from '../MyFootPrints/MyFootPrints'; + +interface FootPrintListProps { + year: number; + plan: planType; +} + +export default function FootPrintList({ year, plan }: FootPrintListProps) { + return ( +
{`${year}와 ${plan.planTitle}에 해당하는 FootPrintList 출력`}
+ ); +} diff --git a/src/app/footprints/_Components/FootPrintList/index.scss b/src/app/footprints/_Components/FootPrintList/index.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx b/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx new file mode 100644 index 00000000..d46c6f4e --- /dev/null +++ b/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx @@ -0,0 +1,11 @@ +import React from 'react'; + +interface FootPrintTabProps { + isMyFootPrintsTab: boolean; + setMyFootPrintsTab: () => void; + setAllFootPrintsTab: () => void; +} + +export default function FootPrintTab({}: FootPrintTabProps) { + return
; +} diff --git a/src/app/footprints/_Components/FootPrintTab/index.scss b/src/app/footprints/_Components/FootPrintTab/index.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx b/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx new file mode 100644 index 00000000..fc22b62a --- /dev/null +++ b/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx @@ -0,0 +1,25 @@ +import React, { useState } from 'react'; +import FootPrintFilter from '../FootPrintFilter/FootPrintFilter'; +import FootPrintList from '../FootPrintList/FootPrintList'; + +export type planType = { + planTitle: string; + planId: number; +}; + +export default function MyFootPrints() { + const [year, setYear] = useState(2024); + const [plan, setPlan] = useState({ + planTitle: '모든 계획', + planId: -1, + }); + + // Filter에서 검색 버튼을 누르면, setYear와 setPlan이 실행되어 year과 plan이 바뀌면 + // FootPrintList에 변경된 year와 plan이 전달될 것임 + return ( +
+ + +
+ ); +} diff --git a/src/app/footprints/_Components/MyFootPrints/index.scss b/src/app/footprints/_Components/MyFootPrints/index.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/footprints/page.tsx b/src/app/footprints/page.tsx index 893a8048..59d43faf 100644 --- a/src/app/footprints/page.tsx +++ b/src/app/footprints/page.tsx @@ -1,5 +1,28 @@ 'use client'; +import { useState } from 'react'; +import AllFootPrints from './_Components/AllFootPrints/AllFootPrints'; +import FootPrintTab from './_Components/FootPrintTab/FootPrintTab'; +import MyFootPrints from './_Components/MyFootPrints/MyFootPrints'; + export default function FootPrintsPage() { - return
; + const [isMyFootPrintsTab, setIsMyFootPrintsTab] = useState(true); + const setMyFootPrintsTab = () => { + setIsMyFootPrintsTab(true); + }; + + const setAllFootPrintsTab = () => { + setIsMyFootPrintsTab(false); + }; + + return ( + <> + + {isMyFootPrintsTab ? : } + + ); } From 7b29439f4b3e307edd52dd44b0af1f30c5a1907d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Wed, 27 Mar 2024 23:32:27 +0900 Subject: [PATCH 03/18] =?UTF-8?q?=E2=9C=A8=20:=20#492=20-=20=EB=B0=9C?= =?UTF-8?q?=EC=9E=90=EC=B7=A8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=83=81?= =?UTF-8?q?=EB=8B=A8=20=ED=83=AD=20FootPrintTab=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B8=B0=EB=8A=A5=20=EB=B0=8F=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FootPrintFilter/FootPrintFilter.tsx | 12 +++- .../_Components/FootPrintTab/FootPrintTab.tsx | 64 ++++++++++++++++++- .../_Components/FootPrintTab/index.scss | 34 ++++++++++ src/app/footprints/index.scss | 7 ++ src/app/footprints/page.tsx | 6 +- 5 files changed, 117 insertions(+), 6 deletions(-) diff --git a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx index e7f0d61a..95ae8241 100644 --- a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx +++ b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx @@ -21,14 +21,22 @@ export default function FootPrintFilter({ // plan-DropDown의 selectedValue 값으로 setPlan() 호출 // 자체 state - // year에 해당하는 모든 계획 리스트 state + // TODO: props으로 받은 year에 해당하는 모든 계획들을 return 하는 useQuery 정의하고 여기서로부터 data return + // 이를 plan-dropdown의 options로 넣어주기 // const [selectedYear, setSelectedYear] = useState(2024); // const [selectedPlan, setSelectedPlan] = useState({ // planId: -1, // planTitle: '모든 계획', // }); - // useEffect로 year이 바뀔 때마다, selectedPlan의 값은 "모든 계획" + // TODO: useEffect로 year이 바뀔 때마다, selectedPlan의 값은 "모든 계획"으로 변경해주기 + // useEffect(() => { + // setSelectedPlan({ + // planId: -1, + // planTitle: '모든 계획', + // }); + // }, [year]); + return (
{ diff --git a/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx b/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx index d46c6f4e..1e33d24d 100644 --- a/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx +++ b/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx @@ -1,4 +1,6 @@ +import classNames from 'classnames'; import React from 'react'; +import './index.scss'; interface FootPrintTabProps { isMyFootPrintsTab: boolean; @@ -6,6 +8,64 @@ interface FootPrintTabProps { setAllFootPrintsTab: () => void; } -export default function FootPrintTab({}: FootPrintTabProps) { - return
; +const TAB_MENU = { + MY: '내 발자취', + ALL: '둘러보기', +}; + +export default function FootPrintTab({ + isMyFootPrintsTab, + setMyFootPrintsTab, + setAllFootPrintsTab, +}: FootPrintTabProps) { + // TODO: isMyFootPrintsTab이 true => 내 발자취, false => 둘러보기 표시 + + const handleClickMyFootPrintsTab = () => { + if (!isMyFootPrintsTab) { + setMyFootPrintsTab(); + } + }; + + const handleClickAllFootPrintsTab = () => { + if (isMyFootPrintsTab) { + setAllFootPrintsTab(); + } + }; + + return ( +
+
+ {TAB_MENU.MY} +
+
+
+ {TAB_MENU.ALL} +
+
+
+ ); } diff --git a/src/app/footprints/_Components/FootPrintTab/index.scss b/src/app/footprints/_Components/FootPrintTab/index.scss index e69de29b..61c7b637 100644 --- a/src/app/footprints/_Components/FootPrintTab/index.scss +++ b/src/app/footprints/_Components/FootPrintTab/index.scss @@ -0,0 +1,34 @@ +.footprint-tab { + margin-top: 2rem; + display: flex; + gap: 0rem; + &:hover { + cursor: pointer; + } + + &__menu { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + width: 6rem; + } + + &__underline { + background-color: var(--origin-secondary); + height: 0.125rem; + width: 100%; + + &--focused { + background-color: var(--origin-primary); + } + } + + &--normal { + color: var(--origin-secondary); + } + + &--focused { + color: var(--origin-primary); + } +} diff --git a/src/app/footprints/index.scss b/src/app/footprints/index.scss index e69de29b..133932ca 100644 --- a/src/app/footprints/index.scss +++ b/src/app/footprints/index.scss @@ -0,0 +1,7 @@ +.footprint-page { + display: flex; + flex-direction: column; + gap: 1.5rem; + width: 100%; + height: 100%; +} diff --git a/src/app/footprints/page.tsx b/src/app/footprints/page.tsx index 59d43faf..de12aba0 100644 --- a/src/app/footprints/page.tsx +++ b/src/app/footprints/page.tsx @@ -1,9 +1,11 @@ 'use client'; +import classNames from 'classnames'; import { useState } from 'react'; import AllFootPrints from './_Components/AllFootPrints/AllFootPrints'; import FootPrintTab from './_Components/FootPrintTab/FootPrintTab'; import MyFootPrints from './_Components/MyFootPrints/MyFootPrints'; +import './index.scss'; export default function FootPrintsPage() { const [isMyFootPrintsTab, setIsMyFootPrintsTab] = useState(true); @@ -16,13 +18,13 @@ export default function FootPrintsPage() { }; return ( - <> +
{isMyFootPrintsTab ? : } - +
); } From 454925dcaeb69c078c86d835cb4a9149f746977e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Thu, 28 Mar 2024 16:08:16 +0900 Subject: [PATCH 04/18] =?UTF-8?q?=E2=9C=A8=20:=20#492=20-=20FootPrintFilte?= =?UTF-8?q?r=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FootPrintFilter/FootPrintFilter.tsx | 87 ++++++++++++++----- .../_Components/FootPrintFilter/index.scss | 7 ++ .../_Components/FootPrintTab/FootPrintTab.tsx | 2 - .../_Components/MyFootPrints/MyFootPrints.tsx | 6 +- .../_Components/MyFootPrints/index.scss | 6 ++ 5 files changed, 80 insertions(+), 28 deletions(-) diff --git a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx index 95ae8241..661aec85 100644 --- a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx +++ b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx @@ -1,14 +1,17 @@ -import React from 'react'; +import { Dropdown } from '@/components'; +import classNames from 'classnames'; +import React, { useEffect, useState } from 'react'; import { planType } from '../MyFootPrints/MyFootPrints'; +import './index.scss'; interface FootPrintFilterProps { - year: number; setYear: (year: number) => void; setPlan: (plan: planType) => void; } +const yearOptions = [{ value: 2024, name: '2024년' }]; + export default function FootPrintFilter({ - year, setYear, setPlan, }: FootPrintFilterProps) { @@ -20,30 +23,66 @@ export default function FootPrintFilter({ // year-DropDown의 selectedValue 값으로 setYear() 호출 // plan-DropDown의 selectedValue 값으로 setPlan() 호출 - // 자체 state + const [selectedYear, setSelectedYear] = useState(2024); + const [selectedPlan, setSelectedPlan] = useState({ + planId: -1, + planTitle: '모든 계획', + }); + + const handleSelectedPlan = (newSelectedPlanId: number) => { + const newSelectedPlan = planOptions.find( + (plan) => plan.value === newSelectedPlanId, + ); + setSelectedPlan({ + planId: newSelectedPlan!.value, + planTitle: newSelectedPlan!.name, + }); + }; + // TODO: props으로 받은 year에 해당하는 모든 계획들을 return 하는 useQuery 정의하고 여기서로부터 data return - // 이를 plan-dropdown의 options로 넣어주기 - // const [selectedYear, setSelectedYear] = useState(2024); - // const [selectedPlan, setSelectedPlan] = useState({ - // planId: -1, - // planTitle: '모든 계획', - // }); - - // TODO: useEffect로 year이 바뀔 때마다, selectedPlan의 값은 "모든 계획"으로 변경해주기 - // useEffect(() => { - // setSelectedPlan({ - // planId: -1, - // planTitle: '모든 계획', - // }); - // }, [year]); + // 서버로부터 현재 year에 해당하는 계획들을 받아 planDropdown에 넣어줄 planOptions 만들기 + const planOptions = [ + { value: -1, name: '모든 계획' }, + { value: 52, name: '1일 1커밋하기' }, + { value: 53, name: '매일 운동하기' }, + ]; + + useEffect(() => { + // useEffect로 selectedYear이 바뀔 때마다, selectedPlan의 값은 "모든 계획"으로 변경해주기 + setSelectedPlan({ + planId: -1, + planTitle: '모든 계획', + }); + }, [selectedYear]); + + const handleClickSearchBtn = () => { + setYear(selectedYear); + setPlan(selectedPlan); + }; return ( -
{ - setYear(year); - setPlan({ planId: -1, planTitle: '1' }); - }}> - {year} +
+ { + setSelectedYear(newSelectedYear); + }} + classNameList={['footprint-filter__dropdown--year']} + /> + + + +
{`검색`}
); } diff --git a/src/app/footprints/_Components/FootPrintFilter/index.scss b/src/app/footprints/_Components/FootPrintFilter/index.scss index e69de29b..9f065845 100644 --- a/src/app/footprints/_Components/FootPrintFilter/index.scss +++ b/src/app/footprints/_Components/FootPrintFilter/index.scss @@ -0,0 +1,7 @@ +.footprint-filter { + display: flex; + justify-content: space-between; + + &__search-btn { + } +} diff --git a/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx b/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx index 1e33d24d..73c66c0c 100644 --- a/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx +++ b/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx @@ -18,8 +18,6 @@ export default function FootPrintTab({ setMyFootPrintsTab, setAllFootPrintsTab, }: FootPrintTabProps) { - // TODO: isMyFootPrintsTab이 true => 내 발자취, false => 둘러보기 표시 - const handleClickMyFootPrintsTab = () => { if (!isMyFootPrintsTab) { setMyFootPrintsTab(); diff --git a/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx b/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx index fc22b62a..000e3429 100644 --- a/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx +++ b/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx @@ -1,6 +1,8 @@ +import classNames from 'classnames'; import React, { useState } from 'react'; import FootPrintFilter from '../FootPrintFilter/FootPrintFilter'; import FootPrintList from '../FootPrintList/FootPrintList'; +import './index.scss'; export type planType = { planTitle: string; @@ -17,8 +19,8 @@ export default function MyFootPrints() { // Filter에서 검색 버튼을 누르면, setYear와 setPlan이 실행되어 year과 plan이 바뀌면 // FootPrintList에 변경된 year와 plan이 전달될 것임 return ( -
- +
+
); diff --git a/src/app/footprints/_Components/MyFootPrints/index.scss b/src/app/footprints/_Components/MyFootPrints/index.scss index e69de29b..60ceeb91 100644 --- a/src/app/footprints/_Components/MyFootPrints/index.scss +++ b/src/app/footprints/_Components/MyFootPrints/index.scss @@ -0,0 +1,6 @@ +.my-footprints { + margin-top: 0.5rem; + display: flex; + flex-direction: column; + gap: 1rem; +} From ef5eeb5c337ef561f025168de0816c80bcd2fa8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Thu, 28 Mar 2024 16:50:11 +0900 Subject: [PATCH 05/18] =?UTF-8?q?=E2=9C=A8=20:=20#492=20-=20=EB=B0=9C?= =?UTF-8?q?=EC=9E=90=EC=B7=A8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=EC=97=90=20=EC=82=AC=EC=9A=A9=ED=95=A0=20=EA=B3=84?= =?UTF-8?q?=ED=9A=8D=20List=EB=A5=BC=20=EB=B6=88=EB=9F=AC=EC=98=A4?= =?UTF-8?q?=EB=8A=94=20useGetMyPlansForFootprintQuery=20=ED=9B=85=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/queryKey.ts | 1 + src/hooks/apis/index.ts | 1 + .../apis/useGetMyPlansForFootprintQuery.ts | 26 +++++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 src/hooks/apis/useGetMyPlansForFootprintQuery.ts diff --git a/src/constants/queryKey.ts b/src/constants/queryKey.ts index 3ce653a6..312508f7 100644 --- a/src/constants/queryKey.ts +++ b/src/constants/queryKey.ts @@ -1,5 +1,6 @@ export const QUERY_KEY = { MY_PLANS: 'getMyPlans', + MY_PLANS_FOR_FOOTPRINT: 'getMyPlans-footprint', ALL_PLANS: 'getAllPlans', PLAN: 'getPlan', REMIND: 'getRemind', diff --git a/src/hooks/apis/index.ts b/src/hooks/apis/index.ts index 6137aa7f..00e70e42 100644 --- a/src/hooks/apis/index.ts +++ b/src/hooks/apis/index.ts @@ -4,6 +4,7 @@ export { useEditPlanMutation } from '@/hooks/apis/useEditPlanMutation'; export { useEditRemindMutation } from '@/hooks/apis/useEditRemindMutation'; export { useGetFeedbacksQuery } from '@/hooks/apis/useGetFeedbacksQuery'; export { useGetMyPlansQuery } from '@/hooks/apis/useGetMyPlansQuery'; +export { useGetMyPlansForFootprintQuery } from '@/hooks/apis/useGetMyPlansForFootprintQuery'; export { useGetPlanQuery } from '@/hooks/apis/useGetPlanQuery'; export { useGetRemindQuery } from '@/hooks/apis/useGetRemindQuery'; export { useGetUserInformationQuery } from '@/hooks/apis/useGetUserInformationQuery'; diff --git a/src/hooks/apis/useGetMyPlansForFootprintQuery.ts b/src/hooks/apis/useGetMyPlansForFootprintQuery.ts new file mode 100644 index 00000000..e526ac6e --- /dev/null +++ b/src/hooks/apis/useGetMyPlansForFootprintQuery.ts @@ -0,0 +1,26 @@ +import { getMyPlans } from '@/apis/client/getMyPlans'; +import { QUERY_KEY } from '@/constants/queryKey'; +import { useSuspenseQuery } from '@tanstack/react-query'; + +export const useGetMyPlansForFootprintQuery = (year: number) => { + const { data } = useSuspenseQuery({ + queryKey: [QUERY_KEY.MY_PLANS_FOR_FOOTPRINT], + queryFn: getMyPlans, + staleTime: Infinity, + select: (data) => { + const planData = data.data.find((item) => item.year === year); + return planData + ? [ + { planId: -1, planTitle: '모든 계획' }, + ...planData.getPlanList.map((plan) => { + return { + planId: plan.planId, + planTitle: plan.title, + }; + }), + ] + : [{ planId: -2, planTitle: '계획 없음' }]; + }, + }); + return { yearPlans: data! }; +}; From 6efe877e728ffae331e6cb3a22e05fad46bad8ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Thu, 28 Mar 2024 16:55:02 +0900 Subject: [PATCH 06/18] =?UTF-8?q?=E2=9C=A8=20:=20#492=20-=20FootPrintFilte?= =?UTF-8?q?r=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=82=B4=20useGetMy?= =?UTF-8?q?PlansForFootprintQuery=20=ED=9B=85=20=EC=82=AC=EC=9A=A9=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FootPrintFilter/FootPrintFilter.tsx | 30 ++++++++----------- .../_Components/FootPrintFilter/index.scss | 1 + 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx index 661aec85..70cee616 100644 --- a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx +++ b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx @@ -1,6 +1,7 @@ import { Dropdown } from '@/components'; +import { useGetMyPlansForFootprintQuery } from '@/hooks/apis'; import classNames from 'classnames'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { planType } from '../MyFootPrints/MyFootPrints'; import './index.scss'; @@ -15,14 +16,6 @@ export default function FootPrintFilter({ setYear, setPlan, }: FootPrintFilterProps) { - // TODO: - // 1. props로 받은 year값을 기본값으로 year-DropDown의 selectedValue로 설정 - // 2. year에 해당하는 모든 계획 리스트 state를 보유한다. - // 3. 모든 계획 리스트 state를 plan-DropDown의 options로 넣어준다. - // 4. 검색 버튼을 클릭 시, - // year-DropDown의 selectedValue 값으로 setYear() 호출 - // plan-DropDown의 selectedValue 값으로 setPlan() 호출 - const [selectedYear, setSelectedYear] = useState(2024); const [selectedPlan, setSelectedPlan] = useState({ planId: -1, @@ -39,16 +32,18 @@ export default function FootPrintFilter({ }); }; - // TODO: props으로 받은 year에 해당하는 모든 계획들을 return 하는 useQuery 정의하고 여기서로부터 data return - // 서버로부터 현재 year에 해당하는 계획들을 받아 planDropdown에 넣어줄 planOptions 만들기 - const planOptions = [ - { value: -1, name: '모든 계획' }, - { value: 52, name: '1일 1커밋하기' }, - { value: 53, name: '매일 운동하기' }, - ]; + const { yearPlans } = useGetMyPlansForFootprintQuery(selectedYear); + + const planOptions = useMemo(() => { + // 서버로부터 받아온 yearPlans가 변경되지 않는 이상 변하지 않는 변수 + return yearPlans.map((plan) => ({ + value: plan.planId, + name: plan.planTitle, + })); + }, [yearPlans]); useEffect(() => { - // useEffect로 selectedYear이 바뀔 때마다, selectedPlan의 값은 "모든 계획"으로 변경해주기 + // selectedYear이 바뀔 때마다, selectedPlan의 값은 "모든 계획"으로 변경해주기 setSelectedPlan({ planId: -1, planTitle: '모든 계획', @@ -56,6 +51,7 @@ export default function FootPrintFilter({ }, [selectedYear]); const handleClickSearchBtn = () => { + // 현재 dropdown에서 선택되어있는 year, plan 값으로 부모의 year, plan을 변경 setYear(selectedYear); setPlan(selectedPlan); }; diff --git a/src/app/footprints/_Components/FootPrintFilter/index.scss b/src/app/footprints/_Components/FootPrintFilter/index.scss index 9f065845..c8f42302 100644 --- a/src/app/footprints/_Components/FootPrintFilter/index.scss +++ b/src/app/footprints/_Components/FootPrintFilter/index.scss @@ -1,6 +1,7 @@ .footprint-filter { display: flex; justify-content: space-between; + align-items: center; &__search-btn { } From 5210f928e81ecb39ddc6d8ad0a23ae798240a2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Thu, 28 Mar 2024 17:55:59 +0900 Subject: [PATCH 07/18] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20:=20#492=20-=20Icon?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=82=B4=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EC=95=84=EC=9D=B4=EC=BD=98=20search=20=EC=A2=85?= =?UTF-8?q?=EB=A5=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Icon/Icon.tsx | 1 + src/types/IconName.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/Icon/Icon.tsx b/src/components/Icon/Icon.tsx index 852f53e1..4b1303b5 100644 --- a/src/components/Icon/Icon.tsx +++ b/src/components/Icon/Icon.tsx @@ -40,6 +40,7 @@ const ICON_NAME_MAP = { COPY: 'content_copy', ARROW_RIGHT: 'subdirectory_arrow_right', CANCEL: 'cancel', + SEARCH: 'search', }; interface IconProps { diff --git a/src/types/IconName.ts b/src/types/IconName.ts index 226b7609..d2cd0659 100644 --- a/src/types/IconName.ts +++ b/src/types/IconName.ts @@ -36,4 +36,5 @@ export type IconName = | 'COPY' | 'HELP' | 'ARROW_RIGHT' - | 'CANCEL'; + | 'CANCEL' + | 'SEARCH'; From 659b77332d67f73b971c91dfefbf395d5a87f202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Thu, 28 Mar 2024 17:56:55 +0900 Subject: [PATCH 08/18] =?UTF-8?q?=F0=9F=92=84=20:=20#492=20-=20FootPrintFi?= =?UTF-8?q?lter=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EB=B2=84=ED=8A=BC=20CSS=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_Components/FootPrintFilter/FootPrintFilter.tsx | 8 +++++--- .../footprints/_Components/FootPrintFilter/index.scss | 11 ++++++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx index 70cee616..16588bbf 100644 --- a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx +++ b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx @@ -1,4 +1,4 @@ -import { Dropdown } from '@/components'; +import { Dropdown, Icon } from '@/components'; import { useGetMyPlansForFootprintQuery } from '@/hooks/apis'; import classNames from 'classnames'; import React, { useEffect, useMemo, useState } from 'react'; @@ -76,9 +76,11 @@ export default function FootPrintFilter({ classNameList={['footprint-filter__dropdown--filter']} /> -
{`검색`}
+ onClick={handleClickSearchBtn}> + +
); } diff --git a/src/app/footprints/_Components/FootPrintFilter/index.scss b/src/app/footprints/_Components/FootPrintFilter/index.scss index c8f42302..e1d8d3b6 100644 --- a/src/app/footprints/_Components/FootPrintFilter/index.scss +++ b/src/app/footprints/_Components/FootPrintFilter/index.scss @@ -1,8 +1,17 @@ .footprint-filter { display: flex; - justify-content: space-between; + gap: 0.75rem; align-items: center; &__search-btn { + &:hover { + cursor: pointer; + } + display: flex; + justify-content: center; + padding: 0.25rem; + align-items: center; + border-radius: 10px; + background-color: var(--origin-primary); } } From e5527f6b6e11415bb0ffbdeb6c6ff0db80bd3c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Fri, 29 Mar 2024 16:02:12 +0900 Subject: [PATCH 09/18] =?UTF-8?q?=F0=9F=92=84=20:=20#492=20-=20Dropdown=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=82=B4=20text=20?= =?UTF-8?q?=EA=B3=A0=EC=A0=95=20width=20=EB=B0=8F=20=EB=A7=90=EC=A4=84?= =?UTF-8?q?=EC=9E=84=ED=91=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Dropdown/index.scss | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/Dropdown/index.scss b/src/components/Dropdown/index.scss index fbafb3b3..93ed2e4b 100644 --- a/src/components/Dropdown/index.scss +++ b/src/components/Dropdown/index.scss @@ -24,13 +24,17 @@ justify-content: center; align-items: center; position: relative; - padding: 0.5rem 2rem; + padding: 0.5rem 1rem; border: 1px solid var(--origin-primary); border-radius: var(--border-radius); cursor: pointer; &__text { text-align: center; + width: 6rem; /* 1rem 크기로 고정된 div */ + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; font-size: 1rem; line-height: 1rem; } @@ -82,14 +86,14 @@ } } -.dropdown__remind-option__first{ +.dropdown__remind-option__first { z-index: 13; } -.dropdown__remind-option__second{ +.dropdown__remind-option__second { z-index: 12; } -.dropdown__remind-option__third{ +.dropdown__remind-option__third { z-index: 11; } From f878dd7f1d39d6e422e29d6e2b74f1f79e6a7905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Fri, 29 Mar 2024 16:51:09 +0900 Subject: [PATCH 10/18] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20:=20#492=20-=20FOOTP?= =?UTF-8?q?RINT=5FPLAN=20=EC=83=81=EC=88=98=20=EC=A0=95=EC=9D=98=20=3D>=20?= =?UTF-8?q?=EB=AA=A8=EB=93=A0=20=EA=B3=84=ED=9A=8D,=20=EA=B3=84=ED=9A=8D?= =?UTF-8?q?=20=EC=97=86=EC=9D=8C=20data=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FootPrintFilter/FootPrintFilter.tsx | 23 ++++++++++--------- .../FootPrintList/FootPrintList.tsx | 4 ++++ .../_Components/MyFootPrints/MyFootPrints.tsx | 6 ++--- src/constants/footprint.ts | 10 ++++++++ src/constants/index.ts | 1 + .../apis/useGetMyPlansForFootprintQuery.ts | 7 ++++-- 6 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 src/constants/footprint.ts diff --git a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx index 16588bbf..2771cdd4 100644 --- a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx +++ b/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx @@ -1,4 +1,5 @@ import { Dropdown, Icon } from '@/components'; +import { FOOTPRINT_PLAN } from '@/constants'; import { useGetMyPlansForFootprintQuery } from '@/hooks/apis'; import classNames from 'classnames'; import React, { useEffect, useMemo, useState } from 'react'; @@ -17,10 +18,9 @@ export default function FootPrintFilter({ setPlan, }: FootPrintFilterProps) { const [selectedYear, setSelectedYear] = useState(2024); - const [selectedPlan, setSelectedPlan] = useState({ - planId: -1, - planTitle: '모든 계획', - }); + const [selectedPlan, setSelectedPlan] = useState( + FOOTPRINT_PLAN.ALL_PLAN, + ); const handleSelectedPlan = (newSelectedPlanId: number) => { const newSelectedPlan = planOptions.find( @@ -43,17 +43,18 @@ export default function FootPrintFilter({ }, [yearPlans]); useEffect(() => { - // selectedYear이 바뀔 때마다, selectedPlan의 값은 "모든 계획"으로 변경해주기 - setSelectedPlan({ - planId: -1, - planTitle: '모든 계획', - }); + // selectedYear이 바뀔 때마다, yearPlans의 값이 바뀔테니 + // selectedPlan의 값은 "모든 계획"으로 변경해주기 + setSelectedPlan(FOOTPRINT_PLAN.ALL_PLAN); }, [selectedYear]); const handleClickSearchBtn = () => { // 현재 dropdown에서 선택되어있는 year, plan 값으로 부모의 year, plan을 변경 - setYear(selectedYear); - setPlan(selectedPlan); + if (selectedPlan.planId !== FOOTPRINT_PLAN.EMPTY.planId) { + // "계획 없음"이 선택되지 않았을 때만 변경 가능하도록 + setYear(selectedYear); + setPlan(selectedPlan); + } }; return ( diff --git a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx index aae2d9f7..a6bc9cc1 100644 --- a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx +++ b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx @@ -7,6 +7,10 @@ interface FootPrintListProps { } export default function FootPrintList({ year, plan }: FootPrintListProps) { + // TODO: prop으로 받은 year과 plan에 해당하는 발자취 list들을 서버로부터 받아온다. + // - plan.planId === -1 => 모든 계획일 것 + // - plan.planId === -2 => 해당 year에 해당하는 계획이 없는 것 + return (
{`${year}와 ${plan.planTitle}에 해당하는 FootPrintList 출력`}
); diff --git a/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx b/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx index 000e3429..11766092 100644 --- a/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx +++ b/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx @@ -1,3 +1,4 @@ +import { FOOTPRINT_PLAN } from '@/constants'; import classNames from 'classnames'; import React, { useState } from 'react'; import FootPrintFilter from '../FootPrintFilter/FootPrintFilter'; @@ -11,10 +12,7 @@ export type planType = { export default function MyFootPrints() { const [year, setYear] = useState(2024); - const [plan, setPlan] = useState({ - planTitle: '모든 계획', - planId: -1, - }); + const [plan, setPlan] = useState(FOOTPRINT_PLAN.ALL_PLAN); // Filter에서 검색 버튼을 누르면, setYear와 setPlan이 실행되어 year과 plan이 바뀌면 // FootPrintList에 변경된 year와 plan이 전달될 것임 diff --git a/src/constants/footprint.ts b/src/constants/footprint.ts new file mode 100644 index 00000000..36fdccc4 --- /dev/null +++ b/src/constants/footprint.ts @@ -0,0 +1,10 @@ +export const FOOTPRINT_PLAN = { + ALL_PLAN: { + planId: -1, + planTitle: '모든 계획', + }, + EMPTY: { + planId: -2, + planTitle: '계획 없음', + }, +}; diff --git a/src/constants/index.ts b/src/constants/index.ts index fbf3d3a6..eaf3e4d1 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -23,3 +23,4 @@ export { REMIND_TIME_TEXT } from '@/constants/remindTimeText'; export { INPUT_MAX_LENGTH } from '@/constants/userInputMaxLength'; export { address } from '@/constants/addressRegex'; export { options } from '@/constants/radio'; +export { FOOTPRINT_PLAN } from '@/constants/footprint'; diff --git a/src/hooks/apis/useGetMyPlansForFootprintQuery.ts b/src/hooks/apis/useGetMyPlansForFootprintQuery.ts index e526ac6e..151c076d 100644 --- a/src/hooks/apis/useGetMyPlansForFootprintQuery.ts +++ b/src/hooks/apis/useGetMyPlansForFootprintQuery.ts @@ -1,8 +1,11 @@ import { getMyPlans } from '@/apis/client/getMyPlans'; +import { FOOTPRINT_PLAN } from '@/constants'; import { QUERY_KEY } from '@/constants/queryKey'; import { useSuspenseQuery } from '@tanstack/react-query'; export const useGetMyPlansForFootprintQuery = (year: number) => { + // TODO: year이 바뀔 때마다 이 Query가 다시 호출되지 않고, 호출은 한 번만 되고 + // 바뀌는 year에 따라 select를 통해서 return 하는 data만 바꿔주기 const { data } = useSuspenseQuery({ queryKey: [QUERY_KEY.MY_PLANS_FOR_FOOTPRINT], queryFn: getMyPlans, @@ -11,7 +14,7 @@ export const useGetMyPlansForFootprintQuery = (year: number) => { const planData = data.data.find((item) => item.year === year); return planData ? [ - { planId: -1, planTitle: '모든 계획' }, + FOOTPRINT_PLAN.ALL_PLAN, ...planData.getPlanList.map((plan) => { return { planId: plan.planId, @@ -19,7 +22,7 @@ export const useGetMyPlansForFootprintQuery = (year: number) => { }; }), ] - : [{ planId: -2, planTitle: '계획 없음' }]; + : [FOOTPRINT_PLAN.EMPTY]; }, }); return { yearPlans: data! }; From 3befbb98eed5cda109f60e701965a432fc9e9f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Sat, 20 Apr 2024 18:06:28 +0900 Subject: [PATCH 11/18] =?UTF-8?q?=E2=9C=A8=20:=20#492=20-=20FootPrintItem?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FootPrintList/FootPrintList.tsx | 4 +- .../FootprintItem/FootprintItem.tsx | 44 +++++++++++++++++++ .../_Components/FootprintItem/index.scss | 16 +++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/app/footprints/_Components/FootprintItem/FootprintItem.tsx create mode 100644 src/app/footprints/_Components/FootprintItem/index.scss diff --git a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx index a6bc9cc1..10fcd0b5 100644 --- a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx +++ b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx @@ -12,6 +12,8 @@ export default function FootPrintList({ year, plan }: FootPrintListProps) { // - plan.planId === -2 => 해당 year에 해당하는 계획이 없는 것 return ( -
{`${year}와 ${plan.planTitle}에 해당하는 FootPrintList 출력`}
+
    {`${year}와 ${plan.planTitle}에 해당하는 FootPrintList 출력`}
+ + // TODO: footPrintList.map((item)=>{return }) ); } diff --git a/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx b/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx new file mode 100644 index 00000000..40b598dc --- /dev/null +++ b/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx @@ -0,0 +1,44 @@ +import { AjajaButton, Tag } from '@/components'; +import classNames from 'classnames'; +import Link from 'next/link'; +import React from 'react'; +import './index.scss'; + +interface FootprintItemProps { + id: number; + iconNumber: number; + title: string; + createdAt: string; + ajajas: number; + tags: string[]; +} + +export default function FootprintItem({ + id, + iconNumber, + title, + createdAt, + ajajas, + tags, +}: FootprintItemProps) { + return ( +
  • + +
    + {iconNumber + title} +
    +
    + {`${createdAt} 작성`} +
    + +
    + {tags.map((tagString, idx) => { + return {tagString}; + })} +
    + +
  • + ); +} diff --git a/src/app/footprints/_Components/FootprintItem/index.scss b/src/app/footprints/_Components/FootprintItem/index.scss new file mode 100644 index 00000000..dbac66af --- /dev/null +++ b/src/app/footprints/_Components/FootprintItem/index.scss @@ -0,0 +1,16 @@ +.footprint-item { + display: flex; + flex-direction: column; + + &__title{ + + } + + &__createdAt{ + + } + + &__tags{ + + } +} From e71a5beb95b8433aa5d7baa2d5c14f5f3eb88db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Mon, 22 Apr 2024 18:30:28 +0900 Subject: [PATCH 12/18] =?UTF-8?q?=E2=9C=A8=20:=20#492=20-=20FootPrintItem?= =?UTF-8?q?=20dummy=20data=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20css=20?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FootPrintList/FootPrintList.tsx | 61 ++++++++++++++++++- .../_Components/FootPrintList/index.scss | 6 ++ .../FootprintItem/FootprintItem.tsx | 26 ++++++-- .../_Components/FootprintItem/index.scss | 33 ++++++++-- 4 files changed, 113 insertions(+), 13 deletions(-) diff --git a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx index 10fcd0b5..39a9a46c 100644 --- a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx +++ b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx @@ -1,19 +1,74 @@ +import classNames from 'classnames'; import React from 'react'; +import FootprintItem from '../FootprintItem/FootprintItem'; import { planType } from '../MyFootPrints/MyFootPrints'; +import './index.scss'; interface FootPrintListProps { year: number; plan: planType; } +type FootPrintItemType = { + id: number; + iconNumber: number; + title: string; + createdAt: string; + ajajas: number; + tags: string[]; +}; + +const dummyFootPrintList: FootPrintItemType[] = [ + { + id: 1, + iconNumber: 0, + title: '발자취1', + createdAt: '2024.04.22', + ajajas: 1, + tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], + }, + { + id: 2, + iconNumber: 1, + title: '발자취2', + createdAt: '2024.04.22', + ajajas: 2, + tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], + }, + { + id: 3, + iconNumber: 1, + title: '발자취1', + createdAt: '2024.04.22', + ajajas: 3, + tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], + }, +]; + export default function FootPrintList({ year, plan }: FootPrintListProps) { // TODO: prop으로 받은 year과 plan에 해당하는 발자취 list들을 서버로부터 받아온다. // - plan.planId === -1 => 모든 계획일 것 // - plan.planId === -2 => 해당 year에 해당하는 계획이 없는 것 return ( -
      {`${year}와 ${plan.planTitle}에 해당하는 FootPrintList 출력`}
    - - // TODO: footPrintList.map((item)=>{return }) + <> +
      + {dummyFootPrintList.map((item) => { + return ( + + ); + })} +
    +
    {`${year}와 ${plan.planTitle}에 해당하는 FootPrintList 출력`}
    + + // TODO: `${year}와 ${plan.planTitle}에 해당하는 FootPrintList 출력` ); } diff --git a/src/app/footprints/_Components/FootPrintList/index.scss b/src/app/footprints/_Components/FootPrintList/index.scss index e69de29b..058209b2 100644 --- a/src/app/footprints/_Components/FootPrintList/index.scss +++ b/src/app/footprints/_Components/FootPrintList/index.scss @@ -0,0 +1,6 @@ +.footprint-list{ + display: flex; + flex-direction: column; + gap: 1rem; + overflow-y: scroll; +} \ No newline at end of file diff --git a/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx b/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx index 40b598dc..a55a4a24 100644 --- a/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx +++ b/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx @@ -13,6 +13,15 @@ interface FootprintItemProps { tags: string[]; } +type FootPrintIconMapType = { + [key: number]: string; +}; + +const FOOTPRINT_ICON_MAP: FootPrintIconMapType = { + 0: '🤗', + 1: '🗽', +}; + export default function FootprintItem({ id, iconNumber, @@ -25,11 +34,20 @@ export default function FootprintItem({
  • -
    - {iconNumber + title} + className={classNames( + 'footprint-item', + 'border-origin-secondary', + 'border-round', + )}> +
    + {FOOTPRINT_ICON_MAP[iconNumber] + title}
    -
    +
    {`${createdAt} 작성`}
    diff --git a/src/app/footprints/_Components/FootprintItem/index.scss b/src/app/footprints/_Components/FootprintItem/index.scss index dbac66af..0ab6647f 100644 --- a/src/app/footprints/_Components/FootprintItem/index.scss +++ b/src/app/footprints/_Components/FootprintItem/index.scss @@ -1,16 +1,37 @@ +@mixin ellipsis($line) { + text-overflow: ellipsis; + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: $line; + -webkit-box-orient: vertical; +} + .footprint-item { display: flex; flex-direction: column; + justify-content: center; + padding: 1.5rem 2rem 1.25rem 2rem; + width: 100%; + box-shadow: var(--origin-shadow); + text-decoration: none; + color: var(--origin-text-100); - &__title{ - + &__title { + @include ellipsis(1); } - &__createdAt{ - + &__createdAt { + @include ellipsis(1); + margin-left: 0.25rem; + margin-top: 0.5rem; + margin-bottom: 0.75rem; } - &__tags{ - + &__tags { + @include ellipsis(2); + display: flex; + gap: 0 0.5rem; + height: 2.5rem; + flex-wrap: wrap; } } From 37638f04188c2c1b55d3f599ea74dab4acb92b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Tue, 23 Apr 2024 17:02:40 +0900 Subject: [PATCH 13/18] =?UTF-8?q?=F0=9F=92=84=20:=20#492=20-=20FootPrintLi?= =?UTF-8?q?st=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=9C=84=ED=95=B4=20height?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FootPrintList/FootPrintList.tsx | 60 +++++++++++++------ .../_Components/MyFootPrints/index.scss | 2 +- src/app/footprints/index.scss | 4 +- 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx index 39a9a46c..7e50e961 100644 --- a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx +++ b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx @@ -38,7 +38,31 @@ const dummyFootPrintList: FootPrintItemType[] = [ { id: 3, iconNumber: 1, - title: '발자취1', + title: '발자취3', + createdAt: '2024.04.22', + ajajas: 3, + tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], + }, + { + id: 4, + iconNumber: 0, + title: '발자취4', + createdAt: '2024.04.22', + ajajas: 1, + tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], + }, + { + id: 5, + iconNumber: 1, + title: '발자취5', + createdAt: '2024.04.22', + ajajas: 2, + tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], + }, + { + id: 6, + iconNumber: 1, + title: '발자취6', createdAt: '2024.04.22', ajajas: 3, tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], @@ -51,24 +75,22 @@ export default function FootPrintList({ year, plan }: FootPrintListProps) { // - plan.planId === -2 => 해당 year에 해당하는 계획이 없는 것 return ( - <> -
      - {dummyFootPrintList.map((item) => { - return ( - - ); - })} -
    -
    {`${year}와 ${plan.planTitle}에 해당하는 FootPrintList 출력`}
    - +
      + {dummyFootPrintList.map((item) => { + return ( + + ); + })} +
      {`${year}와 ${plan}에 해당하는 FootPrintList`}
      +
    // TODO: `${year}와 ${plan.planTitle}에 해당하는 FootPrintList 출력` ); } diff --git a/src/app/footprints/_Components/MyFootPrints/index.scss b/src/app/footprints/_Components/MyFootPrints/index.scss index 60ceeb91..bb13768f 100644 --- a/src/app/footprints/_Components/MyFootPrints/index.scss +++ b/src/app/footprints/_Components/MyFootPrints/index.scss @@ -1,5 +1,5 @@ .my-footprints { - margin-top: 0.5rem; + height: calc(100% - 2rem - 34px); display: flex; flex-direction: column; gap: 1rem; diff --git a/src/app/footprints/index.scss b/src/app/footprints/index.scss index 133932ca..286513d5 100644 --- a/src/app/footprints/index.scss +++ b/src/app/footprints/index.scss @@ -1,7 +1,7 @@ .footprint-page { display: flex; flex-direction: column; - gap: 1.5rem; + gap: 1rem; width: 100%; - height: 100%; + height: calc(100% - 1rem); } From f7f4ea9696f99748d3d35992e7c2b2df8e9adb48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Wed, 24 Apr 2024 18:24:28 +0900 Subject: [PATCH 14/18] =?UTF-8?q?=E2=9C=A8=20:=20#492=20-=20=EB=B0=9C?= =?UTF-8?q?=EC=9E=90=EC=B7=A8=20=EC=A1=B0=ED=9A=8C=20=EB=AC=B4=ED=95=9C=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=A0=81=EC=9A=A9=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20=EC=9E=84=EC=8B=9C=EB=A1=9C=20getAllPlans=20API=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/client/getMyFootPrints.ts | 19 +++ .../FootPrintList/FootPrintList.tsx | 126 ++++++++++-------- .../FootprintItem/FootprintItem.tsx | 14 ++ src/constants/queryKey.ts | 1 + src/hooks/apis/useMyFootPrintsQuery.ts | 56 ++++++++ 5 files changed, 157 insertions(+), 59 deletions(-) create mode 100644 src/apis/client/getMyFootPrints.ts create mode 100644 src/hooks/apis/useMyFootPrintsQuery.ts diff --git a/src/apis/client/getMyFootPrints.ts b/src/apis/client/getMyFootPrints.ts new file mode 100644 index 00000000..e26b0574 --- /dev/null +++ b/src/apis/client/getMyFootPrints.ts @@ -0,0 +1,19 @@ +import { DOMAIN } from '@/constants/api'; +import { + GetAllPlansRequestQuery, + GetAllPlansResponse, +} from '@/types/apis/plan/GetAllPlans'; +import { axiosInstanceClient } from '../axiosInstanceClient'; + +export const getMyFootPrints = async (query: GetAllPlansRequestQuery) => { + const { data } = await axiosInstanceClient.get( + DOMAIN.GET_PLANS_ALL, + { + authorization: false, + params: { + ...query, + }, + }, + ); + return data; +}; diff --git a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx index 7e50e961..88f67afe 100644 --- a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx +++ b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx @@ -1,3 +1,6 @@ +'use client'; + +import { useMyFootPrintsQuery } from '@/hooks/apis/useMyFootPrintsQuery'; import classNames from 'classnames'; import React from 'react'; import FootprintItem from '../FootprintItem/FootprintItem'; @@ -9,74 +12,79 @@ interface FootPrintListProps { plan: planType; } -type FootPrintItemType = { - id: number; - iconNumber: number; - title: string; - createdAt: string; - ajajas: number; - tags: string[]; -}; +// type FootPrintItemType = { +// id: number; +// iconNumber: number; +// title: string; +// createdAt: string; +// ajajas: number; +// tags: string[]; +// }; -const dummyFootPrintList: FootPrintItemType[] = [ - { - id: 1, - iconNumber: 0, - title: '발자취1', - createdAt: '2024.04.22', - ajajas: 1, - tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], - }, - { - id: 2, - iconNumber: 1, - title: '발자취2', - createdAt: '2024.04.22', - ajajas: 2, - tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], - }, - { - id: 3, - iconNumber: 1, - title: '발자취3', - createdAt: '2024.04.22', - ajajas: 3, - tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], - }, - { - id: 4, - iconNumber: 0, - title: '발자취4', - createdAt: '2024.04.22', - ajajas: 1, - tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], - }, - { - id: 5, - iconNumber: 1, - title: '발자취5', - createdAt: '2024.04.22', - ajajas: 2, - tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], - }, - { - id: 6, - iconNumber: 1, - title: '발자취6', - createdAt: '2024.04.22', - ajajas: 3, - tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], - }, -]; +// const dummyFootPrintList: FootPrintItemType[] = [ +// { +// id: 1, +// iconNumber: 0, +// title: '발자취1', +// createdAt: '2024.04.22', +// ajajas: 1, +// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], +// }, +// { +// id: 2, +// iconNumber: 1, +// title: '발자취2', +// createdAt: '2024.04.22', +// ajajas: 2, +// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], +// }, +// { +// id: 3, +// iconNumber: 1, +// title: '발자취3', +// createdAt: '2024.04.22', +// ajajas: 3, +// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], +// }, +// { +// id: 4, +// iconNumber: 0, +// title: '발자취4', +// createdAt: '2024.04.22', +// ajajas: 1, +// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], +// }, +// { +// id: 5, +// iconNumber: 1, +// title: '발자취5', +// createdAt: '2024.04.22', +// ajajas: 2, +// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], +// }, +// { +// id: 6, +// iconNumber: 1, +// title: '발자취6', +// createdAt: '2024.04.22', +// ajajas: 3, +// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], +// }, +// ]; export default function FootPrintList({ year, plan }: FootPrintListProps) { // TODO: prop으로 받은 year과 plan에 해당하는 발자취 list들을 서버로부터 받아온다. // - plan.planId === -1 => 모든 계획일 것 // - plan.planId === -2 => 해당 year에 해당하는 계획이 없는 것 + const { tempFootPrintList } = useMyFootPrintsQuery({ + sort: 'latest', + current: true, + }); + return (
      - {dummyFootPrintList.map((item) => { + {tempFootPrintList.map((item) => { return ( { + const { + data, + fetchNextPage, + hasNextPage, + isLoading, + isFetchingNextPage, + isError, + } = useSuspenseInfiniteQuery({ + queryKey: [QUERY_KEY.MY_FOOTPRINTS, query.sort, query.current], // sort와 current를 쿼리 키에 넣는 게 맞을까? + queryFn: async ({ pageParam = {} }) => { + let params = { + sort: query.sort, + current: query.current, + }; + + if (pageParam) { + // start, ajaja가 들어있을 것임 + params = { ...params, ...pageParam }; + } + + const result = await getMyFootPrints(params); + return result?.data; + }, + initialPageParam: {}, // 초기 pageParam => 빈 객체 + getNextPageParam: (lastPage) => { + // 더 불러올 data가 있는 지 확인하는 함수 + if (lastPage.length === 0) { + // 빈 배열이라면 + return undefined; + } + + const lastItem = lastPage[lastPage.length - 1]; // 가장 최근 받아온 3개 data 중 마지막 ite + return query.sort === 'ajaja' + ? { start: lastItem.id, ajaja: lastItem.ajajas } // 인기순이면 start, ajaja 모두 params에 넣어주기 위해 + : { start: lastItem.id }; // 인기순이면 start를 params에 넣어주기 위해 + }, + staleTime: 10000, + }); + return { + tempFootPrintList: data?.pages.flat() || [], // TODO: flat() 없애기 + fetchNextPage, + hasNextPage, + isLoading, + isFetchingNextPage, + isError, + }; +}; From 2a671982377daf2aa94b5a44a2341d060b31381c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Wed, 24 Apr 2024 18:33:39 +0900 Subject: [PATCH 15/18] =?UTF-8?q?=F0=9F=90=9B=20:=20#492=20-=20npm=20react?= =?UTF-8?q?-intersection-observer=20=EB=9D=BC=EC=9D=B4=EB=B8=8C=EB=9F=AC?= =?UTF-8?q?=EB=A6=AC=20=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 15 +++++++++++++++ package.json | 1 + 2 files changed, 16 insertions(+) diff --git a/package-lock.json b/package-lock.json index 1d7044cd..c1e3a7de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "react-form-stepper": "^2.0.3", "react-hot-toast": "^2.4.1", "react-infinite-scroller": "^1.2.6", + "react-intersection-observer": "^9.8.2", "react-spinners": "^0.13.8", "recoil": "^0.7.7" }, @@ -4832,6 +4833,20 @@ "react": "^0.14.9 || ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-intersection-observer": { + "version": "9.8.2", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.8.2.tgz", + "integrity": "sha512-901naEiiZmse3p+AmtbQ3NL9xx+gQ8TXLiGDc+8GiE3JKJkNV3vP737aGuWTAXBA+1QqxPrDDE+fIEgYpGDlrQ==", + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/package.json b/package.json index 2970ddec..67c1357d 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "react-form-stepper": "^2.0.3", "react-hot-toast": "^2.4.1", "react-infinite-scroller": "^1.2.6", + "react-intersection-observer": "^9.8.2", "react-spinners": "^0.13.8", "recoil": "^0.7.7" }, From 44e6590cce389c63e7872070260e694408118c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Mon, 3 Jun 2024 17:45:40 +0900 Subject: [PATCH 16/18] =?UTF-8?q?=E2=9C=A8=20:=20#492=20-=20useInView=20ho?= =?UTF-8?q?ok=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=B4=20=EB=B0=9C=EC=9E=90?= =?UTF-8?q?=EC=B7=A8=EC=A1=B0=ED=9A=8C=20=EB=AC=B4=ED=95=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FootPrintList/FootPrintList.tsx | 97 ++++++------------- .../_Components/FootPrintList/index.scss | 17 +++- .../FootprintItem/FootprintItem.tsx | 6 +- .../_Components/FootprintItem/index.scss | 1 + .../DebounceSwitchButton.tsx | 2 +- src/hooks/apis/useMyFootPrintsQuery.ts | 4 +- 6 files changed, 53 insertions(+), 74 deletions(-) diff --git a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx index 88f67afe..aa7b9b25 100644 --- a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx +++ b/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx @@ -1,8 +1,11 @@ 'use client'; +import { COLOR } from '@/constants'; import { useMyFootPrintsQuery } from '@/hooks/apis/useMyFootPrintsQuery'; import classNames from 'classnames'; -import React from 'react'; +import React, { useEffect } from 'react'; +import { useInView } from 'react-intersection-observer'; +import { FadeLoader } from 'react-spinners'; import FootprintItem from '../FootprintItem/FootprintItem'; import { planType } from '../MyFootPrints/MyFootPrints'; import './index.scss'; @@ -12,75 +15,26 @@ interface FootPrintListProps { plan: planType; } -// type FootPrintItemType = { -// id: number; -// iconNumber: number; -// title: string; -// createdAt: string; -// ajajas: number; -// tags: string[]; -// }; - -// const dummyFootPrintList: FootPrintItemType[] = [ -// { -// id: 1, -// iconNumber: 0, -// title: '발자취1', -// createdAt: '2024.04.22', -// ajajas: 1, -// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], -// }, -// { -// id: 2, -// iconNumber: 1, -// title: '발자취2', -// createdAt: '2024.04.22', -// ajajas: 2, -// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], -// }, -// { -// id: 3, -// iconNumber: 1, -// title: '발자취3', -// createdAt: '2024.04.22', -// ajajas: 3, -// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], -// }, -// { -// id: 4, -// iconNumber: 0, -// title: '발자취4', -// createdAt: '2024.04.22', -// ajajas: 1, -// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], -// }, -// { -// id: 5, -// iconNumber: 1, -// title: '발자취5', -// createdAt: '2024.04.22', -// ajajas: 2, -// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], -// }, -// { -// id: 6, -// iconNumber: 1, -// title: '발자취6', -// createdAt: '2024.04.22', -// ajajas: 3, -// tags: ['태그1', '태그2', '태그3', '태그4', '태그5'], -// }, -// ]; - export default function FootPrintList({ year, plan }: FootPrintListProps) { // TODO: prop으로 받은 year과 plan에 해당하는 발자취 list들을 서버로부터 받아온다. // - plan.planId === -1 => 모든 계획일 것 // - plan.planId === -2 => 해당 year에 해당하는 계획이 없는 것 + console.log(`${year}과 ${plan}에 해당하는 발자취 List로 변경 필요`); + + const { tempFootPrintList, fetchNextPage, isFetchingNextPage } = + useMyFootPrintsQuery({ + sort: 'latest', + current: true, + }); - const { tempFootPrintList } = useMyFootPrintsQuery({ - sort: 'latest', - current: true, - }); + const { ref, inView } = useInView(); + + useEffect(() => { + // ref로 참조하고 있는 div 요소가 viewPort에 보여진다면 다음 페이지 fetch + if (inView) { + fetchNextPage(); + } + }, [inView]); return (
        @@ -97,8 +51,17 @@ export default function FootPrintList({ year, plan }: FootPrintListProps) { /> ); })} -
        {`${year}와 ${plan}에 해당하는 FootPrintList`}
        + +
        + {isFetchingNextPage ? ( + + ) : ( +
        + )} +
      - // TODO: `${year}와 ${plan.planTitle}에 해당하는 FootPrintList 출력` + + // TODO: ${year}와 ${plan.planTitle}에 해당하는 FootPrintList 출력 + // -> 지금은 임시로 "계획 전체조회 api(계획 둘러보기)"를 사용하고 있음 ); } diff --git a/src/app/footprints/_Components/FootPrintList/index.scss b/src/app/footprints/_Components/FootPrintList/index.scss index 058209b2..c113e6fb 100644 --- a/src/app/footprints/_Components/FootPrintList/index.scss +++ b/src/app/footprints/_Components/FootPrintList/index.scss @@ -1,6 +1,19 @@ -.footprint-list{ +.footprint-list { display: flex; flex-direction: column; gap: 1rem; overflow-y: scroll; -} \ No newline at end of file + + &__loading-wrapper { + display: flex; + justify-content: center; + } + + &__end { + &:before { + content: ''; + display: block; + height: 12px; + } + } +} diff --git a/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx b/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx index 79298e60..f5359365 100644 --- a/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx +++ b/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx @@ -1,4 +1,5 @@ import { AjajaButton, Tag } from '@/components'; +import { changeCreatedAtToDate } from '@/utils'; import classNames from 'classnames'; import Link from 'next/link'; import React from 'react'; @@ -17,6 +18,7 @@ type FootPrintIconMapType = { [key: number]: string; }; +// TODO: 임시로 정의 const FOOTPRINT_ICON_MAP: FootPrintIconMapType = { 0: '🤗', 1: '🗽', @@ -47,7 +49,7 @@ export default function FootprintItem({ return (
    • - {`${createdAt} 작성`} + {`${changeCreatedAtToDate(createdAt)} 작성`}
    diff --git a/src/app/footprints/_Components/FootprintItem/index.scss b/src/app/footprints/_Components/FootprintItem/index.scss index 0ab6647f..554e6888 100644 --- a/src/app/footprints/_Components/FootprintItem/index.scss +++ b/src/app/footprints/_Components/FootprintItem/index.scss @@ -29,6 +29,7 @@ &__tags { @include ellipsis(2); + padding-left: 0.2rem; display: flex; gap: 0 0.5rem; height: 2.5rem; diff --git a/src/components/DebounceSwitchButton/DebounceSwitchButton.tsx b/src/components/DebounceSwitchButton/DebounceSwitchButton.tsx index bae990f1..07dc7058 100644 --- a/src/components/DebounceSwitchButton/DebounceSwitchButton.tsx +++ b/src/components/DebounceSwitchButton/DebounceSwitchButton.tsx @@ -44,7 +44,7 @@ export default function DebounceSwitchButton({ const submitIfReallyChanged = () => { if (isOn !== originalIsOn) { - submitToggleAPI(); + submitToggleAPI(); // TODO: 여기서 만약 실패하면 아래 isOn은 바뀌면 안되는 거 아닌가? setOriginalIsOn(isOn); } }; diff --git a/src/hooks/apis/useMyFootPrintsQuery.ts b/src/hooks/apis/useMyFootPrintsQuery.ts index 67909279..ea210ddc 100644 --- a/src/hooks/apis/useMyFootPrintsQuery.ts +++ b/src/hooks/apis/useMyFootPrintsQuery.ts @@ -5,7 +5,7 @@ import { QUERY_KEY } from '@/constants/queryKey'; import { GetAllPlansRequestQuery } from '@/types/apis/plan/GetAllPlans'; import { useSuspenseInfiniteQuery } from '@tanstack/react-query'; -// TODO: 수정 필요 +// TODO: 계획 전체조회 API -> 발자취 전체 조회 API로 수정 필요 export const useMyFootPrintsQuery = (query: GetAllPlansRequestQuery) => { const { data, @@ -38,7 +38,7 @@ export const useMyFootPrintsQuery = (query: GetAllPlansRequestQuery) => { return undefined; } - const lastItem = lastPage[lastPage.length - 1]; // 가장 최근 받아온 3개 data 중 마지막 ite + const lastItem = lastPage[lastPage.length - 1]; // 가장 최근 받아온 3개 data 중 마지막 item return query.sort === 'ajaja' ? { start: lastItem.id, ajaja: lastItem.ajajas } // 인기순이면 start, ajaja 모두 params에 넣어주기 위해 : { start: lastItem.id }; // 인기순이면 start를 params에 넣어주기 위해 From d071d135f7cc029819d1204aeb39d121dac4bd51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Mon, 3 Jun 2024 17:47:26 +0900 Subject: [PATCH 17/18] =?UTF-8?q?=E2=9C=A8=20:=20#492=20-=20=EA=B3=84?= =?UTF-8?q?=ED=9A=8D=20=EC=9E=91=EC=84=B1=20=EB=82=A0=EC=A7=9C=EB=A5=BC=20?= =?UTF-8?q?YYYY-MM-DD=20=ED=98=95=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B0=94?= =?UTF-8?q?=EA=BF=94=EC=A3=BC=EB=8A=94=20changeCreateAtToDate=20hook=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/changeCreatedAtToDate.ts | 4 ++++ src/utils/index.ts | 1 + 2 files changed, 5 insertions(+) create mode 100644 src/utils/changeCreatedAtToDate.ts diff --git a/src/utils/changeCreatedAtToDate.ts b/src/utils/changeCreatedAtToDate.ts new file mode 100644 index 00000000..d1bd725e --- /dev/null +++ b/src/utils/changeCreatedAtToDate.ts @@ -0,0 +1,4 @@ +export const changeCreatedAtToDate = (createdAt: string) => { + const [yearMonthDate] = createdAt.split('T'); + return yearMonthDate.replace(/-/g, '.'); +}; diff --git a/src/utils/index.ts b/src/utils/index.ts index f25a1c96..76dafa1a 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,5 @@ export { alertAndLogin } from '@/utils/alertAndLogin'; +export { changeCreatedAtToDate } from '@/utils/changeCreatedAtToDate'; export { changeRemindTimeToNumber } from '@/utils/changeRemindTimeToNumber'; export { changeRemindTimeToString } from '@/utils/changeRemindTimeToString'; export { checkEmailValidation } from '@/utils/checkEmailValidation'; From 1053af75a0ed41ea6b911dbb17520667ee765c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EB=AF=BC=EC=9A=B0?= Date: Mon, 3 Jun 2024 18:26:22 +0900 Subject: [PATCH 18/18] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20:=20#492=20-=20footp?= =?UTF-8?q?rints=20=ED=8F=B4=EB=8D=94=EB=AA=85=20url=EC=97=90=20=EB=A7=9E?= =?UTF-8?q?=EA=B2=8C=20footprint=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 --- .../_Components/AllFootPrints/AllFootPrints.tsx | 0 .../_Components/AllFootPrints/index.scss | 0 .../_Components/FootPrintFilter/FootPrintFilter.tsx | 0 .../_Components/FootPrintFilter/index.scss | 0 .../_Components/FootPrintList/FootPrintList.tsx | 0 .../_Components/FootPrintList/index.scss | 0 .../_Components/FootPrintTab/FootPrintTab.tsx | 0 .../{footprints => footprint}/_Components/FootPrintTab/index.scss | 0 .../_Components/FootprintItem/FootprintItem.tsx | 0 .../_Components/FootprintItem/index.scss | 0 .../_Components/MyFootPrints/MyFootPrints.tsx | 0 .../{footprints => footprint}/_Components/MyFootPrints/index.scss | 0 src/app/{footprints => footprint}/index.scss | 0 src/app/{footprints => footprint}/page.tsx | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename src/app/{footprints => footprint}/_Components/AllFootPrints/AllFootPrints.tsx (100%) rename src/app/{footprints => footprint}/_Components/AllFootPrints/index.scss (100%) rename src/app/{footprints => footprint}/_Components/FootPrintFilter/FootPrintFilter.tsx (100%) rename src/app/{footprints => footprint}/_Components/FootPrintFilter/index.scss (100%) rename src/app/{footprints => footprint}/_Components/FootPrintList/FootPrintList.tsx (100%) rename src/app/{footprints => footprint}/_Components/FootPrintList/index.scss (100%) rename src/app/{footprints => footprint}/_Components/FootPrintTab/FootPrintTab.tsx (100%) rename src/app/{footprints => footprint}/_Components/FootPrintTab/index.scss (100%) rename src/app/{footprints => footprint}/_Components/FootprintItem/FootprintItem.tsx (100%) rename src/app/{footprints => footprint}/_Components/FootprintItem/index.scss (100%) rename src/app/{footprints => footprint}/_Components/MyFootPrints/MyFootPrints.tsx (100%) rename src/app/{footprints => footprint}/_Components/MyFootPrints/index.scss (100%) rename src/app/{footprints => footprint}/index.scss (100%) rename src/app/{footprints => footprint}/page.tsx (100%) diff --git a/src/app/footprints/_Components/AllFootPrints/AllFootPrints.tsx b/src/app/footprint/_Components/AllFootPrints/AllFootPrints.tsx similarity index 100% rename from src/app/footprints/_Components/AllFootPrints/AllFootPrints.tsx rename to src/app/footprint/_Components/AllFootPrints/AllFootPrints.tsx diff --git a/src/app/footprints/_Components/AllFootPrints/index.scss b/src/app/footprint/_Components/AllFootPrints/index.scss similarity index 100% rename from src/app/footprints/_Components/AllFootPrints/index.scss rename to src/app/footprint/_Components/AllFootPrints/index.scss diff --git a/src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx b/src/app/footprint/_Components/FootPrintFilter/FootPrintFilter.tsx similarity index 100% rename from src/app/footprints/_Components/FootPrintFilter/FootPrintFilter.tsx rename to src/app/footprint/_Components/FootPrintFilter/FootPrintFilter.tsx diff --git a/src/app/footprints/_Components/FootPrintFilter/index.scss b/src/app/footprint/_Components/FootPrintFilter/index.scss similarity index 100% rename from src/app/footprints/_Components/FootPrintFilter/index.scss rename to src/app/footprint/_Components/FootPrintFilter/index.scss diff --git a/src/app/footprints/_Components/FootPrintList/FootPrintList.tsx b/src/app/footprint/_Components/FootPrintList/FootPrintList.tsx similarity index 100% rename from src/app/footprints/_Components/FootPrintList/FootPrintList.tsx rename to src/app/footprint/_Components/FootPrintList/FootPrintList.tsx diff --git a/src/app/footprints/_Components/FootPrintList/index.scss b/src/app/footprint/_Components/FootPrintList/index.scss similarity index 100% rename from src/app/footprints/_Components/FootPrintList/index.scss rename to src/app/footprint/_Components/FootPrintList/index.scss diff --git a/src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx b/src/app/footprint/_Components/FootPrintTab/FootPrintTab.tsx similarity index 100% rename from src/app/footprints/_Components/FootPrintTab/FootPrintTab.tsx rename to src/app/footprint/_Components/FootPrintTab/FootPrintTab.tsx diff --git a/src/app/footprints/_Components/FootPrintTab/index.scss b/src/app/footprint/_Components/FootPrintTab/index.scss similarity index 100% rename from src/app/footprints/_Components/FootPrintTab/index.scss rename to src/app/footprint/_Components/FootPrintTab/index.scss diff --git a/src/app/footprints/_Components/FootprintItem/FootprintItem.tsx b/src/app/footprint/_Components/FootprintItem/FootprintItem.tsx similarity index 100% rename from src/app/footprints/_Components/FootprintItem/FootprintItem.tsx rename to src/app/footprint/_Components/FootprintItem/FootprintItem.tsx diff --git a/src/app/footprints/_Components/FootprintItem/index.scss b/src/app/footprint/_Components/FootprintItem/index.scss similarity index 100% rename from src/app/footprints/_Components/FootprintItem/index.scss rename to src/app/footprint/_Components/FootprintItem/index.scss diff --git a/src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx b/src/app/footprint/_Components/MyFootPrints/MyFootPrints.tsx similarity index 100% rename from src/app/footprints/_Components/MyFootPrints/MyFootPrints.tsx rename to src/app/footprint/_Components/MyFootPrints/MyFootPrints.tsx diff --git a/src/app/footprints/_Components/MyFootPrints/index.scss b/src/app/footprint/_Components/MyFootPrints/index.scss similarity index 100% rename from src/app/footprints/_Components/MyFootPrints/index.scss rename to src/app/footprint/_Components/MyFootPrints/index.scss diff --git a/src/app/footprints/index.scss b/src/app/footprint/index.scss similarity index 100% rename from src/app/footprints/index.scss rename to src/app/footprint/index.scss diff --git a/src/app/footprints/page.tsx b/src/app/footprint/page.tsx similarity index 100% rename from src/app/footprints/page.tsx rename to src/app/footprint/page.tsx