Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

๐ŸŽ‰ ์ด๋ฏธ์ง€ ์Šฌ๋ผ์ด๋” ๊ตฌํ˜„ - ์ƒ์„ธ์ •๋ณดํŽ˜์ด์ง€, ํ™ˆ ๋ฐฐ๋„ˆ์— ์ ์šฉ #64

Merged
merged 7 commits into from
Nov 11, 2023
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@
"classnames": "^2.3.2",
"clsx": "^2.0.0",
"date-fns": "^2.30.0",
"lucide-react": "^0.291.0",
"js-cookie": "^3.0.5",
"next": "14.0.1",
"next-themes": "^0.2.1",
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.47.0",
"swiper": "^11.0.3",
"tailwind-merge": "^1.14.0",
"tailwindcss": "^3.3.3",
"tailwindcss-animate": "^1.0.7",
Expand All @@ -45,7 +45,6 @@
"zod": "^3.22.4"
},
"devDependencies": {
"@tanstack/react-query-devtools": "^5.7.2",
"@storybook/addon-essentials": "7.5.0",
"@storybook/addon-interactions": "7.5.0",
"@storybook/addon-links": "7.5.0",
Expand All @@ -57,6 +56,7 @@
"@storybook/testing-library": "0.2.2",
"@storybook/theming": "^7.5.1",
"@tanstack/eslint-plugin-query": "^5.0.0",
"@tanstack/react-query-devtools": "^5.7.2",
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
"@types/js-cookie": "^3.0.5",
"@types/node": "^20",
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/images/Banner1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/Banner2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/Banner3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src/app/(root)/(routes)/(home)/components/HomSlider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Slider from '@/components/domain/Slider'
import Assets from '@/config/assets'

const HomeSlider = () => {
const bannerArr = [
{ _id: 1, image: Assets.banner1 },
{ _id: 2, image: Assets.banner2 },
{ _id: 3, image: Assets.banner3 },
]
return <Slider imageData={bannerArr} imageAspectRatio="auto" />
}

export default HomeSlider
7 changes: 5 additions & 2 deletions src/app/(root)/(routes)/(home)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import Link from 'next/link'
import { DarkModeButton } from '@/components/ui/DarkModeButton'
import HomeSlider from './components/HomSlider'
import TestBlock from './components/TestBlock'

function HomePage() {
return (
<main className="flex flex-col items-center justify-between min-h-screen p-24 text-4xl font-bold text-text-color bg-background-color">
hi
<main className="flex flex-col items-center justify-between min-h-screen text-4xl font-bold text-text-color bg-background-color">
<section>
<HomeSlider />
</section>
<Link href={'/test-auth-only'}>auth only</Link>
<Link href={'/test-not-auth-only'}>not auth only</Link>
<TestBlock />
Expand Down
6 changes: 4 additions & 2 deletions src/app/(root)/(routes)/items/[itemId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Slider from '@/components/domain/Slider/Slider'
import { getItemInfo } from '@/services/item/item'
import ProfileSection from './components/ProfileSection'
import DescriptionSection from './components/description-section'
Expand All @@ -21,11 +22,12 @@ async function getItemValue(itemId: string) {
const ItemPage = async ({ params }: ItemPageProps) => {
const data = await getItemValue(params.itemId)
console.log(data)
const { cardId, userName, priceRange, tradeType, tradeArea, userId } = data
const { cardId, userName, priceRange, tradeType, tradeArea, userId, images } =
data

return (
<main className="flex-col min-h-screen bg-background-color">
<div>์ด๋ฏธ์ง€ ์Šฌ๋ผ์ด๋” ์˜์—ญ</div>
<Slider imageData={images} imageAspectRatio="square" />
<div className="p-4">
<ProfileSection profileImg={null} userName={userName} />
<DescriptionSection itemData={data} />
Expand Down
46 changes: 0 additions & 46 deletions src/components/domain/Slider/Slider.stories.tsx

This file was deleted.

172 changes: 33 additions & 139 deletions src/components/domain/Slider/Slider.tsx
Original file line number Diff line number Diff line change
@@ -1,155 +1,49 @@
'use client'

import { useState, useEffect, useRef, useCallback } from 'react'
import Image from 'next/image'
import Assets from '@/config/assets'
import SwiperCore from 'swiper'
import 'swiper/css'
import 'swiper/css/pagination'
import { Pagination, Autoplay } from 'swiper/modules'
import { Swiper, SwiperSlide } from 'swiper/react'
import { itemImages } from '@/types/item'
import './index.css'

type SliderProps = {
autoSlide?: boolean
autoSlideInterval?: number
slides: string[]
imageAspectRatio?: string
imageData: itemImages[]
imageAspectRatio: string
}

const Slider = ({
autoSlide = false,
autoSlideInterval = 3000,
slides,
imageAspectRatio = 'auto',
}: SliderProps) => {
const [currentIndex, setCurrentIndex] = useState(1)
const [coordinate, setCoordinate] = useState({ start: 0, end: 0 })
const [style, setStyle] = useState({
transform: `translateX(-${currentIndex}00%)`,
transition: `all 0.4s ease-out`,
})

const ref = useRef<HTMLDivElement>(null)
const imageList = [slides.at(-1), ...slides, slides[0]]

const goPrevSlide = () => {
setCurrentIndex(currentIndex - 1)
setStyle({
transform: `translateX(-${currentIndex - 1}00%)`,
transition: `all 0.4s ease-out`,
})
}
const goNextSlide = useCallback(() => {
setCurrentIndex(currentIndex + 1)
setStyle({
transform: `translateX(-${currentIndex + 1}00%)`,
transition: `all 0.4s ease-out`,
})
}, [currentIndex])

const handleTouchStart = (e: React.TouchEvent) => {
setCoordinate({
...coordinate,
start: e.touches[0].pageX,
})
}

const handleTouchMove = (e: React.TouchEvent) => {
if (ref.current) {
const current = ref.current.clientWidth * currentIndex
const result = -current + (e.targetTouches[0].pageX - coordinate.start)
setStyle({
transform: `translate3d(${result}px, 0px, 0px)`,
transition: '0ms',
})
}
}

const handleTouchEnd = (e: React.TouchEvent) => {
const end = e.changedTouches[0].pageX
const distance = Math.abs(coordinate.start - end)

if (coordinate.start > end && distance > 2) {
goNextSlide()
} else if (coordinate.start < end && distance < 2) {
goPrevSlide()
}
setCoordinate({
...coordinate,
end,
})
}

useEffect(() => {
if (!autoSlide) return
const slideInterval = setInterval(goNextSlide, autoSlideInterval)
return () => clearInterval(slideInterval)
}, [autoSlide, autoSlideInterval, currentIndex, goNextSlide])

useEffect(() => {
if (currentIndex === 0) {
setCurrentIndex(imageList.length - 2)
setTimeout(function () {
setStyle({
transform: `translateX(-${imageList.length - 2}00%)`,
transition: '0ms',
})
}, 400)
}

if (currentIndex >= imageList.length - 1) {
setCurrentIndex(1)
setTimeout(() => {
setStyle({
transform: `translateX(-100%)`,
transition: '0ms',
})
}, 400)
}
}, [currentIndex, imageList.length])

/**
* @param {ImageData} ์ด๋ฏธ์ง€ ์•„์ด๋””, ์ด๋ฏธ์ง€ url์„ ๋‹ด์€ ๋ฐ์ดํ„ฐ
* @param {imageAspectRatio} swiper ํฌ๊ธฐ ์ง€์ •์„ ์œ„ํ•œ ๋ณ€์ˆ˜
*/
const Slider = ({ imageData, imageAspectRatio }: SliderProps) => {
SwiperCore.use([Pagination, Autoplay])
return (
<div
className="overflow-hidden relative"
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
<Swiper
loop={true}
pagination={{ clickable: true }}
allowTouchMove={true}
className={`aspect-${imageAspectRatio}`}
autoplay={{
delay: 5000,
disableOnInteraction: false,
}}
>
<div ref={ref} className="flex " style={style}>
{imageList.map((url, i) => (
{imageData.map((v) => (
<SwiperSlide key={v._id}>
<Image
src={url as string}
alt="itemImage"
key={i}
priority
width={0}
height={0}
className={`w-full cursor-pointer aspect-${imageAspectRatio}`}
alt="sliderImage"
src={v.image}
sizes="100vw"
style={{ width: '100%' }}
/>
))}
</div>
<div className="absolute p-2 w-full flex justify-between top-[50%]">
<button onClick={goPrevSlide} className="p-1 rounded-full bg-white/20">
<Image src={Assets.leftIcon} alt="left" />
</button>

<button onClick={goNextSlide} className="p-1 rounded-full bg-white/20">
<Image src={Assets.rightIcon} alt="right" priority />
</button>
</div>
<div className="absolute bottom-4 right-0 left-0">
<div className="flex items-center justify-center gap-2" ref={ref}>
{slides.map((_, i) => (
<button
key={i}
className={`
transition-all w-3 h-3 rounded-full
${
currentIndex === i + 1
? 'w-4 h-4 bg-primary-color'
: 'bg-white bg-opacity-50'
}
`}
></button>
))}
</div>
</div>
</div>
</SwiperSlide>
))}
</Swiper>
)
}

Expand Down
23 changes: 23 additions & 0 deletions src/components/domain/Slider/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.swiper {
@apply w-full h-full max-w-[640px];
}

.swiper-slide {
@apply flex justify-center items-center w-full h-full;
}

.swiper-slide img {
@apply w-full h-full
/* display: block; */;
}

.swiper-pagination-bullet {
@apply w-2 h-2 bg-bullet-inactive-color opacity-100;
}

.swiper-pagination {
@apply inline-flex justify-center;
}
.swiper-pagination-bullet-active {
@apply bg-bullet-active-color;
}
6 changes: 6 additions & 0 deletions src/config/assets.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import Banner1 from '/public/images/Banner1.png'
import Banner2 from '/public/images/Banner2.png'
import Banner3 from '/public/images/Banner3.png'
import ArrowLeftIcon from '/public/images/arrow-left.svg'
import AlarmIcon from '/public/images/bell.svg'
import FilterIcon from '/public/images/filter.svg'
Expand Down Expand Up @@ -38,6 +41,9 @@ const Assets = {
usersIcon: UsersIcon,
markerIcon: MarkerIcon,
moneyIcon: MoneyIcon,
banner1: Banner1,
banner2: Banner2,
banner3: Banner3,
xCircleIcon: XCircleIcon,
plusIcon: PlusIcon,
editIcon: editIcon,
Expand Down
6 changes: 4 additions & 2 deletions src/lib/msw/mocks/itemHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@ export const itemHandlers = [
images: [
{
_id: 1,
image: '์ด๋ฏธ์ง€ url',
image:
'https://cdn.cetizen.com/CDN/market/market_large_crop/202311/20231109/231109182102_1_2797370.jpg',
},
{
_id: 2,
image: '์ด๋ฏธ์ง€ url',
image:
'https://cdn.cetizen.com/CDN/market/market_large_crop/202311/20231109/231109182111_4_2797370.jpg',
},
],
dibsCount: 11,
Expand Down
Loading
Loading