Skip to content

Commit e60f7bf

Browse files
committed
Chore: meeting tutorial
1 parent 69e627a commit e60f7bf

File tree

11 files changed

+288
-485
lines changed

11 files changed

+288
-485
lines changed

package-lock.json

Lines changed: 29 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@
2222
"regenerator-runtime": "^0.14.1",
2323
"sass": "^1.85.1",
2424
"sockjs-client": "^1.6.1",
25-
"stompjs": "^2.3.3"
25+
"stompjs": "^2.3.3",
26+
"swiper": "^11.2.10"
2627
},
2728
"devDependencies": {
2829
"@eslint/js": "^9.17.0",
29-
"@types/node": "^22.13.10",
30+
"@types/node": "^22.17.0",
3031
"@types/react": "^18.3.18",
3132
"@types/react-dom": "^18.3.5",
3233
"@types/react-speech-recognition": "^3.9.6",
98.3 KB
Loading
236 KB
Loading
113 KB
Loading
85.9 KB
Loading

src/sass/helpers/_variables.sass

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ $gray-900: #161618
1717

1818
$purple-50: #EEE8FD
1919
$purple-100: #D3C6FA
20+
$purple-300: #9776F6
2021
$purple-400: #7C55F4
2122
$purple-500: #5E35F0
2223
$purple-600: #4F31E9
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { useRef, useState } from "react";
2+
import img1 from "@/assets/imgs/meeting/tutorial/img-1.png";
3+
import img2 from "@/assets/imgs/meeting/tutorial/img-2.png";
4+
import img3 from "@/assets/imgs/meeting/tutorial/img-3.png";
5+
import img4 from "@/assets/imgs/meeting/tutorial/img-4.png";
6+
import "@/views/meeting/style/tutorial-modal.sass";
7+
import Modal from "@/views/components/modal";
8+
import { Swiper, SwiperSlide } from 'swiper/react';
9+
import { Swiper as SwiperClass } from "swiper";
10+
import { Pagination, EffectFade } from 'swiper/modules';
11+
12+
import 'swiper/css';
13+
import 'swiper/css/effect-fade';
14+
import 'swiper/css/pagination';
15+
16+
const slides = [
17+
{
18+
img: img1,
19+
title: "함께할 팀원을 초대하고 프로젝트를 시작하세요",
20+
desc: [
21+
"‘공유하기’ 버튼을 눌러 이메일 또는 링크로 팀원을 간편하게 초대해요.",
22+
"초대한 팀원은 공유 목록에서 바로 확인할 수 있어요.",
23+
"프로젝트명을 클릭해 자유롭게 수정할 수 있어요.",
24+
],
25+
},
26+
{
27+
img: img2,
28+
title: "녹음을 시작하면 자동으로 펼쳐지는 아이디어",
29+
desc: [
30+
"음성 녹음을 시작하면, 대화 중 자주 언급되거나 중요한 단어는",
31+
"키워드로 실시간 추출되며 아이디어 마인드맵이 실시간으로 정리돼요.",
32+
"또한 AI가 대화 흐름을 분석해 요약본도 함께 제공해요.",
33+
],
34+
},
35+
{
36+
img: img3,
37+
title: "마인드맵을 직접 수정하며 생각을 확장해보세요!",
38+
desc: [
39+
"라이브모드를 해제하면 마인드맵을 직접 수정할 수 있어요.",
40+
"직접 키워드를 선택해 마인드맵에 추가하거나, 추천 키워드를 참고해",
41+
"아이디어를 확장해보세요. 키워드를 추가할수록 마인드맵이 더 풍부해져요.",
42+
],
43+
},
44+
{
45+
img: img4,
46+
title: "아이디어를 정리하고, 언제든 다시 꺼내봐요",
47+
desc: [
48+
"‘회의 종료’ 버튼을 누르면 지금까지의 아이디어들이 정리돼 저장돼요.",
49+
"언제든 메인 페이지에서 프로젝트 파일을 한눈에 확인하세요.",
50+
"마인드맵, 키워드, 요약본을 각 파일로 다운로드할 수도 있어요!",
51+
],
52+
},
53+
];
54+
55+
interface TutorialModalProps {
56+
onCloseModal: () => void;
57+
}
58+
59+
const TutorialModal = ({
60+
onCloseModal,
61+
}: TutorialModalProps) => {
62+
const swiperRef = useRef<SwiperClass | null>(null);
63+
const [activeIndex, setActiveIndex] = useState(0);
64+
const isLastSlide = activeIndex === slides.length - 1;
65+
66+
return (
67+
<Modal onCloseModal={onCloseModal}>
68+
<div className="modal-wrap">
69+
<Swiper
70+
onSwiper={(swiper) => (swiperRef.current = swiper)}
71+
onSlideChange={(swiper) => setActiveIndex(swiper.activeIndex)}
72+
effect="fade"
73+
speed={500}
74+
fadeEffect={{ crossFade: true }}
75+
pagination={{ clickable: true }}
76+
allowTouchMove={false}
77+
modules={[EffectFade, Pagination]}
78+
className="mySwiper"
79+
>
80+
{slides.map((slide, index) => (
81+
<SwiperSlide key={index}>
82+
<div className="img-wrap">
83+
<img src={slide.img} alt={`slide-${index}`} />
84+
</div>
85+
<div className="desc-wrap">
86+
<b>{slide.title}</b>
87+
<p>
88+
{slide.desc.map((line, i) => (
89+
<span key={i}>
90+
{line}
91+
<br />
92+
</span>
93+
))}
94+
</p>
95+
</div>
96+
</SwiperSlide>
97+
))}
98+
</Swiper>
99+
<div className="btn-wrap">
100+
<button onClick={onCloseModal}>건너뛰기</button>
101+
<button className="btn-next" onClick={() => {
102+
if (isLastSlide) {
103+
onCloseModal();
104+
} else {
105+
swiperRef.current?.slideNext();
106+
}
107+
}}>{isLastSlide ? "시작하기" : "다음"}</button>
108+
</div>
109+
</div>
110+
</Modal>
111+
);
112+
};
113+
114+
export default TutorialModal;

src/views/meeting/page/MeetingPage.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import { useState, useRef, useEffect } from "react";
1313
// api
1414
import { getMeetingId } from "@/api/meeting/meeting";
1515

16+
// component
17+
import TutorialModal from "@/views/meeting/components/TutorialModal";
18+
1619
// type
1720
import { conferenceData } from "@/types/conferanceData";
1821
import { RealTimeSummaryData } from "@/types/realTimeSummaryData";
@@ -35,7 +38,7 @@ const MeetingPage = () => {
3538
});
3639

