Skip to content

Commit 365e90e

Browse files
jun-0411young-52
andauthored
๐Ÿ’„ Fix the event page & user avatar UI (#117)
### ๐Ÿ“ ์ž‘์—… ๋‚ด์šฉ - ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ์—์„œ ์ฐธ์—ฌ์ž ํŽ˜์ด์ง€์™€ ์ผ์ • ์ƒ์„ธ ํŽ˜์ด์ง€์˜ ์ฐธ์—ฌ์ž ๋ฏธ๋ฆฌ๋ณด๊ธฐ ui๊ฐ€ ๊นจ์ง€๋Š” ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. - ์•„๋ฐ”ํƒ€ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋””์ž์ธ์„ `UserAvatar` ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๋“ค๊ณ  ํ—ค๋”, ์ฐธ์—ฌ์ž ๋ฏธ๋ฆฌ๋ณด๊ธฐ, ์ฐธ์—ฌ์ž ํŽ˜์ด์ง€์— ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ### ๐Ÿ“ธ ์Šคํฌ๋ฆฐ์ƒท (์„ ํƒ) <img width="560" height="997" alt="์Šคํฌ๋ฆฐ์ƒท 2026-03-06 234933" src="https://github.com/user-attachments/assets/be5e420e-c82a-4b05-844f-6186aae442f3" /> <img width="1901" height="1295" alt="์Šคํฌ๋ฆฐ์ƒท 2026-03-06 234940" src="https://github.com/user-attachments/assets/611a3aa8-9204-4a55-884a-803e56300334" /> <img width="561" height="1000" alt="์Šคํฌ๋ฆฐ์ƒท 2026-03-06 234953" src="https://github.com/user-attachments/assets/0b085c55-65b6-4176-9046-93a1b03074d9" /> <img width="1889" height="1296" alt="์Šคํฌ๋ฆฐ์ƒท 2026-03-06 234959" src="https://github.com/user-attachments/assets/e69d3eb2-3df4-41bd-af26-a99a83df438b" /> ### ๐Ÿš€ ๋ฆฌ๋ทฐ ์š”๊ตฌ์‚ฌํ•ญ (์„ ํƒ) - ํ”„๋กœํ•„ ์ด๋ฏธ์ง€๊ฐ€ ์—†์„ ๋•Œ ๋””์ž์ธ์€ ์ž„์˜๋กœ ๋งŒ๋“ค์–ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ํ˜น์‹œ ์–ด๋– ์‹ ๊ฐ€์š”..? - ํ—ค๋” ๋ถ€๋ถ„์˜ ํ”„๋กœํ•„ ์ด๋ฏธ์ง€ ์•„๋ฐ”ํƒ€๋„ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ํฌ๊ธฐ๊ฐ€ ๋ณ€ํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. - ํ—ค๋” ๋†’์ด๊ฐ€ ๋ณ€ํ•˜๋ฉด ๋‹ค๋ฅธ ํŽ˜์ด์ง€์—์„œ ๋ณธ๋ฌธ์„ ๊ฐ€๋ฆฌ๋Š” ๋“ฑ ์˜ค๋ฅ˜๊ฐ€ ๋‚ ๊นŒ ์‹ถ์–ด ๊ธฐ์กด ํฌ๊ธฐ์˜€๋˜ 64px๋กœ ๊ณ ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์‚ฌ์‹ค ํ—ค๋” ์•„๋ฐ”ํƒ€ ํฌ๊ธฐ๋Š” ๋ณ€ํ•˜์ง€ ์•Š์•„๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ์›น์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํฌ๊ธฐ๋ฅผ ๋ณด๋ฉด ํ—ค๋”๊ฐ€ ๋„ˆ๋ฌด ๊ฝ‰ ์ฐจ์žˆ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค๊ธฐ๋„ ํ•ด์„œ ๊ทธ๋ƒฅ ๋ชจ๋ฐ”์ผ ๋ฒ„์ „์˜ ํฌ๊ธฐ๋กœ ์•„๋ฐ”ํƒ€๋ฅผ ๊ณ ์ •ํ• ๊นŒ์š”? - ์—ฌ๋Ÿฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ์„œ๋กœ ์ข…์†์ ์ธ ๋‚ด์šฉ์ด ์—†์œผ๋ฉด, ์ž‘์—…๋ฌผ2 ๋ธŒ๋žœ์น˜๋ฅผ ์ž‘์—…๋ฌผ1 ๋ธŒ๋žœ์น˜์—์„œ ๋งŒ๋“œ๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ๊ทธ๋ƒฅ main(dev)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋”ฐ๋กœ ๋งŒ๋“ค๋ผ๋Š” ์ œ๋ฏธ๋‚˜์ด์˜ ์กฐ์–ธ์„ ๋ฐ›์•„ ์ด๋ฒˆ ์ž‘์—…์€ `feat/api-registragion-delete`์ด ์•„๋‹Œ `dev`๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฆฌ๋ทฐํ•˜๊ธฐ ๋” ํŽธํ•˜์‹œ๋ฉด ์•ž์œผ๋กœ ์ด๋Ÿฐ ์‹์œผ๋กœ ์ž‘์—…ํ• ๊ฒŒ์š”. --------- Co-authored-by: Park Junyoung <bloomwayz@snu.ac.kr>
1 parent be9508d commit 365e90e

File tree

6 files changed

+62
-37
lines changed

6 files changed

+62
-37
lines changed

โ€Žsrc/components/GuestsPreview.tsxโ€Ž

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
1+
import UserAvatar from '@/components/UserAvatar';
22
import type { UserPreview } from '@/types/events';
33
import type { EventId } from '@/types/schemas';
44
import { ChevronRightIcon } from 'lucide-react';
@@ -36,27 +36,19 @@ export default function GuestsPreview({
3636
</button>
3737

3838
{/* ์•„๋ฐ”ํƒ€ ๋ฐ ํ”Œ๋Ÿฌ์Šค ์•„์ด์ฝ˜ ๋ฐฐ์น˜ ์˜์—ญ */}
39-
<div className="flex items-center justify-start gap-2.5">
39+
<div className="flex items-center justify-start gap-1.5 sm:gap-3 min-w-0 flex-1">
4040
{/* ์ตœ๋Œ€ 5๊ฐœ์˜ ์•„๋ฐ”ํƒ€ ๋…ธ์ถœ */}
4141
{guests.map((p) => (
42-
<Avatar
42+
<UserAvatar
4343
key={p.id}
44-
title={p.name}
45-
className="w-16 h-16 border-none shadow-sm"
46-
>
47-
<AvatarImage
48-
src={p.profileImage ?? undefined}
49-
className="object-cover"
50-
/>
51-
<AvatarFallback className="bg-blue-100 text-primary text-sm font-bold">
52-
{p.name?.slice(0, 2)}
53-
</AvatarFallback>
54-
</Avatar>
44+
name={p.name}
45+
imageUrl={p.profileImage ?? undefined}
46+
/>
5547
))}
5648

5749
{/* ์กฐ๊ฑด๋ถ€ ํ”Œ๋Ÿฌ์Šค(+) ์•„์ด์ฝ˜ (์ตœ๋Œ€ 6๋ฒˆ์งธ ์ž๋ฆฌ์— ๋ฐฐ์น˜) */}
5850
{showPlusIcon && (
59-
<div className="w-16 h-16 rounded-full bg-gray-100 flex items-center justify-center border border-gray-50 shadow-sm">
51+
<div className="w-12 h-12 sm:w-16 sm:h-16 rounded-full bg-gray-100 flex items-center justify-center border border-gray-50 shadow-sm shrink-0">
6052
<span className="text-sm font-bold text-gray-500">
6153
+{extraCount}
6254
</span>

โ€Žsrc/components/Header.tsxโ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ export default function Header() {
2424
}, [isLoggedIn, refreshUser]);
2525

2626
return (
27-
<header className="sticky top-0 z-40 flex w-full justify-center border bg-white">
28-
<div className="flex w-full items-center justify-between px-6 py-4 sm:w-screen-sm md:w-screen-md lg:w-screen-lg xl:max-w-screen-xl">
27+
<header className="sticky top-0 z-40 flex w-full h-16 justify-center border-b box-content bg-white">
28+
<div className="flex w-full h-full items-center justify-between px-6 sm:w-screen-sm md:w-screen-md lg:w-screen-lg xl:max-w-screen-xl">
2929
<Link to="/" className="flex items-center space-x-2">
3030
<img src="/moiming-symbol.svg" alt="logo" />
3131
<p className="moiming">๋ชจ์ด๋ฐ</p>

โ€Žsrc/components/ProfileButton.tsxโ€Ž

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
1+
import UserAvatar from '@/components/UserAvatar';
22
import {
33
DropdownMenu,
44
DropdownMenuContent,
@@ -30,10 +30,12 @@ export default function ProfileButton({
3030
<DropdownMenu>
3131
<DropdownMenuTrigger asChild>
3232
<button>
33-
<Avatar className="border-2">
34-
<AvatarImage src={user.profileImage} />
35-
<AvatarFallback>CN</AvatarFallback>
36-
</Avatar>
33+
<UserAvatar
34+
name={user.name}
35+
imageUrl={user.profileImage}
36+
className="w-8 h-8 sm:w-10 sm:h-10 border-2"
37+
fallbackClassName="text-[10px] sm:text-[12px]"
38+
/>
3739
</button>
3840
</DropdownMenuTrigger>
3941
<DropdownMenuContent className="w-40" align="end">
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
2+
3+
interface UserAvatarProps {
4+
name?: string | null;
5+
imageUrl?: string | null;
6+
className?: string; // ์ปจํ…Œ์ด๋„ˆ(Avatar)์šฉ ํด๋ž˜์Šค
7+
fallbackClassName?: string; // ์ด๋‹ˆ์…œ(AvatarFallback)์šฉ ํด๋ž˜์Šค
8+
}
9+
10+
export default function UserAvatar({
11+
name,
12+
imageUrl,
13+
className = '',
14+
fallbackClassName = '',
15+
}: UserAvatarProps) {
16+
return (
17+
<Avatar
18+
className={`w-12 h-12 sm:w-16 sm:h-16 border-none shadow-sm shrink-0 ${className}`.trim()}
19+
title={name ?? undefined}
20+
>
21+
<AvatarImage
22+
src={imageUrl ?? undefined}
23+
alt={name ?? '์‚ฌ์šฉ์ž ์•„๋ฐ”ํƒ€'}
24+
className="object-cover"
25+
/>
26+
<AvatarFallback
27+
className={`bg-blue-100 text-primary text-xs sm:text-sm font-semibold ${fallbackClassName}`.trim()}
28+
>
29+
{name?.slice(0, 3)}
30+
</AvatarFallback>
31+
</Avatar>
32+
);
33+
}

โ€Žsrc/mocks/handlers/event.tsโ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export const eventHandlers = [
6060
name: `์ฐธ์—ฌ์ž ${i + 1}`,
6161
email: i < 8 ? `user${i}@example.com` : null,
6262
status: i < 8 ? 'CONFIRMED' : 'WAITLISTED',
63-
profileImage: 'https://github.com/shadcn.png',
63+
profileImage: i != 1 ? 'https://github.com/shadcn.png' : undefined,
6464
createdAt: new Date().toISOString(),
6565
waitingNum: i >= 8 ? i - 7 : null,
6666
})),

โ€Žsrc/routes/Guests.tsxโ€Ž

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useNavigate, useParams } from 'react-router';
66
import { toast } from 'sonner';
77
import useInfiniteGuests from '../hooks/useInfiniteGuests';
88

9+
import UserAvatar from '@/components/UserAvatar';
910
// shadcn UI ์ปดํฌ๋„ŒํŠธ
1011
import {
1112
AlertDialog,
@@ -18,7 +19,6 @@ import {
1819
AlertDialogTitle,
1920
AlertDialogTrigger,
2021
} from '@/components/ui/alert-dialog';
21-
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
2222
import { Button } from '@/components/ui/button';
2323
import type { GuestStatus } from '@/types/schemas';
2424
import { ChevronLeftIcon, Loader2 } from 'lucide-react';
@@ -118,24 +118,22 @@ export default function Guests() {
118118
page.participants.map((guest) => (
119119
<div
120120
key={guest.registrationId}
121-
className="flex items-center justify-between w-full"
121+
className="flex items-center justify-between w-full gap-2 sm:gap-4"
122122
>
123-
<div className="flex items-center gap-4">
124-
<Avatar className="w-16 h-16 border-none shadow-sm">
125-
<AvatarImage src={guest.profileImage || undefined} />
126-
<AvatarFallback className="bg-black text-white text-xs">
127-
{guest.name?.slice(0, 2)}
128-
</AvatarFallback>
129-
</Avatar>
130-
<div className="flex flex-col">
131-
<span className="text-xl font-bold text-black">
123+
<div className="flex items-center gap-3 sm:gap-4 min-w-0 flex-1">
124+
<UserAvatar name={guest.name} imageUrl={guest.profileImage} />
125+
126+
<div className="flex flex-col min-w-0 flex-1">
127+
<span className="text-lg sm:text-xl font-bold text-black truncate">
132128
{guest.name}
133129
</span>
134130
{guest.email ? (
135-
<span className="text-gray-400 text-lg">{guest.email}</span>
131+
<span className="text-sm sm:text-lg text-gray-400 truncate">
132+
{guest.email}
133+
</span>
136134
) : null}
137135
{guest.status === 'WAITLISTED' && (
138-
<span className="text-blue-400 text-lg font-semibold">
136+
<span className="text-sm sm:text-lg text-blue-400 font-semibold truncate">
139137
๋Œ€๊ธฐ {guest.waitingNum}๋ฒˆ
140138
</span>
141139
)}
@@ -148,7 +146,7 @@ export default function Guests() {
148146
<AlertDialogTrigger asChild>
149147
<Button
150148
variant="secondary"
151-
className="bg-[#333333] hover:bg-black text-white rounded-lg px-4 py-6 text-base font-bold"
149+
className="bg-[#333333] hover:bg-black text-white rounded-lg px-3 py-2 sm:px-4 sm:py-3 h-auto text-sm sm:text-base font-bold shrink-0"
152150
>
153151
๊ฐ•์ œ์ทจ์†Œ
154152
</Button>

0 commit comments

Comments
ย (0)