Skip to content

Commit e8ef2fb

Browse files
committed
Merge branch 'develop' into feature/16
2 parents 22fdf1e + a665244 commit e8ef2fb

File tree

21 files changed

+452
-19
lines changed

21 files changed

+452
-19
lines changed

public/assets/svg/dropdown.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react';
2+
3+
interface IconBellProps extends React.SVGProps<SVGSVGElement> {
4+
size?: number;
5+
color?: string;
6+
}
7+
8+
const IconDropdown = ({ size = 64, color = '#000', ...props }) => (
9+
<svg
10+
width={size}
11+
height={size}
12+
viewBox='0 0 52 52'
13+
fill={color}
14+
xmlns='http://www.w3.org/2000/svg'
15+
{...props}
16+
>
17+
<path
18+
fill='#535358'
19+
d='M16 10a2 2 0 100-4 2 2 0 000 4zM16 18a2 2 0 100-4 2 2 0 000 4zM16 26a2 2 0 100-4 2 2 0 000 4z'
20+
/>
21+
</svg>
22+
);
23+
24+
export default IconDropdown;

public/assets/svg/location.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react';
2+
3+
const Location = ({ size = 24, color = '#9fa6b2', ...props }) => (
4+
<svg
5+
xmlns='http://www.w3.org/2000/svg'
6+
width={size}
7+
height={size}
8+
fill={color}
9+
viewBox='0 0 24 24'
10+
11+
>
12+
<path
13+
fill='#121'
14+
d='M9 7.875a1.125 1.125 0 1 0 0-2.25 1.125 1.125 0 0 0 0 2.25'
15+
></path>
16+
<path
17+
fill='#121'
18+
d='M9 1.125c-3.101 0-5.625 2.413-5.625 5.379 0 1.412.644 3.29 1.913 5.582 1.02 1.84 2.2 3.504 2.813 4.332a1.117 1.117 0 0 0 1.8 0c.613-.828 1.793-2.492 2.813-4.332 1.267-2.291 1.911-4.17 1.911-5.582 0-2.966-2.524-5.379-5.625-5.379M9 9a2.25 2.25 0 1 1 0-4.5A2.25 2.25 0 0 1 9 9'
19+
></path>
20+
</svg>
21+
);
22+
23+
export default Location;

public/test/image1.png

2.37 MB
Loading

public/test/image2.png

980 KB
Loading

public/test/image3.png

396 KB
Loading

public/test/image4.png

1.38 MB
Loading

public/test/image5.png

709 KB
Loading

src/app/(non-header)/layout.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Layout({ children }: { children: React.ReactNode }) {
2+
return <main className='min-h-screen'>{children}</main>;
3+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
'use client';
2+
3+
import Image from 'next/image';
4+
import React, { useState } from 'react';
5+
6+
interface ActivityImageProps {
7+
mainImage: string;
8+
subImages: string[];
9+
}
10+
11+
export default function ImageGrid({
12+
mainImage,
13+
subImages,
14+
}: ActivityImageProps) {
15+
const images = [mainImage, ...subImages];
16+
const [currentIndex, setCurrentIndex] = useState(0); //캐러셀 구현용 state
17+
18+
// 첫번째 이미지면 마지막 이미지로 아니면 -1
19+
const prevSlide = () => {
20+
setCurrentIndex((prev) => (prev === 0 ? images.length - 1 : prev - 1));
21+
};
22+
23+
// 현재 마지막 이미지면 첫 이미지로 아니면 +1
24+
const nextSlide = () => {
25+
setCurrentIndex((prev) => (prev === images.length - 1 ? 0 : prev + 1));
26+
};
27+
28+
return (
29+
<>
30+
{/* 모바일 */}
31+
<div className='relative block aspect-square h-[300px] w-full overflow-hidden rounded-lg md:hidden'>
32+
<Image
33+
src={images[currentIndex]}
34+
alt={`${currentIndex + 1}`}
35+
fill
36+
className='object-cover hover:animate-pulse'
37+
/>
38+
39+
<button
40+
onClick={prevSlide}
41+
className='absolute top-1/2 left-2 -translate-y-1/2 rounded-full bg-black/50 px-6 py-10 text-white'
42+
>
43+
44+
</button>
45+
<button
46+
onClick={nextSlide}
47+
className='absolute top-1/2 right-2 -translate-y-1/2 rounded-full bg-black/50 px-6 py-10 text-white'
48+
>
49+
50+
</button>
51+
52+
<div className='absolute bottom-2 left-1/2 flex -translate-x-1/2 gap-1'>
53+
{images.map((_, i) => (
54+
<div
55+
key={i}
56+
className={`h-10 w-10 rounded-full ${
57+
i === currentIndex ? 'bg-white' : 'bg-white/40'
58+
}`}
59+
/>
60+
))}
61+
</div>
62+
</div>
63+
{/* PC 태블릿 */}
64+
<div className='hidden h-[500px] grid-cols-4 grid-rows-4 gap-6 md:grid'>
65+
<div className='relative col-span-2 row-span-4 hover:animate-pulse'>
66+
<Image
67+
src={mainImage}
68+
alt='메인이미지'
69+
fill
70+
className='rounded-lg object-cover'
71+
/>
72+
</div>
73+
74+
{subImages.slice(0, 4).map((image, index) => (
75+
<div
76+
key={index}
77+
className='relative col-span-1 row-span-2 h-full hover:animate-pulse'
78+
>
79+
<Image
80+
src={image}
81+
alt={`서브이미지 ${index + 1}`}
82+
fill
83+
className='rounded-lg object-cover'
84+
/>
85+
</div>
86+
))}
87+
</div>
88+
</>
89+
);
90+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react';
2+
import IconDropdown from '@assets/svg/dropdown';
3+
4+
interface TitleProps {
5+
title: string;
6+
category: string;
7+
rating: number;
8+
reviewCount: number;
9+
address: string;
10+
isDropDown?: boolean;
11+
}
12+
13+
export default function Title({
14+
title,
15+
category,
16+
rating,
17+
reviewCount,
18+
address,
19+
isDropDown,
20+
}: TitleProps) {
21+
return (
22+
<div className='mb-6 flex items-start justify-between'>
23+
<div className='flex flex-col gap-8'>
24+
<p>{category}</p>
25+
<h1 className='mb-2 text-2xl font-bold text-black md:text-3xl'>
26+
{title}
27+
</h1>
28+
<div className='flex items-center gap-4 text-sm text-gray-600'>
29+
<div className='flex items-center gap-1'>
30+
<span className='text-yellow-500'></span>
31+
<span className='font-medium'>
32+
{rating.toFixed(1)} ({reviewCount}명)
33+
</span>
34+
</div>
35+
<span>{address}</span>
36+
</div>
37+
</div>
38+
39+
{isDropDown && (
40+
<div className='mt-30 flex items-center gap-2'>
41+
<IconDropdown />
42+
</div>
43+
)}
44+
</div>
45+
);
46+
}

0 commit comments

Comments
 (0)