diff --git a/apps/jurumarble/src/app/map/components/RegionBottomsheet.tsx b/apps/jurumarble/src/app/map/components/RegionBottomsheet.tsx index 5acf08a6..8b3bcbf8 100644 --- a/apps/jurumarble/src/app/map/components/RegionBottomsheet.tsx +++ b/apps/jurumarble/src/app/map/components/RegionBottomsheet.tsx @@ -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"; @@ -33,7 +33,7 @@ const RegionBottomSheet = ({ on, onToggleDrinkSearchModal, setChangeMapCenter }: />{" "} - {REGION_LIST_BOUNDS.map(({ label, value, lat, long }) => ( + {REGION_LIST.map(({ label, value, lat, long }) => ( { setChangeMapCenter(lat, long); diff --git a/apps/jurumarble/src/app/my/components/UseInfoContainer.tsx b/apps/jurumarble/src/app/my/components/UseInfoContainer.tsx index 8de9b957..54c53777 100644 --- a/apps/jurumarble/src/app/my/components/UseInfoContainer.tsx +++ b/apps/jurumarble/src/app/my/components/UseInfoContainer.tsx @@ -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 ( @@ -30,11 +37,9 @@ function UserInfoContainer() { {gender === "MALE" ? "남" : "여"} - {ageType} + {ageRange}대 {mbti} - - {alcoholLimit} {nickname} @@ -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; `}; diff --git a/apps/jurumarble/src/app/my/components/VoteCountContainer.tsx b/apps/jurumarble/src/app/my/components/VoteCountContainer.tsx index da89a1cd..64c4798a 100644 --- a/apps/jurumarble/src/app/my/components/VoteCountContainer.tsx +++ b/apps/jurumarble/src/app/my/components/VoteCountContainer.tsx @@ -2,6 +2,7 @@ import { TabList, TAB_LIST } from "src/types/my"; import styled, { css } from "styled-components"; +import useGetTheNumberOfMyVoteService from "../services/useGetCountedVoteService"; interface Props { selectedTab: string; @@ -9,6 +10,13 @@ interface Props { } function VoteCountContainer({ selectedTab, onClickSelectedTab }: Props) { + const theNumberOfMyVote = useGetTheNumberOfMyVoteService(); + const { writtenVoteCnt, joinedVoteCnt, bookmarkedVoteCnt } = theNumberOfMyVote ?? { + writtenVoteCnt: 0, + joinedVoteCnt: 0, + bookmarkedVoteCnt: 0, + }; + return ( {TAB_LIST.map(({ id, name }) => { @@ -18,7 +26,15 @@ function VoteCountContainer({ selectedTab, onClickSelectedTab }: Props) { onClick={() => onClickSelectedTab(id)} isSelected={id === selectedTab} > - 0 + + {id === "created-vote" + ? writtenVoteCnt + : id === "paticipated-vote" + ? joinedVoteCnt + : id === "bookmarked-vote" + ? bookmarkedVoteCnt + : 0} + {name} ); diff --git a/apps/jurumarble/src/app/my/components/VoteListContainer.tsx b/apps/jurumarble/src/app/my/components/VoteListContainer.tsx index f3594bd2..8026a8b7 100644 --- a/apps/jurumarble/src/app/my/components/VoteListContainer.tsx +++ b/apps/jurumarble/src/app/my/components/VoteListContainer.tsx @@ -44,6 +44,7 @@ function VoteListContainer() { {myVoteList.map(({ voteId, region, title, imageA, imageB }) => ( ))} +
); diff --git a/apps/jurumarble/src/app/my/edit/components/SelectMBTI.tsx b/apps/jurumarble/src/app/my/edit/components/SelectMBTI.tsx index 77acbb72..e1c575d8 100644 --- a/apps/jurumarble/src/app/my/edit/components/SelectMBTI.tsx +++ b/apps/jurumarble/src/app/my/edit/components/SelectMBTI.tsx @@ -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; diff --git a/apps/jurumarble/src/app/my/edit/components/UserInfoEditContainer.tsx b/apps/jurumarble/src/app/my/edit/components/UserInfoEditContainer.tsx index 110de3c6..8b981f58 100644 --- a/apps/jurumarble/src/app/my/edit/components/UserInfoEditContainer.tsx +++ b/apps/jurumarble/src/app/my/edit/components/UserInfoEditContainer.tsx @@ -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"; @@ -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, @@ -24,8 +22,6 @@ function UserInfoEditContainer() { deleteUser, } = useEditProfileService(); - const router = useRouter(); - const [isToggleWithdrawalModal, onToggleWithdrawalModal] = useToggle(); return ( @@ -45,7 +41,7 @@ function UserInfoEditContainer() {

나이

- +

MBTI

