diff --git a/apps/mobile/next.config.mjs b/apps/mobile/next.config.mjs
index b20c99f..fbd9685 100644
--- a/apps/mobile/next.config.mjs
+++ b/apps/mobile/next.config.mjs
@@ -41,6 +41,12 @@ const nextConfig = {
port: '',
pathname: '/**',
},
+ {
+ protocol: 'https',
+ hostname: 'raw.githubusercontent.com',
+ port: '',
+ pathname: '/**',
+ },
],
},
};
diff --git a/apps/web/next.config.mjs b/apps/web/next.config.mjs
index b20c99f..fbd9685 100644
--- a/apps/web/next.config.mjs
+++ b/apps/web/next.config.mjs
@@ -41,6 +41,12 @@ const nextConfig = {
port: '',
pathname: '/**',
},
+ {
+ protocol: 'https',
+ hostname: 'raw.githubusercontent.com',
+ port: '',
+ pathname: '/**',
+ },
],
},
};
diff --git a/apps/web/src/app/(main)/page.tsx b/apps/web/src/app/(main)/page.tsx
index bdfe034..16745c3 100644
--- a/apps/web/src/app/(main)/page.tsx
+++ b/apps/web/src/app/(main)/page.tsx
@@ -1,8 +1,8 @@
'use client';
-import { Flex, Spinner } from '@radix-ui/themes';
import Link from 'next/link';
-import { useRef, useState } from 'react';
+import { useRouter } from 'next/navigation';
+import { useEffect, useRef, useState } from 'react';
import Button from '@/shared/components/button/button';
import Input from '@/shared/components/input/input';
import { useGetUserList } from '@/shared/apis/main/queries';
@@ -28,6 +28,7 @@ import {
} from './mainPage.css';
export default function MainPage() {
+ const router = useRouter();
const [유저검색키워드, set유저검색키워드] = useState('');
const { data } = useGetUserList({ searchedname: 유저검색키워드 });
diff --git a/apps/web/src/app/auth/_components/authCompletion/authCompletion.tsx b/apps/web/src/app/auth/_components/authCompletion/authCompletion.tsx
index d26e3ad..a937c86 100644
--- a/apps/web/src/app/auth/_components/authCompletion/authCompletion.tsx
+++ b/apps/web/src/app/auth/_components/authCompletion/authCompletion.tsx
@@ -20,7 +20,7 @@ const AuthCompletion = () => {
const handleHomeClick = () => {
queryClient.invalidateQueries({ queryKey: ['userInfo'] });
- router.push('/');
+ window.location.href = '/';
};
return (
diff --git a/apps/web/src/app/auth/_components/authRedirect/authRedirect.tsx b/apps/web/src/app/auth/_components/authRedirect/authRedirect.tsx
index 5691638..b01b04e 100644
--- a/apps/web/src/app/auth/_components/authRedirect/authRedirect.tsx
+++ b/apps/web/src/app/auth/_components/authRedirect/authRedirect.tsx
@@ -28,10 +28,10 @@ const AuthRedirect = ({ handleNextStep }: AuthRedirectProps) => {
console.error('토큰이 제공되지 않았습니다.');
return;
}
- console.log(isRegistered);
+
if (isRegistered) {
queryClient.invalidateQueries({ queryKey: ['userInfo'] });
- router.replace('/', { scroll: false });
+ window.location.href = '/';
} else {
handleNextStep('school');
}
diff --git a/apps/web/src/app/auth/_components/authRegion/authRegion.tsx b/apps/web/src/app/auth/_components/authRegion/authRegion.tsx
index 070cf66..93bdab1 100644
--- a/apps/web/src/app/auth/_components/authRegion/authRegion.tsx
+++ b/apps/web/src/app/auth/_components/authRegion/authRegion.tsx
@@ -39,10 +39,10 @@ const AuthRegion = ({ handleNextStep, 대학교 }: AuthRegionProps) => {
set지역검색키워드(region);
};
- console.log(대학교, 지역검색키워드);
const handle회원가입 = () => {
+ console.log(대학교, 지역검색키워드);
mutate(
- { univName: 대학교, regionName: 지역검색키워드 },
+ { univName: 대학교, region: 지역검색키워드 },
{
onSuccess: () => {
handleNextStep('completion');
diff --git a/apps/web/src/app/board/_components/board.tsx b/apps/web/src/app/board/_components/board.tsx
index 31cf8dc..5d66a27 100644
--- a/apps/web/src/app/board/_components/board.tsx
+++ b/apps/web/src/app/board/_components/board.tsx
@@ -19,8 +19,10 @@ const Board = () => {
- {data?.map(({ userId, profileImg, boardContent }) => (
- -
+ {data?.map(({ userId, profileImg, boardContent }, index) => (
+
-
{boardContent}
diff --git a/apps/web/src/app/board/page.tsx b/apps/web/src/app/board/page.tsx
index 413e3f6..1b367f1 100644
--- a/apps/web/src/app/board/page.tsx
+++ b/apps/web/src/app/board/page.tsx
@@ -1,12 +1,10 @@
'use client';
import React, { useEffect, useRef, useState } from 'react';
-import { useIsMutating } from '@tanstack/react-query';
import Input from '@/shared/components/input/input';
import { usePostGuestBook } from '@/shared/apis/board/queries';
import { getAuthHeader } from '@/shared/utils/auth';
import Board from './_components/board';
-import useDebounce from './_hooks/useDebounce';
import {
containerStyle,
headingStyle,
diff --git a/apps/web/src/app/user/[userId]/UserPage.css.ts b/apps/web/src/app/user/[userId]/UserPage.css.ts
index 09876fb..7ee644c 100644
--- a/apps/web/src/app/user/[userId]/UserPage.css.ts
+++ b/apps/web/src/app/user/[userId]/UserPage.css.ts
@@ -96,3 +96,19 @@ export const topSectionStyle = style({
display: 'flex',
marginBottom: '8.8rem',
});
+
+export const spinnerTopDiveStyle = style({
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: '100%',
+ height: '46.2rem',
+});
+
+export const spinnerMiddleDivStyle = style({
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: '100%',
+ height: '33.9rem',
+});
diff --git a/apps/web/src/app/user/[userId]/_components/SVGTier/SVGTier.tsx b/apps/web/src/app/user/[userId]/_components/SVGTier/SVGTier.tsx
index 4a30a34..fa973bb 100644
--- a/apps/web/src/app/user/[userId]/_components/SVGTier/SVGTier.tsx
+++ b/apps/web/src/app/user/[userId]/_components/SVGTier/SVGTier.tsx
@@ -11,31 +11,36 @@ import Tier3SmallIcon from '@/shared/assets/svgs/tier/sm/tier_3.svg';
import Tier4SmallIcon from '@/shared/assets/svgs/tier/sm/tier_4.svg';
import Tier5SmallIcon from '@/shared/assets/svgs/tier/sm/tier_5.svg';
import Tier6SmallIcon from '@/shared/assets/svgs/tier/sm/tier_6.svg';
+import { TierTypes } from '../profile/_types';
interface SVGTierProps extends SVGAttributes {
size?: 'default' | 'sm';
- tier?: number;
+ tier?: TierTypes;
}
-const defaultComponent: Record>> = {
- 1: Tier1DefaultIcon,
- 2: Tier2DefaultIcon,
- 3: Tier3DefaultIcon,
- 4: Tier4DefaultIcon,
- 5: Tier5DefaultIcon,
- 6: Tier6DefaultIcon,
+const defaultComponent: Record>> = {
+ YELLOW: Tier1DefaultIcon,
+ GREEN: Tier2DefaultIcon,
+ BLUE: Tier3DefaultIcon,
+ RED: Tier4DefaultIcon,
+ GREY: Tier5DefaultIcon,
+ PURPLE: Tier6DefaultIcon,
};
-const smComponent: Record>> = {
- 1: Tier1SmallIcon,
- 2: Tier2SmallIcon,
- 3: Tier3SmallIcon,
- 4: Tier4SmallIcon,
- 5: Tier5SmallIcon,
- 6: Tier6SmallIcon,
+const smComponent: Record>> = {
+ YELLOW: Tier1SmallIcon,
+ GREEN: Tier2SmallIcon,
+ BLUE: Tier3SmallIcon,
+ RED: Tier4SmallIcon,
+ GREY: Tier5SmallIcon,
+ PURPLE: Tier6SmallIcon,
};
-const SVGTier = ({ size = 'default', tier = 1, ...props }: SVGTierProps) => {
+const SVGTier = ({
+ size = 'default',
+ tier = 'YELLOW',
+ ...props
+}: SVGTierProps) => {
const TierComponent =
size === 'default' ? defaultComponent[tier] : smComponent[tier];
diff --git a/apps/web/src/app/user/[userId]/_components/cardProfile/cardProfile.tsx b/apps/web/src/app/user/[userId]/_components/cardProfile/cardProfile.tsx
index 53e2cf9..64596b0 100644
--- a/apps/web/src/app/user/[userId]/_components/cardProfile/cardProfile.tsx
+++ b/apps/web/src/app/user/[userId]/_components/cardProfile/cardProfile.tsx
@@ -1,5 +1,6 @@
import Image from 'next/image';
import SVGTier from '../SVGTier/SVGTier';
+import { TierTypes } from '../profile/_types';
import {
containerStyle,
contentDivStyle,
@@ -11,30 +12,30 @@ import {
} from './cardProfile.css';
interface CardProfileProps {
- profileSrc?: string;
+ profileImg?: string;
language: string;
- tier: number;
- userName: string;
- school: string;
- region: string;
+ grade: TierTypes;
+ username: string;
+ schoolName: string;
+ regionName: string;
}
const CardProfile = ({
- profileSrc = 'https://avatars.githubusercontent.com/u/127329855?v=4',
+ profileImg = 'https://avatars.githubusercontent.com/u/127329855?v=4',
language,
- tier,
- userName,
- school,
- region,
+ grade,
+ username,
+ schoolName,
+ regionName,
}: CardProfileProps) => {
return (
@@ -43,13 +44,13 @@ const CardProfile = ({
{language}
-
-
{userName}
+
+ {username}
- {school}
- {region}
+ {schoolName}
+ {regionName}
diff --git a/apps/web/src/app/user/[userId]/_components/introduction/introduction.css.ts b/apps/web/src/app/user/[userId]/_components/introduction/introduction.css.ts
index cb032d9..e249360 100644
--- a/apps/web/src/app/user/[userId]/_components/introduction/introduction.css.ts
+++ b/apps/web/src/app/user/[userId]/_components/introduction/introduction.css.ts
@@ -1,19 +1,54 @@
-import { style } from '@vanilla-extract/css';
+import { style, styleVariants } from '@vanilla-extract/css';
import { globalTheme } from '@/shared/styles/globalTheme.css';
-export const headingTitleStyle = style({
- ...globalTheme.fonts.headBold36,
- color: globalTheme.colors.gray_19,
+export const container = style({
+ display: 'flex',
+ flexDirection: 'column',
+ width: '100%',
+});
+
+export const headingTitleStyle = styleVariants({
+ default: {
+ ...globalTheme.fonts.headBold36,
+ padding: '0 1.2rem',
+ boxSizing: 'border-box',
+ color: globalTheme.colors.gray_19,
+ border: '1px solid transparent',
+ },
+ edit: {
+ ...globalTheme.fonts.headBold36,
+ padding: '0 1.2rem',
+ boxSizing: 'border-box',
+ color: globalTheme.colors.gray_19,
+ backgroundColor: globalTheme.colors.gray_bg_05,
+ border: `1px solid ${globalTheme.colors.blue_main}`,
+ borderRadius: 8,
+ },
});
export const headingSubTitleStyle = style({
...globalTheme.fonts.subheadBold20,
+ padding: '0 1.2rem',
color: globalTheme.colors.gray_19,
});
-export const paragraphContentStyle = style({
- ...globalTheme.fonts.bodyReg16,
- color: globalTheme.colors.blue_33,
+export const paragraphContentStyle = styleVariants({
+ default: {
+ ...globalTheme.fonts.bodyReg16,
+ color: globalTheme.colors.blue_33,
+ padding: '0.9rem 1.2rem',
+ boxSizing: 'border-box',
+ border: '1px solid transparent',
+ },
+ edit: {
+ ...globalTheme.fonts.bodyReg16,
+ padding: '0.9rem 1.2rem',
+ boxSizing: 'border-box',
+ color: globalTheme.colors.blue_33,
+ backgroundColor: globalTheme.colors.gray_bg_05,
+ border: `1px solid ${globalTheme.colors.blue_main}`,
+ borderRadius: 8,
+ },
});
export const contentDivStyle = style({
diff --git a/apps/web/src/app/user/[userId]/_components/introduction/introduction.tsx b/apps/web/src/app/user/[userId]/_components/introduction/introduction.tsx
index 41d3bb5..8f64ab7 100644
--- a/apps/web/src/app/user/[userId]/_components/introduction/introduction.tsx
+++ b/apps/web/src/app/user/[userId]/_components/introduction/introduction.tsx
@@ -1,38 +1,108 @@
+import { on } from 'events';
+import { useState, ChangeEvent } from 'react';
+import { usePutIntroduction } from '@/shared/apis/user/queries';
+import { GetUserIntroduction } from '@/shared/apis/user/types';
import {
headingTitleStyle,
headingSubTitleStyle,
paragraphContentStyle,
contentDivStyle,
contentStyle,
+ container,
} from './introduction.css';
-const Introduction = () => {
+interface IntroductionProps {
+ isEdit?: boolean;
+ username?: string;
+ title?: string;
+ oneLiner?: string;
+ goodAt?: string;
+ learningGoal?: string;
+ 소개입력값: GetUserIntroduction.Res;
+ on소개입력값변경: (
+ e: ChangeEvent,
+ ) => void;
+}
+
+const Introduction = ({
+ isEdit = false,
+ username,
+ title,
+ oneLiner,
+ goodAt,
+ learningGoal,
+ 소개입력값,
+ on소개입력값변경,
+}: IntroductionProps) => {
+ const defaultValue = '//수정 버튼을 눌러 자기소개를 수정해주세요';
+
+ const styleVariants = isEdit ? 'edit' : 'default';
+
return (
-
-
- {'//수정 버튼을 눌러 자기소개를 수정해주세요'}
-
+
+ {isEdit ? (
+
+ ) : (
+
+ {title || defaultValue}
+
+ )}
-
{'{jamooooong}의 한줄 소개'}
-
- {'//수정 버튼을 눌러 자기소개를 수정해주세요.'}
-
+
{`${username || '등록 중'}의 한줄 소개`}
+ {isEdit ? (
+
+ ) : (
+
+ {oneLiner || defaultValue}
+
+ )}
저는 이런거를 잘해요.
-
- {'//수정 버튼을 눌러 자기소개를 수정해주세요.'}
-
+ {isEdit ? (
+
+ ) : (
+
+ {goodAt || defaultValue}
+
+ )}
저는 이런걸 배우고 싶어요.
-
- {'//수정 버튼을 눌러 자기소개를 수정해주세요.'}
-
+ {isEdit ? (
+
+ ) : (
+
+ {learningGoal || defaultValue}
+
+ )}
diff --git a/apps/web/src/app/user/[userId]/_components/profile/_types/index.ts b/apps/web/src/app/user/[userId]/_components/profile/_types/index.ts
new file mode 100644
index 0000000..50f626d
--- /dev/null
+++ b/apps/web/src/app/user/[userId]/_components/profile/_types/index.ts
@@ -0,0 +1 @@
+export type TierTypes = 'PURPLE' | 'GREY' | 'RED' | 'BLUE' | 'GREEN' | 'YELLOW';
diff --git a/apps/web/src/app/user/[userId]/_components/profile/_utils/index.ts b/apps/web/src/app/user/[userId]/_components/profile/_utils/index.ts
new file mode 100644
index 0000000..0ac4c86
--- /dev/null
+++ b/apps/web/src/app/user/[userId]/_components/profile/_utils/index.ts
@@ -0,0 +1,19 @@
+import { TierTypes } from '../_types';
+
+export const nextTierMap: Record
= {
+ YELLOW: 'GREEN',
+ GREEN: 'BLUE',
+ BLUE: 'RED',
+ RED: 'GREY',
+ GREY: 'PURPLE',
+ PURPLE: 'PURPLE',
+};
+
+/**
+ * 현재 티어의 다음 티어를 반환하는 함수
+ * @param currentTier 현재 티어
+ * @returns 다음 티어
+ */
+export function getNextTier(currentTier: TierTypes): TierTypes {
+ return nextTierMap[currentTier];
+}
diff --git a/apps/web/src/app/user/[userId]/_components/profile/profile.tsx b/apps/web/src/app/user/[userId]/_components/profile/profile.tsx
index 57087e7..4818f34 100644
--- a/apps/web/src/app/user/[userId]/_components/profile/profile.tsx
+++ b/apps/web/src/app/user/[userId]/_components/profile/profile.tsx
@@ -1,6 +1,7 @@
import CircleImage from '@/shared/components/circleImage/circleImage';
import SVGTier from '../SVGTier/SVGTier';
import ButtonGithub from './_components/buttonGithub/buttonGithub';
+import { TierTypes } from './_types';
import {
paragraphLanguageStyle,
headingNameStyle,
@@ -9,21 +10,33 @@ import {
containerStyle,
} from './profile.css';
-const Profile = () => {
+interface ProfileProps {
+ profileImg: string;
+ language: string;
+ userName: string;
+ tier?: TierTypes;
+}
+
+const Profile = ({ profileImg, language, userName, tier }: ProfileProps) => {
return (
-
+
-
javascript
+
{language}
-
-
jamooong
+
+ {userName}
-
+
+
+
);
};
diff --git a/apps/web/src/app/user/[userId]/_components/progressBar/progressBar.tsx b/apps/web/src/app/user/[userId]/_components/progressBar/progressBar.tsx
index 5e42135..91eab8a 100644
--- a/apps/web/src/app/user/[userId]/_components/progressBar/progressBar.tsx
+++ b/apps/web/src/app/user/[userId]/_components/progressBar/progressBar.tsx
@@ -1,5 +1,6 @@
import { assignInlineVars } from '@vanilla-extract/dynamic';
import SVGTier from '../SVGTier/SVGTier';
+import { TierTypes } from '../profile/_types';
import {
outsideStyle,
insideStyle,
@@ -13,8 +14,8 @@ import {
interface ProgressBarProps {
width: number;
- currentTier: number;
- nextTier: number;
+ currentTier?: TierTypes;
+ nextTier?: TierTypes;
}
const ProgressBar = ({ width, currentTier, nextTier }: ProgressBarProps) => {
@@ -33,13 +34,13 @@ const ProgressBar = ({ width, currentTier, nextTier }: ProgressBarProps) => {
-
{`level ${1}`}
+
{`level ${currentTier}`}
5,000
-
{`level ${2} 까지`}
-
-3,000
+
{`level ${nextTier} 까지`}
+
3,000
);
diff --git a/apps/web/src/app/user/[userId]/_hooks/useIntroduction.ts b/apps/web/src/app/user/[userId]/_hooks/useIntroduction.ts
new file mode 100644
index 0000000..3f26f25
--- /dev/null
+++ b/apps/web/src/app/user/[userId]/_hooks/useIntroduction.ts
@@ -0,0 +1,48 @@
+import { useEffect, useState } from 'react';
+import { usePutIntroduction } from '@/shared/apis/user/queries';
+import { GetUserIntroduction } from '@/shared/apis/user/types';
+
+export const useIntroduction = (초기값?: GetUserIntroduction.Res) => {
+ const defaultValues = '//수정 버튼을 눌러 자기소개를 수정해주세요';
+
+ const 소개입력초기값 = {
+ title: defaultValues,
+ oneLiner: defaultValues,
+ goodAt: defaultValues,
+ learningGoal: defaultValues,
+ };
+
+ console.log(초기값);
+
+ const [소개입력값, set소개입력값] = useState(초기값 || 소개입력초기값);
+
+ const handle소개입력값변경 = (
+ e: React.ChangeEvent,
+ ) => {
+ const { name, value } = e.target;
+ set소개입력값((prev) => ({ ...prev, [name]: value }));
+ };
+
+ const { mutate } = usePutIntroduction();
+
+ const handle소개입력값초기화 = () => {
+ set소개입력값(초기값 || 소개입력초기값);
+ };
+
+ const 소개변경함수 = () => {
+ mutate(소개입력값);
+ };
+
+ useEffect(() => {
+ if (초기값) {
+ set소개입력값(초기값);
+ }
+ }, [초기값]);
+
+ return {
+ 소개입력값,
+ handle소개입력값변경,
+ handle소개입력값초기화,
+ 소개변경함수,
+ };
+};
diff --git a/apps/web/src/app/user/[userId]/main-setting/page.tsx b/apps/web/src/app/user/[userId]/main-setting/page.tsx
index 385c66d..6782ac5 100644
--- a/apps/web/src/app/user/[userId]/main-setting/page.tsx
+++ b/apps/web/src/app/user/[userId]/main-setting/page.tsx
@@ -5,10 +5,7 @@ import { ModalContentMainSetting } from '../../../../shared/components/modalCont
const page = () => {
return (
-
+
);
};
diff --git a/apps/web/src/app/user/[userId]/page.tsx b/apps/web/src/app/user/[userId]/page.tsx
index 143f892..ea222e6 100644
--- a/apps/web/src/app/user/[userId]/page.tsx
+++ b/apps/web/src/app/user/[userId]/page.tsx
@@ -1,4 +1,22 @@
+'use client';
+
+import { Spinner } from '@radix-ui/themes';
+import Link from 'next/link';
+import { useParams, useRouter } from 'next/navigation';
+import { useState } from 'react';
import Button from '@/shared/components/button/button';
+import { useGetUserInfo } from '@/shared/apis/auth/queries';
+import {
+ useGetUserRegion,
+ useGetUserSchool,
+ useGetUserRank,
+ useGetUserLang,
+ useGetUserExp,
+ useGetSuggestFriend,
+ useGetUserPageUserInfo,
+ useGetUserIntroduction,
+} from '@/shared/apis/user/queries';
+import { getAuthHeader } from '@/shared/utils/auth';
import {
bottomDivHeadingStyle,
bottomDivRefreshButtonStyle,
@@ -9,6 +27,8 @@ import {
middleContentDivStyle,
middleDivStyle,
sharedDivStyle,
+ spinnerMiddleDivStyle,
+ spinnerTopDiveStyle,
topDivStyle,
topSectionStyle,
} from './UserPage.css';
@@ -16,78 +36,159 @@ import CardInfo from './_components/cardInfo/cardInfo';
import CardProfile from './_components/cardProfile/cardProfile';
import Contributions from './_components/contributions/contributions';
import Introduction from './_components/introduction/introduction';
+import { getNextTier } from './_components/profile/_utils';
import Profile from './_components/profile/profile';
import ProgressBar from './_components/progressBar/progressBar';
-
-//임시 목데이터
-const cardProfileData = [
- {
- imageSrc: 'https://avatars.githubusercontent.com/u/48755175?v=4',
- language: 'javascript',
- tier: 1,
- userName: 'suwonthugger1',
- school: '광운대학교',
- region: '경기도',
- },
- {
- imageSrc: 'https://avatars.githubusercontent.com/u/48755175?v=4',
- language: 'javascript',
- tier: 1,
- userName: 'suwonthugger2',
- school: '광운대학교',
- region: '경기도',
- },
- {
- imageSrc: 'https://avatars.githubusercontent.com/u/48755175?v=4',
- language: 'javascript',
- tier: 1,
- userName: 'suwonthugger3',
- school: '광운대학교',
- region: '경기도',
- },
- {
- imageSrc: 'https://avatars.githubusercontent.com/u/48755175?v=4',
- language: 'javascript',
- tier: 1,
- userName: 'suwonthugger4',
- school: '광운대학교',
- region: '경기도',
- },
-];
+import { useIntroduction } from './_hooks/useIntroduction';
const UserPage = () => {
+ const username = useParams().userId as string;
+ const router = useRouter();
+
+ const [자기소개수정중, set자기소개수정중] = useState(false);
+
+ const isLoggedIn = !!getAuthHeader();
+
+ const { data: authUserInfo } = useGetUserInfo();
+ const { data: userInfo } = useGetUserPageUserInfo({ username });
+ const { data: userRank } = useGetUserRank({ username });
+ const { data: userSchool } = useGetUserSchool({ username });
+ const { data: userRegion } = useGetUserRegion({ username });
+ const { data: userLang } = useGetUserLang({ username });
+ const { data: userExp } = useGetUserExp({ username });
+ const { data: suggestedFriends } = useGetSuggestFriend(isLoggedIn);
+ const { data: userIntroduction } = useGetUserIntroduction({ username });
+
+ const {
+ 소개입력값,
+ handle소개입력값변경,
+ handle소개입력값초기화,
+ 소개변경함수,
+ } = useIntroduction(userIntroduction);
+
+ const handle자기소개수정 = () => {
+ set자기소개수정중(true);
+ };
+
+ const handle자기소개수정완료 = () => {
+ set자기소개수정중(false);
+ 소개변경함수();
+ };
+
+ const handle자기소개수정취소 = () => {
+ set자기소개수정중(false);
+ handle소개입력값초기화();
+ };
+
+ const isAuthUser = authUserInfo?.username === userInfo?.username;
+
return (
-
-
+ {userInfo ? (
+ <>
+
+
+ >
+ ) : (
+
+
+
+ )}
-
-
-
-
+ {isAuthUser && (
+
+
+
+
+
+ )}
-
+ {userExp &&
+ userRank &&
+ userInfo &&
+ userSchool &&
+ userRegion &&
+ userLang ? (
+ <>
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
+ >
+ ) : (
+
+
+
+ )}
@@ -98,11 +199,13 @@ const UserPage = () => {
- {cardProfileData.map((data) => (
- -
-
+ {suggestedFriends?.map((data, index) => (
+
-
+
+
+
))}
diff --git a/apps/web/src/shared/apis/auth/axios.ts b/apps/web/src/shared/apis/auth/axios.ts
index 5d70263..9e68450 100644
--- a/apps/web/src/shared/apis/auth/axios.ts
+++ b/apps/web/src/shared/apis/auth/axios.ts
@@ -43,11 +43,11 @@ export const postUnivValidate = async ({
export const postAuthJoin = async ({
univName,
- regionName,
+ region,
}: PostAuthJoin.Params) => {
await authClient.post(AUTH_URL.POST_AUTH_JOIN, {
univName,
- regionName,
+ region,
});
};
diff --git a/apps/web/src/shared/apis/auth/queries.ts b/apps/web/src/shared/apis/auth/queries.ts
index 5c58699..6bc7c73 100644
--- a/apps/web/src/shared/apis/auth/queries.ts
+++ b/apps/web/src/shared/apis/auth/queries.ts
@@ -36,8 +36,8 @@ export const usePostUnivValidate = () => {
export const usePostAuthJoin = () => {
return useMutation({
- mutationFn: ({ univName, regionName }: PostAuthJoin.Params) =>
- postAuthJoin({ univName, regionName }),
+ mutationFn: ({ univName, region }: PostAuthJoin.Params) =>
+ postAuthJoin({ univName, region }),
});
};
diff --git a/apps/web/src/shared/apis/auth/types/index.ts b/apps/web/src/shared/apis/auth/types/index.ts
index 25a9aab..2cb31a7 100644
--- a/apps/web/src/shared/apis/auth/types/index.ts
+++ b/apps/web/src/shared/apis/auth/types/index.ts
@@ -16,7 +16,7 @@ export namespace PostUnivValidate {
export namespace PostAuthJoin {
export interface Params {
univName: string;
- regionName: string;
+ region: string;
}
}
diff --git a/apps/web/src/shared/apis/user/axios.ts b/apps/web/src/shared/apis/user/axios.ts
new file mode 100644
index 0000000..372f835
--- /dev/null
+++ b/apps/web/src/shared/apis/user/axios.ts
@@ -0,0 +1,133 @@
+import { getAuthHeader } from '@/shared/utils/auth';
+import { authClient, client } from '../client';
+import type {
+ GetUserExp,
+ GetUserLang,
+ GetUserRegion,
+ GetUserSchool,
+ GetUserRank,
+ GetSuggestFriend,
+ GetUserPageUserInfo,
+ GetUserIntroduction,
+} from './types';
+
+const USER_URL = {
+ GET_USER_RANK: '/userPage/rank/userRanking',
+ GET_SCHOOL: '/userPage/rank/school',
+ GET_REGION: '/userPage/rank/region',
+ GET_LANG: '/userPage/rank/lang',
+ GET_EXP: '/userPage/rank/exp',
+ GET_SUGGESTED_FRIENDS: '/userPage/suggest/friend',
+ GET_USER_INTRODUCTION: '/userPage/get/introduction',
+ GET_USERPAGE_USERINFO: '/userPage/userInfo',
+
+ PUT_INTRODUCTION: '/userPage/my/update/introduction',
+ PUT_SCHOOL: '/userPage/my/config/school',
+ PUT_REGION: '/userPage/my/config/region',
+
+ DELETE_USER: '/auth/withdraw',
+};
+
+export const getUserRank = async (
+ username: string,
+): Promise
=> {
+ const response = await client.get(USER_URL.GET_USER_RANK, {
+ params: {
+ username,
+ },
+ });
+ return response.data;
+};
+
+export const getUserSchool = async (
+ username: string,
+): Promise => {
+ const response = await client.get(USER_URL.GET_SCHOOL, {
+ params: {
+ username,
+ },
+ });
+ return response.data;
+};
+
+export const getUserRegion = async (
+ username: string,
+): Promise => {
+ const response = await client.get(USER_URL.GET_REGION, {
+ params: {
+ username,
+ },
+ });
+ return response.data;
+};
+
+export const getUserLang = async (
+ username: string,
+): Promise => {
+ const response = await client.get(USER_URL.GET_LANG, {
+ params: {
+ username,
+ },
+ });
+ return response.data;
+};
+
+export const getUserExp = async (username: string): Promise => {
+ const response = await client.get(USER_URL.GET_EXP, {
+ params: {
+ username,
+ },
+ });
+ return response.data;
+};
+
+export const getSuggestFriend = async (
+ isLoggedIn: boolean,
+): Promise => {
+ const axiosFunction = isLoggedIn ? authClient : client;
+
+ const response = await axiosFunction.get(USER_URL.GET_SUGGESTED_FRIENDS);
+ return response.data;
+};
+
+export const getUserIntroduction = async (
+ username: string,
+): Promise => {
+ const response = await client.get(USER_URL.GET_USER_INTRODUCTION, {
+ params: {
+ username,
+ },
+ });
+ return response.data;
+};
+
+export const getUserPageUserInfo = async (
+ username: string,
+): Promise => {
+ const response = await client.get(USER_URL.GET_USERPAGE_USERINFO, {
+ params: {
+ username,
+ },
+ });
+ return response.data;
+};
+
+export const putRegion = async (modifyRegionName: string) => {
+ await authClient.put(USER_URL.PUT_REGION, undefined, {
+ params: { modifyRegionName },
+ });
+};
+
+export const putUserIntroduction = async (
+ introduction: GetUserIntroduction.Res,
+) => {
+ await authClient.put(USER_URL.PUT_INTRODUCTION, introduction);
+};
+
+export const putSchool = async (modifyRegionName: string) => {
+ await authClient.put(USER_URL.PUT_SCHOOL, { params: { modifyRegionName } });
+};
+
+export const deleteWithdraw = async () => {
+ await authClient.delete(USER_URL.DELETE_USER);
+};
diff --git a/apps/web/src/shared/apis/user/queries.ts b/apps/web/src/shared/apis/user/queries.ts
new file mode 100644
index 0000000..ae101b8
--- /dev/null
+++ b/apps/web/src/shared/apis/user/queries.ts
@@ -0,0 +1,142 @@
+import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
+import {
+ getUserExp,
+ getUserLang,
+ getUserRegion,
+ getUserSchool,
+ getUserRank,
+ getSuggestFriend,
+ getUserPageUserInfo,
+ putSchool,
+ putRegion,
+ deleteWithdraw,
+ putUserIntroduction,
+ getUserIntroduction,
+} from './axios';
+import {
+ GetUserExp,
+ GetUserLang,
+ GetUserRegion,
+ GetUserRank,
+ GetUserPageUserInfo,
+ GetUserIntroduction,
+} from './types';
+
+export const useGetUserRank = ({ username }: GetUserRank.Params) => {
+ return useQuery({
+ queryKey: ['user', 'userRank', username],
+ queryFn: () => getUserRank(username),
+ });
+};
+
+export const useGetUserSchool = ({ username }: GetUserRank.Params) => {
+ return useQuery({
+ queryKey: ['user', 'userSchool', username],
+ queryFn: () => getUserSchool(username),
+ });
+};
+
+export const useGetUserRegion = ({ username }: GetUserRegion.Params) => {
+ return useQuery({
+ queryKey: ['user', 'userRegion', username],
+ queryFn: () => getUserRegion(username),
+ });
+};
+
+export const useGetUserLang = ({ username }: GetUserLang.Params) => {
+ return useQuery({
+ queryKey: ['user', 'userLang', username],
+ queryFn: () => getUserLang(username),
+ });
+};
+
+export const useGetUserExp = ({ username }: GetUserExp.Params) => {
+ return useQuery({
+ queryKey: ['user', 'userExp', username],
+ queryFn: () => getUserExp(username),
+ });
+};
+
+export const useGetSuggestFriend = (isLoggedIn: boolean) => {
+ return useQuery({
+ queryKey: ['user', 'suggestFriend'],
+ queryFn: () => getSuggestFriend(isLoggedIn),
+ });
+};
+
+export const useGetUserIntroduction = ({
+ username,
+}: GetUserIntroduction.Params) => {
+ const queryClient = useQueryClient();
+
+ return useQuery({
+ queryKey: ['user', 'introduction', username],
+ queryFn: () => getUserIntroduction(username),
+ });
+};
+
+export const useGetUserPageUserInfo = ({
+ username,
+}: GetUserPageUserInfo.Params) => {
+ return useQuery({
+ queryKey: ['user', 'userInfo', username],
+ queryFn: () => getUserPageUserInfo(username),
+ });
+};
+
+export const usePutIntroduction = () => {
+ const queryClient = useQueryClient();
+
+ return useMutation({
+ mutationFn: (introduction: GetUserIntroduction.Res) =>
+ putUserIntroduction(introduction),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['user', 'introduction'] });
+ },
+ onError: () => {
+ alert('소개 변경에 실패했습니다.');
+ },
+ });
+};
+
+export const usePutSchool = () => {
+ const queryClient = useQueryClient();
+
+ return useMutation({
+ mutationFn: (modifySchoolName: string) => putSchool(modifySchoolName),
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey: ['userInfo'] });
+ },
+ onError: () => {
+ alert('학교 변경에 실패했습니다.');
+ },
+ });
+};
+
+export const usePutRegion = () => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: (modifyRegionName: string) => putRegion(modifyRegionName),
+ onSuccess: () => {
+ alert('지역이 변경되었습니다.');
+ queryClient.invalidateQueries({ queryKey: ['userInfo'] });
+ },
+ onError: () => {
+ alert('지역 변경에 실패했습니다.');
+ },
+ });
+};
+
+export const useDeleteWithdraw = () => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: () => deleteWithdraw(),
+ onSuccess: () => {
+ alert('회원 탈퇴가 완료되었습니다.');
+ queryClient.invalidateQueries({ queryKey: ['userInfo'] });
+ },
+ onError: () => {
+ alert('회원 탈퇴에 실패했습니다.');
+ },
+ });
+};
diff --git a/apps/web/src/shared/apis/user/types/index.ts b/apps/web/src/shared/apis/user/types/index.ts
new file mode 100644
index 0000000..83abd9c
--- /dev/null
+++ b/apps/web/src/shared/apis/user/types/index.ts
@@ -0,0 +1,95 @@
+import { TierTypes } from '@/app/user/[userId]/_components/profile/_types';
+
+export namespace GetUserRank {
+ export interface Params {
+ username: string;
+ }
+
+ export interface Res {
+ userRank: number;
+ }
+}
+
+export namespace GetUserSchool {
+ export interface Params {
+ username: string;
+ }
+
+ export interface Res {
+ schoolRankDto: {
+ schoolName: string;
+ schoolRank: number;
+ };
+ }
+}
+
+export namespace GetUserRegion {
+ export interface Params {
+ username: string;
+ }
+
+ export interface Res {
+ regionRankDto: {
+ regionName: string;
+ regionRank: number;
+ };
+ }
+}
+
+export namespace GetUserLang {
+ export interface Params {
+ username: string;
+ }
+
+ export interface Res {
+ langName: string;
+ }
+}
+
+export namespace GetUserExp {
+ export interface Params {
+ username: string;
+ }
+
+ export interface Res {
+ percent: number;
+ }
+}
+
+export namespace GetSuggestFriend {
+ type dataType = {
+ grade: TierTypes;
+ language: string;
+ profileImg: string;
+ regionName: string;
+ schoolName: string;
+ username: string;
+ };
+
+ export type Res = dataType[];
+}
+
+export namespace GetUserIntroduction {
+ export interface Params {
+ username: string;
+ }
+
+ export interface Res {
+ title: string;
+ oneLiner: string;
+ goodAt: string;
+ learningGoal: string;
+ }
+}
+
+export namespace GetUserPageUserInfo {
+ export interface Params {
+ username: string;
+ }
+
+ export interface Res {
+ username: string;
+ grade: TierTypes;
+ profileImg: string;
+ }
+}
diff --git a/apps/web/src/shared/components/alertDialog/AlertDialog.tsx b/apps/web/src/shared/components/alertDialog/AlertDialog.tsx
index 91e8bad..28898b5 100644
--- a/apps/web/src/shared/components/alertDialog/AlertDialog.tsx
+++ b/apps/web/src/shared/components/alertDialog/AlertDialog.tsx
@@ -19,6 +19,8 @@ interface CustomAlertDialogProps {
cancelText: string;
confirmText: string;
triggerText: string;
+ isOpen?: boolean;
+ onTrigger?: () => void; // 트리거 버튼을 눌렀을 때 실행할 함수
onConfirm?: () => void; // 확인 버튼을 눌렀을 때 실행할 함수
}
@@ -31,11 +33,13 @@ const CustomAlertDialog = ({
cancelText,
confirmText,
triggerText,
+ isOpen,
+ onTrigger,
onConfirm,
}: CustomAlertDialogProps) => {
return (
-
-
+
+
{triggerText}
diff --git a/apps/web/src/shared/components/circleImage/circleImage.tsx b/apps/web/src/shared/components/circleImage/circleImage.tsx
index 36bbfc6..535efac 100644
--- a/apps/web/src/shared/components/circleImage/circleImage.tsx
+++ b/apps/web/src/shared/components/circleImage/circleImage.tsx
@@ -1,5 +1,4 @@
import Image from 'next/image';
-import Link from 'next/link';
import EmptyProfileImage from '@/shared/assets/svgs/profile.svg';
import { divStyle, imageStyle } from './circleImage.css';
@@ -20,9 +19,7 @@ const CircleImage = ({ src, size = 'sm' }: CircleImageProps) => {
className={imageStyle}
/>
) : (
-
-
-
+
)}
);
diff --git a/apps/web/src/shared/components/layout/header/header.tsx b/apps/web/src/shared/components/layout/header/header.tsx
index 073cd94..4c4a88e 100644
--- a/apps/web/src/shared/components/layout/header/header.tsx
+++ b/apps/web/src/shared/components/layout/header/header.tsx
@@ -9,6 +9,8 @@ import { contentStyle, headerStyle, navStyle } from './header.css';
const Header = () => {
const { data } = useGetUserInfo();
+ const profileLink = data ? `/user/${data.username}` : '/auth?step=github';
+
return (
);
diff --git a/apps/web/src/shared/components/modal/modal.tsx b/apps/web/src/shared/components/modal/modal.tsx
index 4cd27fa..c025c5d 100644
--- a/apps/web/src/shared/components/modal/modal.tsx
+++ b/apps/web/src/shared/components/modal/modal.tsx
@@ -1,6 +1,6 @@
'use client';
-import { useRouter } from 'next/navigation';
+import { usePathname, useRouter } from 'next/navigation';
import ArrowBack from '@/shared/assets/svgs/arrow_back.svg';
import {
modalStyle,
@@ -28,11 +28,12 @@ export function Modal({
-
{
router.back();
- }}
- />
+ }}>
+
+
{title}
{children}
diff --git a/apps/web/src/shared/components/modalContentMainSetting/modalContentMainSetting.tsx b/apps/web/src/shared/components/modalContentMainSetting/modalContentMainSetting.tsx
index 0775839..8e3f2e6 100644
--- a/apps/web/src/shared/components/modalContentMainSetting/modalContentMainSetting.tsx
+++ b/apps/web/src/shared/components/modalContentMainSetting/modalContentMainSetting.tsx
@@ -1,8 +1,13 @@
'use client';
import Link from 'next/link';
+import { useParams, useRouter } from 'next/navigation';
+import { useQueryClient } from '@tanstack/react-query';
import CustomAlertDialog from '@/shared/components/alertDialog/AlertDialog';
import Button from '@/shared/components/button/button';
+import { useGetUserInfo } from '@/shared/apis/auth/queries';
+import { useDeleteWithdraw } from '@/shared/apis/user/queries';
+import { getAuthHeader } from '@/shared/utils/auth';
import {
headingStyle,
sectionStyle,
@@ -10,35 +15,43 @@ import {
paragraphStyle2,
} from './modalContentMainSetting.css';
-export function ModalContentMainSetting({
- userSchool,
- userRegion,
-}: {
- userSchool: string | undefined;
- userRegion: string;
-}) {
+export function ModalContentMainSetting() {
+ const queryClient = useQueryClient();
+ const router = useRouter();
+
+ const username = useParams().userId as string;
+
+ const { data: authUserInfo } = useGetUserInfo();
+ const { mutate: 회원탈퇴함수 } = useDeleteWithdraw();
+
const handleLogOut = () => {
- console.log('로그아웃 확인 눌림');
- // 확인 버튼을 눌렀을 때의 동작을 정의
+ queryClient.invalidateQueries({ queryKey: ['userInfo', getAuthHeader()] });
+ localStorage.removeItem('accessToken');
+ window.location.href = '/';
};
+
const handleDelAuth = () => {
- console.log('탈퇴하기 확인 눌림');
- // 확인 버튼을 눌렀을 때의 동작을 정의
+ 회원탈퇴함수(undefined, {
+ onSuccess: () => {
+ window.location.href = '/';
+ },
+ });
};
+
return (
<>
정보 변경
- 소속학교 == {userSchool || '학교 없음'}
+ 소속학교 == {authUserInfo?.univName || '학교 없음'}
변경 버튼을 눌러 재인증을 통해 소속학교를 변경할 수 있습니다.
-
+
@@ -46,14 +59,14 @@ export function ModalContentMainSetting({
- 소속지역 == {userRegion || '지역 없음'}
+ 소속지역 == {authUserInfo?.regionName || '지역 없음'}
변경 버튼을 눌러 소속지역를 변경할 수 있습니다.
-
+
diff --git a/apps/web/src/shared/components/modalContentRegionSetting/modalContentRegionSetting.css.ts b/apps/web/src/shared/components/modalContentRegionSetting/modalContentRegionSetting.css.ts
index 1915625..9c5fb78 100644
--- a/apps/web/src/shared/components/modalContentRegionSetting/modalContentRegionSetting.css.ts
+++ b/apps/web/src/shared/components/modalContentRegionSetting/modalContentRegionSetting.css.ts
@@ -17,3 +17,10 @@ export const DivParagraphStyle = style({
alignItems: 'center',
gap: '1.2rem',
});
+
+export const InputMenuPlaceholderStyle = style({
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ height: '100%',
+});
diff --git a/apps/web/src/shared/components/modalContentRegionSetting/modalContentRegionSetting.tsx b/apps/web/src/shared/components/modalContentRegionSetting/modalContentRegionSetting.tsx
index 9d4a480..c5140e1 100644
--- a/apps/web/src/shared/components/modalContentRegionSetting/modalContentRegionSetting.tsx
+++ b/apps/web/src/shared/components/modalContentRegionSetting/modalContentRegionSetting.tsx
@@ -1,11 +1,65 @@
+'use client';
+
+import { useRouter } from 'next/navigation';
+import { useState } from 'react';
import Button from '@/shared/components/button/button';
import Input from '@/shared/components/input/input';
-import { DivParagraphStyle, DivStyle } from './modalContentRegionSetting.css';
+import { useGetRegionNames } from '@/shared/apis/auth/queries';
+import { usePutRegion } from '@/shared/apis/user/queries';
+import {
+ DivParagraphStyle,
+ DivStyle,
+ InputMenuPlaceholderStyle,
+} from './modalContentRegionSetting.css';
const ModalContentRegionSetting = () => {
+ const router = useRouter();
+
+ const [지역검색키워드, set지역검색키워드] = useState('');
+
+ const { data } = useGetRegionNames();
+ const { mutate } = usePutRegion();
+
+ const filteredData = data?.filter((region: string) =>
+ region.includes(지역검색키워드),
+ );
+
+ const handle지역검색키워드변경 = (e: React.ChangeEvent
) => {
+ set지역검색키워드(e.target.value);
+ };
+
+ const handle지역선택 = (region: string) => {
+ set지역검색키워드(region);
+ };
+
+ const handle지역변경 = () => {
+ mutate(지역검색키워드, {
+ onSuccess: () => {
+ router.back();
+ },
+ });
+ };
+
return (
-
+
+
+ {filteredData?.length > 0 ? (
+ filteredData.map((region: string) => (
+ handle지역선택(region)}>
+ {region}
+
+ ))
+ ) : (
+ 검색 결과가 없습니다.
+ )}
+
+
본인이 거주 및 출생한 지역을 자유롭게 선택할 수 있습니다. 지역정보는
@@ -14,7 +68,7 @@ const ModalContentRegionSetting = () => {
콘텐츠에 사용됩니다.
-
+
);
};
diff --git a/apps/web/src/shared/components/modalContentSchoolSetting/modalContentSchoolSetting.css.ts b/apps/web/src/shared/components/modalContentSchoolSetting/modalContentSchoolSetting.css.ts
index 1570ea0..43ab9b0 100644
--- a/apps/web/src/shared/components/modalContentSchoolSetting/modalContentSchoolSetting.css.ts
+++ b/apps/web/src/shared/components/modalContentSchoolSetting/modalContentSchoolSetting.css.ts
@@ -26,3 +26,10 @@ export const checkboxButtonStyle = style({
alignItems: 'center',
gap: '1.2rem',
});
+
+export const InputMenuPlaceholderStyle = style({
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ height: '100%',
+});
diff --git a/apps/web/src/shared/components/modalContentSchoolSetting/modalContentSchoolSetting.tsx b/apps/web/src/shared/components/modalContentSchoolSetting/modalContentSchoolSetting.tsx
index 64a3f6f..9a52aaf 100644
--- a/apps/web/src/shared/components/modalContentSchoolSetting/modalContentSchoolSetting.tsx
+++ b/apps/web/src/shared/components/modalContentSchoolSetting/modalContentSchoolSetting.tsx
@@ -1,23 +1,141 @@
+'use client';
+
+import { useParams, useRouter } from 'next/navigation';
+import { useState } from 'react';
+import { useQueryClient } from '@tanstack/react-query';
import Button from '@/shared/components/button/button';
import Input from '@/shared/components/input/input';
-import Checkbox from '@/shared/assets/svgs/check_btn_fill.svg';
+import {
+ useGetSchoolNames,
+ usePostUnivCertificate,
+ usePostUnivValidate,
+} from '@/shared/apis/auth/queries';
+import { usePutSchool } from '@/shared/apis/user/queries';
+import CheckboxEmptyIcon from '@/shared/assets/svgs/check_btn_empty.svg';
+import CheckboxFillIcon from '@/shared/assets/svgs/check_btn_fill.svg';
import CustomAlertDialog from '../alertDialog/AlertDialog';
import {
DivStyle,
DivInputStyle,
checkboxButtonStyle,
+ InputMenuPlaceholderStyle,
} from './modalContentSchoolSetting.css';
export function ModalContentSchoolSetting() {
+ const queryClient = useQueryClient();
+ const router = useRouter();
+
+ const [대학교검색키워드, set대학교검색키워드] = useState('');
+ const [대학교이메일, set대학교이메일] = useState('');
+ const [약관동의, set약관동의] = useState(false);
+ const [인증번호, set인증번호] = useState('');
+ const [isDialogOpen, setIsDialogOpen] = useState(false);
+
+ const { data } = useGetSchoolNames();
+ const { mutate: 인증번호전송함수 } = usePostUnivCertificate();
+ const { mutate: 인증번호검증함수 } = usePostUnivValidate();
+ const { mutate: 학교변경함수 } = usePutSchool();
+
+ const Checkbox = 약관동의 ? CheckboxFillIcon : CheckboxEmptyIcon;
+ const filteredData = data?.filter((school: string) =>
+ school.includes(대학교검색키워드),
+ );
+
+ const handle대학교검색키워드변경 = (
+ e: React.ChangeEvent,
+ ) => {
+ set대학교검색키워드(e.target.value);
+ };
+
+ const handle대학교선택 = (school: string) => {
+ set대학교검색키워드(school);
+ };
+
+ const handle대학교이메일변경 = (e: React.ChangeEvent) => {
+ set대학교이메일(e.target.value);
+ };
+
+ const handle약관동의 = () => {
+ set약관동의(!약관동의);
+ };
+
+ const handle인증번호전송 = () => {
+ 인증번호전송함수(
+ { email: 대학교이메일, univName: 대학교검색키워드 },
+ {
+ onSuccess: () => {
+ setIsDialogOpen(true);
+ queryClient.invalidateQueries({ queryKey: ['userInfo'] });
+ },
+ onError: (error) => {
+ alert('인증번호 전송에 실패했습니다. 다시 시도해주세요.');
+ console.error(error);
+ },
+ },
+ );
+ };
+
+ const handle학교변경함수 = () => {
+ 학교변경함수(대학교검색키워드);
+ };
+
+ const handle인증번호변경 = (e: React.ChangeEvent) => {
+ set인증번호(e.target.value);
+ };
+
+ const handle인증번호검증 = () => {
+ 인증번호검증함수(
+ { email: 대학교이메일, univName: 대학교검색키워드, code: 인증번호 },
+ {
+ onSuccess: () => {
+ alert('인증번호가 검증되었습니다.');
+ router.back();
+ },
+ onError: (error) => {
+ alert('인증번호 검증에 실패했습니다. 다시 시도해주세요.');
+ console.error(error);
+ },
+ },
+ );
+ };
+
+ const handle다이얼로그닫기 = () => {
+ setIsDialogOpen(false);
+ };
+
return (
);