교육과정 관리 등록

This commit is contained in:
2025-11-27 21:31:18 +09:00
parent b1e2f6012c
commit 0963cfdf5b
5 changed files with 545 additions and 185 deletions

View File

@@ -1,17 +1,38 @@
'use client';
import { useState, useMemo } from "react";
import { useState, useMemo, useEffect } from "react";
import AdminSidebar from "@/app/components/AdminSidebar";
import CourseRegistrationModal from "./CourseRegistrationModal";
import ChevronDownSvg from "@/app/svgs/chevrondownsvg";
import { MOCK_COURSES, MOCK_CURRENT_USER, type Course } from "./mockData";
import { getCourses, type Course } from "./mockData";
export default function AdminCoursesPage() {
const [courses, setCourses] = useState<Course[]>(MOCK_COURSES);
const [courses, setCourses] = useState<Course[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [isModalOpen, setIsModalOpen] = useState(false);
const [editingCourse, setEditingCourse] = useState<Course | null>(null);
const [currentPage, setCurrentPage] = useState(1);
const [showToast, setShowToast] = useState(false);
// API에서 과목 리스트 가져오기
useEffect(() => {
async function fetchCourses() {
try {
setIsLoading(true);
const data = await getCourses();
console.log('📋 [AdminCoursesPage] 받은 데이터:', data);
console.log('📋 [AdminCoursesPage] 데이터 개수:', data.length);
setCourses(data);
} catch (error) {
console.error('과목 리스트 로드 오류:', error);
setCourses([]);
} finally {
setIsLoading(false);
}
}
fetchCourses();
}, []);
const totalCount = useMemo(() => courses.length, [courses]);
@@ -30,28 +51,36 @@ export default function AdminCoursesPage() {
return sortedCourses.slice(startIndex, endIndex);
}, [sortedCourses, currentPage]);
const handleSaveCourse = (courseName: string, instructorName: string) => {
const handleSaveCourse = async (courseName: string, instructorName: string) => {
if (editingCourse) {
// 수정 모드
// 수정 모드 - TODO: API 호출로 변경 필요
setCourses(prev => prev.map(course =>
course.id === editingCourse.id
? { ...course, courseName, instructorName }
: course
));
} else {
// 등록 모드
// 등록 모드 - TODO: API 호출로 변경 필요
const newCourse: Course = {
id: String(Date.now()),
courseName,
instructorName,
createdAt: new Date().toISOString().split('T')[0],
createdBy: MOCK_CURRENT_USER,
createdBy: '', // API에서 받아오도록 변경 필요
hasLessons: false, // 기본값: 미포함
};
setCourses(prev => [...prev, newCourse]);
}
setIsModalOpen(false);
setEditingCourse(null);
// 저장 후 리스트 새로고침
try {
const data = await getCourses();
setCourses(data);
} catch (error) {
console.error('과목 리스트 새로고침 오류:', error);
}
};
const handleRowClick = (course: Course) => {
@@ -69,14 +98,23 @@ export default function AdminCoursesPage() {
setIsModalOpen(true);
};
const handleDeleteCourse = () => {
const handleDeleteCourse = async () => {
if (editingCourse) {
// TODO: API 호출로 삭제 처리 필요
setCourses(prev => prev.filter(course => course.id !== editingCourse.id));
setEditingCourse(null);
setShowToast(true);
setTimeout(() => {
setShowToast(false);
}, 3000);
// 삭제 후 리스트 새로고침
try {
const data = await getCourses();
setCourses(data);
} catch (error) {
console.error('과목 리스트 새로고침 오류:', error);
}
}
};
@@ -115,7 +153,13 @@ export default function AdminCoursesPage() {
{/* 콘텐츠 영역 */}
<div className="flex-1 pt-2 flex flex-col">
{courses.length === 0 ? (
{isLoading ? (
<div className="rounded-lg border border-[#dee1e6] bg-white min-h-[400px] flex items-center justify-center">
<p className="text-[16px] font-medium leading-[1.5] text-[#333c47] text-center">
...
</p>
</div>
) : courses.length === 0 ? (
<div className="rounded-lg border border-[#dee1e6] bg-white min-h-[400px] flex items-center justify-center">
<p className="text-[16px] font-medium leading-[1.5] text-[#333c47] text-center">
.
@@ -128,18 +172,16 @@ export default function AdminCoursesPage() {
<div className="w-full rounded-[8px] border border-[#dee1e6] overflow-visible">
<table className="min-w-full border-collapse">
<colgroup>
<col />
<col />
<col style={{ width: 140 }} />
<col />
<col style={{ width: 120 }} />
<col style={{ width: '40%' }} />
<col style={{ width: '25%' }} />
<col style={{ width: '20%' }} />
<col style={{ width: '15%' }} />
</colgroup>
<thead>
<tr className="h-12 bg-gray-50 text-left">
<th className="border-r border-[#dee1e6] px-4 text-[14px] font-semibold leading-[1.5] text-[#4c5561]"></th>
<th className="border-r border-[#dee1e6] px-4 text-[14px] font-semibold leading-[1.5] text-[#4c5561]"></th>
<th className="border-r border-[#dee1e6] px-4 text-[14px] font-semibold leading-[1.5] text-[#4c5561]"></th>
<th className="border-r border-[#dee1e6] px-4 text-[14px] font-semibold leading-[1.5] text-[#4c5561]"></th>
<th className="px-4 text-center text-[14px] font-semibold leading-[1.5] text-[#4c5561]"></th>
</tr>
</thead>
@@ -159,9 +201,6 @@ export default function AdminCoursesPage() {
<td className="border-t border-r border-[#dee1e6] px-4 text-[13px] leading-[1.5] text-[#1b2027] whitespace-nowrap">
{course.createdAt}
</td>
<td className="border-t border-r border-[#dee1e6] px-4 text-[13px] leading-[1.5] text-[#1b2027] whitespace-nowrap">
{course.createdBy}
</td>
<td className="border-t border-[#dee1e6] px-4 text-left text-[13px] leading-[1.5] text-[#1b2027] whitespace-nowrap">
{course.hasLessons ? (
<div className="inline-flex items-center justify-center h-[20px] px-[4px] rounded-[4px] bg-[#ecf0ff]">