From fd52489416fbd6633b65442f13265c09c8627c1e Mon Sep 17 00:00:00 2001 From: jhynsoo Date: Mon, 5 Aug 2024 15:55:50 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=EA=B0=95=EC=82=AC=EB=A7=8C=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EA=B3=B5=EC=9C=A0=20=ED=95=A0=20=EC=88=98?= =?UTF-8?q?=20=EC=9E=88=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/LiveRoom/LiveRoom.jsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/LiveRoom/LiveRoom.jsx b/frontend/src/components/LiveRoom/LiveRoom.jsx index 6d52b2a..5295de5 100644 --- a/frontend/src/components/LiveRoom/LiveRoom.jsx +++ b/frontend/src/components/LiveRoom/LiveRoom.jsx @@ -15,17 +15,19 @@ import { useRoomInfo, useTracks, useParticipants, + useLocalParticipant, } from '@livekit/components-react'; import { RoomEvent, Track } from 'livekit-client'; -import { useEffect, useRef } from 'react'; +import { useEffect, useRef, useState } from 'react'; import ChatRoom from '../ChatRoom/ChatRoom'; export default function LiveRoom() { const lastAutoFocusedScreenShareTrack = useRef(null); + const [role, setRole] = useState(null); - // get livekit identity const room = useRoomInfo(); const participants = useParticipants(); + const { localParticipant } = useLocalParticipant(); const tracks = useTracks( [ @@ -43,6 +45,16 @@ export default function LiveRoom() { const focusTrack = usePinnedTracks(layoutContext)?.[0]; const carouselTracks = tracks.filter((track) => !isEqualTrackRef(track, focusTrack)); + useEffect(() => { + try { + const role = JSON.parse(localParticipant.identity).role; + + setRole(role); + } catch (_) { + return; + } + }, [localParticipant.identity]); + useEffect(() => { if ( screenShareTracks.some((track) => track.publication.isSubscribed) && @@ -103,7 +115,7 @@ export default function LiveRoom() { )} - + From 7a5576613f9e3dc9538dca7e8e2bc6dba6d62cbd Mon Sep 17 00:00:00 2001 From: minwucho Date: Mon, 5 Aug 2024 16:25:32 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=EA=B0=95=EC=9D=98=20=EC=88=98?= =?UTF-8?q?=EA=B0=95=20=EC=8B=A0=EC=B2=AD=20=EC=A3=BC=EA=B3=A0=20=EB=B0=9B?= =?UTF-8?q?=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/Router.jsx | 5 +++ .../src/components/Layout/LectureLayout.jsx | 1 + .../LectureEnroll/LectureEnroll.jsx | 28 +++++++++++++ .../LectureEnroll/LectureEnroll.module.css | 13 ++++++ .../src/components/LectureEnroll/index.js | 1 + frontend/src/hooks/api/useLectureEnroll.js | 10 +++++ .../src/hooks/api/useLectureEnrollAccept.js | 9 +++++ .../src/hooks/api/useLectureEnrollCancel.js | 9 +++++ .../LectureEnrollPage/LectureEnrollPage.jsx | 40 +++++++++++++++++++ frontend/src/pages/LectureEnrollPage/index.js | 1 + .../pages/LectureInfoPage/LectureInfoPage.jsx | 4 +- 11 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 frontend/src/components/LectureEnroll/LectureEnroll.jsx create mode 100644 frontend/src/components/LectureEnroll/LectureEnroll.module.css create mode 100644 frontend/src/components/LectureEnroll/index.js create mode 100644 frontend/src/hooks/api/useLectureEnroll.js create mode 100644 frontend/src/hooks/api/useLectureEnrollAccept.js create mode 100644 frontend/src/hooks/api/useLectureEnrollCancel.js create mode 100644 frontend/src/pages/LectureEnrollPage/LectureEnrollPage.jsx create mode 100644 frontend/src/pages/LectureEnrollPage/index.js diff --git a/frontend/src/Router.jsx b/frontend/src/Router.jsx index 440fbf1..31c0563 100644 --- a/frontend/src/Router.jsx +++ b/frontend/src/Router.jsx @@ -30,6 +30,7 @@ const LectureEditPage = lazy(async () => await import('./pages/LectureEditPage') const QuizsetListPage = lazy(async () => await import('./pages/QuizsetListPage')); const QuizsetWritePage = lazy(async () => await import('./pages/QuizsetWritePage')); const QuizsetDetailPage = lazy(async () => await import('./pages/QuizsetDetailPage')); +const LectureEnrollPage = lazy(async () => await import('./pages/LectureEnrollPage')); const router = createBrowserRouter([ { @@ -148,6 +149,10 @@ const router = createBrowserRouter([ }, ], }, + { + path: 'enroll', + element: , + }, ], }, { diff --git a/frontend/src/components/Layout/LectureLayout.jsx b/frontend/src/components/Layout/LectureLayout.jsx index 64eaeb3..be35438 100644 --- a/frontend/src/components/Layout/LectureLayout.jsx +++ b/frontend/src/components/Layout/LectureLayout.jsx @@ -52,6 +52,7 @@ export default function LectureLayout() { Q&A 수업자료 퀴즈 + {userType === 'teacher' && 수강신청관리} {userType === 'teacher' && ( diff --git a/frontend/src/components/LectureEnroll/LectureEnroll.jsx b/frontend/src/components/LectureEnroll/LectureEnroll.jsx new file mode 100644 index 0000000..5fc5f92 --- /dev/null +++ b/frontend/src/components/LectureEnroll/LectureEnroll.jsx @@ -0,0 +1,28 @@ +import styles from './LectureEnroll.module.css'; +import { useLectureEnrollCancel } from '../../hooks/api/useLectureEnrollCancel'; +import { useLectureEnrollAccept } from '../../hooks/api/useLectureEnrollAccept'; + +export default function LectureEnroll({ userName, enrollid, onDelete }) { + const { lectureEnrollCancel } = useLectureEnrollCancel(); + const { lectureEnrollAccept } = useLectureEnrollAccept(); + + const handleAccept = async (e) => { + e.preventDefault(); + await lectureEnrollAccept(enrollid); + onDelete(enrollid); + }; + + const handleCancel = async (e) => { + e.preventDefault(); + await lectureEnrollCancel(enrollid); + onDelete(enrollid); + }; + + return ( +
+

{userName}

+ + +
+ ); +} diff --git a/frontend/src/components/LectureEnroll/LectureEnroll.module.css b/frontend/src/components/LectureEnroll/LectureEnroll.module.css new file mode 100644 index 0000000..76d5110 --- /dev/null +++ b/frontend/src/components/LectureEnroll/LectureEnroll.module.css @@ -0,0 +1,13 @@ +.enrollLink { + border-radius: 8px; + width: 100%; + display: flex; + justify-content: space-between; + box-sizing: border-box; + padding: 16px 20px; + transition: background-color 0.25s; +} + +.enrollLink:hover { + background-color: var(--background-secondary); +} diff --git a/frontend/src/components/LectureEnroll/index.js b/frontend/src/components/LectureEnroll/index.js new file mode 100644 index 0000000..6686f42 --- /dev/null +++ b/frontend/src/components/LectureEnroll/index.js @@ -0,0 +1 @@ +export { default as LectureEnroll } from './LectureEnroll'; diff --git a/frontend/src/hooks/api/useLectureEnroll.js b/frontend/src/hooks/api/useLectureEnroll.js new file mode 100644 index 0000000..ced34b7 --- /dev/null +++ b/frontend/src/hooks/api/useLectureEnroll.js @@ -0,0 +1,10 @@ +import { useSuspenseQuery } from '@tanstack/react-query'; +import instance from '../../utils/axios/instance'; +import { API_URL } from '../../constants'; + +export function useLectureEnroll(lectureId) { + return useSuspenseQuery({ + queryKey: ['lecturelist', lectureId], + queryFn: () => instance.get(`${API_URL}/registration/${lectureId}`), + }); +} diff --git a/frontend/src/hooks/api/useLectureEnrollAccept.js b/frontend/src/hooks/api/useLectureEnrollAccept.js new file mode 100644 index 0000000..b52a9ca --- /dev/null +++ b/frontend/src/hooks/api/useLectureEnrollAccept.js @@ -0,0 +1,9 @@ +import instance from '../../utils/axios/instance'; +import { API_URL } from '../../constants'; + +export function useLectureEnrollAccept() { + const lectureEnrollAccept = (enrollId) => { + return instance.put(`${API_URL}/registration/${enrollId}`); + }; + return { lectureEnrollAccept }; +} diff --git a/frontend/src/hooks/api/useLectureEnrollCancel.js b/frontend/src/hooks/api/useLectureEnrollCancel.js new file mode 100644 index 0000000..6deb24a --- /dev/null +++ b/frontend/src/hooks/api/useLectureEnrollCancel.js @@ -0,0 +1,9 @@ +import instance from '../../utils/axios/instance'; +import { API_URL } from '../../constants'; + +export function useLectureEnrollCancel() { + const lectureEnrollCancel = (enrollId) => { + return instance.delete(`${API_URL}/registration/${enrollId}`); + }; + return { lectureEnrollCancel }; +} diff --git a/frontend/src/pages/LectureEnrollPage/LectureEnrollPage.jsx b/frontend/src/pages/LectureEnrollPage/LectureEnrollPage.jsx new file mode 100644 index 0000000..f5963eb --- /dev/null +++ b/frontend/src/pages/LectureEnrollPage/LectureEnrollPage.jsx @@ -0,0 +1,40 @@ +import ArticleBoard from '../../components/ArticleBoard/ArticleBoard'; +import LectureEnroll from '../../components/LectureEnroll/LectureEnroll'; +import { useParams } from 'react-router-dom'; +import { useLectureEnroll } from '../../hooks/api/useLectureEnroll'; +import { useState, useEffect } from 'react'; + +export default function QuestionListPage() { + const { lectureId } = useParams(); + const { data } = useLectureEnroll(lectureId); + const [lectures, setLectures] = useState([]); + + useEffect(() => { + if (data?.data) { + setLectures(data.data); + } + }, [data]); + + const handleDelete = async (enrollId) => { + setLectures(lectures.filter((lecture) => lecture.id !== enrollId)); + }; + + return ( + + {lectures.map?.((lecture) => ( + + ))} + + ); +} + +//FIXME: 이 페이지에서 딱 처음 수강신청관리 페이지 들어오면 수강신청 관리용 강의들 안뜨는 문제 있음. +// FIXME: 그리고 왜 그런지는 모르겠는데 강의 목록이 뜨면 HEADER 부분 강의 이름이 안보임. diff --git a/frontend/src/pages/LectureEnrollPage/index.js b/frontend/src/pages/LectureEnrollPage/index.js new file mode 100644 index 0000000..5027442 --- /dev/null +++ b/frontend/src/pages/LectureEnrollPage/index.js @@ -0,0 +1 @@ +export { default } from './LectureEnrollPage'; diff --git a/frontend/src/pages/LectureInfoPage/LectureInfoPage.jsx b/frontend/src/pages/LectureInfoPage/LectureInfoPage.jsx index fd2dbcc..7a31b5b 100644 --- a/frontend/src/pages/LectureInfoPage/LectureInfoPage.jsx +++ b/frontend/src/pages/LectureInfoPage/LectureInfoPage.jsx @@ -25,7 +25,9 @@ export default function LectureInfoPage() { lectureRegister(lectureId) .then(() => { - navigate(`/lecture/${lectureId}`); + // navigate(`/lecture/${lectureId}`); + window.alert('강사가 수강신청 수락시 수업이 시작됩니다.'); + navigate('/'); }) .catch((err) => { console.log(err); From c52ee36ec561738618eed10db6efb4d601fee19c Mon Sep 17 00:00:00 2001 From: jhynsoo Date: Mon, 5 Aug 2024 17:17:05 +0900 Subject: [PATCH 3/6] =?UTF-8?q?design:=20=EB=82=B4=20=EA=B0=95=EC=9D=98=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/icons/compass.svg | 8 ++++++++ frontend/src/assets/icons/plus.svg | 5 +++++ frontend/src/components/ClassCard/ClassCard.jsx | 17 ++++++++++++----- .../components/ClassCard/ClassCard.module.css | 4 ++++ frontend/src/components/LiveRoom/LiveRoom.jsx | 5 ++++- .../src/components/SideBar/SideBar.module.css | 2 +- .../src/components/SideBar/SideLink.module.css | 1 - 7 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 frontend/src/assets/icons/compass.svg create mode 100644 frontend/src/assets/icons/plus.svg diff --git a/frontend/src/assets/icons/compass.svg b/frontend/src/assets/icons/compass.svg new file mode 100644 index 0000000..b71c924 --- /dev/null +++ b/frontend/src/assets/icons/compass.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/src/assets/icons/plus.svg b/frontend/src/assets/icons/plus.svg new file mode 100644 index 0000000..b51a170 --- /dev/null +++ b/frontend/src/assets/icons/plus.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/src/components/ClassCard/ClassCard.jsx b/frontend/src/components/ClassCard/ClassCard.jsx index 8a7f252..2691b29 100644 --- a/frontend/src/components/ClassCard/ClassCard.jsx +++ b/frontend/src/components/ClassCard/ClassCard.jsx @@ -1,5 +1,6 @@ import { Link } from 'react-router-dom'; import styles from './ClassCard.module.css'; +import CompassIcon from '/src/assets/icons/compass.svg?react'; export default function ClassCard({ img, path, children }) { return ( @@ -7,11 +8,17 @@ export default function ClassCard({ img, path, children }) { to={path} className={styles.card} > - 강의 이미지 + {img ? ( + 강의 이미지 + ) : ( +
+ +
+ )}
{children}
); diff --git a/frontend/src/components/ClassCard/ClassCard.module.css b/frontend/src/components/ClassCard/ClassCard.module.css index 1741799..ea3e80c 100644 --- a/frontend/src/components/ClassCard/ClassCard.module.css +++ b/frontend/src/components/ClassCard/ClassCard.module.css @@ -9,9 +9,13 @@ } .thumbnail { + display: flex; + justify-content: center; + align-items: center; width: 295px; height: 220px; border-radius: 20px; background-color: var(--background-secondary); + stroke: var(--text-color); box-sizing: border-box; } diff --git a/frontend/src/components/LiveRoom/LiveRoom.jsx b/frontend/src/components/LiveRoom/LiveRoom.jsx index 5295de5..38d94c6 100644 --- a/frontend/src/components/LiveRoom/LiveRoom.jsx +++ b/frontend/src/components/LiveRoom/LiveRoom.jsx @@ -115,7 +115,10 @@ export default function LiveRoom() { )} - + diff --git a/frontend/src/components/SideBar/SideBar.module.css b/frontend/src/components/SideBar/SideBar.module.css index 3f73801..3d9668b 100644 --- a/frontend/src/components/SideBar/SideBar.module.css +++ b/frontend/src/components/SideBar/SideBar.module.css @@ -18,7 +18,7 @@ .groupList { display: flex; flex-direction: column; - gap: 16px; + gap: 8px; list-style: none; padding: 0; margin: 0; diff --git a/frontend/src/components/SideBar/SideLink.module.css b/frontend/src/components/SideBar/SideLink.module.css index df232f1..3eec140 100644 --- a/frontend/src/components/SideBar/SideLink.module.css +++ b/frontend/src/components/SideBar/SideLink.module.css @@ -15,5 +15,4 @@ .active { font-weight: 700; - text-decoration: underline; } From aeecb835c536352ad6d978060b857fb3076b2999 Mon Sep 17 00:00:00 2001 From: jhynsoo Date: Mon, 5 Aug 2024 17:17:48 +0900 Subject: [PATCH 4/6] =?UTF-8?q?fix:=20useNotices=EA=B0=80=20suspense=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/api/useNotices.js | 4 ++-- .../pages/TeacherHomePage/TeacherHomePage.jsx | 16 ++++++++++---- .../TeacherHomePage.module.css | 21 +++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 frontend/src/pages/TeacherHomePage/TeacherHomePage.module.css diff --git a/frontend/src/hooks/api/useNotices.js b/frontend/src/hooks/api/useNotices.js index b6fd154..dd4b671 100644 --- a/frontend/src/hooks/api/useNotices.js +++ b/frontend/src/hooks/api/useNotices.js @@ -1,9 +1,9 @@ -import { useQuery } from '@tanstack/react-query'; +import { useSuspenseQuery } from '@tanstack/react-query'; import instance from '../../utils/axios/instance'; import { API_URL } from '../../constants'; export function useNotices(lectureId, page = 0) { - return useQuery({ + return useSuspenseQuery({ queryKey: ['noticelist', lectureId, page], queryFn: () => instance.get(`${API_URL}/board?lectureId=${lectureId}&category=announcement&pageNo=${page}`), }); diff --git a/frontend/src/pages/TeacherHomePage/TeacherHomePage.jsx b/frontend/src/pages/TeacherHomePage/TeacherHomePage.jsx index 0236ca9..cc730ec 100644 --- a/frontend/src/pages/TeacherHomePage/TeacherHomePage.jsx +++ b/frontend/src/pages/TeacherHomePage/TeacherHomePage.jsx @@ -1,17 +1,19 @@ +import styles from './TeacherHomePage.module.css'; +import { Link } from 'react-router-dom'; import { ClassCard } from '../../components/ClassCard'; import { ClassGrid } from '../../components/ClassGrid'; import { MaxWidthLayout } from '../../components/Layout'; import { useMyLectures } from '../../hooks/api/useMyLectures'; +import PlusIcon from '/src/assets/icons/plus.svg?react'; export default function TeacherHomePage() { const { data: myLectures } = useMyLectures(); const onGoingClasses = myLectures?.data ?? []; - console.log(onGoingClasses); - // TODO: 새 강의 만들기 스타일 추가, 추가 기능 필요시 추가 + return ( - {onGoingClasses.map?.((lecture) => ( + {onGoingClasses.map((lecture) => ( ))} - 새 강의 만들기 + + + 새 강의 만들기 + ); diff --git a/frontend/src/pages/TeacherHomePage/TeacherHomePage.module.css b/frontend/src/pages/TeacherHomePage/TeacherHomePage.module.css new file mode 100644 index 0000000..0e94798 --- /dev/null +++ b/frontend/src/pages/TeacherHomePage/TeacherHomePage.module.css @@ -0,0 +1,21 @@ +.add { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 20px; + margin-bottom: 32px; + background-color: var(--background); + color: var(--text-color); + stroke: var(--text-color); + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 1.4; + border-radius: 20px; + transition: background-color 0.2s ease; + + &:hover { + background-color: var(--background-secondary); + } +} From ad4952fec73dcf73d4cde266d8fe35fca78a4aee Mon Sep 17 00:00:00 2001 From: jhynsoo Date: Mon, 5 Aug 2024 17:18:29 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=EB=9D=BC=EC=9D=B4=EB=B8=8C=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B6=8C=ED=95=9C=20=EC=B2=B4?= =?UTF-8?q?=ED=81=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/LivePage/LivePage.jsx | 23 ++++++++++++----------- frontend/src/store/index.js | 2 -- frontend/src/store/liveSlice.js | 6 ------ 3 files changed, 12 insertions(+), 19 deletions(-) delete mode 100644 frontend/src/store/liveSlice.js diff --git a/frontend/src/pages/LivePage/LivePage.jsx b/frontend/src/pages/LivePage/LivePage.jsx index 5356bd2..2a12864 100644 --- a/frontend/src/pages/LivePage/LivePage.jsx +++ b/frontend/src/pages/LivePage/LivePage.jsx @@ -1,31 +1,29 @@ import { LiveRoom } from '../../components/LiveRoom'; import { useParams } from 'react-router-dom'; -import { useCallback, useEffect } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { LiveKitRoom } from '@livekit/components-react'; import instance from '../../utils/axios/instance'; import { API_URL, ROOM_URL } from '../../constants'; -import useBoundStore from '../../store'; import '@livekit/components-styles'; import LoadingIndicator from '../../components/LoadingIndicator.jsx/LoadingIndicator'; export default function LivePage() { const { roomId } = useParams(); + const [liveToken, setLiveToken] = useState(null); const generateToken = useCallback(async () => { await instance.post(`${API_URL}/video/makeroom/${roomId}`); - const { data } = await instance.post(`${API_URL}/video/joinroom/${roomId}`); + const { data } = await instance.post(`${API_URL}/video/joinroom/${roomId}`).catch(() => { + alert('방에 입장할 수 없습니다.'); + }); return data.token; }, [roomId]); - const liveToken = useBoundStore((state) => state.liveToken); - useEffect(() => { - if (!liveToken) { - generateToken().then((token) => { - useBoundStore.setState({ liveToken: token }); - }); - } - }, [generateToken, liveToken]); + generateToken().then((token) => { + setLiveToken(token); + }); + }, [generateToken]); return liveToken ? ( { + instance.post(`${API_URL}/video/deleteroom/${roomId}`).catch(() => {}); + }} > diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js index 7bf42e8..033afc3 100644 --- a/frontend/src/store/index.js +++ b/frontend/src/store/index.js @@ -3,7 +3,6 @@ import { userTypeSlice } from './userTypeSlice'; import { tokenSlice } from './tokenSlice'; import { userNameSlice } from './userNameSlice'; import { persist } from 'zustand/middleware'; -import { liveSlice } from './liveSlice'; const useBoundStore = create( persist( @@ -11,7 +10,6 @@ const useBoundStore = create( ...userTypeSlice(...a), ...tokenSlice(...a), ...userNameSlice(...a), - ...liveSlice(...a), }), { name: 'bound-store' } ) diff --git a/frontend/src/store/liveSlice.js b/frontend/src/store/liveSlice.js deleted file mode 100644 index 12e7014..0000000 --- a/frontend/src/store/liveSlice.js +++ /dev/null @@ -1,6 +0,0 @@ -export const liveSlice = (set) => ({ - liveToken: null, - setLiveToken: (liveToken) => set({ liveToken }), - participants: 0, - setParticipants: (participants) => set({ participants }), -}); From 4448a1114c740217d87d7362f46f54546840c2db Mon Sep 17 00:00:00 2001 From: jhynsoo Date: Mon, 5 Aug 2024 17:32:34 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20=EB=9D=BC=EC=9D=B4=EB=B8=8C=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20ux=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/Router.jsx | 2 +- frontend/src/components/Header/Header.jsx | 7 ++- frontend/src/components/Layout/index.js | 1 + .../LectureHeader/LectureHeader.jsx | 43 +++++++++++++------ .../LectureHeader/LectureHeader.module.css | 8 ++++ frontend/src/pages/LivePage/LivePage.jsx | 4 +- 6 files changed, 50 insertions(+), 15 deletions(-) diff --git a/frontend/src/Router.jsx b/frontend/src/Router.jsx index 94d80e9..529a465 100644 --- a/frontend/src/Router.jsx +++ b/frontend/src/Router.jsx @@ -7,8 +7,8 @@ import { lazy } from 'react'; import MyPageLayout from './components/Layout/MyPageLayout'; import LivePage from './pages/LivePage'; import ErrorPage from './pages/ErrorPage'; +import { LectureLayout } from './components/Layout'; -const LectureLayout = lazy(async () => await import('./components/Layout/LectureLayout')); const LearningLectureDetailPage = lazy(async () => await import('./pages/LearningLectureDetailPage')); const NoticeListPage = lazy(async () => await import('./pages/NoticeListPage')); const NoticeDetailPage = lazy(async () => await import('./pages/NoticeDetailPage')); diff --git a/frontend/src/components/Header/Header.jsx b/frontend/src/components/Header/Header.jsx index 8a720b8..0b75996 100644 --- a/frontend/src/components/Header/Header.jsx +++ b/frontend/src/components/Header/Header.jsx @@ -33,7 +33,12 @@ export default function Header() { 수강중인 강의
  • - live + + live +
    • diff --git a/frontend/src/components/Layout/index.js b/frontend/src/components/Layout/index.js index 06db1a9..7c1c222 100644 --- a/frontend/src/components/Layout/index.js +++ b/frontend/src/components/Layout/index.js @@ -1,3 +1,4 @@ export { default as PageLayout } from './PageLayout'; export { default as MaxWidthLayout } from './MaxWidthLayout'; export { default as LiveLayout } from './LiveLayout'; +export { default as LectureLayout } from './LectureLayout'; diff --git a/frontend/src/components/LectureHeader/LectureHeader.jsx b/frontend/src/components/LectureHeader/LectureHeader.jsx index fd8684a..f1a4257 100644 --- a/frontend/src/components/LectureHeader/LectureHeader.jsx +++ b/frontend/src/components/LectureHeader/LectureHeader.jsx @@ -1,35 +1,54 @@ +import { Link, useParams } from 'react-router-dom'; import styles from './LectureHeader.module.css'; import PlayIcon from '/src/assets/icons/play.svg?react'; +import CompassIcon from '/src/assets/icons/compass.svg?react'; +import UserIcon from '/src/assets/icons/user.svg?react'; export default function LectureHeader({ img, title, tutorImg, tutor, isLive = false }) { + const { lectureId } = useParams(); + return (
      - 강의 이미지 + {img ? ( + 강의 이미지 + ) : ( +
      + +
      + )}

      {title}

      - 강사 사진 + {tutorImg ? ( + 강사 사진 + ) : ( +
      + +
      + )}
      {tutor}
      {isLive ? ( - + ) : null}
      diff --git a/frontend/src/components/LectureHeader/LectureHeader.module.css b/frontend/src/components/LectureHeader/LectureHeader.module.css index 39165df..ee0889b 100644 --- a/frontend/src/components/LectureHeader/LectureHeader.module.css +++ b/frontend/src/components/LectureHeader/LectureHeader.module.css @@ -20,9 +20,13 @@ .thumbnail { flex-shrink: 0; + display: flex; + justify-content: center; + align-items: center; width: 120px; height: 120px; border-radius: 16px; + stroke: var(--text-color); border: 1px solid var(--border-color); } @@ -53,9 +57,13 @@ } .tutorImg { + display: flex; + justify-content: center; + align-items: center; width: 48px; height: 48px; border-radius: 50%; + stroke: var(--text-color-secondary); border: 1px solid var(--border-color); } diff --git a/frontend/src/pages/LivePage/LivePage.jsx b/frontend/src/pages/LivePage/LivePage.jsx index 2a12864..d209a8b 100644 --- a/frontend/src/pages/LivePage/LivePage.jsx +++ b/frontend/src/pages/LivePage/LivePage.jsx @@ -11,9 +11,10 @@ export default function LivePage() { const { roomId } = useParams(); const [liveToken, setLiveToken] = useState(null); const generateToken = useCallback(async () => { - await instance.post(`${API_URL}/video/makeroom/${roomId}`); + await instance.post(`${API_URL}/video/makeroom/${roomId}`).catch(() => {}); const { data } = await instance.post(`${API_URL}/video/joinroom/${roomId}`).catch(() => { alert('방에 입장할 수 없습니다.'); + window.close(); }); return data.token; @@ -33,6 +34,7 @@ export default function LivePage() { data-lk-theme="default" onDisconnected={() => { instance.post(`${API_URL}/video/deleteroom/${roomId}`).catch(() => {}); + window.close(); }} >