diff --git a/apps/jurumarble/src/app/my/edit/services/useEditProfileService.ts b/apps/jurumarble/src/app/my/edit/services/useEditProfileService.ts index b925e79e..cfa43aa3 100644 --- a/apps/jurumarble/src/app/my/edit/services/useEditProfileService.ts +++ b/apps/jurumarble/src/app/my/edit/services/useEditProfileService.ts @@ -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"; @@ -48,12 +49,6 @@ export default function useEditProfileService() { (newUserInfo: UpdateUserInfoRequest) => updateUserInfoAPI(newUserInfo), { onSuccess: () => router.push(Path.MY_PAGE), - onError: () => { - /** - * @TODO 서버 메시지와 연동 - */ - alert("MBTI 수정시 2개월간 바꿀 수 없습니다."); - }, }, ); @@ -61,6 +56,7 @@ export default function useEditProfileService() { onSuccess: () => { toast("회원 탈퇴가 완료되었습니다."); router.push(Path.MAIN_PAGE); + logout(); }, }); diff --git a/apps/jurumarble/src/app/my/services/useGetCountedVoteService.ts b/apps/jurumarble/src/app/my/services/useGetCountedVoteService.ts new file mode 100644 index 00000000..e7b595a6 --- /dev/null +++ b/apps/jurumarble/src/app/my/services/useGetCountedVoteService.ts @@ -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; +} diff --git a/apps/jurumarble/src/app/search/components/RegionSmallSelect.tsx b/apps/jurumarble/src/app/search/components/RegionSmallSelect.tsx index fd3a428f..f0c3126e 100644 --- a/apps/jurumarble/src/app/search/components/RegionSmallSelect.tsx +++ b/apps/jurumarble/src/app/search/components/RegionSmallSelect.tsx @@ -9,8 +9,6 @@ interface Props { onChangeSortOption: (id: string) => void; } -REGION_LIST.unshift({ value: "", label: "지역" }); - function RegionSmallSelect({ defaultOption, onChangeSortOption }: Props) { const [isOpen, onToggleOpen] = useToggle(); @@ -19,7 +17,7 @@ function RegionSmallSelect({ defaultOption, onChangeSortOption }: Props) { - - - - ); -} - -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; - - #indicator { - display: flex; - align-items: center; - color: ${theme.colors.black_01}; - } - #select-list { - overflow: auto; - top: 6px; - left: -100px; - width: 335px; - height: 60vh; - display: flex; - flex-direction: column; - } - li { - display: flex; - justify-content: center; - padding: 16px 0; - ${theme.typography.button02}; - :hover { - background-color: ${theme.colors.bg_02}; - } - } - svg { - ${isOpen && "transform: rotateX( 180deg )"} - } - `} -`; - -export default RegionSelect; diff --git a/apps/jurumarble/src/lib/apis/http/http.ts b/apps/jurumarble/src/lib/apis/http/http.ts index 37b17a35..aeae8040 100644 --- a/apps/jurumarble/src/lib/apis/http/http.ts +++ b/apps/jurumarble/src/lib/apis/http/http.ts @@ -1,8 +1,8 @@ import axios from "axios"; -import type { AxiosInstance, AxiosRequestConfig } from "axios"; import { SERVER_URL } from "lib/constants"; import userStorage from "lib/utils/userStorage"; import { logout } from "lib/utils/auth"; +import { toast } from "react-toastify"; const axiosInstance = axios.create({ baseURL: SERVER_URL, @@ -30,6 +30,10 @@ axiosInstance.interceptors.response.use( } = error; switch (status) { + case 400: + toast.error(error.response.data.message); + throw new Error(error.response.data.message); + case 401: const tokens = userStorage.get(); if (!tokens) throw new Error("No tokens found"); diff --git a/apps/jurumarble/src/lib/apis/my.ts b/apps/jurumarble/src/lib/apis/my.ts index ba59d117..9dbc0fa5 100644 --- a/apps/jurumarble/src/lib/apis/my.ts +++ b/apps/jurumarble/src/lib/apis/my.ts @@ -59,3 +59,14 @@ export const deleteUserAPI = async () => { const response = await http.delete("api/users"); return response.data; }; + +interface GetTheNumberOfMyVote { + writtenVoteCnt: number; + joinedVoteCnt: number; + bookmarkedVoteCnt: number; +} + +export const getTheNumberOfMyVoteAPI = async () => { + const response = await http.get("api/votes/myActivities"); + return response.data; +}; diff --git a/apps/jurumarble/src/lib/apis/user.ts b/apps/jurumarble/src/lib/apis/user.ts index 00275f1b..53c6242e 100644 --- a/apps/jurumarble/src/lib/apis/user.ts +++ b/apps/jurumarble/src/lib/apis/user.ts @@ -3,13 +3,11 @@ import { http } from "./http/http"; type GenderType = keyof typeof GENDER; -export type Agetype = "teenager" | "twenties" | "thirties" | "forties" | "fifties" | null; - export interface GetUserInfoResponse { nickname: string; email: string; imageUrl: string; - ageType: Agetype; + yearOfBirth: number; gender: GenderType; mbti: string; alcoholLimit: string; diff --git a/apps/jurumarble/src/lib/constants.tsx b/apps/jurumarble/src/lib/constants.tsx index e805d317..7167a10a 100644 --- a/apps/jurumarble/src/lib/constants.tsx +++ b/apps/jurumarble/src/lib/constants.tsx @@ -25,26 +25,6 @@ export const NAVER_LOGIN_REDIRECT_URL = : `${CLIENT_URL}${Path.NAVER_LOGIN_PROCESS}`; export const REGION_LIST = [ - { value: "SEOUL", label: "서울" }, - { value: "INCHEON", label: "인천" }, - { value: "DAEJEON", label: "대전" }, - { value: "DAEGU", label: "대구" }, - { value: "GWANGJU", label: "광주" }, - { value: "BUSAN", label: "부산" }, - { value: "ULSAN", label: "울산" }, - { value: "SEJONG", label: "세종" }, - { value: "GYEONGGI", label: "경기도" }, - { value: "GANGWON", label: "강원도" }, - { value: "CHUNGBUK", label: "충청북도" }, - { value: "CHUNGNAM", label: "충청남도" }, - { value: "GYEONGBUK", label: "경상북도" }, - { value: "GYEONGNAM", label: "경상남도" }, - { value: "JEONBUK", label: "전라북도" }, - { value: "JEONNAM", label: "전라남도" }, - { value: "JEJU", label: "제주" }, -]; - -export const REGION_LIST_BOUNDS = [ { value: "SEOUL", label: "서울", lat: 37.53391, long: 126.9775 }, { value: "INCHEON", label: "인천", lat: 37.45323333333334, long: 126.70735277777779 }, { value: "DAEJEON", label: "대전", lat: 36.347119444444445, long: 127.38656666666667 }, @@ -53,14 +33,14 @@ export const REGION_LIST_BOUNDS = [ { value: "BUSAN", label: "부산", lat: 35.17701944444444, long: 129.07695277777776 }, { value: "ULSAN", label: "울산", lat: 35.53540833333333, long: 129.3136888888889 }, { value: "SEJONG", label: "세종", lat: 36.4800121, long: 127.289069 }, - { value: "GYEONGGI", label: "경기도", lat: 37.39067, long: 126.7888 }, - { value: "GANGWON", label: "강원도", lat: 38.642618, long: 127.170231 }, - { value: "CHUNGBUK", label: "충청북도", lat: 36.6325, long: 127.49358611111111 }, - { value: "CHUNGNAM", label: "충청남도", lat: 36.32387222222223, long: 127.42295555555556 }, - { value: "GYEONGBUK", label: "경상북도", lat: 36.491286, long: 128.889433 }, - { value: "GYEONGNAM", label: "경상남도", lat: 35.459369, long: 128.214826 }, - { value: "JEONBUK", label: "전라북도", lat: 35.81727, long: 127.11105277777777 }, - { value: "JEONNAM", label: "전라남도", lat: 34.813044444444444, long: 126.465 }, + { value: "GYEONGGI", label: "경기", lat: 37.39067, long: 126.7888 }, + { value: "GANGWON", label: "강원", lat: 38.642618, long: 127.170231 }, + { value: "CHUNGBUK", label: "충북", lat: 36.6325, long: 127.49358611111111 }, + { value: "CHUNGNAM", label: "충남", lat: 36.32387222222223, long: 127.42295555555556 }, + { value: "GYEONGBUK", label: "경북", lat: 36.491286, long: 128.889433 }, + { value: "GYEONGNAM", label: "경남", lat: 35.459369, long: 128.214826 }, + { value: "JEONBUK", label: "전북", lat: 35.81727, long: 127.11105277777777 }, + { value: "JEONNAM", label: "전남", lat: 34.813044444444444, long: 126.465 }, { value: "JEJU", label: "제주", lat: 33.48569444444445, long: 126.50033333333333 }, ]; diff --git a/apps/jurumarble/src/lib/queryKeys.ts b/apps/jurumarble/src/lib/queryKeys.ts index 9b2f00b4..3acb2402 100644 --- a/apps/jurumarble/src/lib/queryKeys.ts +++ b/apps/jurumarble/src/lib/queryKeys.ts @@ -18,6 +18,7 @@ export const queryKeys = { MY_PARTICIPATED_VOTE: "myParticipatedVote" as const, MY_CREATED_VOTE: "myCreatedVote" as const, MY_BOOKMARKED_VOTE: "myBookmarkedVote" as const, + THE_NUMBER_OF_MY_VOTE: "theNumberOfMyVote" as const, DRINKS_MAP: "drinksMap" as const, }; diff --git a/apps/jurumarble/src/services/useGetUserInfo.ts b/apps/jurumarble/src/services/useGetUserInfo.ts index 5e4b63f3..f8f55d26 100644 --- a/apps/jurumarble/src/services/useGetUserInfo.ts +++ b/apps/jurumarble/src/services/useGetUserInfo.ts @@ -8,8 +8,8 @@ export default function useGetUserInfo() { const { data: userInfo } = useQuery(getQueryKey, getUserInfo, { placeholderData: () => ({ gender: "MALE", - nickname: "", - ageType: "twenties", + nickname: "주루마블", + yearOfBirth: 1990, imageUrl: "", mbti: "ESTJ", alcoholLimit: "LOW",