3740
// modal
38-
type ModalType = "share" | null;
41+
type ModalType = "tutorial" | "share" | null;
3942
const [modalType, setModalType] = useState<ModalType>(null);
4043
const closeModal = () => setModalType(null);
4144
const openModal = () => setModalType("share");
@@ -45,6 +48,7 @@ const MeetingPage = () => {
4548
useEffect(() => {
4649
getMeetingId().then((res: any) => {
4750
setConferenceData(res.data.data);
51+
setModalType("tutorial");
4852
});
4953
}, []);
5054

@@ -67,6 +71,18 @@ const MeetingPage = () => {
6771
/>
6872
</div>
6973
)}
74+
{modalType === "tutorial" && (
75+
<div
76+
className="modal-container"
77+
onClick={(e) => {
78+
if (e.target === e.currentTarget) {
79+
closeModal();
80+
}
81+
}}
82+
>
83+
<TutorialModal onCloseModal={closeModal} />
84+
</div>
85+
)}
7086
</div>
7187

7288
<SideBar
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
@import '@/sass/helpers/_variables.sass'
2+
@import '@/sass/helpers/_mixins.scss'
3+
@import '@/sass/uix/_button.sass'
4+
5+
.modal-content
6+
+size(568px)
7+
padding: 0 !important
8+
overflow: hidden
9+
10+
.modal-close-btn
11+
z-index: 10
12+
13+
.modal-wrap
14+
.swiper
15+
.swiper-wrapper
16+
.swiper-slide
17+
+flex-box(center, center)
18+
flex-direction: column
19+
20+
.img-wrap
21+
+size(100%)
22+
+flex-box(center)
23+
+padding(40px 0)
24+
background: linear-gradient(155deg, #9EA5F8 -20.39%, #A48CE7 64.22%)
25+
26+
img
27+
+size(440px, 275px)
28+
border-radius: 8px
29+
30+
.desc-wrap
31+
+padding(50px 0 32px 0)
32+
+size(488px)
33+
text-align: center
34+
35+
b
36+
font-size: 22px
37+
line-height: 33px
38+
39+
p
40+
+margin(top 12px)
41+
font-size: 16px
42+
font-weight: 500
43+
line-height: 26.4px
44+
color: #363638
45+
46+
.swiper-pagination
47+
top: 375px
48+
49+
.swiper-pagination-bullet-active
50+
background: $purple-300
51+
52+
.btn-wrap
53+
+flex-box(center, center, 12px)
54+
+padding(bottom 28px)
55+
56+
button
57+
+btn(208px, 48px, 8px)
58+
font-weight: 500px
59+
60+
.btn-next
61+
font-weight: 700
62+
color: $white
63+
background: $black
64+
65+

0 commit comments

Comments
 (0)