Skip to content

Commit fedb3db

Browse files
authored
Merge pull request #159 from codeit-2team/fix/158
Fix/158 리팩토링
2 parents 044afb7 + 93acc70 commit fedb3db

38 files changed

+412
-491
lines changed

next.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ const nextConfig: NextConfig = {
1717
},
1818
],
1919
},
20+
21+
compiler: {
22+
removeConsole: process.env.NODE_ENV === 'production',
23+
},
2024
};
2125

2226
export default nextConfig;

public/assets/img/default-bg.png

854 Bytes
Loading

src/app/(with-header)/activities/[id]/components/ActivityDetailForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export default function ActivityDetailForm() {
138138
<LocationMap address={activityData.address} />
139139

140140
<ReviewSection
141-
activityId={id as string}
141+
activityId={Number(id)}
142142
reviewCount={activityData.reviewCount}
143143
rating={activityData.rating}
144144
/>

src/app/(with-header)/activities/[id]/components/ImageGrid.tsx

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,41 @@ import Image from 'next/image';
44
import React, { useState } from 'react';
55
import { ImageGridProps } from '@/types/activityDetailType';
66
import { AnimatePresence, motion } from 'framer-motion';
7+
import Modal from '@/components/Modal';
8+
import { DEFAULT_BG } from '@/constants/AvatarConstants';
79

810
function ImageGrid({ mainImage, subImages }: ImageGridProps) {
9-
const images = [mainImage, ...subImages];
10-
11+
const [image, setImage] = useState([mainImage, ...subImages]);
1112
const [currentIndex, setCurrentIndex] = useState(0);
1213
const [direction, setDirection] = useState(0);
14+
const [isOpen, setIsOpen] = useState(false);
15+
const [selectedImage, setSelectedImage] = useState<string | null>(null);
16+
17+
const handleImageClick = (image: string) => {
18+
setSelectedImage(image);
19+
setIsOpen(true);
20+
};
21+
22+
const handleImageError = (index: number) => {
23+
setImage((prev) => prev.map((src, i) => (i === index ? DEFAULT_BG : src)));
24+
};
1325

1426
const prevSlide = () => {
1527
setDirection(-1);
16-
setCurrentIndex((prev) => (prev === 0 ? images.length - 1 : prev - 1));
28+
setCurrentIndex((prev) => (prev === 0 ? image.length - 1 : prev - 1));
1729
};
1830

1931
const nextSlide = () => {
2032
setDirection(1);
21-
setCurrentIndex((prev) => (prev === images.length - 1 ? 0 : prev + 1));
33+
setCurrentIndex((prev) => (prev === image.length - 1 ? 0 : prev + 1));
2234
};
2335

2436
const variants = {
2537
enter: (direction: number) => ({
2638
x: direction > 0 ? 300 : -300,
2739
opacity: 0,
2840
}),
29-
center: {
30-
x: 0,
31-
opacity: 1,
32-
},
41+
center: { x: 0, opacity: 1 },
3342
exit: (direction: number) => ({
3443
x: direction > 0 ? -300 : 300,
3544
opacity: 0,
@@ -55,11 +64,13 @@ function ImageGrid({ mainImage, subImages }: ImageGridProps) {
5564
className='absolute inset-0'
5665
>
5766
<Image
58-
src={images[currentIndex]}
59-
alt={` ${currentIndex + 1}`}
67+
src={image[currentIndex]}
68+
alt={`${currentIndex + 1}`}
6069
fill
6170
className='rounded-lg object-cover'
6271
priority
72+
unoptimized
73+
onError={() => handleImageError(currentIndex)}
6374
/>
6475
</motion.div>
6576
</AnimatePresence>
@@ -81,7 +92,7 @@ function ImageGrid({ mainImage, subImages }: ImageGridProps) {
8192
</button>
8293

8394
<div className='absolute bottom-2 left-1/2 flex -translate-x-1/2 gap-1'>
84-
{images.map((_, i) => (
95+
{image.map((_, i) => (
8596
<div
8697
key={i}
8798
className={`h-10 w-10 rounded-full ${
@@ -94,28 +105,55 @@ function ImageGrid({ mainImage, subImages }: ImageGridProps) {
94105

95106
{/* PC/태블릿 */}
96107
<div className='hidden h-[500px] grid-cols-4 grid-rows-4 gap-6 md:grid'>
97-
<div className='relative col-span-2 row-span-4 hover:animate-pulse'>
108+
<div
109+
onClick={() => handleImageClick(mainImage)}
110+
className='relative col-span-2 row-span-4 hover:animate-pulse'
111+
>
98112
<Image
99-
src={mainImage}
113+
src={image[0]}
100114
alt='메인이미지'
101115
fill
102116
className='rounded-lg object-cover'
117+
onError={() => handleImageError(0)}
103118
/>
104119
</div>
105-
{subImages.slice(0, 4).map((image, index) => (
120+
{image.slice(1, 5).map((image, index) => (
106121
<div
107-
key={index}
122+
key={index + 1}
123+
onClick={() => handleImageClick(image)}
108124
className='relative col-span-1 row-span-2 h-full hover:animate-pulse'
109125
>
110126
<Image
111127
src={image}
112128
alt={`서브이미지 ${index + 1}`}
113129
fill
114130
className='rounded-lg object-cover'
131+
onError={() => handleImageError(index + 1)}
115132
/>
116133
</div>
117134
))}
118135
</div>
136+
<Modal onOpenChange={setIsOpen} isOpen={isOpen}>
137+
<Modal.Content className='rounded-md'>
138+
<Modal.Header>
139+
<Modal.Close />
140+
</Modal.Header>
141+
<Modal.Item className='flex items-center justify-center'>
142+
<div className='relative aspect-square w-[1200px]'>
143+
{selectedImage && (
144+
<Image
145+
src={selectedImage}
146+
alt='확대 이미지'
147+
fill
148+
className='rounded-lg object-cover p-18'
149+
/>
150+
)}
151+
</div>
152+
</Modal.Item>
153+
154+
<Modal.Footer></Modal.Footer>
155+
</Modal.Content>
156+
</Modal>
119157
</>
120158
);
121159
}

src/app/(with-header)/activities/[id]/components/ReviewSection.tsx

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,9 @@ import { privateInstance } from '@/apis/privateInstance';
99
import ReviewTitle from './ReviewTitle';
1010
import useUserStore from '@/stores/authStore';
1111
import cn from '@/lib/cn';
12-
1312
import ReviewCardSkeleton from './Skeletons/ReviewCardSkeleton';
14-
15-
interface ReviewSectionProps {
16-
activityId: string;
17-
reviewCount: number;
18-
rating: number;
19-
}
20-
21-
interface ReviewProps {
22-
id: string;
23-
user: {
24-
nickname: string;
25-
profileImageUrl: string;
26-
};
27-
createdAt: string;
28-
content: string;
29-
}
13+
import { ReviewSectionProps } from '@/types/activityDetailType';
14+
import { ReviewProps } from '@/types/activityDetailType';
3015

3116
function ReviewSection({
3217
activityId,

src/app/(with-header)/activities/[id]/components/ReviewTitle.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@
22

33
import Star from '@assets/svg/star';
44
import { useState, useEffect } from 'react';
5+
import { ReviewTitleProps } from '@/types/activityDetailType';
56

6-
interface ReviewTitleProps {
7-
reviewCount: number;
8-
rating: number;
9-
}
107
export default function ReviewTitle({
118
reviewCount = 0,
129
rating = 0,

src/app/(with-header)/activities/[id]/components/Title.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,7 @@ import { useParams, useRouter } from 'next/navigation';
1111
import { useQueryClient } from '@tanstack/react-query';
1212
import { useDeleteActivity } from '../hooks/useDeleteActivity';
1313
import Popup from '@/components/Popup';
14-
15-
interface TitleProps {
16-
title: string;
17-
category: string;
18-
rating: number;
19-
reviewCount: number;
20-
address: string;
21-
isOwner: boolean;
22-
}
14+
import { TitleProps } from '@/types/activityDetailType';
2315

2416
function Title({
2517
title,
@@ -43,10 +35,9 @@ function Title({
4335

4436
const handleDeleteConfirm = () => {
4537
if (!id) return;
46-
mutate(id as string);
38+
mutate(Number(id));
4739
setIsPopupOpen(false);
4840
};
49-
5041

5142
return (
5243
<>

src/app/(with-header)/activities/[id]/hooks/useDeleteActivity.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { AxiosError } from 'axios';
44
import { useRouter } from 'next/navigation';
55
import { toast } from 'sonner';
66

7-
const deleteActivity = async (id: string) => {
7+
const deleteActivity = async (id: number) => {
88
const response = await privateInstance.delete(`/deleteActivity/${id}`);
99
return response.data;
1010
};
@@ -23,6 +23,7 @@ export const useDeleteActivity = () => {
2323
});
2424
queryClient.invalidateQueries({ queryKey: ['popularExperiences'] });
2525
router.push(`/`);
26+
toast.success('체험이 삭제되었습니다!');
2627
},
2728
onError: (error: AxiosError) => {
2829
const responseData = error.response?.data as

src/app/(with-header)/activities/[id]/mock/mock.ts

Lines changed: 0 additions & 58 deletions
This file was deleted.

src/app/(with-header)/myactivity/[id]/components/EditActivityForm.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,7 @@ import { ScheduleSelectForm } from '../../components/ScheduleSelectForm';
66
import { ImageSection } from '../../components/ImageSection';
77
import { useEditActivityForm } from '../hooks/useEditActivityForm';
88
import EditActivityFormSkeleton from '../../loading';
9-
10-
interface SubImageType {
11-
id?: number;
12-
url: string | File;
13-
}
9+
import { SubImageType } from '@/types/addEditExperienceType';
1410

1511
export default function EditActivityForm() {
1612
const {

0 commit comments

Comments
 (0)