From 1e7d2b465147fa5da61da76ed646b0767d6113b8 Mon Sep 17 00:00:00 2001 From: Huiju <61102301+Joie-Kim@users.noreply.github.com> Date: Fri, 1 Mar 2024 16:07:39 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B0=9C=ED=91=9C=20=EC=97=B0=EC=8A=B5=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=97=A4=EB=8D=94=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=20=EC=B2=98=EB=A6=AC=20=EB=B0=8F=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20API=20=EC=97=B0=EB=8F=99=20(#39)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 발표 연습 상세 조회 API 연동 * refact: CloseIcon 색상 값으로 분기하도록 수정 * feat: PracticeNav 컴포넌트 내 버튼 로직 구현 - PracticeNav layout에서 제거 - 일시정지 여부에 맞춰서 헤더 컬러 및 버튼 노출 여부 변경되도록 구현 - 버튼 클릭 시 이벤트 바인딩 - 그 외 데이터 바인딩 --- .../practice/[id]/page.module.scss | 10 +- src/app/(afterlogin)/practice/[id]/page.tsx | 153 ++++++++++++++---- .../_components/PracticeNav.module.scss | 13 +- .../practice/_components/PracticeNav.tsx | 39 +++-- .../practice/_components/Recorder.tsx | 53 +----- .../practice/_hooks/useRecorder.ts | 13 ++ .../practice/_svgs/RecordIcon.tsx | 95 +++++++++++ .../practice/_svgs/RecordOnIcon.tsx | 26 --- src/app/(afterlogin)/practice/layout.tsx | 8 +- .../setting/[id]/_components/SettingNav.tsx | 4 +- src/app/_components/_modules/SpeechBubble.tsx | 4 +- src/app/_components/_modules/_modal/Modal.tsx | 4 +- .../{CloseIconBlack.tsx => CloseIcon.tsx} | 31 +++- src/app/_svgs/CloseIconWhite.tsx | 20 --- src/services/client/practice.ts | 15 ++ src/types/service.ts | 111 ++++++++++--- 16 files changed, 421 insertions(+), 178 deletions(-) create mode 100644 src/app/(afterlogin)/practice/_svgs/RecordIcon.tsx delete mode 100644 src/app/(afterlogin)/practice/_svgs/RecordOnIcon.tsx rename src/app/_svgs/{CloseIconBlack.tsx => CloseIcon.tsx} (60%) delete mode 100644 src/app/_svgs/CloseIconWhite.tsx create mode 100644 src/services/client/practice.ts diff --git a/src/app/(afterlogin)/practice/[id]/page.module.scss b/src/app/(afterlogin)/practice/[id]/page.module.scss index 36dc5a1..0cd122c 100644 --- a/src/app/(afterlogin)/practice/[id]/page.module.scss +++ b/src/app/(afterlogin)/practice/[id]/page.module.scss @@ -2,6 +2,8 @@ @import '@/styles/mixins'; .container { + display: flex; + justify-content: center; position: relative; width: 100%; padding: 60px; @@ -15,8 +17,8 @@ .presentation { width: 900px; height: 100%; + border: 1px solid $gray-1; border-radius: 15px; - background: $purple-1; &__box { display: flex; @@ -58,8 +60,8 @@ width: 100%; height: 100%; margin-top: 12px; + border: 1px solid $gray-1; border-radius: 15px; - background: $purple-1; } &__box { @@ -86,6 +88,6 @@ .bubble { position: absolute; - top: 8px; - left: 30%; + top: 75px; + left: 35%; } diff --git a/src/app/(afterlogin)/practice/[id]/page.tsx b/src/app/(afterlogin)/practice/[id]/page.tsx index 62b8aaa..f0752db 100644 --- a/src/app/(afterlogin)/practice/[id]/page.tsx +++ b/src/app/(afterlogin)/practice/[id]/page.tsx @@ -7,63 +7,140 @@ import { useEffect, useState } from 'react'; import useRecorder from '../_hooks/useRecorder'; import Alert from '@/app/_components/_modules/_modal/Alert'; import SpeechBubble from '@/app/_components/_modules/SpeechBubble'; +import { useQuery } from '@tanstack/react-query'; +import { PracticeDetail } from '@/types/service'; +import { PracticeService } from '@/services/client/practice'; +import Image from 'next/image'; +import PracticeNav from '../_components/PracticeNav'; +import Confirm from '@/app/_components/_modules/_modal/Confirm'; export default function Page({ params }: { params: { id: string } }) { + const id = Number(params.id); + + // #region state + const [slideIdx, setSlideIdx] = useState(0); const modal = useToggle(); + const confirm = useToggle(); const bubble = useToggle(); const recorder = useRecorder(); + // #endregion + // const cx = classNames.bind(styles); + // #region query + const { isLoading, data } = useQuery({ + queryKey: ['practice', id], + queryFn: () => PracticeService.getPracticeDetail(Number(id)), + }); + + /** 발표 이름 */ + const title = data?.title ?? ''; + + /** 슬라이드 페이징 문자열 */ + const slidePaging = `${slideIdx}/${data?.slides.length ?? 0}`; + + /** 마지막 슬라이드 여부 */ + const isLastSlide = data?.slides.length === slideIdx + 1; + // #endregion + useEffect(() => { modal.onOpen(); recorder.getMedia(); recorder.processPermission(); }, []); + // #region event-handler const handleModalAction = () => { recorder.startRecording(); modal.onClose(); bubble.onOpen(); }; + const handleNextSlide = () => { + console.log('go to next slide'); + }; + + const handleRecordingPause = () => { + if (recorder.isRecording) recorder.pauseRecording(); + else recorder.resumeRecording(); + }; + + const handleClose = () => { + console.log('close ... '); + confirm.onOpen(); + }; + // #endregion + + // #region function + const goToPresentationsPage = () => { + console.log('go to presentation page...'); + confirm.onClose(); + }; + // #endregion + return ( -
-
-
-
img...
-
-
-

- 다음 슬라이드 - 2/15 -

-
img...
-
-
-

- 메모하기 - - 발표 연습 중 메모를 입력하면 녹음이 일시정지돼요. - -

-