From 13747c72e536a402d065840f6dc7bc4fdea4d11a Mon Sep 17 00:00:00 2001 From: jaychang99 Date: Sat, 12 Aug 2023 11:30:58 +0900 Subject: [PATCH 01/23] =?UTF-8?q?feat(Mypage):=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EA=B3=A8=EA=B2=A9=20=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/mypage/delete/index.tsx | 40 +++++++++++++++++++++++++++++ src/pages/mypage/delete/success.tsx | 36 ++++++++++++++++++++++++++ src/pages/mypage/edit.tsx | 38 +++++++++++++++++++++++++++ src/pages/mypage/index.tsx | 38 +++++++++++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 src/pages/mypage/delete/index.tsx create mode 100644 src/pages/mypage/delete/success.tsx create mode 100644 src/pages/mypage/edit.tsx create mode 100644 src/pages/mypage/index.tsx diff --git a/src/pages/mypage/delete/index.tsx b/src/pages/mypage/delete/index.tsx new file mode 100644 index 0000000..f37be66 --- /dev/null +++ b/src/pages/mypage/delete/index.tsx @@ -0,0 +1,40 @@ +import styled from "@emotion/styled"; +import PageMarker from "components/pageMarker/PageMarker"; +import { GetServerSideProps } from "next"; +import Link from "next/link"; + +const PageMyPageDelete = () => { + return ( + + + + 임시: 계정 삭제 성공 페이지 이동 + + + ); +}; + +export default PageMyPageDelete; + +const EmotionWrapper = styled.div``; + +export const getServerSideProps: GetServerSideProps = async ({ req, res, query }) => { + /** + * 로그인하지 않은 경우 메인 페이지로 이동 + * 마이페이지로부터 유입되지 않은 경우 메인 페이지로 이동 + */ + + const referer = req.headers.referer; + const isLoggedIn = true; + const isFromMyPage = referer?.includes("/mypage"); + const shouldRedirect = !isLoggedIn || !isFromMyPage; + + if (shouldRedirect) { + res.writeHead(302, { Location: "/" }); + res.end(); + } + + return { + props: {}, + }; +}; diff --git a/src/pages/mypage/delete/success.tsx b/src/pages/mypage/delete/success.tsx new file mode 100644 index 0000000..5f4e085 --- /dev/null +++ b/src/pages/mypage/delete/success.tsx @@ -0,0 +1,36 @@ +import styled from "@emotion/styled"; +import PageMarker from "components/pageMarker/PageMarker"; +import { GetServerSideProps } from "next"; + +const PageMyPageDeleteSuccess = () => { + return ( + + + + ); +}; + +export default PageMyPageDeleteSuccess; + +const EmotionWrapper = styled.div``; + +export const getServerSideProps: GetServerSideProps = async ({ req, res, query }) => { + /** + * 로그인하지 않은 경우 메인 페이지로 이동 + * 로그인 되어 있으나, 탈퇴 페이지로부터 유입되지 않은 경우 메인 페이지로 이동 + */ + const referer = req.headers.referer; + const isLoggedIn = false; + const isFromDeletePage = referer?.includes("/mypage/delete"); + + const shouldRedirect = !isLoggedIn || !isFromDeletePage; + + if (shouldRedirect) { + res.writeHead(302, { Location: "/" }); + res.end(); + } + + return { + props: {}, + }; +}; diff --git a/src/pages/mypage/edit.tsx b/src/pages/mypage/edit.tsx new file mode 100644 index 0000000..1ede146 --- /dev/null +++ b/src/pages/mypage/edit.tsx @@ -0,0 +1,38 @@ +import styled from "@emotion/styled"; +import PageMarker from "components/pageMarker/PageMarker"; +import { GetServerSideProps } from "next"; +import Link from "next/link"; + +const PageMyPageEdit = () => { + return ( + + + + 임사: 계정 삭제 페이지 이동 + + + ); +}; + +export default PageMyPageEdit; + +const EmotionWrapper = styled.div``; + +export const getServerSideProps: GetServerSideProps = async ({ req, res, query }) => { + /** + * 로그인하지 않은 경우 로그인 페이지로 이동 + */ + const isLoggedIn = true; + + if (!isLoggedIn) { + res.writeHead(302, { Location: "/login" }); + res.end(); + } + + return { + props: {}, + }; +}; diff --git a/src/pages/mypage/index.tsx b/src/pages/mypage/index.tsx new file mode 100644 index 0000000..a7bba96 --- /dev/null +++ b/src/pages/mypage/index.tsx @@ -0,0 +1,38 @@ +import styled from "@emotion/styled"; +import PageMarker from "components/pageMarker/PageMarker"; +import { GetServerSideProps } from "next"; +import Link from "next/link"; + +const PageMyPage = () => { + return ( + + + + 임사: 계정 삭제 페이지 이동 + + + ); +}; + +export default PageMyPage; + +const EmotionWrapper = styled.div``; + +export const getServerSideProps: GetServerSideProps = async ({ req, res, query }) => { + /** + * 로그인하지 않은 경우 로그인 페이지로 이동 + */ + const isLoggedIn = true; + + if (!isLoggedIn) { + res.writeHead(302, { Location: "/login" }); + res.end(); + } + + return { + props: {}, + }; +}; From 591901e272774ac5e524675df05a5029ad8bc01c Mon Sep 17 00:00:00 2001 From: jaychang99 Date: Sat, 12 Aug 2023 14:16:12 +0900 Subject: [PATCH 02/23] =?UTF-8?q?feat:=20ProfileImage=20=EC=97=90=20?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=EC=A6=88=20=EC=B6=94=EA=B0=80=ED=95=A0=20?= =?UTF-8?q?=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/profileImage/ProfileImage.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/profileImage/ProfileImage.tsx b/src/components/profileImage/ProfileImage.tsx index 8a717d8..52b03dc 100644 --- a/src/components/profileImage/ProfileImage.tsx +++ b/src/components/profileImage/ProfileImage.tsx @@ -3,15 +3,16 @@ import Image from "next/image"; interface Props { src?: string; + size?: number; // in pixels defaultPhotoId: number; } -const ProfileImage = ({ src, defaultPhotoId }: Props) => { +const ProfileImage = ({ src, defaultPhotoId, size = 30 }: Props) => { const imageSrc = src ?? `/images/profile-image-default-${defaultPhotoId}.png`; return ( - 프로필 이미지 + 프로필 이미지 ); }; From 502adc5e875f7fcc523961ad03b15260d5ac2973 Mon Sep 17 00:00:00 2001 From: jaychang99 Date: Sat, 12 Aug 2023 14:17:22 +0900 Subject: [PATCH 03/23] =?UTF-8?q?feat(MyPage):=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=83=81=EB=8B=A8=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=EA=B9=8C=EC=A7=80=20=ED=8D=BC=EB=B8=94?= =?UTF-8?q?=EB=A6=AC=EC=8B=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/MyPageProfileInfo.tsx | 40 +++++++++++++++++++ src/feature/mypage/views/ViewMypage.tsx | 34 ++++++++++++++++ src/pages/mypage/index.tsx | 18 +-------- 3 files changed, 76 insertions(+), 16 deletions(-) create mode 100644 src/feature/mypage/components/MyPageProfileInfo.tsx create mode 100644 src/feature/mypage/views/ViewMypage.tsx diff --git a/src/feature/mypage/components/MyPageProfileInfo.tsx b/src/feature/mypage/components/MyPageProfileInfo.tsx new file mode 100644 index 0000000..b18e126 --- /dev/null +++ b/src/feature/mypage/components/MyPageProfileInfo.tsx @@ -0,0 +1,40 @@ +import styled from "@emotion/styled"; +import ProfileImage from "components/profileImage/ProfileImage"; + +interface Props {} + +const MyPageProfileInfo = ({}: Props) => { + return ( + +
+ +
+

홍길동

+

이 시대 최고의 미식 탐험가

+
+
+
+ ); +}; + +export default MyPageProfileInfo; + +const EmotionWrapper = styled.div` + .profile-section { + display: flex; + column-gap: 16px; + align-items: center; + + .user-name { + font-size: 16px; + font-weight: 700; + color: ${({ theme }) => theme.color.black}; + margin-bottom: 8px; + } + + .user-description { + font-size: 12px; + color: ${({ theme }) => theme.color.gray400}; + } + } +`; diff --git a/src/feature/mypage/views/ViewMypage.tsx b/src/feature/mypage/views/ViewMypage.tsx new file mode 100644 index 0000000..cce047d --- /dev/null +++ b/src/feature/mypage/views/ViewMypage.tsx @@ -0,0 +1,34 @@ +import styled from "@emotion/styled"; +import MyPageProfileInfo from "feature/mypage/components/MyPageProfileInfo"; + +interface Props {} + +const ViewMypage = ({}: Props) => { + return ( + + + + ); +}; + +export default ViewMypage; + +const EmotionWrapper = styled.div` + .profile-section { + display: flex; + column-gap: 16px; + align-items: center; + + .user-name { + font-size: 16px; + font-weight: 700; + color: ${({ theme }) => theme.color.black}; + margin-bottom: 8px; + } + + .user-description { + font-size: 12px; + color: ${({ theme }) => theme.color.gray400}; + } + } +`; diff --git a/src/pages/mypage/index.tsx b/src/pages/mypage/index.tsx index a7bba96..161f4a6 100644 --- a/src/pages/mypage/index.tsx +++ b/src/pages/mypage/index.tsx @@ -1,26 +1,12 @@ -import styled from "@emotion/styled"; -import PageMarker from "components/pageMarker/PageMarker"; import { GetServerSideProps } from "next"; -import Link from "next/link"; +import ViewMypage from "feature/mypage/views/ViewMypage"; const PageMyPage = () => { - return ( - - - - 임사: 계정 삭제 페이지 이동 - - - ); + return ; }; export default PageMyPage; -const EmotionWrapper = styled.div``; - export const getServerSideProps: GetServerSideProps = async ({ req, res, query }) => { /** * 로그인하지 않은 경우 로그인 페이지로 이동 From 5ab490f1f2ce80d9b23ec3ea243b49167c9a02c0 Mon Sep 17 00:00:00 2001 From: jaychang99 Date: Sat, 12 Aug 2023 14:30:16 +0900 Subject: [PATCH 04/23] =?UTF-8?q?feat(Mypage):=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=82=B4=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EB=B0=8F=20=EC=83=81=EC=84=B8=20=EC=98=81=EC=97=AD,=20?= =?UTF-8?q?=EB=8B=A8=EC=B2=B4=20=EC=A0=95=EB=B3=B4=20=EC=A0=9C=EC=99=B8=20?= =?UTF-8?q?=ED=8D=BC=EB=B8=94=EB=A6=AC=EC=8B=B1=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/MyPageActionButtons.tsx | 23 ++++++++++++ .../mypage/components/MyPageBasicInfo.tsx | 29 +++++++++++++++ .../components/MyPageOrganizationInfo.tsx | 18 ++++++++++ .../mypage/components/MyPageProfileInfo.tsx | 2 ++ .../components/typography/MyPageInfoItem.tsx | 35 +++++++++++++++++++ .../typography/MyPageSectionTitle.tsx | 19 ++++++++++ src/feature/mypage/views/ViewMypage.tsx | 6 ++++ 7 files changed, 132 insertions(+) create mode 100644 src/feature/mypage/components/MyPageActionButtons.tsx create mode 100644 src/feature/mypage/components/MyPageBasicInfo.tsx create mode 100644 src/feature/mypage/components/MyPageOrganizationInfo.tsx create mode 100644 src/feature/mypage/components/typography/MyPageInfoItem.tsx create mode 100644 src/feature/mypage/components/typography/MyPageSectionTitle.tsx diff --git a/src/feature/mypage/components/MyPageActionButtons.tsx b/src/feature/mypage/components/MyPageActionButtons.tsx new file mode 100644 index 0000000..c4bdc79 --- /dev/null +++ b/src/feature/mypage/components/MyPageActionButtons.tsx @@ -0,0 +1,23 @@ +import styled from "@emotion/styled"; +import Link from "next/link"; + +interface Props {} + +const MyPageActionButtons = ({}: Props) => { + return ( + + {/* TODO: 공통 컴포넌트 Button 으로 대체 */} + + + + + ); +}; + +export default MyPageActionButtons; + +const EmotionWrapper = styled.div` + display: flex; + justify-content: flex-end; + column-gap: 16px; +`; diff --git a/src/feature/mypage/components/MyPageBasicInfo.tsx b/src/feature/mypage/components/MyPageBasicInfo.tsx new file mode 100644 index 0000000..7a5ca12 --- /dev/null +++ b/src/feature/mypage/components/MyPageBasicInfo.tsx @@ -0,0 +1,29 @@ +import styled from "@emotion/styled"; +import MyPageInfoItem from "feature/mypage/components/typography/MyPageInfoItem"; +import MyPageSectionTitle from "feature/mypage/components/typography/MyPageSectionTitle"; + +interface Props {} + +const MyPageBasicInfo = ({}: Props) => { + return ( + + 내 정보 +
+ + +
+
+ ); +}; + +export default MyPageBasicInfo; + +const EmotionWrapper = styled.div` + margin-bottom: 48px; + + .item-container { + display: flex; + flex-direction: column; + row-gap: 8px; + } +`; diff --git a/src/feature/mypage/components/MyPageOrganizationInfo.tsx b/src/feature/mypage/components/MyPageOrganizationInfo.tsx new file mode 100644 index 0000000..4cd2af9 --- /dev/null +++ b/src/feature/mypage/components/MyPageOrganizationInfo.tsx @@ -0,0 +1,18 @@ +import styled from "@emotion/styled"; +import MyPageSectionTitle from "feature/mypage/components/typography/MyPageSectionTitle"; + +interface Props {} + +const MyPageOrganizationInfo = ({}: Props) => { + return ( + + 내가 속한 단체 정보 + + ); +}; + +export default MyPageOrganizationInfo; + +const EmotionWrapper = styled.div` + margin-bottom: 64px; +`; diff --git a/src/feature/mypage/components/MyPageProfileInfo.tsx b/src/feature/mypage/components/MyPageProfileInfo.tsx index b18e126..1e11eb7 100644 --- a/src/feature/mypage/components/MyPageProfileInfo.tsx +++ b/src/feature/mypage/components/MyPageProfileInfo.tsx @@ -20,6 +20,8 @@ const MyPageProfileInfo = ({}: Props) => { export default MyPageProfileInfo; const EmotionWrapper = styled.div` + margin-bottom: 32px; + .profile-section { display: flex; column-gap: 16px; diff --git a/src/feature/mypage/components/typography/MyPageInfoItem.tsx b/src/feature/mypage/components/typography/MyPageInfoItem.tsx new file mode 100644 index 0000000..07637fe --- /dev/null +++ b/src/feature/mypage/components/typography/MyPageInfoItem.tsx @@ -0,0 +1,35 @@ +import styled from "@emotion/styled"; + +interface Props { + label: string; + value: string; +} + +const MyPageInfoItem = ({ label, value }: Props) => { + return ( + +

{label}

+

{value}

+
+ ); +}; + +export default MyPageInfoItem; + +const EmotionWrapper = styled.div` + display: flex; + align-items: center; + column-gap: 16px; + + .label { + font-size: 12px; + color: ${({ theme }) => theme.color.gray400}; + min-width: 60px; + } + + .value { + font-size: 12px; + font-weight: 700; + color: ${({ theme }) => theme.color.black}; + } +`; diff --git a/src/feature/mypage/components/typography/MyPageSectionTitle.tsx b/src/feature/mypage/components/typography/MyPageSectionTitle.tsx new file mode 100644 index 0000000..ff238da --- /dev/null +++ b/src/feature/mypage/components/typography/MyPageSectionTitle.tsx @@ -0,0 +1,19 @@ +import styled from "@emotion/styled"; +import { ReactNode } from "react"; + +interface Props { + children?: ReactNode; +} + +const MyPageSectionTitle = ({ children }: Props) => { + return {children}; +}; + +export default MyPageSectionTitle; + +const EmotionWrapper = styled.h2` + font-size: 16px; + font-weight: 700; + color: ${({ theme }) => theme.color.black}; + margin-bottom: 16px; +`; diff --git a/src/feature/mypage/views/ViewMypage.tsx b/src/feature/mypage/views/ViewMypage.tsx index cce047d..eaa4cb1 100644 --- a/src/feature/mypage/views/ViewMypage.tsx +++ b/src/feature/mypage/views/ViewMypage.tsx @@ -1,4 +1,7 @@ import styled from "@emotion/styled"; +import MyPageActionButtons from "feature/mypage/components/MyPageActionButtons"; +import MyPageBasicInfo from "feature/mypage/components/MyPageBasicInfo"; +import MyPageOrganizationInfo from "feature/mypage/components/MyPageOrganizationInfo"; import MyPageProfileInfo from "feature/mypage/components/MyPageProfileInfo"; interface Props {} @@ -7,6 +10,9 @@ const ViewMypage = ({}: Props) => { return ( + + + ); }; From 482aabecdbf872cab3dae725b230366a12224a71 Mon Sep 17 00:00:00 2001 From: jaychang99 Date: Sat, 12 Aug 2023 14:32:19 +0900 Subject: [PATCH 05/23] =?UTF-8?q?feat(Mypage):=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=8A=A4=ED=83=80=EC=9D=BC=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/feature/mypage/components/MyPageBasicInfo.tsx | 2 +- src/feature/mypage/components/typography/MyPageInfoItem.tsx | 4 ++-- .../mypage/components/typography/MyPageSectionTitle.tsx | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/feature/mypage/components/MyPageBasicInfo.tsx b/src/feature/mypage/components/MyPageBasicInfo.tsx index 7a5ca12..69cb578 100644 --- a/src/feature/mypage/components/MyPageBasicInfo.tsx +++ b/src/feature/mypage/components/MyPageBasicInfo.tsx @@ -24,6 +24,6 @@ const EmotionWrapper = styled.div` .item-container { display: flex; flex-direction: column; - row-gap: 8px; + row-gap: 12px; } `; diff --git a/src/feature/mypage/components/typography/MyPageInfoItem.tsx b/src/feature/mypage/components/typography/MyPageInfoItem.tsx index 07637fe..eef7312 100644 --- a/src/feature/mypage/components/typography/MyPageInfoItem.tsx +++ b/src/feature/mypage/components/typography/MyPageInfoItem.tsx @@ -22,13 +22,13 @@ const EmotionWrapper = styled.div` column-gap: 16px; .label { - font-size: 12px; + font-size: 16px; color: ${({ theme }) => theme.color.gray400}; min-width: 60px; } .value { - font-size: 12px; + font-size: 16px; font-weight: 700; color: ${({ theme }) => theme.color.black}; } diff --git a/src/feature/mypage/components/typography/MyPageSectionTitle.tsx b/src/feature/mypage/components/typography/MyPageSectionTitle.tsx index ff238da..7d74391 100644 --- a/src/feature/mypage/components/typography/MyPageSectionTitle.tsx +++ b/src/feature/mypage/components/typography/MyPageSectionTitle.tsx @@ -12,8 +12,7 @@ const MyPageSectionTitle = ({ children }: Props) => { export default MyPageSectionTitle; const EmotionWrapper = styled.h2` - font-size: 16px; - font-weight: 700; - color: ${({ theme }) => theme.color.black}; + font-size: 12px; + color: ${({ theme }) => theme.color.gray500}; margin-bottom: 16px; `; From cf9fd899757a0cb183d09020527c7bcd218513f8 Mon Sep 17 00:00:00 2001 From: jaychang99 Date: Sun, 27 Aug 2023 14:51:55 +0900 Subject: [PATCH 06/23] =?UTF-8?q?fix(Mypage):=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=82=B4=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B2=84=ED=8A=BC=20=EA=B3=B5=ED=86=B5=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EB=A1=9C=20=EB=8C=80?= =?UTF-8?q?=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/feature/mypage/components/MyPageActionButtons.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/feature/mypage/components/MyPageActionButtons.tsx b/src/feature/mypage/components/MyPageActionButtons.tsx index c4bdc79..17d60c4 100644 --- a/src/feature/mypage/components/MyPageActionButtons.tsx +++ b/src/feature/mypage/components/MyPageActionButtons.tsx @@ -1,4 +1,5 @@ import styled from "@emotion/styled"; +import Button from "components/button/Button"; import Link from "next/link"; interface Props {} @@ -8,7 +9,7 @@ const MyPageActionButtons = ({}: Props) => { {/* TODO: 공통 컴포넌트 Button 으로 대체 */} - + ); From 8b22a4c6f1e4e1605183f2ffc18046bdeedee10d Mon Sep 17 00:00:00 2001 From: jaychang99 Date: Sun, 27 Aug 2023 17:10:30 +0900 Subject: [PATCH 07/23] =?UTF-8?q?fix(Button):=20=EB=B2=84=ED=8A=BC?= =?UTF-8?q?=EC=9D=B4=20=EC=99=B8=EB=B6=80=20className=20=EB=8F=84=20?= =?UTF-8?q?=EB=B0=9B=EC=9D=84=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/button/Button.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/button/Button.tsx b/src/components/button/Button.tsx index 9423c43..01b961b 100644 --- a/src/components/button/Button.tsx +++ b/src/components/button/Button.tsx @@ -22,6 +22,7 @@ const Button = ({ fullWidth = false, loading = false, onClick, + className, ...props }: Props) => { const [isActive, setIsActive] = useState(false); @@ -47,7 +48,7 @@ const Button = ({ icon={icon} onMouseDown={handleMouseDown} onMouseUp={handleMouseUp} - className={isActive ? "active" : ""} + className={isActive ? `active ${className}` : className} > {loading && } {icon} From 10c112bde3aa4a18cdae2037bdff52c32b9f70ff Mon Sep 17 00:00:00 2001 From: jaychang99 Date: Sun, 27 Aug 2023 17:11:05 +0900 Subject: [PATCH 08/23] =?UTF-8?q?feat(MyPage):=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=88=98=EC=A0=95=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B8=B0=EB=B3=B8=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constant/GenderDropdownValueList.ts | 14 +++++ src/feature/mypage/views/ViewMyPageEdit.tsx | 52 +++++++++++++++++++ src/pages/mypage/edit.tsx | 12 ++--- 3 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 src/feature/mypage/constant/GenderDropdownValueList.ts create mode 100644 src/feature/mypage/views/ViewMyPageEdit.tsx diff --git a/src/feature/mypage/constant/GenderDropdownValueList.ts b/src/feature/mypage/constant/GenderDropdownValueList.ts new file mode 100644 index 0000000..aa1813c --- /dev/null +++ b/src/feature/mypage/constant/GenderDropdownValueList.ts @@ -0,0 +1,14 @@ +export const GENDER_DROPDOWN_VALUE_LIST = [ + { + value: "F", + label: "여성", + }, + { + value: "M", + label: "남성", + }, + { + value: "U", + label: "선택안함", + }, +]; diff --git a/src/feature/mypage/views/ViewMyPageEdit.tsx b/src/feature/mypage/views/ViewMyPageEdit.tsx new file mode 100644 index 0000000..11ab71f --- /dev/null +++ b/src/feature/mypage/views/ViewMyPageEdit.tsx @@ -0,0 +1,52 @@ +import styled from "@emotion/styled"; +import Button from "components/button/Button"; +import Dropdown from "components/dropdown/Dropdown"; +import TextInput from "components/inputs/TextInput/TextInput"; +import { GENDER_DROPDOWN_VALUE_LIST } from "feature/mypage/constant/GenderDropdownValueList"; + +const { Option } = Dropdown; + +interface Props {} + +const ViewMyPageEdit = ({}: Props) => { + return ( + +
+ + +
이 자리에 생년월일을 고르는 DatePicker 가 들어갈 예정입니다.
+ {/* TODO => placeholder 가 적용되지 않는 문제 핵결*/} + + {GENDER_DROPDOWN_VALUE_LIST.map(({ value, label }) => ( + + ))} + +
+ +
+ ); +}; + +export default ViewMyPageEdit; + +const EmotionWrapper = styled.div` + .input-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + row-gap: 32px; + } + + .button-save { + margin-top: 32px; + } +`; diff --git a/src/pages/mypage/edit.tsx b/src/pages/mypage/edit.tsx index 1ede146..54c08d8 100644 --- a/src/pages/mypage/edit.tsx +++ b/src/pages/mypage/edit.tsx @@ -1,18 +1,14 @@ import styled from "@emotion/styled"; -import PageMarker from "components/pageMarker/PageMarker"; import { GetServerSideProps } from "next"; -import Link from "next/link"; +import ViewMyPageEdit from "feature/mypage/views/ViewMyPageEdit"; const PageMyPageEdit = () => { return ( - - + + {/* 임사: 계정 삭제 페이지 이동 - + */} ); }; From d3cd3ded0e7d29ca51b226d0e8917c896769d43d Mon Sep 17 00:00:00 2001 From: jaychang99 Date: Sun, 27 Aug 2023 18:12:29 +0900 Subject: [PATCH 09/23] =?UTF-8?q?fix(TextInput):=20=EB=B9=84=EB=8F=99?= =?UTF-8?q?=EA=B8=B0=20api=20=ED=98=B8=EC=B6=9C=EC=97=90=20=EC=9D=98?= =?UTF-8?q?=ED=95=9C=20value=20=EB=B3=80=ED=99=94=EB=A5=BC=20=EA=B0=90?= =?UTF-8?q?=EC=A7=80=ED=95=98=EC=A7=80=20=EB=AA=BB=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/inputs/TextInput/TextInput.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/inputs/TextInput/TextInput.tsx b/src/components/inputs/TextInput/TextInput.tsx index 33318fb..49763fc 100644 --- a/src/components/inputs/TextInput/TextInput.tsx +++ b/src/components/inputs/TextInput/TextInput.tsx @@ -75,6 +75,11 @@ const TextInput: React.FC = ({ } }, [enteredValue, status, onTextChange]); + useEffect(() => { + // 비동기 API 호출로 인한 value 변경 시에만 실행 + setEnteredValue(value); + }, [value]); + return ( {label && {label}} From 6e4121b43be88205eb243949a7dd33568ffa7ddf Mon Sep 17 00:00:00 2001 From: jaychang99 Date: Sun, 27 Aug 2023 18:13:29 +0900 Subject: [PATCH 10/23] =?UTF-8?q?feat(MyPage):=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A0=95=EB=B3=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=83=9D=EB=85=84?= =?UTF-8?q?=EC=9B=94=EC=9D=BC=20=EC=A0=9C=EC=99=B8=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EB=B0=8F=20=EB=AA=A8=ED=82=B9=20=EA=B5=AC?= =?UTF-8?q?=EC=84=B1=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/feature/mypage/mockup/MockupMypage.tsx | 8 +++ src/feature/mypage/types/TMypageFormValues.ts | 19 +++++ src/feature/mypage/views/ViewMyPageEdit.tsx | 70 +++++++++++++++++-- src/pages/mypage/edit.tsx | 14 +--- 4 files changed, 94 insertions(+), 17 deletions(-) create mode 100644 src/feature/mypage/mockup/MockupMypage.tsx create mode 100644 src/feature/mypage/types/TMypageFormValues.ts diff --git a/src/feature/mypage/mockup/MockupMypage.tsx b/src/feature/mypage/mockup/MockupMypage.tsx new file mode 100644 index 0000000..4bfb419 --- /dev/null +++ b/src/feature/mypage/mockup/MockupMypage.tsx @@ -0,0 +1,8 @@ +import { TUser } from "feature/mypage/types/TMypageFormValues"; + +export const MOCKUP_MYPAGE_INITIAL_VALUES: TUser = { + nickname: "홍길동", + introduction: "안녕하세요. 저는 홍길동입니다.", + birthYear: "1990", + gender: "M", +}; diff --git a/src/feature/mypage/types/TMypageFormValues.ts b/src/feature/mypage/types/TMypageFormValues.ts new file mode 100644 index 0000000..23cc06b --- /dev/null +++ b/src/feature/mypage/types/TMypageFormValues.ts @@ -0,0 +1,19 @@ +type TFormValueItem = { + value: string; + isValid: boolean; +}; + +// TODO: API 응답 형식에 따라 달라질 수 있음 +export type TUser = { + nickname: string; + introduction: string; + birthYear: string; + gender: string; +}; + +export type TMypageFormValues = { + nickname: TFormValueItem; + introduction: TFormValueItem; + birthYear: TFormValueItem; + gender: TFormValueItem; +}; diff --git a/src/feature/mypage/views/ViewMyPageEdit.tsx b/src/feature/mypage/views/ViewMyPageEdit.tsx index 11ab71f..42bae4d 100644 --- a/src/feature/mypage/views/ViewMyPageEdit.tsx +++ b/src/feature/mypage/views/ViewMyPageEdit.tsx @@ -3,24 +3,74 @@ import Button from "components/button/Button"; import Dropdown from "components/dropdown/Dropdown"; import TextInput from "components/inputs/TextInput/TextInput"; import { GENDER_DROPDOWN_VALUE_LIST } from "feature/mypage/constant/GenderDropdownValueList"; +import { MOCKUP_MYPAGE_INITIAL_VALUES } from "feature/mypage/mockup/MockupMypage"; +import { TMypageFormValues } from "feature/mypage/types/TMypageFormValues"; +import Link from "next/link"; +import { useCallback, useEffect, useState } from "react"; const { Option } = Dropdown; interface Props {} -const ViewMyPageEdit = ({}: Props) => { +const ViewMypageEdit = ({}: Props) => { + const [formValues, setFormValues] = useState({ + nickname: { value: "", isValid: false }, + introduction: { value: "", isValid: false }, + birthYear: { value: "", isValid: false }, + gender: { value: "", isValid: false }, + }); + + const handleChangeInput = useCallback( + (name: string) => (value: string, isValid: boolean) => { + setFormValues((prev) => ({ + ...prev, // TODO: ... 연산자가 1레벨까지만 복사한다는 것을 기억하자. + [name]: { value, isValid }, + })); + }, + [] + ); + + const handleChangeNickname = useCallback(handleChangeInput("nickname"), []); + const handleChangeDescription = useCallback(handleChangeInput("introduction"), []); + + const { nickname, introduction, gender } = formValues; + const deleteUserAccountLink = "/mypage/delete"; + + // TODO: 서버 데이터 받아오는 작업 모킹 + useEffect(() => { + const nextFormValues = {} as TMypageFormValues; + + Object.keys(MOCKUP_MYPAGE_INITIAL_VALUES).forEach((key) => { + const value = MOCKUP_MYPAGE_INITIAL_VALUES[key as keyof TMypageFormValues]; + + nextFormValues[key as keyof TMypageFormValues] = { + value, + isValid: true, + }; + }); + setFormValues(nextFormValues); + }, []); + return (
- +
이 자리에 생년월일을 고르는 DatePicker 가 들어갈 예정입니다.
{/* TODO => placeholder 가 적용되지 않는 문제 핵결*/} - + {GENDER_DROPDOWN_VALUE_LIST.map(({ value, label }) => (