Skip to content

Commit 7c9c0f9

Browse files
committed
feat/#1 : register ui, post api 추가
- page routing을 위한 MMM-pages modules 추가(ignore Signed-off-by: EunJiJung <bianbbc87@gmail.com>
1 parent 8e0b846 commit 7c9c0f9

3 files changed

Lines changed: 308 additions & 0 deletions

File tree

Lines changed: 4 additions & 0 deletions
Loading
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
.flex-column {
2+
display: flex;
3+
flex-direction: column;
4+
align-items: center; /* 가운데 정렬 */
5+
gap: 1rem; /* 요소 간 간격 */
6+
padding: 1rem;
7+
}
8+
9+
.flex-row {
10+
display: flex;
11+
align-items: center;
12+
justify-content: center;
13+
gap: 1rem; /* 요소 간 간격 */
14+
padding: 1rem;
15+
cursor: pointer;
16+
}
17+
18+
.width-100 {
19+
width: 100%;
20+
}
21+
22+
.bottom-sheet {
23+
display: flex;
24+
flex-direction: column;
25+
align-items: center;
26+
justify-content: center;
27+
position: fixed;
28+
bottom: 0;
29+
left: 0;
30+
right: 0;
31+
height: 100%;
32+
padding: 1em;
33+
text-align: center;
34+
z-index: 9999;
35+
border-top-left-radius: 28px;
36+
border-top-right-radius: 28px;
37+
background: black;
38+
39+
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.3);
40+
transform: translateY(100%);
41+
transition: transform 0.4s ease-in-out;
42+
}
43+
44+
.bottom-sheet.show {
45+
transform: translateY(0);
46+
opacity: 1;
47+
}
48+
49+
.bottom-sheet.hidden {
50+
transform: translateY(200%);
51+
opacity: 0;
52+
}
53+
54+
.sheet-container video {
55+
border-radius: 8px;
56+
}
57+
58+
.sheet-container button {
59+
margin-top: 2em;
60+
}
61+
62+
.sheet-info-box {
63+
display: flex;
64+
flex-direction: column;
65+
width: 80%;
66+
justify-content: flex-start;
67+
text-align: left;
68+
}
69+
70+
.sheet-info-box p {
71+
margin: 0;
72+
padding: 0;
73+
}
74+
75+
/** html style **/
76+
input {
77+
all: unset; /* 기본 스타일 초기화 */
78+
box-sizing: border-box;
79+
width: 100%;
80+
padding: 12px 16px;
81+
border-radius: 12px;
82+
border: 1px solid #e0e0e0;
83+
background-color: #fafafa;
84+
font-size: 1rem;
85+
transition: border-color 0.3s ease, box-shadow 0.3s ease;
86+
cursor: text;
87+
}
88+
89+
input:focus {
90+
border-color: #635bff;
91+
background-color: #fff;
92+
box-shadow: 0 0 8px rgba(99, 91, 255, 0.3);
93+
outline: none;
94+
}
95+
96+
button {
97+
all: unset; /* 기본 스타일 초기화 */
98+
display: inline-block;
99+
padding: 12px 24px;
100+
margin-top: 1em;
101+
border-radius: 12px;
102+
font-weight: 600;
103+
font-size: 1rem;
104+
cursor: pointer;
105+
user-select: none;
106+
transition: background-color 0.3s ease, box-shadow 0.2s ease;
107+
box-shadow: 0 2px 4px rgb(0 0 0 / 0.1);
108+
background-color: #635bff;
109+
color: white;
110+
cursor: pointer;
111+
}
112+
113+
button:hover {
114+
background-color: #4a3dd1;
115+
box-shadow: 0 4px 12px rgba(99, 91, 255, 0.4);
116+
}
117+
118+
p {
119+
font-size: 1.5rem;
120+
}
121+
122+
/** page wrapper **/
123+
.page-wrapper {
124+
padding: 50px;
125+
text-align: center;
126+
animation: fadeIn 1s;
127+
}
128+
129+
.page-wrapper h1 {
130+
color: #2c3e50;
131+
font-size: 2em;
132+
margin-bottom: 20px;
133+
}
134+
135+
.page-wrapper button {
136+
padding: 15px 30px;
137+
font-size: 1em;
138+
background: #4285f4;
139+
color: #fff;
140+
border: none;
141+
border-radius: 8px;
142+
cursor: pointer;
143+
transition: all 0.3s ease;
144+
}
145+
146+
.page-wrapper button:hover {
147+
background: #3073e0;
148+
transform: translateY(-3px);
149+
}
150+
151+
@keyframes fadeIn {
152+
from { opacity: 0; transform: translateY(20px); }
153+
to { opacity: 1; transform: translateY(0); }
154+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
Module.register("register", {
2+
defaults: {
3+
title: "자서전 인터뷰 장비 등록하기",
4+
description: "인터뷰 장비의 serial ID를 입력해 주세요."
5+
},
6+
7+
/** post api 와 page 이동 함수 **/
8+
postData(data) {
9+
this.sendNotification("PAGE_CHANGED", 1); // 200일 때 페이지 이동
10+
},
11+
12+
/** dom, style - bottom sheet control을 위해 dom 사용 **/
13+
getDom() {
14+
const wrapper = document.createElement("div");
15+
wrapper.classList.add("wrapper");
16+
17+
// 타이틀, 설명
18+
const title = document.createElement("h1");
19+
title.textContent = this.config.title;
20+
wrapper.appendChild(title);
21+
22+
const desc = document.createElement("p");
23+
desc.textContent = this.config.description;
24+
wrapper.appendChild(desc);
25+
26+
// 입력 필드
27+
const serial_input = document.createElement("input");
28+
serial_input.placeholder = "Serial ID";
29+
wrapper.appendChild(serial_input);
30+
31+
const buttonContainer = document.createElement("div");
32+
buttonContainer.classList.add("flex-row");
33+
buttonContainer.addEventListener("click", () => this.showBottomSheet())
34+
35+
const information_text = document.createElement("p");
36+
information_text.textContent = "Serial ID를 어디서 확인하나요 ?";
37+
38+
// 등록하기 버튼 (아이콘 이미지)
39+
const information_icon = document.createElement("img");
40+
information_icon.src = "modules/default/register/assets/info_icon.svg"; // 외부 SVG 경로
41+
information_icon.alt = "info icon";
42+
information_icon.classList.add("info_icon");
43+
44+
// 버튼 컨테이너에 요소 추가
45+
buttonContainer.appendChild(information_text);
46+
buttonContainer.appendChild(information_icon);
47+
48+
// 버튼 컨테이너를 wrapper에 추가
49+
wrapper.appendChild(buttonContainer);
50+
51+
// 등록하기 버튼
52+
const submit_btn = document.createElement("button");
53+
submit_btn.textContent = "등록하기";
54+
submit_btn.addEventListener("click", () => {
55+
const serialId = serial_input.value; // input 필드 값 가져오기
56+
if (serialId) {
57+
const data = { serialId }; // 보낼 데이터 구성
58+
this.postData(data); // POST 호출
59+
this.sendNotification("REGISTER_SUBMIT", data); // 알림 전송 (원하면)
60+
this.showBottomSheet(); // 바텀시트 보여주기 (원하면)
61+
} else {
62+
alert("Serial ID를 입력해주세요!");
63+
}
64+
});
65+
wrapper.appendChild(submit_btn);
66+
67+
// Bottom Sheet 생성 (처음에는 hidden)
68+
const sheet = document.createElement("div");
69+
sheet.className = "bottom-sheet hidden";
70+
sheet.innerHTML = `
71+
<h1 id="sheet-title">Serial ID 확인하기</h1>
72+
<div class="sheet-info-box">
73+
<p id="sheet-step">1/2</p>
74+
<p id="sheet-content">아래와 같이 기기의 블루투스를 연결해주세요.</p>
75+
</div>
76+
<video id="sheet-video" src="modules/default/register/video/example_video1.mp4" width="100%" autoplay loop muted></video>
77+
<button id="sheet-button">다음</button>
78+
`;
79+
wrapper.appendChild(sheet);
80+
this.sheetElement = sheet;
81+
82+
// Overlay 생성 (처음에는 hidden)
83+
const overlay = document.createElement("div");
84+
overlay.className = "bottom-sheet-overlay hidden";
85+
wrapper.appendChild(overlay);
86+
87+
// overlay 클릭 시 닫기
88+
overlay.addEventListener("click", () => {
89+
this.hideBottomSheet();
90+
});
91+
92+
return wrapper;
93+
},
94+
95+
getStyles() {
96+
return ["register.css"];
97+
},
98+
99+
/** bottom sheet 영역 **/
100+
showBottomSheet() {
101+
const sheet = document.querySelector(".bottom-sheet");
102+
const overlay = document.querySelector(".bottom-sheet-overlay");
103+
if (sheet && overlay) {
104+
sheet.classList.remove("hidden");
105+
sheet.classList.add("show");
106+
overlay.classList.remove("hidden");
107+
overlay.classList.add("show");
108+
109+
const video = sheet.querySelector("#sheet-video");
110+
const step_t = sheet.querySelector("#sheet-step");
111+
const content = sheet.querySelector("#sheet-content");
112+
const nextBtn = sheet.querySelector("#sheet-button");
113+
114+
const handleClick = () => {
115+
if (nextBtn.textContent === "닫기") {
116+
this.hideBottomSheet();
117+
nextBtn.removeEventListener("click", handleClick); // 이벤트 중복 방지
118+
119+
// 초기화
120+
step_t.textContent = "1/2";
121+
content.textContent = "아래와 같이 기기의 블루투스를 연결해주세요.";
122+
video.src = "modules/default/register/video/example_video1.mp4";
123+
video.load(); // 비디오 소스 변경 후 로드
124+
video.play();
125+
nextBtn.textContent = "다음";
126+
} else {
127+
step_t.textContent = "2/2";
128+
content.textContent = "아래와 같이 화면애 뜬 Serail ID를 확인해주세요.";
129+
video.src = "modules/default/register/video/example_video2.mp4";
130+
video.load(); // 비디오 소스 변경 후 로드
131+
video.play();
132+
nextBtn.textContent = "닫기";
133+
}
134+
};
135+
136+
nextBtn.addEventListener("click", handleClick);
137+
}
138+
},
139+
140+
hideBottomSheet() {
141+
const sheet = document.querySelector(".bottom-sheet");
142+
const overlay = document.querySelector(".bottom-sheet-overlay");
143+
if (sheet && overlay) {
144+
sheet.classList.remove("show");
145+
sheet.classList.add("hidden");
146+
overlay.classList.remove("show");
147+
overlay.classList.add("hidden");
148+
}
149+
},
150+
});

0 commit comments

Comments
 (0)