Skip to content

Commit 5a52158

Browse files
authored
Merge pull request #167 from wafflestudio/haram
fix: 주별뷰 Period Bar 겹침 문제 해결
2 parents 0b5963d + 1ded398 commit 5a52158

7 files changed

Lines changed: 176 additions & 7 deletions

File tree

src/calendar_widgets/week/CustomWeekView.tsx

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ import type {
77
} from "react-big-calendar";
88
import { Views } from "react-big-calendar";
99

10-
import type { Event, CalendarEvent, GetCoursesResponse } from "../../util/types";
10+
import type {
11+
Event,
12+
CalendarEvent,
13+
GetCoursesResponse,
14+
} from "../../util/types";
1115
import {
1216
config,
1317
flattenEventsToBlocks,
@@ -30,6 +34,30 @@ interface CustomWeekViewProps {
3034

3135
type Rect = { left: number; width: number };
3236

37+
function useElementHeight<T extends HTMLElement>(
38+
elementRef: React.RefObject<T | null>,
39+
) {
40+
const [height, setHeight] = useState(0);
41+
42+
useLayoutEffect(() => {
43+
const el = elementRef.current;
44+
if (!el) return;
45+
46+
const update = () => {
47+
setHeight(el.getBoundingClientRect().height);
48+
};
49+
50+
update();
51+
52+
const ro = new ResizeObserver(update);
53+
ro.observe(el);
54+
55+
return () => ro.disconnect();
56+
}, [elementRef]);
57+
58+
return height;
59+
}
60+
3361
function useAnchorRect<T extends HTMLElement>(
3462
anchorRef: React.RefObject<T | null>,
3563
) {
@@ -103,10 +131,11 @@ function CustomWeekView({
103131
cevent.end.getMonth(),
104132
cevent.end.getDate(),
105133
);
106-
const differentDate = (startDay.getFullYear() !== endDay.getFullYear()
107-
&& startDay.getMonth() !== endDay.getMonth()
108-
&& startDay.getDate() !== endDay.getDate());
109-
134+
const differentDate =
135+
startDay.getFullYear() !== endDay.getFullYear() &&
136+
startDay.getMonth() !== endDay.getMonth() &&
137+
startDay.getDate() !== endDay.getDate();
138+
110139
isAllDay = Boolean(cevent.allDay) || differentDate || sameMinute;
111140
}
112141

@@ -166,7 +195,9 @@ function CustomWeekView({
166195
);
167196

168197
const gridRef = useRef<HTMLDivElement>(null);
198+
const periodLayerRef = useRef<HTMLDivElement>(null);
169199
const { left, width } = useAnchorRect(gridRef);
200+
const periodBarHeight = useElementHeight(periodLayerRef);
170201

171202
return (
172203
<div className={styles.weekView}>
@@ -179,6 +210,11 @@ function CustomWeekView({
179210
<div
180211
className={styles.timetableLayer}
181212
data-tour-id="week-tour-participating-events"
213+
style={
214+
{
215+
"--period-bar-height": `${periodBarHeight}px`,
216+
} as React.CSSProperties
217+
}
182218
>
183219
<WeekGrid
184220
ref={gridRef}
@@ -191,6 +227,7 @@ function CustomWeekView({
191227
/>
192228
</div>
193229
<div
230+
ref={periodLayerRef}
194231
className={styles.periodLayer}
195232
style={{ left, width }}
196233
data-tour-id="week-tour-recruiting-events"

src/calendar_widgets/week/WeekView.module.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77
z-index: 10;
88
}
99

10+
@media (min-width: 577px) {
11+
.timetableLayer {
12+
box-sizing: border-box;
13+
padding-bottom: var(--period-bar-height, 0px);
14+
}
15+
}
16+
1017
.periodLayer {
1118
position: fixed;
1219
left: 0;

src/pages/auth/OnBoarding/Onboarding.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export default function Onboarding({
7373
}
7474
setSearchParams((prev) => {
7575
const next = new URLSearchParams(prev);
76-
next.set("step", "complete");
76+
next.set("step", "sign-up-source");
7777
return next;
7878
});
7979
} catch (e) {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.sourceList {
2+
gap: 18px;
3+
}
4+
5+
.sourceOption {
6+
display: flex;
7+
align-items: center;
8+
gap: 14px;
9+
cursor: pointer;
10+
box-shadow:
11+
0 2px 0 rgba(0, 0, 0, 0.04),
12+
0 6px 14px rgba(0, 0, 0, 0.08);
13+
}
14+
15+
.checkbox {
16+
flex: 0 0 auto;
17+
width: 18px;
18+
height: 18px;
19+
margin: 0;
20+
accent-color: #111;
21+
cursor: pointer;
22+
}
23+
24+
.labelText {
25+
overflow: hidden;
26+
text-overflow: ellipsis;
27+
white-space: nowrap;
28+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { useState } from "react";
2+
import { useNavigate, useSearchParams } from "react-router-dom";
3+
import signupStyles from "../Signup/EmailSignUp.module.css";
4+
import styles from "./SignUpSource.module.css";
5+
6+
const SIGN_UP_SOURCES = [
7+
"에브리타임 등 커뮤니티",
8+
"인스타그램 및 SNS 홍보",
9+
"단톡방",
10+
"인터넷 검색",
11+
"지인 추천",
12+
"와플스튜디오의 프로젝트가 궁금해서",
13+
"기타",
14+
] as const;
15+
16+
type SignUpSource = (typeof SIGN_UP_SOURCES)[number];
17+
18+
export default function SignUpSource() {
19+
const navigate = useNavigate();
20+
const [, setSearchParams] = useSearchParams();
21+
const [selectedSources, setSelectedSources] = useState<SignUpSource[]>([]);
22+
23+
const toggleSource = (source: SignUpSource) => {
24+
setSelectedSources((prev) =>
25+
prev.includes(source)
26+
? prev.filter((selected) => selected !== source)
27+
: [...prev, source],
28+
);
29+
};
30+
31+
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
32+
event.preventDefault();
33+
34+
if (selectedSources.length === 0) {
35+
alert("가입 경로를 하나 이상 선택해주세요.");
36+
return;
37+
}
38+
39+
setSearchParams((prev) => {
40+
const next = new URLSearchParams(prev);
41+
next.set("step", "complete");
42+
return next;
43+
});
44+
navigate("/auth/signup?step=complete");
45+
};
46+
47+
return (
48+
<div className={signupStyles.page}>
49+
<div className={signupStyles.box}>
50+
<header className={signupStyles.header}>
51+
<h2 className={signupStyles.title}>가입 경로</h2>
52+
<p className={signupStyles.subtitle}>
53+
행사를 어떻게 알게 되었나요?
54+
</p>
55+
</header>
56+
57+
<form
58+
className={`${signupStyles.form} ${styles.sourceList}`}
59+
onSubmit={handleSubmit}
60+
>
61+
{SIGN_UP_SOURCES.map((source) => {
62+
const inputId = `sign-up-source-${source}`;
63+
64+
return (
65+
<label
66+
key={source}
67+
className={`${signupStyles.input} ${styles.sourceOption}`}
68+
htmlFor={inputId}
69+
>
70+
<input
71+
id={inputId}
72+
className={styles.checkbox}
73+
type="checkbox"
74+
checked={selectedSources.includes(source)}
75+
onChange={() => toggleSource(source)}
76+
/>
77+
<span className={styles.labelText}>{source}</span>
78+
</label>
79+
);
80+
})}
81+
82+
<button className={signupStyles.submit} type="submit">
83+
완료
84+
</button>
85+
</form>
86+
</div>
87+
</div>
88+
);
89+
}

src/pages/auth/Signup/EmailSignUp.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useAuth } from "@contexts/AuthProvider";
66
import CompleteSignUp from "../OnBoarding/CompleteSignUp";
77
import Onboarding from "../OnBoarding/Onboarding";
88
import ProfileSetting from "../OnBoarding/ProfileSetting";
9+
import SignUpSource from "../OnBoarding/SignUpSource";
910
import styles from "./EmailSignUp.module.css";
1011

1112
export default function EmailSignUp() {
@@ -31,6 +32,8 @@ export default function EmailSignUp() {
3132
return <ProfileSetting />;
3233
case "onboarding":
3334
return <Onboarding />;
35+
case "sign-up-source":
36+
return <SignUpSource />;
3437
case "complete":
3538
return <CompleteSignUp />;
3639
}

src/router/AppRoutes.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const Login = lazy(() => import("../pages/auth/Login/Login"));
99
const LoginHandler = lazy(
1010
() => import("../pages/auth/Login/SocialLoginHandler"),
1111
);
12+
const SignupSource = lazy(() => import("../pages/auth/OnBoarding/SignUpSource"));
1213
const EmailSignUp = lazy(() => import("../pages/auth/Signup/EmailSignUp"));
1314
const CalendarView = lazy(() => import("../pages/calendar/CalendarView"));
1415
const MainDay = lazy(() => import("../pages/calendar/MainDay"));
@@ -27,7 +28,11 @@ export default function AppRoutes() {
2728
<Routes>
2829
<Route path="/" element={<Home />} />
2930
<Route path="/auth/login" element={<Login />} />
30-
<Route path="/auth/signup" element={<EmailSignUp />} />
31+
<Route path="/auth/signup" element={<EmailSignUp />} />
32+
<Route
33+
path="/auth/onbording/sign-up-source"
34+
element={<SignupSource />}
35+
/>
3136
{/* <Route path="/auth/complete" element={<CompleteSignUp />} /> */}
3237

3338
{/* OAuth Redirect */}

0 commit comments

Comments
 (0)