Skip to content

Commit f51b95c

Browse files
authored
[FRONTEND] 전문가 인증 (#106)
## 📝작업 내용 > 전문가 인증 및 사용자 설정 라우팅 최적화
1 parent 0bfe6b0 commit f51b95c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+5678
-7769
lines changed

frontend/package-lock.json

Lines changed: 4016 additions & 7568 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
"dependencies": {
1313
"@tanstack/react-query": "^5.90.1",
1414
"@tanstack/react-query-devtools": "^5.90.2",
15+
"@types/react": "^19.1.10",
16+
"@types/react-dom": "^19.1.7",
1517
"axios": "^1.12.2",
1618
"framer-motion": "^12.23.24",
1719
"gsap": "^3.13.0",
@@ -24,22 +26,19 @@
2426
"react-router-dom": "^7.9.1",
2527
"rehype-highlight": "^7.0.2",
2628
"remark-gfm": "^4.0.1",
27-
"vercel": "^48.10.10",
2829
"zustand": "^5.0.8"
2930
},
3031
"devDependencies": {
3132
"@eslint/js": "^9.33.0",
3233
"@types/node": "^24.6.2",
33-
"@types/react": "^19.1.10",
34-
"@types/react-dom": "^19.1.7",
3534
"@vitejs/plugin-react": "^5.0.0",
3635
"baseline-browser-mapping": "^2.8.28",
3736
"eslint": "^9.33.0",
3837
"eslint-plugin-check-file": "^3.3.1",
3938
"eslint-plugin-react-hooks": "^5.2.0",
4039
"eslint-plugin-react-refresh": "^0.4.20",
4140
"globals": "^16.3.0",
42-
"typescript": "~5.8.3",
41+
"typescript": "^5.9.3",
4342
"typescript-eslint": "^8.39.1",
4443
"vite": "^7.2.2"
4544
}

frontend/src/App.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import SignIn from "./pages/SignIn";
1212
import Setting from "./pages/Setting";
1313
import SecondSetting from "./pages/SecondSetting";
1414
import RedirectPage from "./pages/RedirectPage";
15+
import Admin from "./pages/Admin";
1516
import ExpertVerifyLayout from "./components/layout/ExpertVerifyLayout";
1617
import { ProtectedRoute } from "./routes/ProtectedRoute";
18+
import { AdminProtectedRoute } from "./routes/AdminProtectedRoute";
1719
import RootRedirect from "./routes/RootRedirect";
1820
import {
1921
ErrorBoundary,
@@ -87,6 +89,14 @@ const Router = () => {
8789
<Route path="/setting" element={<Setting />} />
8890
<Route path="/second-setting" element={<SecondSetting />} />
8991
<Route path={"/oauth/kakao/redirect"} element={<RedirectPage />} />
92+
<Route
93+
path={"/admin"}
94+
element={
95+
<AdminProtectedRoute>
96+
<Admin />
97+
</AdminProtectedRoute>
98+
}
99+
/>
90100
</Routes>
91101
</BrowserRouter>
92102
);

frontend/src/api/services/useUserProfile.ts renamed to frontend/src/api/Auth/useUserProfile.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { useQuery } from '@tanstack/react-query';
22
import { useAuthStore } from '../../stores/useAuthStore';
3-
import client from '../core';
3+
import { userService } from '../services/userService';
44
import {
55
queryKeys,
66
extractData,
77
} from '../core/queryConfig';
88
import type { CommonQueryOptions } from '../core/queryConfig';
9-
import { API_ENDPOINTS } from '../core/types';
109
import type { UserData } from '../../types/user';
1110

1211
// 사용자 프로필 조회
@@ -16,9 +15,7 @@ export function useUserProfile(options?: CommonQueryOptions<UserData>) {
1615
return useQuery({
1716
queryKey: queryKeys.USER.PROFILE,
1817
queryFn: async () => {
19-
const response = await client.get<UserData>(API_ENDPOINTS.USERS.PROFILE);
20-
21-
// 성공 시 스토어에 자동 저장
18+
const response = await userService.getUserProfile();
2219
if (response.success) {
2320
updateUserFromApi(response);
2421
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { useQuery } from '@tanstack/react-query';
2+
import client from '../../core';
3+
import { API_ENDPOINTS } from '../../core/types';
4+
import type { Certification } from '../../../types/api';
5+
import type { CommonQueryOptions } from '../../core/queryConfig';
6+
7+
// 전문가 인증 목록 전체 조회 (관리자용)
8+
export function useCertificationGetAll(
9+
options?: CommonQueryOptions<Certification[]>
10+
) {
11+
return useQuery({
12+
queryKey: ['certification', 'all'],
13+
queryFn: async () => {
14+
const response = await client.get<Certification[]>(API_ENDPOINTS.CERTIFICATION.ALL);
15+
return response.data;
16+
},
17+
...options,
18+
});
19+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { useMutation, useQueryClient } from '@tanstack/react-query';
2+
import client from '../../core';
3+
import { API_ENDPOINTS } from '../../core/types';
4+
import type { CertificationApproveRequest } from '../../../types/api';
5+
import type { CommonMutationOptions } from '../../core/queryConfig';
6+
7+
// 전문가 인증 승인 (관리자용)
8+
export function useCertificationApprove(
9+
options?: CommonMutationOptions<void, CertificationApproveRequest>
10+
) {
11+
const queryClient = useQueryClient();
12+
13+
return useMutation({
14+
mutationFn: async ({ certId }: CertificationApproveRequest) => {
15+
const response = await client.patch<void>(API_ENDPOINTS.CERTIFICATION.APPROVE(certId));
16+
return response;
17+
},
18+
onSuccess: () => {
19+
queryClient.invalidateQueries({ queryKey: ['certification'] });
20+
},
21+
...options,
22+
});
23+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { useMutation, useQueryClient } from '@tanstack/react-query';
2+
import client from '../../core';
3+
import { API_ENDPOINTS } from '../../core/types';
4+
import type { CertificationRejectRequest } from '../../../types/api';
5+
import type { CommonMutationOptions } from '../../core/queryConfig';
6+
7+
// 전문가 인증 거절 (관리자용)
8+
export function useCertificationReject(
9+
options?: CommonMutationOptions<void, CertificationRejectRequest>
10+
) {
11+
const queryClient = useQueryClient();
12+
13+
return useMutation({
14+
mutationFn: async ({ certId, reason }: CertificationRejectRequest) => {
15+
const response = await client.patch<void>(
16+
`${API_ENDPOINTS.CERTIFICATION.REJECT(certId)}?reason=${encodeURIComponent(reason)}`
17+
);
18+
return response;
19+
},
20+
onSuccess: () => {
21+
queryClient.invalidateQueries({ queryKey: ['certification'] });
22+
},
23+
...options,
24+
});
25+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// 전문가 인증 관련 API export
2+
export { useCertificationGet } from './useCertificationGet';
3+
export { useCertificationGenerate } from './useCertificationGenerate';
4+
export { useCertificationDelete } from './useCertificationDelete';
5+
6+
// 관리자용 API
7+
export { useCertificationGetAll } from './ManagerCeritification/useCertificationGetAll';
8+
export { useCertificationApprove } from './ManagerCeritification/useCertificationGetApproval';
9+
export { useCertificationReject } from './ManagerCeritification/useCertificationGetRefusal';
Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
1-
// 전문가 인증 삭제 훅
2-
export const useCertificationDelete = () => {
3-
// 향후 구현을 위한 자리 표시자
1+
import { useMutation, useQueryClient } from '@tanstack/react-query';
2+
import client from '../core';
3+
import { API_ENDPOINTS } from '../core/types';
4+
import type { CommonMutationOptions } from '../core/queryConfig';
5+
6+
// 전문가 인증 삭제
7+
export function useCertificationDelete(
8+
options?: CommonMutationOptions<void, number>
9+
) {
10+
const queryClient = useQueryClient();
11+
12+
return useMutation({
13+
mutationFn: async (certId: number) => {
14+
const response = await client.delete<void>(API_ENDPOINTS.CERTIFICATION.DELETE(certId));
15+
return response;
16+
},
17+
onSuccess: () => {
18+
queryClient.invalidateQueries({ queryKey: ['certification'] });
19+
},
20+
...options,
21+
});
422
}
Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
1+
import { useMutation, useQueryClient } from '@tanstack/react-query';
2+
import client from '../core';
3+
import { API_ENDPOINTS } from '../core/types';
4+
import type { CertificationGenerateRequest } from '../../types/api';
5+
import type { CommonMutationOptions } from '../core/queryConfig';
6+
17
// 전문가 인증 생성
8+
export function useCertificationGenerate(
9+
options?: CommonMutationOptions<void, CertificationGenerateRequest>
10+
) {
11+
const queryClient = useQueryClient();
212

3-
export const useCertificationGenerate = () => {
4-
// Placeholder for future implementation
13+
return useMutation({
14+
mutationFn: async (data: CertificationGenerateRequest) => {
15+
const response = await client.post<void>(API_ENDPOINTS.CERTIFICATION.BASE, data);
16+
return response;
17+
},
18+
onSuccess: () => {
19+
queryClient.invalidateQueries({ queryKey: ['certification'] });
20+
},
21+
...options,
22+
});
523
}

0 commit comments

Comments
 (0)