Skip to content

Commit

Permalink
[JR-838] 마이페이지 qa 작업 (#159)
Browse files Browse the repository at this point in the history
* fix: 무한 스크롤 작동하도록 수정

* feat: 마이페이지에 투표 갯수를 불러오는 api 연동

* fix: 연령대대신 출생년도를 받도록 수정

* feat: 연령대를 나타내도록 수정

* feat: 회원탈퇴 후 로그아웃 처리

* refactor: 하나의 REGION_LIST를 사용하도록 수정

* refactor: RegionSelect 도메인별 분리 및 리팩터링

* fix: 버튼 안 버튼의 존재로 콘솔창에 뜨던 에러 제거

* feat: 서버의 에러 메시지를 보여주기 위해 axios의 interceptors에서 처리

* feat: 회원가입이 진행되지 않았을 경우 회원가입 페이지로 리다이렉트 처리

* fix: map처리 후 키 추가
  • Loading branch information
Leejha authored Oct 6, 2023
1 parent 8eec288 commit bb83f44
Show file tree
Hide file tree
Showing 21 changed files with 342 additions and 134 deletions.
4 changes: 2 additions & 2 deletions apps/jurumarble/src/app/map/components/RegionBottomsheet.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Button, Portal } from "components/index";
import { REGION_LIST_BOUNDS } from "lib/constants";
import { REGION_LIST } from "lib/constants";
import { transitions } from "lib/styles";
import Image from "next/image";
import React from "react";
Expand Down Expand Up @@ -33,7 +33,7 @@ const RegionBottomSheet = ({ on, onToggleDrinkSearchModal, setChangeMapCenter }:
/>{" "}
</SelectBox>
<List>
{REGION_LIST_BOUNDS.map(({ label, value, lat, long }) => (
{REGION_LIST.map(({ label, value, lat, long }) => (
<RegionItem
onClick={() => {
setChangeMapCenter(lat, long);
Expand Down
17 changes: 11 additions & 6 deletions apps/jurumarble/src/app/my/components/UseInfoContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@ import Path from "lib/Path";
import Link from "next/link";
import styled, { css } from "styled-components";
import Image from "next/image";

import { DrinkImage } from "public/images";
import useGetUserInfo from "services/useGetUserInfo";
import { useRouter } from "next/navigation";

function UserInfoContainer() {
const { userInfo } = useGetUserInfo();

if (!userInfo) return <></>;

const { gender, nickname, ageType, mbti, imageUrl, alcoholLimit } = userInfo;
const { gender, nickname, yearOfBirth, mbti, imageUrl } = userInfo;

const router = useRouter();
if (!(gender && yearOfBirth && mbti)) router.replace(Path.REGISTER_PAGE);

const date = new Date();
const age = date.getFullYear() - yearOfBirth;
const ageRange = Math.floor(age / 10) * 10;

return (
<Container>
Expand All @@ -30,11 +37,9 @@ function UserInfoContainer() {
<UserInfo>
{gender === "MALE" ? "남" : "여"}
<Divider />
{ageType}
{ageRange}
<Divider />
{mbti}
<Divider />
{alcoholLimit}
</UserInfo>
<Nickname>{nickname}</Nickname>
<Link href={Path.PROFILE_EDIT}>
Expand Down Expand Up @@ -73,7 +78,7 @@ const UserInfo = styled.span`
flex-direction: row;
align-items: center;
justify-content: center;
width: 130px;
width: 96px;
height: 24px;
border-radius: 4px;
`};
Expand Down
18 changes: 17 additions & 1 deletion apps/jurumarble/src/app/my/components/VoteCountContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@

import { TabList, TAB_LIST } from "src/types/my";
import styled, { css } from "styled-components";
import useGetTheNumberOfMyVoteService from "../services/useGetCountedVoteService";

interface Props {
selectedTab: string;
onClickSelectedTab: (tab: TabList) => void;
}

function VoteCountContainer({ selectedTab, onClickSelectedTab }: Props) {
const theNumberOfMyVote = useGetTheNumberOfMyVoteService();
const { writtenVoteCnt, joinedVoteCnt, bookmarkedVoteCnt } = theNumberOfMyVote ?? {
writtenVoteCnt: 0,
joinedVoteCnt: 0,
bookmarkedVoteCnt: 0,
};

return (
<Container>
{TAB_LIST.map(({ id, name }) => {
Expand All @@ -18,7 +26,15 @@ function VoteCountContainer({ selectedTab, onClickSelectedTab }: Props) {
onClick={() => onClickSelectedTab(id)}
isSelected={id === selectedTab}
>
<VoteCount>0</VoteCount>
<VoteCount>
{id === "created-vote"
? writtenVoteCnt
: id === "paticipated-vote"
? joinedVoteCnt
: id === "bookmarked-vote"
? bookmarkedVoteCnt
: 0}
</VoteCount>
<VoteTypeText>{name}</VoteTypeText>
</VoteTypeTab>
);
Expand Down
2 changes: 2 additions & 0 deletions apps/jurumarble/src/app/my/components/VoteListContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function VoteListContainer() {
<VoteList>
{myVoteList.map(({ voteId, region, title, imageA, imageB }) => (
<VoteItem
key={voteId}
voteId={voteId}
region={region}
title={title}
Expand All @@ -52,6 +53,7 @@ function VoteListContainer() {
/>
))}
</VoteList>
<div ref={subscribe}></div>
</Container>
</>
);
Expand Down
1 change: 0 additions & 1 deletion apps/jurumarble/src/app/my/edit/components/SelectMBTI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useToggle, useOutsideClick } from "@monorepo/hooks";
import { SvgArrowDown } from "src/assets/icons/components";
import { useId } from "react";
import { MBTI_LIST } from "lib/constants";
import depths from "lib/styles/depths";

interface Props {
MBTI: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Button } from "components/button";
import { GENDER } from "lib/constants";
import Path from "lib/Path";
import { useRouter } from "next/navigation";
import useGetUserInfo from "services/useGetUserInfo";
import styled, { css } from "styled-components";
import useEditProfileService from "../services/useEditProfileService";
Expand All @@ -13,7 +11,7 @@ import { useToggle } from "@monorepo/hooks";

function UserInfoEditContainer() {
const { userInfo } = useGetUserInfo();
const { gender, ageType, alcoholLimit, imageUrl, mbti, nickname } = userInfo!;
const { gender, yearOfBirth, alcoholLimit, imageUrl, mbti, nickname } = userInfo!;

const {
onUploadImage,
Expand All @@ -24,8 +22,6 @@ function UserInfoEditContainer() {
deleteUser,
} = useEditProfileService();

const router = useRouter();

const [isToggleWithdrawalModal, onToggleWithdrawalModal] = useToggle();

return (
Expand All @@ -45,7 +41,7 @@ function UserInfoEditContainer() {
</GenderAndAgeBox>
<GenderAndAgeBox>
<H3>나이</H3>
<Input placeholder={ageType ?? "나이를 설정해주세요."} width="50%" disabled />
<Input placeholder={`${yearOfBirth}`} width="50%" disabled />
</GenderAndAgeBox>
</GenderAndAge>
<H3>MBTI</H3>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { uploadImageAPI } from "lib/apis/common";
import { deleteUserAPI, updateUserInfoAPI } from "lib/apis/my";
import Path from "lib/Path";
import { queryKeys } from "lib/queryKeys";
import { logout } from "lib/utils/auth";
import { useRouter } from "next/navigation";
import { toast } from "react-toastify";

Expand Down Expand Up @@ -48,19 +49,14 @@ export default function useEditProfileService() {
(newUserInfo: UpdateUserInfoRequest) => updateUserInfoAPI(newUserInfo),
{
onSuccess: () => router.push(Path.MY_PAGE),
onError: () => {
/**
* @TODO 서버 메시지와 연동
*/
alert("MBTI 수정시 2개월간 바꿀 수 없습니다.");
},
},
);

const { mutate: deleteUser } = useMutation(() => deleteUserAPI(), {
onSuccess: () => {
toast("회원 탈퇴가 완료되었습니다.");
router.push(Path.MAIN_PAGE);
logout();
},
});

Expand Down
14 changes: 14 additions & 0 deletions apps/jurumarble/src/app/my/services/useGetCountedVoteService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useQuery } from "@tanstack/react-query";
import { getTheNumberOfMyVoteAPI } from "lib/apis/my";
import { queryKeys } from "lib/queryKeys";

const getTheNumberOfMyVoteQueryKey = () => [queryKeys.THE_NUMBER_OF_MY_VOTE];

export default function useGetTheNumberOfMyVoteService() {
const { data: theNumberOfMyVote } = useQuery(
getTheNumberOfMyVoteQueryKey(),
getTheNumberOfMyVoteAPI,
);

return theNumberOfMyVote;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ interface Props {
onChangeSortOption: (id: string) => void;
}

REGION_LIST.unshift({ value: "", label: "지역" });

function RegionSmallSelect({ defaultOption, onChangeSortOption }: Props) {
const [isOpen, onToggleOpen] = useToggle();

Expand All @@ -19,7 +17,7 @@ function RegionSmallSelect({ defaultOption, onChangeSortOption }: Props) {
<Select
defaultValue={defaultOption}
onChangeSelectedOption={onChangeSortOption}
options={REGION_LIST}
options={[{ value: "", label: "지역", lat: 0, long: 0 }, ...REGION_LIST]}
isOpen={isOpen}
onToggleOpen={onToggleOpen}
>
Expand Down
2 changes: 1 addition & 1 deletion apps/jurumarble/src/app/stamp/components/DrinkItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ const NameStampContainer = styled.div`
justify-content: space-between;
`;

const StampWrapper = styled.button`
const StampWrapper = styled.div`
margin-right: 1px;
`;

Expand Down
130 changes: 130 additions & 0 deletions apps/jurumarble/src/app/stamp/components/RegionSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { useToggle, useOutsideClick } from "@monorepo/hooks";
import { REGION_LIST } from "lib/constants";
import { useId } from "react";
import { SvgArrowDown } from "src/assets/icons/components";
import styled, { css } from "styled-components";

interface Props {
regionOption: string;
onChangeRegionOption: (id: string) => void;
}

const COPIED_REGION_LIST = [
{ value: "", label: "지역을 선택해주세요.", lat: 0, long: 0 },
...REGION_LIST,
];

function RegionSelect({ regionOption, onChangeRegionOption }: Props) {
const [isOpen, onToggleOpen] = useToggle();
const { targetEl } = useOutsideClick<HTMLDivElement>(isOpen, onToggleOpen);
const uniqueId = useId();

return (
<SelectStyled isOpen={isOpen}>
<div ref={targetEl}>
<SelectButton
type="button"
id={`select-box-${uniqueId}`}
aria-haspopup="true"
aria-expanded="true"
aria-controls={`select-list-${uniqueId}`}
onClick={onToggleOpen}
>
<SelectedText className="selected-label">
{COPIED_REGION_LIST.find(({ value }) => value === regionOption)?.label}
<span id="indicator">
<SvgArrowDown width={24} height={24} />
</span>
</SelectedText>
</SelectButton>
{isOpen ? (
<Ul
id={`select-list-${uniqueId}`}
aria-labelledby={`select-box-${uniqueId}`}
role="listbox"
>
{COPIED_REGION_LIST.map(({ value, label }) => (
<Li
key={`select_${value}`}
onClick={() => {
onChangeRegionOption(value);
onToggleOpen();
}}
>
{label}
</Li>
))}
</Ul>
) : null}
</div>
</SelectStyled>
);
}

const SelectStyled = styled.div<{ isOpen: boolean }>`
${({ theme, isOpen }) => css`
${theme.typography.button01};
color: ${theme.colors.black_03};
border: 1px solid ${theme.colors.black_05};
display: flex;
align-items: center;
justify-content: center;
height: 40px;
border-radius: 8px;
position: relative;
#indicator {
display: flex;
align-items: center;
color: ${theme.colors.black_01};
}
svg {
${isOpen && "transform: rotateX( 180deg )"}
}
`}
`;

const SelectButton = styled.button`
display: contents;
`;

const SelectedText = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
`;

const Ul = styled.ul`
${({ theme }) =>
css`
position: absolute;
margin-top: 8px;
border-radius: 8px;
box-shadow: 0 0 40px 0 rgba(0, 0, 0, 0.1);
z-index: 99;
overflow: auto;
left: 0px;
top: 38px;
width: 100%;
height: 60vh;
display: flex;
flex-direction: column;
border: solid 1px ${theme.colors.black_05};
background-color: ${theme.colors.white};
`}
`;

const Li = styled.li`
${({ theme }) => css`
display: flex;
align-items: center;
justify-content: center;
padding: 16px 0;
${theme.typography.button02};
:hover {
background-color: ${theme.colors.bg_02};
}
`};
`;

export default RegionSelect;
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import RegionSelect from "components/RegionSelect";
import Path from "lib/Path";
import { useRouter } from "next/navigation";
import { DrinkInfo } from "src/types/drink";
import styled from "styled-components";
import DrinkItem from "./DrinkItem";
import RegionSelect from "./RegionSelect";

interface Props {
regionOption: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import DrinkItem from "app/vote/post/components/DrinkItem";
import SearchInput from "components/SearchInput";
import useInput from "hooks/useInput";
import { DrinkInfoType } from "src/types/vote";
import RegionSelect from "components/RegionSelect";
import useGetDrinkList from "../services/useGetDrinkList";
import RegionSelect from "./RegionSelect";

interface Props {
onToggleDrinkSearchModal: () => void;
Expand Down
Loading

0 comments on commit bb83f44

Please sign in to comment.