Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
9524364
โ™ป๏ธ ํ‰์ ์ด ์—†๋Š” ๊ฒฝ์šฐ ํ…์ŠคํŠธ ์ˆ˜์ •
seong5 Aug 2, 2025
39bd6ae
โ™ป๏ธ refactor: ์‚ญ์ œํ•˜๊ธฐ ๋ชจ๋‹ฌ ํ…์ŠคํŠธ ๋ณ€๊ฒฝ
seong5 Aug 2, 2025
4114120
โœจ feat: page ํŒŒ์ผ ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
98944b8
โœจ feat: main ์š”์†Œ ์Šคํƒ€์ผ ์„ค์ •
Moon-ju-young Aug 2, 2025
1cffd95
๐ŸŽจ style: main flex ์Šคํƒ€์ผ ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
44c413f
โ™ป๏ธ refactor: main > form ํƒœ๊ทธ ๋ณ€๊ฒฝ
Moon-ju-young Aug 2, 2025
817ff0b
โ™ป๏ธ refactor: ์ด๋ฏธ์ง€ ์žฅ์ˆ˜์— ๋”ฐ๋ผ ํ™”๋ฉด์— ์•Œ๋งž๊ฒŒ ์ฐจ๊ฒŒ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
seong5 Aug 2, 2025
b802e32
โœจ feat: h1 ์š”์†Œ ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
e4a6f3f
โœจ feat: searchParams ๋ฐ Button ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
3de78f5
โœจ feat: section ์š”์†Œ ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
296423a
โœจ feat: section ๋‚ด๋ถ€ div ์š”์†Œ ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
59dbe51
โœจ feat: ์ œ๋ชฉ input ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
ffa6427
โœจ feat: myActivities.ts ์— CATEGORY, RESERVATION_STATUS ์ƒ์ˆ˜ ๋ฐฐ์—ด ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
54c5a85
โœจ feat: ์นดํ…Œ๊ณ ๋ฆฌ ๋“œ๋กญ๋‹ค์šด ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
18b7b97
๐ŸŽจ style: TextareaInput ๋ˆ„๋ฝ ์Šคํƒ€์ผ ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
d1023dd
โœจ feat: ์„ค๋ช… input ๋ฐ isMobile ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
4b86567
โœจ feat: ๊ฐ€๊ฒฉ input ๋ฐ handlePriceChange ํ•จ์ˆ˜ ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
83e0341
โœจ feat: daum ์šฐํŽธ๋ฒˆํ˜ธ ์„œ๋น„์Šค๋ฅผ ์œ„ํ•œ script ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
8b73611
โœจ feat: handleAddress ๋ฐ ์ฃผ์†Œ Input ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
4935819
โœจ feat: DateInput ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
246ca2d
โœจ feat: DateInput ์ตœ์™ธ๊ณฝ div ์š”์†Œ ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
b5e6756
โœจ feat: DateInput input date ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
756173e
โœจ feat: DateInput Props type ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
5d7b127
๐Ÿ› fix: Props defaultValue optional๋กœ ๋ณ€๊ฒฝ
Moon-ju-young Aug 2, 2025
5cd7100
โœจ feat: DateInput ๋‚ ์งœ input ๋ถ€๋ถ„ ๋ถ„๊ธฐ
Moon-ju-young Aug 2, 2025
ce780ac
โœจ feat: DateInput button ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
66aaacf
๐ŸŽจ style: DateInput ์ผ๋ถ€ ์Šคํƒ€์ผ ์ˆ˜์ •
Moon-ju-young Aug 2, 2025
46bd2c1
โœจ feat: DateInput ์‹œ๊ฐ„ ๋ถ€๋ถ„ ๊ตฌ์กฐ ์„ธํŒ…
Moon-ju-young Aug 2, 2025
deb87c0
โœจ feat: DateInput ์‹œ๊ฐ„ input ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
71ddbbf
โœจ feat: DateInput ๊ธฐ๋ณธ๊ฐ’ ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
d45ffc8
๐ŸŽจ style: Input component ์Šคํƒ€์ผ ์ˆ˜์ •
Moon-ju-young Aug 2, 2025
592991e
๐ŸŽจ style: ๋””์ž์ธ ๋งž๊ฒŒ ์ˆ˜์ •
Moon-ju-young Aug 2, 2025
0de5900
โœจ feat: DateInput onClick ์ฒ˜๋ฆฌ ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
4ec38c1
โœจ feat: label ์š”์†Œ๋“ค ์ถ”๊ฐ€
Moon-ju-young Aug 2, 2025
149c64f
โ™ป๏ธ refactor: DateInput ๊ธฐ๋ณธ๊ฐ’ ๋‹ค์–‘ํ•œ ํ˜•์‹ ๊ณ ๋ ค
Moon-ju-young Aug 2, 2025
2b24891
โœจ feat: DateInput ์ฒจ๋ถ€
Moon-ju-young Aug 2, 2025
86dd9aa
๐ŸŽจ style: button ์œ„์น˜ ์กฐ์ •
Moon-ju-young Aug 2, 2025
23be2bf
โ™ป๏ธ refactor: DateInput ๊ฐœ์„ 
Moon-ju-young Aug 2, 2025
7e336f1
โœจ feat: DateCustomInput minLength ์ถ”๊ฐ€
Moon-ju-young Aug 3, 2025
db60d5d
๐Ÿ› fix: Input component event handler ๋ถ€๋ถ„ ์ˆ˜์ •
Moon-ju-young Aug 3, 2025
14f6129
โ™ป๏ธ refactor: DateCustomInput handleDateChange ํ•จ์ˆ˜ ์ˆ˜์ •
Moon-ju-young Aug 3, 2025
bc417b4
โœจ feat: DateInput errorMessage ๋ฐ disabled prop ์ถ”๊ฐ€
Moon-ju-young Aug 3, 2025
edec78d
โœจ feat: key state ์ถ”๊ฐ€๋กœ dropdown ์ดˆ๊ธฐํ™” ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Moon-ju-young Aug 3, 2025
93bfbbb
โœจ feat: dropdown ์„ ํƒ ํ™•์ธ state ์ถ”๊ฐ€ ๋ฐ hadleClick ๋กœ์ง ๋ณ€๊ฒฝ
Moon-ju-young Aug 3, 2025
09c169f
๐Ÿ› fix: schedule ์‚ญ์ œ logic ๋ณ€๊ฒฝ
Moon-ju-young Aug 3, 2025
398d50b
โœจ feat: query string id๊ฐ€ ์žˆ์„ ์‹œ ๊ธฐ์กด๊ฐ’ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
Moon-ju-young Aug 3, 2025
657627c
๐Ÿ› fix: dropdownInput prop ๋ณ€๊ฒฝ ์‹œ์—๋„ ๋ฐ˜์˜๋˜์ง€ ์•Š๋Š” ์˜ค๋ฅ˜ ์ˆ˜์ •
Moon-ju-young Aug 3, 2025
3004862
โœจ feat: modal / router ๋ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์˜ค๋ฅ˜ ์‹œ error ์ฒ˜๋ฆฌ ์ถ”๊ฐ€
Moon-ju-young Aug 3, 2025
7ffca52
Merge branch 'develop' into feat/133-myactivity-update-page
Moon-ju-young Aug 3, 2025
264def2
Merge branch 'develop' into fix/205-page-test
seong5 Aug 3, 2025
d4589f3
โœจ feat: imageUpload ๋ฐ ๊ด€๋ จ state ์ถ”๊ฐ€
Moon-ju-young Aug 3, 2025
64ecaa8
โ™ป๏ธ refactor: ์ด๋ฏธ์ง€ ์žฅ์ˆ˜์— ๋”ฐ๋ฅธ ์ด๋ฏธ์ง€ ํฌ๊ธฐ ๋ฐ ๋น„์œจ ์กฐ์ •
seong5 Aug 3, 2025
f651382
โ™ป๏ธ refactor: ์ฒดํ—˜์„ค๋ช… ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ
seong5 Aug 3, 2025
342ca8a
๐Ÿ”ฅ remove: ๋ถˆํ•„์š”ํ•œ margin ์ œ๊ฑฐ ๋ฐ padding ์ˆ˜์ •
seong5 Aug 3, 2025
23de9f6
โ™ป๏ธ refactor: ์ˆ˜์ •ํ•˜๊ธฐ ํŽ˜์ด์ง€ ๊ฒฝ๋กœ ๋ณ€๊ฒฝ
seong5 Aug 3, 2025
5388368
โ™ป๏ธ refactor: ์›” ์ด๋ฆ„ ์˜์–ด๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ํ•จ์ˆ˜ ์ด๋™
seong5 Aug 3, 2025
0af2cf0
Merge branch 'develop' into fix/205-page-test
seong5 Aug 3, 2025
2b8f8eb
โ™ป๏ธ refactor: ๋‚ด๊ฐ€ ์ƒ์„ฑํ•œ ์ฒดํ—˜์ธ ๊ฒฝ์šฐ alert ๋ฅผ Modal ๋กœ ๋ณ€๊ฒฝ
seong5 Aug 3, 2025
4067f0c
โœจ feat: ๋ฐฐ๋„ˆ์ด๋ฏธ์ง€ ์„œ๋ธŒ์ด๋ฏธ์ง€๊ฐ€ ์—†์„ ๋•Œ fallback ์œผ๋กœ ๋ฉ”์ธ ๋กœ๊ณ ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
seong5 Aug 3, 2025
00666e5
๐Ÿ› fix: signup์œผ๋กœ ์ด๋™ํ•˜๋Š”์ฃผ์†Œ ์ˆ˜์ •
dain823 Aug 3, 2025
b0a5664
๐Ÿ”ฅ remove: margin ์ œ๊ฑฐ 2์ฐจ
seong5 Aug 3, 2025
d086656
โœจ feat: ์ด๋ฏธ์ง€ ๋“œ๋ž˜๊ทธ ๋ฐฉ์ง€ํ•˜๋Š” ๊ธฐ๋Šฅ
seong5 Aug 3, 2025
42d9926
โ™ป๏ธ refactor: isSameMonth ํ•จ์ˆ˜ utils ๋กœ ์ด๋™
seong5 Aug 3, 2025
64f7c3a
๐Ÿ“chore: utils ํŒŒ์ผ ๊ฒฝ๋กœ ๋ณ€๊ฒฝ
seong5 Aug 3, 2025
7d631c3
โ™ป๏ธ refactor: activity ๋ฅผ ๊ฐ์ฒดํ™” ์‹œ์ผœ์„œ ์ƒํƒœ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋ฐ”๊ฟจ์Šต๋‹ˆ๋‹ค.
seong5 Aug 3, 2025
c494206
โœจ feat: ์นด์นด์˜ค๋งตํ‚ค ํƒ€์ž… ์„ค์ •
seong5 Aug 3, 2025
25098b4
๐Ÿ› fix: signup์œผ๋กœ ์ด๋™ํ•˜๋Š”์ฃผ์†Œ ์ˆ˜์ •
dain823 Aug 3, 2025
7de8707
๐Ÿ› fix: ํšŒ์›๊ฐ€์ž… ํ›„ ๋กœ๊ทธ์ธํŽ˜์ด์ง€๋กœ ์ด๋™
dain823 Aug 3, 2025
72f8960
โœจ feat: ํ”ผ๊ทธ๋งˆ๋Œ€๋กœ ๊ตฌํ˜„ ๋ชปํ•œ๋ถ€๋ถ„ ์ถ”๊ฐ€ ๊ตฌํ˜„
seong5 Aug 3, 2025
6e4eb3b
โœจ feat: ์ฐธ์—ฌ์ธ์›์ˆ˜ ๊ณ ๋ฅด๋Š” ๊ธฐ๋Šฅ ๋ถ„๋ฆฌ
seong5 Aug 3, 2025
4cf48bd
โ™ป๏ธ refactor: ๋‹ค์Œ๋‹จ๊ณ„ ์ด๋™ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๋ชจ๋‹ฌ์ด ๋‹ซํžˆ๋Š” ํ˜„์ƒ ์ˆ˜์ •
seong5 Aug 3, 2025
966eda2
โœจ feat: ํƒœ๋ธ”๋ฆฟ ํ™˜๊ฒฝ ํ”ผ๊ทธ๋งˆ ์‹œ์•ˆ์œผ๋กœ ๊ตฌํ˜„
seong5 Aug 3, 2025
134a54b
๐Ÿ› fix: ๋‹ค์Œ ์šฐํŽธ๋ฒˆํ˜ธ ์„œ๋น„์Šค ์˜ค๋ฅ˜ ์ˆ˜์ •
Moon-ju-young Aug 3, 2025
3517993
โœจ feat: ์ œ์ถœ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
Moon-ju-young Aug 3, 2025
a624056
โœจ feat: schedule ์ •๋ ฌ ๋ฐ ์ค‘๋ณต schedule ์ถ”๊ฐ€ ๋ฐฉ์ง€
Moon-ju-young Aug 4, 2025
5eeba73
๐Ÿ› fix: ๋‚ ์งœ ์ดˆ๊ธฐํ™”๊ฐ€ ๋œ ๋˜๋Š” ์˜ค๋ฅ˜ ์ˆ˜์ •
Moon-ju-young Aug 4, 2025
e544756
Merge branch 'develop' into feat/133-myactivity-update-page
Moon-ju-young Aug 4, 2025
d341710
๐Ÿ› fix: schedules ๋ถ€๋ถ„ ํ˜•์‹ ์˜ค๋ฅ˜ ์ˆ˜์ •
Moon-ju-young Aug 4, 2025
9ed0753
๐ŸŽจ style: ๋„ˆ๋น„ ์Šคํƒ€์ผ ์ˆ˜์ •
Moon-ju-young Aug 4, 2025
65b3c6b
โœจ feat: Suspense๋ฅผ ์œ„ํ•œ layout ํŒŒ์ผ ์ถ”๊ฐ€
Moon-ju-young Aug 4, 2025
2c294bb
โ™ป๏ธ refactor: script ์œ„์น˜ ๋ณ€๊ฒฝ
Moon-ju-young Aug 4, 2025
3eecaee
๐Ÿ› fix: schedules ๋ถ€๋ถ„ ํ˜•์‹ ํ˜ผ์šฉ ์˜ค๋ฅ˜ ์ˆ˜์ •
Moon-ju-young Aug 4, 2025
ba74233
๐Ÿ› fix: ํšŒ์›๊ฐ€์ž… ํ›„ ๋กœ๊ทธ์ธํŽ˜์ด์ง€๋กœ ์ด๋™
dain823 Aug 4, 2025
735ecbf
โ™ป๏ธ refactor: ์ฝ”๋“œ๋ฆฌ๋ทฐ ์ˆ˜์ •
seong5 Aug 4, 2025
a9c0f76
Merge pull request #214 from Act-It-FE/fix/205-page-test
seong5 Aug 4, 2025
1cc704b
Merge pull request #218 from Act-It-FE/feat/133-myactivity-update-page
Moon-ju-young Aug 4, 2025
61ef8a3
โœจ feat: ๊ฒ€์ƒ‰ ์‹œ ์Šคํฌ๋กค ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๋„๋ก ๊ตฌํ˜„
Yun-Jinwoo Aug 4, 2025
4d24a71
โ™ป๏ธ refactor: mypage/(Layout)/ ํด๋” ์ถ”๊ฐ€ ๋ฐ ์ด๋™
Moon-ju-young Aug 4, 2025
21274c4
โ™ป๏ธ refactor: mypage/(NoLayout)/ ํด๋” ์ถ”๊ฐ€ ๋ฐ ์ด๋™
Moon-ju-young Aug 4, 2025
28590d5
โœจ feat: favicon ์„ค์ •
Yun-Jinwoo Aug 4, 2025
13cd513
โœจ feat: ๋ฉ”ํƒ€ ๋ฐ์ดํƒ€ ์„ค์ •
Yun-Jinwoo Aug 4, 2025
36a7f08
๐ŸŽจ style: ๋””์ž์ธ ์˜ค๋ฅ˜ ์ˆ˜์ •
Moon-ju-young Aug 4, 2025
7016244
Merge pull request #223 from Act-It-FE/fix/219-add-acitvitiy-page-sidโ€ฆ
Moon-ju-young Aug 4, 2025
12895a7
๐Ÿ› fix: ์˜ค๋ฅ˜ ๋ชจ๋‹ฌ+์ด๋™ ์ฒ˜๋ฆฌ
dain823 Aug 4, 2025
7c8304e
๐Ÿ› fix: ActivityRegisterPayload schedule > schedules ์ด๋ฆ„ ๋ณ€๊ฒฝ
Moon-ju-young Aug 4, 2025
0c1ad93
Merge pull request #221 from Act-It-FE/feat/220-search-scroll
Yun-Jinwoo Aug 4, 2025
ab37e23
Merge pull request #222 from Act-It-FE/feat/settings-215
Yun-Jinwoo Aug 4, 2025
9367667
fix:ํ•„์š”์—†๋Š” ์ฝ”๋“œ ์‚ญ์ œ
dain823 Aug 4, 2025
ae3ffaa
Merge pull request #226 from Act-It-FE/fix/216-signup-to-login
Yun-Jinwoo Aug 4, 2025
3db02fc
Merge pull request #227 from Act-It-FE/fix/225-add-activity-post
Yun-Jinwoo Aug 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ interface ImportMetaEnv {
readonly NEXT_PUBLIC_API_BASE_URL: string;
readonly NEXT_PUBLIC_OAUTH_APP_KEY: string;
readonly NEXT_PUBLIC_APP_URL: string;
readonly NEXT_PUBLIC_KAKAO_MAP_KEY: string;
}

