diff --git a/src/app/NavBar.tsx b/src/app/NavBar.tsx index 1083d1f..e999dfa 100644 --- a/src/app/NavBar.tsx +++ b/src/app/NavBar.tsx @@ -12,15 +12,23 @@ const NAV_ITEMS = [ { label: "공지사항", href: "/notices" }, ]; +const INSTRUCTOR_NAV_ITEMS = [ + { label: "강좌 현황", href: "/admin/courses" }, + { label: "학습 자료실", href: "/admin/resources" }, + { label: "공지사항", href: "/admin/notices" }, +]; + export default function NavBar() { const pathname = usePathname(); const router = useRouter(); const [isUserMenuOpen, setIsUserMenuOpen] = useState(false); const [userName, setUserName] = useState(''); + const [userRole, setUserRole] = useState(''); const userMenuRef = useRef(null); const userButtonRef = useRef(null); const hideCenterNav = /^\/[^/]+\/review$/.test(pathname); const isAdminPage = pathname.startsWith('/admin'); + const isInstructorPage = pathname === '/instructor'; // 사용자 정보 가져오기 및 비활성화 계정 체크 useEffect(() => { @@ -86,8 +94,12 @@ export default function NavBar() { return; } - if (isMounted && data.name) { - setUserName(data.name); + if (isMounted) { + const role = data.role || data.userRole || ''; + setUserRole(role); + if (data.name) { + setUserName(data.name); + } } } catch (error) { console.error('사용자 정보 조회 오류:', error); @@ -129,11 +141,30 @@ export default function NavBar() {
- + XR LMS - {!hideCenterNav && !isAdminPage && ( + {!hideCenterNav && !isAdminPage && isInstructorPage && ( + + )} + {!hideCenterNav && !isAdminPage && !isInstructorPage && (
- {isAdminPage ? ( + {(isAdminPage || isInstructorPage) ? ( <> - - 내 정보 - + {isUserMenuOpen && ( +
+ +
+ )} ) : ( <> diff --git a/src/app/instructor/page.tsx b/src/app/instructor/page.tsx new file mode 100644 index 0000000..5bed73c --- /dev/null +++ b/src/app/instructor/page.tsx @@ -0,0 +1,355 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { useRouter } from 'next/navigation'; +import Link from 'next/link'; +import MainLogoSvg from '../svgs/mainlogosvg'; +import ChevronDownSvg from '../svgs/chevrondownsvg'; + +// 아이콘 컴포넌트들 +function BookIcon({ className }: { className?: string }) { + return ( + + + + + ); +} + +function DocumentIcon({ className }: { className?: string }) { + return ( + + + + + + + + ); +} + +function CheckCircleIcon({ className }: { className?: string }) { + return ( + + + + + ); +} + +function UserIcon({ className }: { className?: string }) { + return ( + + + + + ); +} + +function ChevronRightIcon({ className }: { className?: string }) { + return ( + + + + ); +} + +type Activity = { + id: string; + userName: string; + message: string; + timestamp: string; +}; + +export default function InstructorPage() { + const router = useRouter(); + const [userName, setUserName] = useState(''); + const [userRole, setUserRole] = useState(''); + const [totalCourses, setTotalCourses] = useState(5); + const [submissionStatus, setSubmissionStatus] = useState<{ current: number; total: number }>({ current: 10, total: 50 }); + const [completionStatus, setCompletionStatus] = useState<{ current: number; total: number }>({ current: 14, total: 50 }); + const [activities, setActivities] = useState([ + { id: '1', userName: '김하늘', message: '{강좌명} 문제를 제출했습니다.', timestamp: '2025-12-12 14:44' }, + { id: '2', userName: '김하늘', message: '{강좌명} 문제를 제출했습니다.', timestamp: '2025-12-12 14:44' }, + { id: '3', userName: '김하늘', message: '모든 강좌를 수강했습니다.', timestamp: '2025-12-12 14:44' }, + ]); + + // 사용자 정보 가져오기 + useEffect(() => { + let isMounted = true; + + async function fetchUserInfo() { + try { + const localStorageToken = localStorage.getItem('token'); + const cookieToken = document.cookie + .split('; ') + .find(row => row.startsWith('token=')) + ?.split('=')[1]; + + const token = localStorageToken || cookieToken; + + if (!token) { + router.push('/login'); + return; + } + + const apiUrl = process.env.NEXT_PUBLIC_API_BASE_URL + ? `${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) { + localStorage.removeItem('token'); + document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; + if (isMounted) { + router.push('/login'); + } + } + return; + } + + const data = await response.json(); + + if (isMounted) { + const role = data.role || data.userRole || ''; + setUserRole(role); + + // admin이 아니면 접근 불가 + if (role !== 'ADMIN' && role !== 'admin') { + router.push('/'); + return; + } + + if (data.name) { + setUserName(data.name); + } + } + } catch (error) { + console.error('사용자 정보 조회 오류:', error); + if (isMounted) { + router.push('/login'); + } + } + } + + fetchUserInfo(); + + return () => { + isMounted = false; + }; + }, [router]); + + return ( +
+
+
+ {/* 강좌별 상세 내역 섹션 */} +
+
+

+ 강좌별 상세 내역 +

+ + 전체보기 + + +
+
+
+ {/* 총 강좌 수 카드 */} +
+
+ +
+
+

+ 총 강좌 수 +

+

+ {totalCourses} +

+
+
+ + {/* 학습자 문제 제출 현황 카드 */} +
+
+ +
+
+

+ 학습자 문제 제출 현황 +

+

+ {submissionStatus.current} / {submissionStatus.total} +

+
+
+ + {/* 학습자 수료 현황 카드 */} +
+
+ +
+
+

+ 학습자 수료 현황 +

+

+ {completionStatus.current} / {completionStatus.total} +

+
+
+
+
+
+ + {/* 최근 학습자 활동 섹션 */} +
+
+

+ 최근 학습자 활동 +

+
+
+
+ {activities.map((activity) => ( +
+
+ +
+
+
+ {activity.userName} + {activity.message} +
+
+

+ {activity.timestamp} +

+
+ ))} +
+
+
+
+
+
+ ); +} +