Skip to content

Commit b848f65

Browse files
committed
feat(guide): 가이드북 반응형 UI 개선 및 경매 플로우 데이터/이벤트 보완
- 가이드북 페이지 및 네비게이션을 모바일/태블릿 대응으로 개선하고 레이아웃, 간격, 폰트 크기를 조정 - step indicator, price bar, chat bubble의 비주얼 스타일을 다듬어 가독성과 일관성 개선 - SSE 이벤트 타입을 추가
1 parent 0b4f7f8 commit b848f65

8 files changed

Lines changed: 253 additions & 236 deletions

File tree

src/features/notification/ui/notification-sse-provider.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ const SSE_EVENT_TYPES = [
1919
"auctionFailedSubscriber",
2020
"auctionSuccessSeller",
2121
"auctionSuccessSubscriber",
22+
"reviewRegistered",
23+
"chatMessage",
2224
] as const;
2325
const MAX_RECONNECT_DELAY_MS = 30_000;
2426
const RECONNECT_BASE_DELAY_MS = 1_000;

src/screens/guide/model/guide-data.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ export interface PricePoint {
3030
export const priceData: PricePoint[] = [
3131
{ time: "00:00", price: 100000, label: "시작" },
3232
{ time: "00:05", price: 95000 },
33-
{ time: "00:10", price: 90000 },
34-
{ time: "00:15", price: 85000 },
35-
{ time: "00:20", price: 80000, label: "구매 완료" },
33+
{ time: "00:10", price: 90000, label: "구매 완료" },
3634
];
3735

3836
export interface ChatMessage {

src/screens/guide/ui/guide.tsx

Lines changed: 62 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { useRouter } from "next/navigation";
77
import { ChevronLeft, ChevronRight } from "lucide-react";
88
import { AnimatePresence, motion } from "motion/react";
99

10+
import { Container } from "@/shared/ui";
11+
1012
import {
1113
GuidebookPage1,
1214
GuidebookPage2,
@@ -58,84 +60,84 @@ export function Guidebook() {
5860
}, []);
5961

6062
return (
61-
<div ref={containerRef} className="bg-background fixed inset-0 overflow-hidden outline-none">
62-
<div className="flex h-full items-center justify-center px-6">
63-
<div className="relative w-full max-w-5xl">
64-
<motion.button
65-
type="button"
66-
className="absolute top-0 right-0 z-50 rounded-full border border-gray-200 bg-white px-4 py-2 text-sm font-semibold text-gray-700 shadow-sm transition hover:bg-gray-50"
67-
whileHover={{ scale: 1.04 }}
68-
whileTap={{ scale: 0.98 }}
69-
onClick={() => {
70-
if (typeof window !== "undefined") {
71-
window.localStorage.setItem(GUIDE_STORAGE_KEY, "true");
72-
}
73-
router.replace("/");
74-
}}
75-
>
76-
Skip
77-
</motion.button>
78-
<motion.div
79-
className="mb-8 text-center"
80-
key={`title-${currentPage}`}
81-
initial={{ opacity: 0, y: -10 }}
82-
animate={{ opacity: 1, y: 0 }}
83-
transition={{ duration: 0.3 }}
84-
>
85-
<p className="mb-2 text-sm text-gray-500">
86-
Chapter {currentPage + 1} / {totalPages}
87-
</p>
88-
<h2 className="text-2xl font-semibold">{pages[currentPage].title}</h2>
89-
</motion.div>
90-
91-
<div className="bg-card relative overflow-hidden rounded-3xl shadow-2xl">
92-
<div className="h-[min(70dvh,820px)] min-h-[600px]">
93-
<AnimatePresence mode="wait" custom={direction}>
94-
<motion.div
95-
key={currentPage}
96-
custom={direction}
97-
variants={pageVariants}
98-
initial="enter"
99-
animate="center"
100-
exit="exit"
101-
transition={{
102-
x: { type: "spring", stiffness: 300, damping: 30 },
103-
opacity: { duration: 0.3 },
104-
scale: { duration: 0.3 },
105-
}}
106-
className="h-full p-12"
107-
>
108-
{pages[currentPage].node}
109-
</motion.div>
110-
</AnimatePresence>
111-
</div>
63+
<div ref={containerRef} className="bg-background w-full overflow-hidden outline-none">
64+
<Container className="flex max-h-[calc(100dvh-var(--header-h,0px))] min-h-[calc(100dvh-var(--header-h,0px))] w-full flex-col items-center justify-center py-2">
65+
<div className="flex h-full w-full flex-col gap-4">
66+
<header className="relative flex items-center justify-center">
67+
<motion.button
68+
type="button"
69+
className="absolute top-0 right-1 rounded-full border border-zinc-200 bg-white px-3 py-1.5 text-xs font-semibold text-zinc-700 shadow-sm transition hover:bg-zinc-50"
70+
whileHover={{ scale: 1.04 }}
71+
whileTap={{ scale: 0.98 }}
72+
onClick={() => {
73+
if (typeof window !== "undefined") {
74+
window.localStorage.setItem(GUIDE_STORAGE_KEY, "true");
75+
}
76+
router.replace("/");
77+
}}
78+
>
79+
Skip
80+
</motion.button>
81+
<motion.div
82+
className="flex flex-col gap-1 text-center"
83+
key={`title-${currentPage}`}
84+
initial={{ opacity: 0, y: -10 }}
85+
animate={{ opacity: 1, y: 0 }}
86+
transition={{ duration: 0.3 }}
87+
>
88+
<p className="text-xs text-zinc-500">
89+
Chapter {currentPage + 1} / {totalPages}
90+
</p>
91+
<h2 className="text-xl font-semibold">{pages[currentPage].title}</h2>
92+
</motion.div>
93+
</header>
94+
95+
<div className="bg-card h-[65dvh] overflow-hidden rounded-3xl px-4 shadow-2xl">
96+
<AnimatePresence mode="wait" custom={direction}>
97+
<motion.div
98+
key={currentPage}
99+
custom={direction}
100+
variants={pageVariants}
101+
initial="enter"
102+
animate="center"
103+
exit="exit"
104+
transition={{
105+
x: { type: "spring", stiffness: 300, damping: 30 },
106+
opacity: { duration: 0.3 },
107+
scale: { duration: 0.3 },
108+
}}
109+
className="h-full w-full"
110+
>
111+
{pages[currentPage].node}
112+
</motion.div>
113+
</AnimatePresence>
112114
</div>
113115

114-
<div className="mt-8 flex items-center justify-between">
116+
<div className="flex items-center justify-between">
115117
<motion.button
116118
onClick={goPrev}
117119
disabled={currentPage === 0}
118-
className="flex items-center gap-2 rounded-full px-6 py-3 transition-all disabled:cursor-not-allowed disabled:opacity-30"
120+
className="flex items-center gap-2 rounded-full px-4 py-2 text-sm transition-all disabled:cursor-not-allowed disabled:opacity-30"
119121
style={{
120122
backgroundColor: currentPage === 0 ? "#F3F4F6" : "oklch(0.4758 0.2241 288.5 / 0.1)",
121123
color: currentPage === 0 ? "#9CA3AF" : "oklch(0.4758 0.2241 288.5)",
122124
}}
123125
whileHover={currentPage !== 0 ? { scale: 1.05, x: -5 } : {}}
124126
whileTap={currentPage !== 0 ? { scale: 0.95 } : {}}
125127
>
126-
<ChevronLeft className="h-5 w-5" />
128+
<ChevronLeft className="size-4" />
127129
<span className="font-medium">이전</span>
128130
</motion.button>
129131

130-
<div className="flex items-center gap-2">
132+
<div className="flex items-center gap-1.5">
131133
{pages.map((page, index) => (
132134
<motion.button
133135
key={page.title}
134136
onClick={() => goTo(index)}
135137
className="rounded-full transition-all"
136138
style={{
137-
width: index === currentPage ? "32px" : "8px",
138-
height: "8px",
139+
width: index === currentPage ? "28px" : "6px",
140+
height: "6px",
139141
backgroundColor:
140142
index === currentPage ? "oklch(0.4758 0.2241 288.5)" : "#D1D5DB",
141143
}}
@@ -149,7 +151,7 @@ export function Guidebook() {
149151
<motion.button
150152
onClick={goNext}
151153
disabled={currentPage === totalPages - 1}
152-
className="flex items-center gap-2 rounded-full px-6 py-3 transition-all disabled:cursor-not-allowed disabled:opacity-30"
154+
className="flex items-center gap-2 rounded-full px-4 py-2 text-sm transition-all disabled:cursor-not-allowed disabled:opacity-30"
153155
style={{
154156
backgroundColor:
155157
currentPage === totalPages - 1 ? "#F3F4F6" : "oklch(0.4758 0.2241 288.5)",
@@ -159,11 +161,11 @@ export function Guidebook() {
159161
whileTap={currentPage !== totalPages - 1 ? { scale: 0.95 } : {}}
160162
>
161163
<span className="font-medium">다음</span>
162-
<ChevronRight className="h-5 w-5" />
164+
<ChevronRight className="size-4" />
163165
</motion.button>
164166
</div>
165167
</div>
166-
</div>
168+
</Container>
167169
</div>
168170
);
169171
}

src/screens/guide/ui/pages/guidebook-page1.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ export function GuidebookPage1() {
1111
initial={{ opacity: 0, y: 20 }}
1212
animate={{ opacity: 1, y: 0 }}
1313
transition={{ delay: 0.1, duration: 0.6 }}
14-
className="mb-8"
14+
className="mb-6 max-[1024px]:mb-4"
1515
>
1616
<motion.h1
17-
className="mb-4 text-5xl font-bold"
17+
className="mb-3 text-4xl font-bold max-[1024px]:text-3xl"
1818
style={{ color: "oklch(0.4758 0.2241 288.5)" }}
1919
>
2020
네덜란드 경매
2121
</motion.h1>
2222
<motion.p
23-
className="text-xl text-gray-600"
23+
className="text-base text-gray-600 max-[1024px]:text-sm"
2424
initial={{ opacity: 0 }}
2525
animate={{ opacity: 1 }}
2626
transition={{ delay: 0.3, duration: 0.6 }}
@@ -30,14 +30,14 @@ export function GuidebookPage1() {
3030
</motion.div>
3131

3232
<motion.div
33-
className="mb-12 h-1 w-24 rounded-full"
33+
className="mb-8 h-1 w-20 rounded-full max-[1024px]:mb-6 max-[1024px]:w-16"
3434
style={{ backgroundColor: "oklch(0.4758 0.2241 288.5 / 0.3)" }}
3535
initial={{ width: 0 }}
3636
animate={{ width: 96 }}
3737
transition={{ delay: 0.5, duration: 0.6 }}
3838
/>
3939

40-
<div className="grid w-full max-w-3xl grid-cols-3 gap-8">
40+
<div className="grid w-full max-w-3xl grid-cols-1 gap-4 max-[1024px]:gap-3 sm:grid-cols-3">
4141
{KEYWORDS.map((keyword, index) => (
4242
<motion.div
4343
key={keyword.label}
@@ -47,15 +47,18 @@ export function GuidebookPage1() {
4747
className="flex flex-col items-center"
4848
>
4949
<motion.div
50-
className="mb-4 flex h-20 w-20 items-center justify-center rounded-full"
50+
className="mb-3 flex h-16 w-16 items-center justify-center rounded-full max-[1024px]:h-14 max-[1024px]:w-14"
5151
style={{ backgroundColor: "oklch(0.4758 0.2241 288.5 / 0.1)" }}
5252
whileHover={{ scale: 1.1, backgroundColor: "oklch(0.4758 0.2241 288.5 / 0.2)" }}
5353
>
54-
<keyword.icon className="h-10 w-10" style={{ color: "oklch(0.4758 0.2241 288.5)" }} />
54+
<keyword.icon
55+
className="h-8 w-8 max-[1024px]:h-7 max-[1024px]:w-7"
56+
style={{ color: "oklch(0.4758 0.2241 288.5)" }}
57+
/>
5558
</motion.div>
5659

5760
<motion.h3
58-
className="mb-2 text-xl font-semibold"
61+
className="mb-1 text-lg font-semibold max-[1024px]:text-base"
5962
style={{ color: "oklch(0.4758 0.2241 288.5)" }}
6063
>
6164
{keyword.label}
@@ -68,13 +71,13 @@ export function GuidebookPage1() {
6871
transition={{ delay: 0.8 + index * 0.15, duration: 0.6 }}
6972
/>
7073

71-
<p className="text-sm text-gray-600">{keyword.description}</p>
74+
<p className="text-xs text-gray-600 max-[1024px]:text-[11px]">{keyword.description}</p>
7275
</motion.div>
7376
))}
7477
</div>
7578

7679
<motion.p
77-
className="mt-12 max-w-2xl text-sm text-gray-500"
80+
className="mt-8 max-w-2xl text-xs text-gray-500 max-[1024px]:mt-6 max-[1024px]:text-[11px]"
7881
initial={{ opacity: 0 }}
7982
animate={{ opacity: 1 }}
8083
transition={{ delay: 1.5, duration: 0.6 }}

0 commit comments

Comments
 (0)