interface ImportMeta {
Expand Down
Binary file added public/images/actit-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/api/types/activities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export interface ActivityRegisterPayload {
price: number;
bannerImageUrl: string;
subImageUrls: string[];
schedule: ActivityRegisterSchedule[];
schedules: ActivityRegisterSchedule[];
}

export interface ActivityRegisterSchedule {
Expand Down
30 changes: 17 additions & 13 deletions src/api/types/myActivities.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
// refactoring ํ•„์š”
export type Category =
| '๋ฌธํ™” ยท ์˜ˆ์ˆ '
| '์‹์Œ๋ฃŒ'
| '์Šคํฌ์ธ '
| 'ํˆฌ์–ด'
| '๊ด€๊ด‘'
| '์›ฐ๋น™';
export const CATEGORY = [
'๋ฌธํ™” ยท ์˜ˆ์ˆ ',
'์‹์Œ๋ฃŒ',
'์Šคํฌ์ธ ',
'ํˆฌ์–ด',
'๊ด€๊ด‘',
'์›ฐ๋น™',
] as const;
export type Category = (typeof CATEGORY)[number];

// refactoring ํ•„์š”
// ReservationResponse, ReservationWithActivityResponse ์— ์‚ฌ์šฉ
export type ReservationStatus =
| 'pending'
| 'confirmed'
| 'declined'
| 'canceled'
| 'completed';
export const RESERVATION_STATUS = [
'pending',
'confirmed',
'declined',
'canceled',
'completed',
] as const;
export type ReservationStatus = (typeof RESERVATION_STATUS)[number];

// refactoring ํ•„์š”
export interface CreateScheduleBody {
Expand Down
54 changes: 2 additions & 52 deletions src/app/[activityId]/_components/ActivityDescription.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
'use client';

import { useActivityDescription } from '@/app/[activityId]/_hooks/useActivityDescription';
import {
getImageColumnWrapperClass,
getImageContainerClass,
getSubImageClass,
} from '@/app/[activityId]/_utils/getImageClass';

type Props = {
activityId: number;
};

export default function ActivityDescription({ activityId }: Props) {
const { description, bannerImageUrl, subImages, errorMessage, isLoading } =
const { description, isLoading, errorMessage } =
useActivityDescription(activityId);

const isSingleSubImage = subImages.length === 1;

if (isLoading) {
return (
<div className='border-primary-500 size-50 animate-spin rounded-full border-2 border-t-transparent' />
Expand All @@ -28,50 +21,7 @@ export default function ActivityDescription({ activityId }: Props) {
}

return (
<section className='my-40 flex flex-col gap-24'>
<div className='flex w-full gap-12'>
{bannerImageUrl && (
<div className={getImageContainerClass(isSingleSubImage)}>
<img
alt='๋ฐฐ๋„ˆ ์ด๋ฏธ์ง€'
className='h-full w-full rounded-tl-[24px] rounded-bl-[24px] object-cover'
src={bannerImageUrl}
/>
</div>
)}

<div
className={`flex ${getImageColumnWrapperClass(isSingleSubImage)} flex-col gap-12`}
>
{subImages[0] && (
<div className='aspect-[6/3] flex-1 overflow-hidden'>
<img
alt='์„œ๋ธŒ ์ด๋ฏธ์ง€ 1'
className={getSubImageClass({
isSingle: isSingleSubImage,
isFirst: true,
isLast: subImages.length === 1,
})}
src={subImages[0]}
/>
</div>
)}
{subImages[1] && !isSingleSubImage && (
<div className='aspect-[6/3] flex-1 overflow-hidden'>
<img
alt='์„œ๋ธŒ ์ด๋ฏธ์ง€ 2'
className={getSubImageClass({
isSingle: false,
isFirst: false,
isLast: true,
})}
src={subImages[1]}
/>
</div>
)}
</div>
</div>

<section className='flex flex-col gap-24'>
<div className='md:txt-18_B txt-16_B'>์ฒดํ—˜ ์„ค๋ช…</div>
<p className='txt-16_M whitespace-pre-line text-gray-950'>
{description}
Expand Down
109 changes: 109 additions & 0 deletions src/app/[activityId]/_components/ActivityDetailImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'use client';

import FallbackImage from '@/app/[activityId]/_components/FallbackImage';
import { useActivityDescription } from '@/app/[activityId]/_hooks/useActivityDescription';
import {
getImageColumnWrapperClass,
getSubImageClass,
} from '@/app/[activityId]/_utils/getImageClass';

type Props = {
activityId: number;
};

export default function ActivityDetailImage({ activityId }: Props) {
const { bannerImageUrl, subImages, errorMessage, isLoading } =
useActivityDescription(activityId);

const isSingleSubImage = subImages.length === 1;

if (isLoading) {
return (
<div className='border-primary-500 size-50 animate-spin rounded-full border-2 border-t-transparent' />
);
}

if (errorMessage) {
return <div className='text-center text-red-500'>{errorMessage}</div>;
}

const showOnlyFallbackImage =
!bannerImageUrl && (!subImages || subImages.length === 0);

return (
<section className='flex w-full gap-12'>
{showOnlyFallbackImage ? (
<div className='aspect-[6/3] w-full overflow-hidden rounded-[24px]'>
<FallbackImage
alt='๊ธฐ๋ณธ ์ด๋ฏธ์ง€'
className='h-full w-full object-cover'
src=''
/>
</div>
) : (
<>
{/* ๋ฐฐ๋„ˆ ์ด๋ฏธ์ง€ */}
{bannerImageUrl && (
<div
className={`aspect-[6/3] overflow-hidden ${
subImages.length === 0 ? 'w-full' : 'w-1/2'
}`}
>
<FallbackImage
alt='๋ฐฐ๋„ˆ ์ด๋ฏธ์ง€'
className={`h-full w-full rounded-tl-[24px] object-cover ${
subImages.length === 0
? 'rounded-tr-[24px] rounded-br-[24px] rounded-bl-[24px]'
: 'rounded-bl-[24px]'
}`}
src={bannerImageUrl}
/>
</div>
)}

{/* ์„œ๋ธŒ ์ด๋ฏธ์ง€ */}
{subImages.length > 0 && (
<div
className={`flex flex-col gap-12 ${getImageColumnWrapperClass(
isSingleSubImage,
)}`}
>
{subImages[0] && (
<div
className={`${
isSingleSubImage
? 'h-full flex-1 overflow-hidden'
: 'aspect-[6/3] flex-1 overflow-hidden'
}`}
>
<FallbackImage
alt='์„œ๋ธŒ ์ด๋ฏธ์ง€ 1'
className={getSubImageClass({
isSingle: isSingleSubImage,
isFirst: true,
isLast: subImages.length === 1,
})}
src={subImages[0]}
/>
</div>
)}
{subImages[1] && !isSingleSubImage && (
<div className='aspect-[6/3] flex-1 overflow-hidden'>
<FallbackImage
alt='์„œ๋ธŒ ์ด๋ฏธ์ง€ 2'
className={getSubImageClass({
isSingle: false,
isFirst: false,
isLast: true,
})}
src={subImages[1]}
/>
</div>
)}
</div>
)}
</>
)}
</section>
);
}
5 changes: 3 additions & 2 deletions src/app/[activityId]/_components/ActivityReviews.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export default function ActivityReviews({ activityId }: Props) {
} = useActivityReviews({ activityId });

const getRatingText = (rating: number) => {
if (rating >= 0 && rating <= 1) return '๋งค์šฐ ๋ถˆ๋งŒ์กฑ';
if (rating === 0) return 'ํ‰์ ์ด ์•„์ง ์—†์Šต๋‹ˆ๋‹ค.';
if (rating > 0 && rating <= 1) return '๋งค์šฐ ๋ถˆ๋งŒ์กฑ';
if (rating > 1 && rating <= 2) return '๋ถˆ๋งŒ์กฑ';
if (rating > 2 && rating <= 3) return '๋ณดํ†ต';
if (rating > 3 && rating <= 4) return '๋งŒ์กฑ';
Expand All @@ -32,7 +33,7 @@ export default function ActivityReviews({ activityId }: Props) {
};

return (
<div className='my-40'>
<div className='py-40'>
<div className='txt-16_B md:txt-18_B flex flex-row gap-10 leading-19 md:leading-21'>
์ฒดํ—˜ ํ›„๊ธฐ
<span className='md:txt-16_B txt-14_M leading-20 font-semibold text-gray-500 md:leading-20'>
Expand Down
5 changes: 3 additions & 2 deletions src/app/[activityId]/_components/ActivitySummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ export default function ActivitySummary({ activityId }: Props) {
const { averageRating, totalCount } = review;

return (
<section className='relative my-20 flex flex-col gap-6 md:my-40'>
<section className='relative flex flex-col gap-6'>
{isMyActivity && (
<div className='absolute top-0 right-0'>
<DropDown
items={[
{
text: '์ˆ˜์ •ํ•˜๊ธฐ',
onClick: () =>
router.push(`/mypage/add-activity?id={activityId}`),
router.push(`/mypage/add-activity?id=${activityId}`),
},
{
text: '์‚ญ์ œํ•˜๊ธฐ',
Expand Down Expand Up @@ -121,6 +121,7 @@ export default function ActivitySummary({ activityId }: Props) {
{isModalOpen && (
<div className='fixed inset-0 z-50 flex items-center justify-center bg-black/50'>
<WarningContent
confirmText='์‚ญ์ œํ•˜๊ธฐ'
message='์ฒดํ—˜์„ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?'
variant='warning'
onCancel={() => setIsModalOpen(false)}
Expand Down
30 changes: 30 additions & 0 deletions src/app/[activityId]/_components/FallbackImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { SyntheticEvent } from 'react';

type FallbackImageProps = {
src?: string;
alt: string;
className?: string;
fallbackSrc?: string; // ์ปค์Šคํ…€ fallback ์ด๋ฏธ์ง€๋„ ํ—ˆ์šฉ
};

export default function FallbackImage({
src,
alt,
className,
fallbackSrc = '/images/logo-lg.png',
}: FallbackImageProps) {
const handleError = (e: SyntheticEvent<HTMLImageElement, Event>) => {
const target = e.currentTarget;
target.src = fallbackSrc;
};

return (
<img
alt={alt}
className={className}
draggable={false}
src={src || fallbackSrc}
onError={handleError}
/>
);
}
Loading