diff --git a/app/mylecture/page.tsx b/app/mylecture/page.tsx new file mode 100644 index 0000000..6eb221b --- /dev/null +++ b/app/mylecture/page.tsx @@ -0,0 +1,367 @@ +"use client"; + +import { useEffect, useState } from 'react'; +import { useRouter } from 'next/navigation'; +import LoginPage from '../login/page'; +import Image from 'next/image'; +import logo from '../logo.svg'; +import RadioOff from '../../public/svg/radio_off'; +import RadioOn from '../../public/svg/radio_on'; + +const imgImage2 = "http://localhost:3845/assets/89fda8e949171025b1232bae70fc9d442e4e70c8.png"; +const imgLine2 = "http://localhost:3845/assets/6ee8cf4ebb6bc2adb14aab8c9940b3002c20af35.svg"; + +type CourseStatus = 'all' | 'completed' | 'in-progress'; + +interface Course { + id: number; + title: string; + progress: number; + score: number; + maxScore: number; + status: 'in-progress' | 'completed' | 'not-started'; +} + +export default function MyLecturePage() { + const router = useRouter(); + const [isLoggedIn, setIsLoggedIn] = useState(false); + const [isLoading, setIsLoading] = useState(true); + const [filter, setFilter] = useState('all'); + + // 샘플 강좌 데이터 + const [courses] = useState([ + { + id: 1, + title: '원자로 기본 원리와 주료 계동 원리', + progress: 10, + score: 0, + maxScore: 100, + status: 'in-progress', + }, + { + id: 2, + title: '핵연료 제조 공정 및 특성', + progress: 10, + score: 0, + maxScore: 100, + status: 'in-progress', + }, + { + id: 3, + title: '핵분열과 핵연료 주기 이해', + progress: 10, + score: 0, + maxScore: 100, + status: 'completed', + }, + { + id: 4, + title: '핵연료 성능 평가와 열수력 해석', + progress: 10, + score: 0, + maxScore: 100, + status: 'not-started', + }, + ]); + + useEffect(() => { + // 로그인 상태 확인 + const loginStatus = localStorage.getItem('isLoggedIn') === 'true'; + setIsLoggedIn(loginStatus); + setIsLoading(false); + }, []); + + if (isLoading) { + return null; // 로딩 중 + } + + // 로그인되지 않았으면 로그인 페이지 표시 + if (!isLoggedIn) { + return ; + } + + // 필터에 따른 강좌 필터링 + const filteredCourses = courses.filter((course) => { + if (filter === 'all') return true; + if (filter === 'completed') return course.status === 'completed'; + if (filter === 'in-progress') return course.status === 'in-progress'; + return true; + }); + + return ( +
+ {/* 헤더 */} +
+
+ {/* 로고 */} +
+
+ +
+
+ {/* 메뉴 */} +
+
+
+

+ 교육 과정 목록 +

+
+
+
+
+

+ 학습 자료실 +

+
+
+
+
+

+ 공지사항 +

+
+
+
+
+ {/* 사용자 메뉴 */} +
+
+

+ 내 강좌실 +

+
+ +
+
+ + {/* 구분선 */} +
+
+ +
+
+ + {/* 사이드바 */} +
+
+ + + + +
+
+ + {/* 메인 콘텐츠 - 내 강좌실 */} +
+ {/* 필터 섹션 */} +
+
+
+

+ 수강 중인 강좌 +

+
+
+ + + +
+
+
+ + {/* 강좌 리스트 */} +
+ {filteredCourses.map((course, index) => ( +
+
+ {/* 썸네일 */} +
+

+ 강좌 관련 썸네일 +

+
+ {/* 강좌 정보 */} +
+
+
+

+ {course.title} +

+

+ 진도율: {course.progress}% +

+

+ 점수: {course.score}점 / {course.maxScore}점 +

+
+ {/* 액션 버튼들 */} +
+ {/* 상태 표시 */} +
+

+ {course.status === 'in-progress' && '수강중'} + {course.status === 'completed' && '수강 완료'} + {course.status === 'not-started' && '수강 전'} +

+
+ {/* 수강 취소 버튼 */} + {course.status !== 'completed' && ( + + )} + {/* 이어서 수강 / 수강하기 버튼 */} + {course.status === 'in-progress' && ( + + )} + {course.status === 'not-started' && ( + + )} + {course.status === 'completed' && ( + + )} +
+
+
+
+ {/* 구분선 */} + {index < filteredCourses.length - 1 && ( +
+ )} +
+ ))} +
+
+ + {/* 푸터 */} +
+
+ {/* 로고 */} +
+
+ +
+
+ {/* 푸터 정보 */} +
+
+
+

+ 이용 약관 +

+
+
+

+ 개인정보처리방침 +

+
+
+

+ 고객센터 +

+
+
+
+

+ (12345) 서울특별시 광진구 구의동 123-12(구의타워1) +

+

+ 문의: 1234-1234 (평일 09:00 ~ 18:00) +

+

+ 이메일: qwer1234@go.or.kr +

+
+
+
+
+
+ ); +} + diff --git a/app/register/page.tsx b/app/register/page.tsx index 4c59f0e..5ac251a 100644 --- a/app/register/page.tsx +++ b/app/register/page.tsx @@ -7,6 +7,7 @@ import RadioOff from '../../public/svg/radio_off'; import RadioOn from '../../public/svg/radio_on'; import CheckOff from '../../public/svg/check_off'; import CheckOn from '../../public/svg/check_on'; +import ChevronSmall from '../../public/svg/chevron_small'; const imgRiCheckboxCircleLine = "http://localhost:3845/assets/e4c498605e2559d2764a3112ae9a9019e6ad798e.svg"; const imgFormkitRadio = "http://localhost:3845/assets/ea30a9a80d95ced4bfb1174d3a8475a4a1dbbabb.svg"; @@ -46,6 +47,7 @@ export default function RegisterPage() { const [isVerificationSent, setIsVerificationSent] = useState(false); const [isVerificationComplete, setIsVerificationComplete] = useState(false); const [verificationError, setVerificationError] = useState(''); + const [activeSelect, setActiveSelect] = useState(null); const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target; @@ -66,6 +68,32 @@ export default function RegisterPage() { setVerificationCode(''); setIsVerificationComplete(false); } + // 비밀번호 확인 실시간 검증 + if (name === 'passwordConfirm' && value && formData.password && value !== formData.password) { + setErrors((prev) => ({ + ...prev, + passwordConfirm: '비밀번호와 일치하지 않아요.', + })); + } else if (name === 'passwordConfirm' && value && formData.password && value === formData.password) { + setErrors((prev) => ({ + ...prev, + passwordConfirm: '', + })); + } + // 비밀번호가 변경되면 비밀번호 확인도 다시 검증 + if (name === 'password' && formData.passwordConfirm) { + if (formData.passwordConfirm !== value) { + setErrors((prev) => ({ + ...prev, + passwordConfirm: '비밀번호와 일치하지 않아요.', + })); + } else { + setErrors((prev) => ({ + ...prev, + passwordConfirm: '', + })); + } + } }; const handlePhoneChange = (e: React.ChangeEvent) => { @@ -258,7 +286,7 @@ export default function RegisterPage() { name="name" value={formData.name} onChange={handleChange} - className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border border-[#b9b9b9] placeholder:text-[#b9b9b9] bg-white ${errors.name ? 'border-[#E85D5D] text-[#E85D5D]' : 'text-[#515151]'}`} + className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border placeholder:text-[#b9b9b9] bg-white focus:border-[#1669CA] focus:outline-none ${errors.name ? 'border-[#E85D5D] text-[#E85D5D]' : 'border-[#b9b9b9] text-[#515151]'}`} placeholder="이름을 입력해 주세요." />
@@ -279,7 +307,7 @@ export default function RegisterPage() { value={formData.phone} onChange={handlePhoneChange} maxLength={11} - className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border border-[#b9b9b9] placeholder:text-[#b9b9b9] bg-white ${errors.phone ? 'border-[#E85D5D] text-[#E85D5D]' : 'text-[#515151]'}`} + className={`flex-1 h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border placeholder:text-[#b9b9b9] bg-white focus:border-[#1669CA] focus:outline-none ${errors.phone ? 'border-[#E85D5D] text-[#E85D5D]' : 'border-[#b9b9b9] text-[#515151]'}`} placeholder="-없이 입력해 주세요." /> @@ -299,7 +327,7 @@ export default function RegisterPage() { name="email" value={formData.email} onChange={handleChange} - className={`h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border border-[#b9b9b9] placeholder:text-[#b9b9b9] bg-white w-[401px] ${errors.email ? 'border-[#E85D5D] text-[#E85D5D]' : 'text-[#515151]'}`} + className={`h-[42px] px-[10px] text-[18px] font-medium rounded-[8px] border placeholder:text-[#b9b9b9] bg-white w-[401px] focus:border-[#1669CA] focus:outline-none ${errors.email ? 'border-[#E85D5D] text-[#E85D5D]' : 'border-[#b9b9b9] text-[#515151]'}`} placeholder="이메일을 입력해 주세요." />