diff --git a/src/components/header/MeetingInfoBox.tsx b/src/components/header/MeetingInfoBox.tsx
index 8154d14..671296b 100644
--- a/src/components/header/MeetingInfoBox.tsx
+++ b/src/components/header/MeetingInfoBox.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect } from 'react';
+import React, { useEffect, useState } from 'react';
import { Modal } from '@/components/base';
import {
conversionDepartment,
@@ -16,6 +16,7 @@ import { useMeetingSessionState, useToggle } from '@/hooks/common';
function MeetingInfoBox() {
const { initMeetingState, setMeetingData } = useMeetingSessionState();
const [isErrorModal, onToggleErrorModal] = useToggle();
+ const [doSurvey, setDoSurvey] = useState(true);
const {
ourDepartments,
domesticAreas,
@@ -31,21 +32,35 @@ function MeetingInfoBox() {
preferHeight,
} = initMeetingState;
- const getMeetingData = async () => {
- try {
- const res = await getMeetingSurvey();
- if (res) {
- setMeetingData(res);
- }
- } catch (e) {
- onToggleErrorModal();
- }
- };
-
useEffect(() => {
+ const getMeetingData = async () => {
+ try {
+ const res = await getMeetingSurvey();
+ if (res) {
+ setMeetingData(res);
+ }
+ } catch (e) {
+ if ((e as any).request.status === 400) {
+ setDoSurvey(false);
+ return;
+ }
+ if ((e as any).request.status === 500) {
+ onToggleErrorModal();
+ return;
+ }
+ }
+ };
getMeetingData();
}, []);
+ if (!doSurvey)
+ return (
+
+ Team
+ 설문 진행 전
+
+ );
+
return (
<>
diff --git a/src/hooks/survey/useAboardAreaLoad.ts b/src/hooks/survey/useAboardAreaLoad.ts
new file mode 100644
index 0000000..8f8d324
--- /dev/null
+++ b/src/hooks/survey/useAboardAreaLoad.ts
@@ -0,0 +1,17 @@
+import { getAboardAreaAPI } from '@/lib/api/area';
+import { useEffect, useState } from 'react';
+
+function useAboardAreaLoad() {
+ const [area, setArea] = useState([]);
+ useEffect(() => {
+ const getAboardArea = async () => {
+ const data = await getAboardAreaAPI();
+ setArea(data);
+ };
+ getAboardArea();
+ }, []);
+
+ return { area };
+}
+
+export default useAboardAreaLoad;
diff --git a/src/hooks/survey/useUnivLoad.ts b/src/hooks/survey/useUnivLoad.ts
new file mode 100644
index 0000000..aa4b28e
--- /dev/null
+++ b/src/hooks/survey/useUnivLoad.ts
@@ -0,0 +1,22 @@
+import { SearchData } from '@/components/domain/survey/SearchSelector';
+import { getUnivAPI } from '@/lib/api/university';
+import { useEffect, useState } from 'react';
+
+function useUnivLoad() {
+ const [univs, setUnivs] = useState
([]);
+ useEffect(() => {
+ const getAllUniv = async () => {
+ try {
+ const data = await getUnivAPI();
+ setUnivs(data);
+ } catch (error) {
+ console.log(error);
+ }
+ };
+ getAllUniv();
+ }, []);
+
+ return { univs };
+}
+
+export default useUnivLoad;
diff --git a/src/lib/api/admin.ts b/src/lib/api/admin.ts
new file mode 100644
index 0000000..683d5d9
--- /dev/null
+++ b/src/lib/api/admin.ts
@@ -0,0 +1,22 @@
+import apiClient from './index';
+import { AdminUsersStatus } from '@/types/user';
+
+export const getMeetingUsers = async () => {
+ const res = await apiClient.get('/admin/users/meeting/status');
+ return res.data;
+};
+
+export const getDatingUsers = async () => {
+ const res = await apiClient.get('/admin/users/dating/status');
+ return res.data;
+};
+
+export const patchMeetingPayment = async (kakaoId: string) => {
+ const res = await apiClient.patch('/admin/users/meeting/payment', { kakaoId });
+ return res.data;
+};
+
+export const patchDatingPayment = async (kakaoId: string) => {
+ const res = await apiClient.patch('/admin/users/dating/payment', { kakaoId });
+ return res.data;
+};
diff --git a/src/lib/api/area.ts b/src/lib/api/area.ts
new file mode 100644
index 0000000..1f9b408
--- /dev/null
+++ b/src/lib/api/area.ts
@@ -0,0 +1,13 @@
+import apiClient from '.';
+
+export const getAboardAreaAPI = async () => {
+ const res = await apiClient.get('/areas');
+ console.log(res);
+
+ return res.data;
+};
+
+export const postAboardAreaAPI = async (body: { id: number; name: string }) => {
+ const res = await apiClient.post('/areas', body);
+ return res.data;
+};
diff --git a/src/lib/api/index.ts b/src/lib/api/index.ts
index d78085e..e353ca1 100644
--- a/src/lib/api/index.ts
+++ b/src/lib/api/index.ts
@@ -2,12 +2,23 @@ import axios from 'axios';
import { SERVER_URL } from '@/lib/constants';
import Cookies from 'js-cookie';
+console.log(Cookies.get('AccessToken') || '');
const apiClient = axios.create({
baseURL: SERVER_URL,
withCredentials: false,
- headers: {
- Authorization: Cookies.get('AccessToken') ?? '',
- },
});
+apiClient.interceptors.request.use(
+ (config) => {
+ if (!config?.headers) {
+ throw new Error(`Expected 'config' and 'config.headers' not to be undefined`);
+ }
+ const token = Cookies.get('AccessToken');
+ config.headers.Authorization = token || '';
+ return config;
+ },
+ (error) => {
+ return Promise.reject(error);
+ },
+);
export default apiClient;
diff --git a/src/lib/api/login.ts b/src/lib/api/login.ts
index 2820a2e..faca56a 100644
--- a/src/lib/api/login.ts
+++ b/src/lib/api/login.ts
@@ -5,7 +5,13 @@ import { LoginResponse, LoginRequest } from '@/types/user';
임시 아이디 비번: test1
*/
+export const postJoin = async (payload: LoginRequest): Promise => {
+ const res = await apiClient.post('/join', payload);
+ return res.data;
+};
+
export const postLogin = async (payload: LoginRequest): Promise => {
+ await apiClient.post('/join', payload);
const res = await apiClient.post('/login', payload);
return res.data;
};
diff --git a/src/lib/api/meeting.ts b/src/lib/api/meeting.ts
index e174bc1..dde4dd8 100644
--- a/src/lib/api/meeting.ts
+++ b/src/lib/api/meeting.ts
@@ -12,7 +12,7 @@ export const getMeetingSurvey = async () => {
return res.data;
};
-export const postReMathcingMettingSurvey = async () => {
+export const postReMatchMettingSurvey = async () => {
const res = await apiClient.post('/meeting/survey/rematch');
return res.data;
};
diff --git a/src/lib/api/university.ts b/src/lib/api/university.ts
new file mode 100644
index 0000000..033a7e8
--- /dev/null
+++ b/src/lib/api/university.ts
@@ -0,0 +1,11 @@
+import apiClient from '.';
+
+export const getUnivAPI = async () => {
+ const res = await apiClient.get('/university');
+ return res.data;
+};
+
+export const postUnivAPI = async (body: { id: number; name: string }) => {
+ const res = await apiClient.post('/university', body);
+ return res.data;
+};
diff --git a/src/pages/AbroadAreasSurvey.tsx b/src/pages/AbroadAreasSurvey.tsx
index 360f2bc..2c19d46 100644
--- a/src/pages/AbroadAreasSurvey.tsx
+++ b/src/pages/AbroadAreasSurvey.tsx
@@ -5,11 +5,12 @@ import { SurveyTemplate } from '@/components/domain/survey';
import Path from '@/router/Path';
import { Title } from '@/lib/styles/styledComponents';
import SearchSelector from '@/components/domain/survey/SearchSelector';
-import { schools } from '@/mock/schools';
import { useMeetingSessionState, useDatingSessionState } from '@/hooks/common';
+import useAboardAreaLoad from '@/hooks/survey/useAboardAreaLoad';
const AbroadAreasSurvey = () => {
const matchMeeting = useMatch('/meeting/*');
+ const { area } = useAboardAreaLoad();
const meetingNavigate = matchMeeting ? useMeetingNavigate() : useDatingNavigate();
const { initMeetingState, setMeetingData } = useMeetingSessionState();
const { initDatingState, setDatingData } = useDatingSessionState();
@@ -39,7 +40,7 @@ const AbroadAreasSurvey = () => {
diff --git a/src/pages/AdminPage.tsx b/src/pages/AdminPage.tsx
new file mode 100644
index 0000000..46e7061
--- /dev/null
+++ b/src/pages/AdminPage.tsx
@@ -0,0 +1,135 @@
+import { Button } from '@/components/base';
+import { getMeetingUsers, getDatingUsers, patchDatingPayment, patchMeetingPayment } from '@/lib/api/admin';
+import { useEffect, useState } from 'react';
+import styled from 'styled-components';
+import { type AdminUsersStatus } from '@/types/user';
+
+type UserType = 'meeting' | 'dating';
+
+const AdminPage = () => {
+ const [userType, setUserType] = useState('meeting');
+ const [datingUsers, setDatingUsers] = useState([]);
+ const [meetingUsers, setMeetingUsers] = useState([]);
+
+ const users = userType === 'meeting' ? meetingUsers : datingUsers;
+
+ const handlePayment = async (kakaoId: string) => {
+ try {
+ if (userType === 'meeting') {
+ const res = await patchMeetingPayment(kakaoId);
+ setMeetingUsers(res);
+ return;
+ }
+ const res = await patchDatingPayment(kakaoId);
+ setDatingUsers(res);
+ } catch (e) {
+ alert(e.message);
+ }
+ };
+
+ useEffect(() => {
+ const getUsersInfo = async () => {
+ try {
+ if (userType === 'meeting') {
+ const res = await getMeetingUsers();
+ setMeetingUsers(res);
+ return;
+ }
+ const res = await getDatingUsers();
+ setDatingUsers(res);
+ } catch (e) {
+ alert(e.message);
+ }
+ };
+
+ getUsersInfo();
+ }, [userType]);
+
+ return (
+
+
+ setUserType('meeting')}
+ size="medium"
+ variant={userType === 'meeting' ? 'default' : 'gray'}
+ fontWeight={userType === 'dating' ? 700 : 400}
+ >
+ 미팅
+
+ setUserType('dating')}
+ size="medium"
+ variant={userType === 'dating' ? 'default' : 'gray'}
+ fontWeight={userType === 'dating' ? 700 : 400}
+ >
+ 소개팅
+
+
+
+
+
+ kakaoId |
+ status |
+ 지불여부 |
+ 지불버튼 |
+
+
+
+ {users.map(({ kakaoId, matchStatus, paid }) => (
+
+ {kakaoId} |
+ {matchStatus} |
+ {String(paid)}
+ {matchStatus === 'MATCHED' && } |
+
+ ))}
+
+
+
+ );
+};
+
+const AdminPageBlock = styled.div`
+ max-width: 1024px;
+ width: 100%;
+`;
+
+const Table = styled.table`
+ display: table;
+ table-layout: fixed;
+ width: 100%;
+ border: 1px solid #444444;
+ border-collapse: collapse;
+
+ th,
+ td {
+ border: 1px solid #444444;
+ text-align: center;
+ display: table-cell;
+ }
+
+ th {
+ padding: 5px;
+ }
+
+ td {
+ font-weight: 500;
+ padding: 5px;
+ }
+`;
+
+const ButtonWrapper = styled.div`
+ display: flex;
+ justify-content: center;
+`;
+const TypeButton = styled(Button)`
+ margin: 25px 4px 4px 4px;
+ width: 80px;
+ height: 38px;
+`;
+
+const PaidColumn = styled.td<{ paid: boolean }>`
+ color: ${({ paid }) => (paid ? '#1E90FF' : '#DC143C')};
+`;
+
+export default AdminPage;
diff --git a/src/pages/AvoidUniversitiesSurvey.tsx b/src/pages/AvoidUniversitiesSurvey.tsx
index 4485114..1bea504 100644
--- a/src/pages/AvoidUniversitiesSurvey.tsx
+++ b/src/pages/AvoidUniversitiesSurvey.tsx
@@ -3,14 +3,15 @@ import { useMatch } from 'react-router-dom';
import { SurveyTemplate } from '@/components/domain/survey';
import { Title } from '@/lib/styles/styledComponents';
import SearchSelector from '@/components/domain/survey/SearchSelector';
-import { schools } from '@/mock/schools';
import styled from 'styled-components';
import Path from '@/router/Path';
import { useDatingNavigate, useMeetingNavigate } from '@/hooks/common/useNavigate';
import { useMeetingSessionState, useDatingSessionState } from '@/hooks/common';
+import useUnivLoad from '@/hooks/survey/useUnivLoad';
const AvoidUniversitiesSurvey = () => {
const matchMeeting = useMatch('/meeting/*');
+ const { univs } = useUnivLoad();
const meetingNavigate = matchMeeting ? useMeetingNavigate() : useDatingNavigate();
const { initMeetingState, setMeetingData } = useMeetingSessionState();
const { initDatingState, setDatingData } = useDatingSessionState();
@@ -46,7 +47,7 @@ const AvoidUniversitiesSurvey = () => {
diff --git a/src/pages/MatchingPage.tsx b/src/pages/MatchingPage.tsx
index 922f4fd..6562db6 100644
--- a/src/pages/MatchingPage.tsx
+++ b/src/pages/MatchingPage.tsx
@@ -5,14 +5,19 @@ import MatchingTemplete from '@/components/domain/matching/MatchingTemplete';
import SuccessBox from '@/components/domain/matching/SuccessBox';
import WaitingBox from '@/components/domain/matching/WaitingBox';
import { Contents } from '@/lib/styles/styledComponents';
-import React from 'react';
+import React, { useState } from 'react';
import styled from 'styled-components';
+export type Status = 'none' | 'waiting' | 'success' | 'pay' | 'end';
+
const MatchingPage = () => {
- const TempData = { state: 'waiting' };
+ const [status, setStatus] = useState('waiting');
+
+ const handleStatus = (status: Status) => setStatus(status);
+
return (
<>
-
+
{
{
@@ -21,7 +26,7 @@ const MatchingPage = () => {
success: ,
pay: ,
end: ,
- }[TempData.state]
+ }[status]
}
diff --git a/src/pages/MyMbtiHeight.tsx b/src/pages/MyMbtiHeight.tsx
index 776c9c7..decb466 100644
--- a/src/pages/MyMbtiHeight.tsx
+++ b/src/pages/MyMbtiHeight.tsx
@@ -13,6 +13,7 @@ const MyMbtiHeight = () => {
const { initDatingState, setDatingData } = useDatingSessionState();
const [mbti, setMbti] = useState(initDatingState.mbti);
const [myHeight, setMyHeight] = useState(initDatingState.myHeight);
+ const [heightError, setHeightError] = useState(false);
const handleChange = (e: React.ChangeEvent) => {
const { name, value } = e.target;
@@ -20,8 +21,15 @@ const MyMbtiHeight = () => {
case 'mbti':
setMbti(value);
break;
- case 'myHeight':
- setMyHeight(Number(value));
+ case 'myHeight': {
+ const heightValue = Number(value);
+ if (heightValue <= 220) {
+ setMyHeight(Number(value));
+ setHeightError(false);
+ return;
+ }
+ setHeightError(true);
+ }
}
};
@@ -35,7 +43,7 @@ const MyMbtiHeight = () => {
return (
datingNavigate(Path.MyDepartmentCharacter)}
@@ -48,7 +56,7 @@ const MyMbtiHeight = () => {
본인의 키를 알려주세요.
- 키는 220cm 이하여야 합니다.
+ {heightError && '키는 220cm 이하여야 합니다.'}
{
placeholder="키(cm)"
maxLength={3}
onChange={handleChange}
- value={String(myHeight)}
+ value={!myHeight ? '' : String(myHeight)}
/>
@@ -80,8 +88,9 @@ const InputWrapper = styled.div`
margin-top: 63px;
`;
-const Description = styled.p`
+const HeightError = styled.p`
font-size: 14px;
+ height: 14px;
margin-bottom: 30px;
color: ${palette.primary};
`;
diff --git a/src/pages/OauthKakao.tsx b/src/pages/OauthKakao.tsx
index 2d7a575..426b16c 100644
--- a/src/pages/OauthKakao.tsx
+++ b/src/pages/OauthKakao.tsx
@@ -6,12 +6,12 @@ import Path from '@/router/Path';
const OauthKakao = () => {
const code = new URL(window.location.href).searchParams.get('code');
- // const navigate = useNavigate();
+ const navigate = useNavigate();
useEffect(() => {
try {
const data = getToken();
setToken(data);
- // navigate(Path.AuthMail);
+ navigate(Path.AuthMail);
} catch (error) {
console.log(error);
}
diff --git a/src/pages/OurUniversitiesSurvey.tsx b/src/pages/OurUniversitiesSurvey.tsx
index 0ed21d5..3ae7c78 100644
--- a/src/pages/OurUniversitiesSurvey.tsx
+++ b/src/pages/OurUniversitiesSurvey.tsx
@@ -1,16 +1,18 @@
-import React, { useState } from 'react';
+import React, { useMemo, useState } from 'react';
import { Title } from '@/lib/styles/styledComponents';
import { SurveyTemplate } from '@/components/domain/survey';
import SearchSelector from '@/components/domain/survey/SearchSelector';
-import { schools } from '@/mock/schools';
import Path from '@/router/Path';
import { useMeetingNavigate } from '@/hooks/common/useNavigate';
import { useMeetingSessionState } from '@/hooks/common';
+import useUnivLoad from '@/hooks/survey/useUnivLoad';
const OurUniversitiesSurvey = () => {
const meetingNavigate = useMeetingNavigate();
+ const { univs } = useUnivLoad();
const { initMeetingState, setMeetingData } = useMeetingSessionState();
const [ourUniversities, setOurUniversities] = useState(initMeetingState.ourUniversities);
+ const { typeOfMeeting } = initMeetingState;
const handleNextClick = () => {
if (initMeetingState) {
@@ -20,9 +22,22 @@ const OurUniversitiesSurvey = () => {
meetingNavigate(Path.OurDepartmentsAverageHeightSurvey);
};
+ const maxUniv = useMemo(() => {
+ switch (typeOfMeeting) {
+ case 'ONE':
+ return 1;
+ case 'TWO':
+ return 2;
+ case 'THREE':
+ return 3;
+ case 'FOUR':
+ return 4;
+ }
+ }, [typeOfMeeting]);
+
return (
{
);
diff --git a/src/pages/PreferUniversitiesSurvey.tsx b/src/pages/PreferUniversitiesSurvey.tsx
index e438c86..8b242dc 100644
--- a/src/pages/PreferUniversitiesSurvey.tsx
+++ b/src/pages/PreferUniversitiesSurvey.tsx
@@ -3,13 +3,14 @@ import { useMatch } from 'react-router-dom';
import { SurveyTemplate } from '@/components/domain/survey';
import { Title } from '@/lib/styles/styledComponents';
import SearchSelector from '@/components/domain/survey/SearchSelector';
-import { schools } from '@/mock/schools';
import { useDatingNavigate, useMeetingNavigate } from '@/hooks/common/useNavigate';
import Path from '@/router/Path';
import { useMeetingSessionState, useDatingSessionState } from '@/hooks/common';
+import useUnivLoad from '@/hooks/survey/useUnivLoad';
const PreferUniversitiesSurvey = () => {
const matchMeeting = useMatch('/meeting/*');
+ const { univs } = useUnivLoad();
const meetingNavigate = matchMeeting ? useMeetingNavigate() : useDatingNavigate();
const { initMeetingState, setMeetingData } = useMeetingSessionState();
const { initDatingState, setDatingData } = useDatingSessionState();
@@ -45,7 +46,7 @@ const PreferUniversitiesSurvey = () => {
diff --git a/src/pages/TestLogin.tsx b/src/pages/TestLogin.tsx
index 3dcc14e..5e0f6bc 100644
--- a/src/pages/TestLogin.tsx
+++ b/src/pages/TestLogin.tsx
@@ -27,7 +27,7 @@ const TestLogin = () => {
navigate('/type-of-meeting');
}
} catch (e) {
- alert(e.message);
+ onToggleErrorModal();
}
};
diff --git a/src/pages/index.ts b/src/pages/index.ts
index 0a93ce7..49df5c6 100644
--- a/src/pages/index.ts
+++ b/src/pages/index.ts
@@ -31,3 +31,4 @@ export { default as MatchingPage } from './MatchingPage';
export { default as OauthKakao } from './OauthKakao';
export { default as TestLogin } from './TestLogin';
+export { default as AdminPage } from './AdminPage';
diff --git a/src/router/Path.ts b/src/router/Path.ts
index cbcb5f4..3b523cc 100644
--- a/src/router/Path.ts
+++ b/src/router/Path.ts
@@ -1,5 +1,6 @@
enum Path {
LandingPage = '/',
+ AdminPage = '/35D648E599E6DEBBA04060C6DA86C5B64A5975966C4F2D3170B0CE457BE78BE2',
TestLogin = '/test-login',
Component = '/component', // FIXME: 컴포넌트 모아두는 곳 (개발완료 후 삭제)
AuthMail = '/auth-mail',
diff --git a/src/router/Routing.tsx b/src/router/Routing.tsx
index f36a6b4..b619272 100644
--- a/src/router/Routing.tsx
+++ b/src/router/Routing.tsx
@@ -32,6 +32,7 @@ import {
PreferBodyDateCountSurvey,
MatchingPage,
TestLogin,
+ AdminPage,
} from '@/pages';
import Test from '@/components/base/Test';
import UserHeader from '@/components/header/UserHeader';
@@ -44,6 +45,7 @@ function Routing() {
} />
+ } />
} />
} />
} />
diff --git a/src/types/user.ts b/src/types/user.ts
index b3e1cc6..42dfdf2 100644
--- a/src/types/user.ts
+++ b/src/types/user.ts
@@ -6,3 +6,11 @@ export interface LoginRequest {
export interface LoginResponse {
accessToken: 'string';
}
+
+type MatchStatus = 'WAITING' | 'MATCHED' | 'FAILED' | 'DONE' | 'PAID';
+
+export interface AdminUsersStatus {
+ kakaoId: string;
+ matchStatus: MatchStatus;
+ paid: boolean;
+}