api link to page
This commit is contained in:
@@ -5,6 +5,7 @@ import { useEffect, useRef, useState } from "react";
|
|||||||
import { usePathname, useRouter } from "next/navigation";
|
import { usePathname, useRouter } from "next/navigation";
|
||||||
import MainLogoSvg from "./svgs/mainlogosvg";
|
import MainLogoSvg from "./svgs/mainlogosvg";
|
||||||
import ChevronDownSvg from "./svgs/chevrondownsvg";
|
import ChevronDownSvg from "./svgs/chevrondownsvg";
|
||||||
|
import apiService from "./lib/apiService";
|
||||||
|
|
||||||
const NAV_ITEMS = [
|
const NAV_ITEMS = [
|
||||||
{ label: "교육 과정 목록", href: "/course-list" },
|
{ label: "교육 과정 목록", href: "/course-list" },
|
||||||
@@ -54,19 +55,8 @@ export default function NavBar() {
|
|||||||
localStorage.setItem('token', cookieToken);
|
localStorage.setItem('token', cookieToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
const response = await apiService.getCurrentUser();
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/auth/me`
|
|
||||||
: 'https://hrdi.coconutmeet.net/auth/me';
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
// 토큰이 만료되었거나 유효하지 않은 경우
|
// 토큰이 만료되었거나 유효하지 않은 경우
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
@@ -75,11 +65,10 @@ export default function NavBar() {
|
|||||||
if (isMounted && pathname !== '/login') {
|
if (isMounted && pathname !== '/login') {
|
||||||
router.push('/login');
|
router.push('/login');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = response.data;
|
||||||
|
|
||||||
// 계정 상태 확인
|
// 계정 상태 확인
|
||||||
const userStatus = data.status || data.userStatus;
|
const userStatus = data.status || data.userStatus;
|
||||||
|
|||||||
@@ -42,33 +42,9 @@ export default function CourseRegistrationModal({ open, onClose, onSave, onDelet
|
|||||||
|
|
||||||
setIsLoadingInstructors(true);
|
setIsLoadingInstructors(true);
|
||||||
try {
|
try {
|
||||||
const token = localStorage.getItem('token') || document.cookie
|
|
||||||
.split('; ')
|
|
||||||
.find(row => row.startsWith('token='))
|
|
||||||
?.split('=')[1];
|
|
||||||
|
|
||||||
// 외부 API 호출
|
// 외부 API 호출
|
||||||
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
const response = await apiService.getUsersCompact();
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/admin/users/compact`
|
const data = response.data;
|
||||||
: 'https://hrdi.coconutmeet.net/admin/users/compact';
|
|
||||||
|
|
||||||
// 쿼리 파라미터 추가: type=ADMIN
|
|
||||||
const apiUrl = new URL(baseUrl);
|
|
||||||
apiUrl.searchParams.set('type', 'ADMIN');
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl.toString(), {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(token && { Authorization: `Bearer ${token}` }),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`강사 목록을 가져오는데 실패했습니다. (${response.status})`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
// API 응답이 배열이 아닌 경우 처리 (예: { items: [...] } 형태)
|
// API 응답이 배열이 아닌 경우 처리 (예: { items: [...] } 형태)
|
||||||
let usersArray: any[] = [];
|
let usersArray: any[] = [];
|
||||||
@@ -293,15 +269,6 @@ export default function CourseRegistrationModal({ open, onClose, onSave, onDelet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = localStorage.getItem('token') || document.cookie
|
|
||||||
.split('; ')
|
|
||||||
.find(row => row.startsWith('token='))
|
|
||||||
?.split('=')[1];
|
|
||||||
|
|
||||||
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
|
||||||
? process.env.NEXT_PUBLIC_API_BASE_URL
|
|
||||||
: 'https://hrdi.coconutmeet.net';
|
|
||||||
|
|
||||||
const requestBody: {
|
const requestBody: {
|
||||||
title: string;
|
title: string;
|
||||||
instructor: string;
|
instructor: string;
|
||||||
@@ -354,52 +321,24 @@ export default function CourseRegistrationModal({ open, onClose, onSave, onDelet
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 등록 모드: POST /subjects
|
// 등록 모드: POST /subjects
|
||||||
const response = await fetch(`${baseUrl}/subjects`, {
|
try {
|
||||||
method: 'POST',
|
await apiService.createSubject({
|
||||||
headers: {
|
courseName: courseName.trim(),
|
||||||
'Content-Type': 'application/json',
|
instructorName: selectedInstructor.name,
|
||||||
...(token && { Authorization: `Bearer ${token}` }),
|
|
||||||
},
|
|
||||||
body: JSON.stringify(requestBody),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
let errorMessage = `과목 등록 실패 (${response.status})`;
|
|
||||||
try {
|
|
||||||
const errorData = await response.json();
|
|
||||||
if (errorData.error) {
|
|
||||||
errorMessage = errorData.error;
|
|
||||||
} else if (errorData.message) {
|
|
||||||
errorMessage = errorData.message;
|
|
||||||
}
|
|
||||||
} catch (parseError) {
|
|
||||||
// JSON 파싱 실패 시 기본 메시지 사용
|
|
||||||
}
|
|
||||||
console.error('과목 등록 실패:', errorMessage);
|
|
||||||
setErrors({ submit: errorMessage });
|
|
||||||
setIsSaving(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 응답에서 id 추출하여 저장
|
|
||||||
try {
|
|
||||||
const responseData = await response.json();
|
|
||||||
|
|
||||||
// 응답에서 id 추출 (다양한 가능한 필드명 확인)
|
|
||||||
const subjectId = responseData.id
|
|
||||||
|| responseData.data?.id
|
|
||||||
|| responseData.subjectId
|
|
||||||
|| responseData.data?.subjectId
|
|
||||||
|| null;
|
|
||||||
} catch (parseError) {
|
|
||||||
// 응답 파싱 실패 시 무시
|
|
||||||
}
|
|
||||||
|
|
||||||
// 성공 시 onSave 콜백 호출 및 모달 닫기
|
// 성공 시 onSave 콜백 호출 및 모달 닫기
|
||||||
if (onSave && selectedInstructor) {
|
if (onSave && selectedInstructor) {
|
||||||
onSave(courseName.trim(), selectedInstructor.name);
|
onSave(courseName.trim(), selectedInstructor.name);
|
||||||
}
|
}
|
||||||
onClose(); // 모달 닫기
|
onClose(); // 모달 닫기
|
||||||
|
} catch (createError) {
|
||||||
|
const errorMessage = createError instanceof Error ? createError.message : '과목 등록 중 오류가 발생했습니다.';
|
||||||
|
console.error('과목 등록 실패:', errorMessage);
|
||||||
|
setErrors({ submit: errorMessage });
|
||||||
|
setIsSaving(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = error instanceof Error ? error.message : '네트워크 오류가 발생했습니다.';
|
const errorMessage = error instanceof Error ? error.message : '네트워크 오류가 발생했습니다.';
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import apiService from "@/app/lib/apiService";
|
||||||
|
|
||||||
type RoleType = 'learner' | 'instructor' | 'admin';
|
type RoleType = 'learner' | 'instructor' | 'admin';
|
||||||
type AccountStatus = 'active' | 'inactive';
|
type AccountStatus = 'active' | 'inactive';
|
||||||
|
|
||||||
@@ -22,43 +24,8 @@ export async function getInstructors(): Promise<UserRow[]> {
|
|||||||
?.split('=')[1])
|
?.split('=')[1])
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
const response = await apiService.getUsersCompact();
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/admin/users/compact`
|
const data = response.data;
|
||||||
: 'https://hrdi.coconutmeet.net/admin/users/compact';
|
|
||||||
|
|
||||||
// 쿼리 파라미터 추가: type=ADMIN, limit=10
|
|
||||||
const apiUrl = new URL(baseUrl);
|
|
||||||
apiUrl.searchParams.set('type', 'ADMIN');
|
|
||||||
apiUrl.searchParams.set('limit', '10');
|
|
||||||
|
|
||||||
console.log('🔍 [getInstructors] API 호출 정보:', {
|
|
||||||
url: apiUrl.toString(),
|
|
||||||
hasToken: !!token,
|
|
||||||
tokenLength: token?.length || 0
|
|
||||||
});
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl.toString(), {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(token && { Authorization: `Bearer ${token}` }),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('📡 [getInstructors] API 응답 상태:', {
|
|
||||||
status: response.status,
|
|
||||||
statusText: response.statusText,
|
|
||||||
ok: response.ok
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
const errorText = await response.text();
|
|
||||||
console.error('❌ [getInstructors] API 에러 응답:', errorText);
|
|
||||||
console.error('강사 목록 가져오기 실패:', response.status);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
console.log('📦 [getInstructors] 원본 API 응답 데이터:', {
|
console.log('📦 [getInstructors] 원본 API 응답 데이터:', {
|
||||||
type: typeof data,
|
type: typeof data,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useState, useEffect, useRef, useMemo } from "react";
|
|||||||
import AdminSidebar from "@/app/components/AdminSidebar";
|
import AdminSidebar from "@/app/components/AdminSidebar";
|
||||||
import ChevronDownSvg from "@/app/svgs/chevrondownsvg";
|
import ChevronDownSvg from "@/app/svgs/chevrondownsvg";
|
||||||
import { type UserRow } from "./mockData";
|
import { type UserRow } from "./mockData";
|
||||||
|
import apiService from "@/app/lib/apiService";
|
||||||
|
|
||||||
type TabType = 'all' | 'learner' | 'instructor' | 'admin';
|
type TabType = 'all' | 'learner' | 'instructor' | 'admin';
|
||||||
type RoleType = 'learner' | 'instructor' | 'admin';
|
type RoleType = 'learner' | 'instructor' | 'admin';
|
||||||
@@ -45,35 +46,9 @@ export default function AdminIdPage() {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
const token = localStorage.getItem('token') || document.cookie
|
|
||||||
.split('; ')
|
|
||||||
.find(row => row.startsWith('token='))
|
|
||||||
?.split('=')[1];
|
|
||||||
|
|
||||||
// 외부 API 호출
|
// 외부 API 호출
|
||||||
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
const response = await apiService.getUsersCompact();
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/admin/users/compact`
|
const data = response.data;
|
||||||
: 'https://hrdi.coconutmeet.net/admin/users/compact';
|
|
||||||
|
|
||||||
// 쿼리 파라미터 추가: type=STUDENT, limit=10, page=currentPage
|
|
||||||
const apiUrl = new URL(baseUrl);
|
|
||||||
apiUrl.searchParams.set('type', 'STUDENT');
|
|
||||||
apiUrl.searchParams.set('limit', '10');
|
|
||||||
apiUrl.searchParams.set('page', String(currentPage));
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl.toString(), {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(token && { Authorization: `Bearer ${token}` }),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`사용자 데이터를 가져오는데 실패했습니다. (${response.status})`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
// API 응답이 배열이 아닌 경우 처리 (예: { items: [...] } 형태)
|
// API 응답이 배열이 아닌 경우 처리 (예: { items: [...] } 형태)
|
||||||
let usersArray: any[] = [];
|
let usersArray: any[] = [];
|
||||||
@@ -206,48 +181,7 @@ export default function AdminIdPage() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = localStorage.getItem('token') || document.cookie
|
await apiService.unsuspendUser(selectedUserId);
|
||||||
.split('; ')
|
|
||||||
.find(row => row.startsWith('token='))
|
|
||||||
?.split('=')[1];
|
|
||||||
|
|
||||||
if (!token) {
|
|
||||||
setToastMessage('로그인이 필요합니다.');
|
|
||||||
setShowToast(true);
|
|
||||||
setTimeout(() => {
|
|
||||||
setShowToast(false);
|
|
||||||
}, 3000);
|
|
||||||
setIsActivateModalOpen(false);
|
|
||||||
setSelectedUserId(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/admin/users/${selectedUserId}/unsuspend`
|
|
||||||
: `https://hrdi.coconutmeet.net/admin/users/${selectedUserId}/unsuspend`;
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
let errorMessage = `계정 활성화 실패 (${response.status})`;
|
|
||||||
try {
|
|
||||||
const errorData = await response.json();
|
|
||||||
if (errorData.error) {
|
|
||||||
errorMessage = errorData.error;
|
|
||||||
} else if (errorData.message) {
|
|
||||||
errorMessage = errorData.message;
|
|
||||||
}
|
|
||||||
} catch (parseError) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
throw new Error(errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// API 호출 성공 시 로컬 상태 업데이트
|
// API 호출 성공 시 로컬 상태 업데이트
|
||||||
setUsers(prevUsers =>
|
setUsers(prevUsers =>
|
||||||
@@ -295,52 +229,7 @@ export default function AdminIdPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const token = localStorage.getItem('token') || document.cookie
|
await apiService.suspendUser(selectedUserId);
|
||||||
.split('; ')
|
|
||||||
.find(row => row.startsWith('token='))
|
|
||||||
?.split('=')[1];
|
|
||||||
|
|
||||||
if (!token) {
|
|
||||||
setToastMessage('로그인이 필요합니다.');
|
|
||||||
setShowToast(true);
|
|
||||||
setTimeout(() => {
|
|
||||||
setShowToast(false);
|
|
||||||
}, 3000);
|
|
||||||
setIsDeactivateModalOpen(false);
|
|
||||||
setSelectedUserId(null);
|
|
||||||
setDeactivateReason('');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/admin/users/${selectedUserId}/suspend`
|
|
||||||
: `https://hrdi.coconutmeet.net/admin/users/${selectedUserId}/suspend`;
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
reason: deactivateReason,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
let errorMessage = `계정 비활성화 실패 (${response.status})`;
|
|
||||||
try {
|
|
||||||
const errorData = await response.json();
|
|
||||||
if (errorData.error) {
|
|
||||||
errorMessage = errorData.error;
|
|
||||||
} else if (errorData.message) {
|
|
||||||
errorMessage = errorData.message;
|
|
||||||
}
|
|
||||||
} catch (parseError) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
throw new Error(errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// API 호출 성공 시 로컬 상태 업데이트
|
// API 호출 성공 시 로컬 상태 업데이트
|
||||||
setUsers(prevUsers =>
|
setUsers(prevUsers =>
|
||||||
|
|||||||
@@ -158,23 +158,10 @@ export default function AdminLessonsPage() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
const response = await apiService.getCurrentUser();
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/auth/me`
|
|
||||||
: 'https://hrdi.coconutmeet.net/auth/me';
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl, {
|
if (response.data && response.data.name) {
|
||||||
method: 'GET',
|
setCurrentUser(response.data.name);
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
const data = await response.json();
|
|
||||||
if (data.name) {
|
|
||||||
setCurrentUser(data.name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('사용자 정보 조회 오류:', error);
|
console.error('사용자 정보 조회 오류:', error);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { useEffect, useState, useMemo } from 'react';
|
import { useEffect, useState, useMemo } from 'react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import ChevronDownSvg from '../../svgs/chevrondownsvg';
|
import ChevronDownSvg from '../../svgs/chevrondownsvg';
|
||||||
|
import apiService from '../../lib/apiService';
|
||||||
|
|
||||||
// 드롭다운 아이콘 컴포넌트
|
// 드롭다운 아이콘 컴포넌트
|
||||||
function ArrowDownIcon({ className }: { className?: string }) {
|
function ArrowDownIcon({ className }: { className?: string }) {
|
||||||
@@ -139,30 +140,18 @@ export default function InstructorCoursesPage() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
const response = await apiService.getCurrentUser();
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/auth/me`
|
|
||||||
: 'https://hrdi.coconutmeet.net/auth/me';
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
||||||
if (isMounted) {
|
if (isMounted) {
|
||||||
router.push('/login');
|
router.push('/login');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = response.data;
|
||||||
|
|
||||||
if (isMounted) {
|
if (isMounted) {
|
||||||
const role = data.role || data.userRole || '';
|
const role = data.role || data.userRole || '';
|
||||||
@@ -198,26 +187,14 @@ export default function InstructorCoursesPage() {
|
|||||||
.find(row => row.startsWith('token='))
|
.find(row => row.startsWith('token='))
|
||||||
?.split('=')[1];
|
?.split('=')[1];
|
||||||
|
|
||||||
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
const response = await apiService.getSubjects();
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/subjects`
|
|
||||||
: 'https://hrdi.coconutmeet.net/subjects';
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl, {
|
const data = response.data;
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(token && { Authorization: `Bearer ${token}` }),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
const data = await response.json();
|
|
||||||
const coursesArray = Array.isArray(data) ? data : (data.items || data.courses || data.data || []);
|
const coursesArray = Array.isArray(data) ? data : (data.items || data.courses || data.data || []);
|
||||||
setCourses(coursesArray.map((item: any) => ({
|
setCourses(coursesArray.map((item: any) => ({
|
||||||
id: String(item.id || item.subjectId || ''),
|
id: String(item.id || item.subjectId || ''),
|
||||||
name: item.courseName || item.name || item.subjectName || '',
|
name: item.courseName || item.name || item.subjectName || '',
|
||||||
})));
|
})));
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('교육 과정 목록 조회 오류:', error);
|
console.error('교육 과정 목록 조회 오류:', error);
|
||||||
}
|
}
|
||||||
@@ -391,7 +368,7 @@ export default function InstructorCoursesPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="bg-white min-h-screen flex flex-col">
|
<div className="bg-white min-h-screen flex flex-col">
|
||||||
<div className="flex-1 max-w-[1440px] w-full mx-auto px-0">
|
<div className="flex-1 max-w-[1440px] w-full mx-auto px-0">
|
||||||
<div className="flex flex-col gap-[10px] h-[100px] items-start px-[32px]">
|
<div className="flex flex-col h-[100px] items-start justify-center px-[32px] ">
|
||||||
<h1 className="text-[24px] font-bold leading-[1.5] text-[#1b2027]">
|
<h1 className="text-[24px] font-bold leading-[1.5] text-[#1b2027]">
|
||||||
강좌 현황
|
강좌 현황
|
||||||
</h1>
|
</h1>
|
||||||
@@ -625,9 +602,14 @@ export default function InstructorCoursesPage() {
|
|||||||
{/* 테이블 바디 */}
|
{/* 테이블 바디 */}
|
||||||
<div className="bg-white">
|
<div className="bg-white">
|
||||||
{paginatedData.map((item) => (
|
{paginatedData.map((item) => (
|
||||||
<div
|
<button
|
||||||
key={item.id}
|
key={item.id}
|
||||||
className="h-[48px] flex items-center border-b border-[#dee1e6] last:border-b-0"
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
// 상세 페이지로 이동 (API 연동 시 item.id 사용)
|
||||||
|
router.push(`/instructor/courses/${item.id}`);
|
||||||
|
}}
|
||||||
|
className="h-[48px] w-full flex items-center border-b border-[#dee1e6] last:border-b-0 cursor-pointer hover:bg-[#F5F7FF] transition-colors text-left"
|
||||||
>
|
>
|
||||||
<div className="flex-1 border-r border-[#dee1e6] px-[16px] py-[12px]">
|
<div className="flex-1 border-r border-[#dee1e6] px-[16px] py-[12px]">
|
||||||
<span className="text-[15px] font-medium leading-[1.5] text-[#1b2027]">{item.courseName}</span>
|
<span className="text-[15px] font-medium leading-[1.5] text-[#1b2027]">{item.courseName}</span>
|
||||||
@@ -666,7 +648,7 @@ export default function InstructorCoursesPage() {
|
|||||||
<StatusTag text="미완료" type="default" color="gray" />
|
<StatusTag text="미완료" type="default" color="gray" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { useRouter } from 'next/navigation';
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import MainLogoSvg from '../svgs/mainlogosvg';
|
import MainLogoSvg from '../svgs/mainlogosvg';
|
||||||
import ChevronDownSvg from '../svgs/chevrondownsvg';
|
import ChevronDownSvg from '../svgs/chevrondownsvg';
|
||||||
|
import apiService from '../lib/apiService';
|
||||||
|
|
||||||
// 아이콘 컴포넌트들
|
// 아이콘 컴포넌트들
|
||||||
function BookIcon({ className }: { className?: string }) {
|
function BookIcon({ className }: { className?: string }) {
|
||||||
@@ -194,30 +195,18 @@ export default function InstructorPage() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
const response = await apiService.getCurrentUser();
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/auth/me`
|
|
||||||
: 'https://hrdi.coconutmeet.net/auth/me';
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
||||||
if (isMounted) {
|
if (isMounted) {
|
||||||
router.push('/login');
|
router.push('/login');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = response.data;
|
||||||
|
|
||||||
if (isMounted) {
|
if (isMounted) {
|
||||||
const role = data.role || data.userRole || '';
|
const role = data.role || data.userRole || '';
|
||||||
|
|||||||
@@ -339,15 +339,86 @@ class ApiService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 회원 리스트 조회 (컴팩트) - 관리자 전용
|
||||||
|
*/
|
||||||
|
async getUsersCompact() {
|
||||||
|
return this.request('/admin/users/compact');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 단일 회원 정지 (ID 기준) - 관리자 전용
|
||||||
|
*/
|
||||||
|
async suspendUser(userId: string | number) {
|
||||||
|
return this.request(`/admin/users/${userId}/suspend`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 단일 회원 정지 해제 (ID 기준) - 관리자 전용
|
||||||
|
*/
|
||||||
|
async unsuspendUser(userId: string | number) {
|
||||||
|
return this.request(`/admin/users/${userId}/unsuspend`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 대량 정지 (ID 배열) - 관리자 전용
|
||||||
|
*/
|
||||||
|
async suspendUsers(userIds: (string | number)[]) {
|
||||||
|
return this.request('/admin/users/suspend', {
|
||||||
|
method: 'POST',
|
||||||
|
body: { userIds },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ===== 기타 API =====
|
// ===== 기타 API =====
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 공지사항 조회
|
* 공지사항 목록 조회 (페이징)
|
||||||
*/
|
*/
|
||||||
async getNotices() {
|
async getNotices() {
|
||||||
return this.request('/notices');
|
return this.request('/notices');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 공지 단건 조회
|
||||||
|
*/
|
||||||
|
async getNotice(id: string | number) {
|
||||||
|
return this.request(`/notices/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 공지 등록 (ADMIN)
|
||||||
|
*/
|
||||||
|
async createNotice(noticeData: any) {
|
||||||
|
return this.request('/notices', {
|
||||||
|
method: 'POST',
|
||||||
|
body: noticeData,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 공지 수정 (ADMIN)
|
||||||
|
*/
|
||||||
|
async updateNotice(id: string | number, noticeData: any) {
|
||||||
|
return this.request(`/notices/${id}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
body: noticeData,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 공지 삭제 (ADMIN)
|
||||||
|
*/
|
||||||
|
async deleteNotice(id: string | number) {
|
||||||
|
return this.request(`/notices/${id}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 강좌 조회
|
* 강좌 조회
|
||||||
*/
|
*/
|
||||||
@@ -424,6 +495,135 @@ class ApiService {
|
|||||||
return this.request('/resources');
|
return this.request('/resources');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== 학습 자료실 (Library) 관련 API =====
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 학습 자료실 목록 조회 (로그인 필요, 페이징)
|
||||||
|
*/
|
||||||
|
async getLibrary() {
|
||||||
|
return this.request('/library');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 학습 자료 단건 조회
|
||||||
|
*/
|
||||||
|
async getLibraryItem(id: string | number) {
|
||||||
|
return this.request(`/library/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 학습 자료 등록 (ADMIN)
|
||||||
|
*/
|
||||||
|
async createLibraryItem(libraryData: any) {
|
||||||
|
return this.request('/library', {
|
||||||
|
method: 'POST',
|
||||||
|
body: libraryData,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 학습 자료 수정 (ADMIN)
|
||||||
|
*/
|
||||||
|
async updateLibraryItem(id: string | number, libraryData: any) {
|
||||||
|
return this.request(`/library/${id}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
body: libraryData,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 학습 자료 삭제 (ADMIN)
|
||||||
|
*/
|
||||||
|
async deleteLibraryItem(id: string | number) {
|
||||||
|
return this.request(`/library/${id}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== 진행률 (Progress) 관련 API =====
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 특정 강의에서 "내" 진행률 조회
|
||||||
|
*/
|
||||||
|
async getLectureProgress(lectureId: string | number) {
|
||||||
|
return this.request(`/progress/lectures/${lectureId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 강의 진행(Heartbeat) 업서트
|
||||||
|
*/
|
||||||
|
async updateLectureProgress(progressData: any) {
|
||||||
|
return this.request('/progress/lectures/progress', {
|
||||||
|
method: 'POST',
|
||||||
|
body: progressData,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 과목 진행률 요약(내 기준)
|
||||||
|
*/
|
||||||
|
async getSubjectProgressSummary(subjectId: string | number) {
|
||||||
|
return this.request(`/progress/subjects/${subjectId}/summary`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== 평가 (Evaluation) 관련 API =====
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 강의 평가 제출 (60점 이상만 저장)
|
||||||
|
*/
|
||||||
|
async submitEvaluation(evaluationData: any) {
|
||||||
|
return this.request('/evaluations', {
|
||||||
|
method: 'POST',
|
||||||
|
body: evaluationData,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 특정 강의에서 "내" 마지막 평가 결과 조회
|
||||||
|
*/
|
||||||
|
async getMyEvaluation(lectureId: string | number) {
|
||||||
|
return this.request(`/evaluations/lectures/${lectureId}/me`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 특정 강의에서 특정 수강생의 마지막 평가 결과 조회 (ADMIN/INSTRUCTOR)
|
||||||
|
*/
|
||||||
|
async getUserEvaluation(lectureId: string | number, userId: string | number) {
|
||||||
|
return this.request(`/evaluations/lectures/${lectureId}/users/${userId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== 관리자 강의 현황 관련 API =====
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 강좌별 학습/문제 제출/수료 현황 리스트 (관리자/강사용)
|
||||||
|
*/
|
||||||
|
async getLecturesStatus() {
|
||||||
|
return this.request('/admin/lectures/status');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 특정 강좌 + 특정 학습자의 수강/문제 풀이 상세 (관리자/강사용)
|
||||||
|
*/
|
||||||
|
async getLectureStudentDetail(lectureId: string | number, userId: string | number) {
|
||||||
|
return this.request(`/admin/lectures/${lectureId}/students/${userId}/detail`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== 수료증 및 결과 관련 API =====
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 특정 과목 수료증용 정보 조회 (학생 본인)
|
||||||
|
*/
|
||||||
|
async getCertificate(subjectId: string | number) {
|
||||||
|
return this.request(`/certificates/subjects/${subjectId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 학생 기준 학습 결과(수료 과목 목록)
|
||||||
|
*/
|
||||||
|
async getMyResults() {
|
||||||
|
return this.request('/results/my-subjects');
|
||||||
|
}
|
||||||
|
|
||||||
// ===== 파일 업로드 관련 API =====
|
// ===== 파일 업로드 관련 API =====
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import ModalCloseSvg from "../svgs/closexsvg";
|
import ModalCloseSvg from "../svgs/closexsvg";
|
||||||
|
import apiService from "../lib/apiService";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -22,54 +23,7 @@ export default function AccountDeleteModal({ open, onClose, onConfirm }: Props)
|
|||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const token = localStorage.getItem('token');
|
await apiService.deleteAccount();
|
||||||
if (!token) {
|
|
||||||
alert('로그인이 필요합니다.');
|
|
||||||
setIsLoading(false);
|
|
||||||
onClose();
|
|
||||||
router.push('/login');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('회원 탈퇴 요청 시작, 토큰 존재:', !!token);
|
|
||||||
console.log('토큰 길이:', token?.length);
|
|
||||||
console.log('토큰 시작 부분:', token?.substring(0, 20));
|
|
||||||
|
|
||||||
const response = await fetch('https://hrdi.coconutmeet.net/auth/delete/me', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('회원 탈퇴 응답 상태:', response.status);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
let errorMessage = `회원 탈퇴 실패 (${response.status})`;
|
|
||||||
try {
|
|
||||||
const errorData = await response.json();
|
|
||||||
console.error('회원 탈퇴 API 오류 응답:', errorData);
|
|
||||||
if (errorData.error) {
|
|
||||||
errorMessage = errorData.error;
|
|
||||||
} else if (errorData.message) {
|
|
||||||
errorMessage = errorData.message;
|
|
||||||
} else if (errorData.errorMessage) {
|
|
||||||
errorMessage = errorData.errorMessage;
|
|
||||||
} else if (response.statusText) {
|
|
||||||
errorMessage = `${response.statusText} (${response.status})`;
|
|
||||||
}
|
|
||||||
} catch (parseError) {
|
|
||||||
console.error('응답 파싱 오류:', parseError);
|
|
||||||
if (response.statusText) {
|
|
||||||
errorMessage = `${response.statusText} (${response.status})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.error('회원 탈퇴 실패:', errorMessage, '상태 코드:', response.status);
|
|
||||||
alert(errorMessage);
|
|
||||||
setIsLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 성공 시 토큰 제거 및 로그인 페이지로 이동
|
// 성공 시 토큰 제거 및 로그인 페이지로 이동
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import ChangePasswordModal from "../ChangePasswordModal";
|
|||||||
import PasswordChangeDoneModal from "../PasswordChangeDoneModal";
|
import PasswordChangeDoneModal from "../PasswordChangeDoneModal";
|
||||||
import AccountDeleteModal from "../AccountDeleteModal";
|
import AccountDeleteModal from "../AccountDeleteModal";
|
||||||
import MenuAccountOption from "@/app/menu/account/MenuAccountOption";
|
import MenuAccountOption from "@/app/menu/account/MenuAccountOption";
|
||||||
|
import apiService from "@/app/lib/apiService";
|
||||||
|
|
||||||
type VerificationState = 'initial' | 'sent' | 'verified' | 'failed' | 'changed';
|
type VerificationState = 'initial' | 'sent' | 'verified' | 'failed' | 'changed';
|
||||||
|
|
||||||
@@ -51,19 +52,8 @@ export default function AccountPage() {
|
|||||||
localStorage.setItem('token', cookieToken);
|
localStorage.setItem('token', cookieToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
const response = await apiService.getCurrentUser();
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/auth/me`
|
|
||||||
: 'https://hrdi.coconutmeet.net/auth/me';
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(token && { Authorization: `Bearer ${token}` }),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
// 토큰이 만료되었거나 유효하지 않은 경우
|
// 토큰이 만료되었거나 유효하지 않은 경우
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
@@ -72,17 +62,9 @@ export default function AccountPage() {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let errorMessage = `사용자 정보 조회 실패 (${response.status})`;
|
|
||||||
try {
|
if (response.status !== 200) {
|
||||||
const errorData = await response.json();
|
const errorMessage = response.message || `사용자 정보 조회 실패 (${response.status})`;
|
||||||
if (errorData.error) {
|
|
||||||
errorMessage = errorData.error;
|
|
||||||
} else if (errorData.message) {
|
|
||||||
errorMessage = errorData.message;
|
|
||||||
}
|
|
||||||
} catch (parseError) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
console.error('사용자 정보 조회 실패:', errorMessage);
|
console.error('사용자 정보 조회 실패:', errorMessage);
|
||||||
if (isMounted) {
|
if (isMounted) {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -90,7 +72,7 @@ export default function AccountPage() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = response.data;
|
||||||
if (isMounted) {
|
if (isMounted) {
|
||||||
setUserInfo(data);
|
setUserInfo(data);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -191,35 +173,7 @@ export default function AccountPage() {
|
|||||||
onClose={() => setDeleteOpen(false)}
|
onClose={() => setDeleteOpen(false)}
|
||||||
onConfirm={async () => {
|
onConfirm={async () => {
|
||||||
try {
|
try {
|
||||||
const token = localStorage.getItem('token');
|
await apiService.deleteAccount();
|
||||||
const response = await fetch('https://hrdi.coconutmeet.net/auth/delete/me', {
|
|
||||||
method: 'DELETE',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
...(token && { Authorization: `Bearer ${token}` }),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
let errorMessage = `회원 탈퇴 실패 (${response.status})`;
|
|
||||||
try {
|
|
||||||
const errorData = await response.json();
|
|
||||||
if (errorData.error) {
|
|
||||||
errorMessage = errorData.error;
|
|
||||||
} else if (errorData.message) {
|
|
||||||
errorMessage = errorData.message;
|
|
||||||
} else if (response.statusText) {
|
|
||||||
errorMessage = `${response.statusText} (${response.status})`;
|
|
||||||
}
|
|
||||||
} catch (parseError) {
|
|
||||||
if (response.statusText) {
|
|
||||||
errorMessage = `${response.statusText} (${response.status})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.error('회원 탈퇴 실패:', errorMessage);
|
|
||||||
alert(errorMessage);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 성공 시 토큰 제거 및 로그인 페이지로 이동
|
// 성공 시 토큰 제거 및 로그인 페이지로 이동
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import MainLogoSvg from './svgs/mainlogosvg';
|
import MainLogoSvg from './svgs/mainlogosvg';
|
||||||
|
import apiService from './lib/apiService';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -133,23 +134,13 @@ export default function Home() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL
|
const response = await apiService.getCurrentUser();
|
||||||
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/auth/me`
|
|
||||||
: 'https://hrdi.coconutmeet.net/auth/me';
|
|
||||||
|
|
||||||
const response = await fetch(apiUrl, {
|
if (response.status !== 200) {
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = response.data;
|
||||||
|
|
||||||
if (isMounted) {
|
if (isMounted) {
|
||||||
// 사용자 권한 확인
|
// 사용자 권한 확인
|
||||||
|
|||||||
Reference in New Issue
Block a user