Skip to content

Commit

Permalink
feat: 피드 광고 인터랙션 추가, 캐러셀 요소 랜덤 순서로 보여주기, 하나의 캐러셀에 여러 링크 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
borimong committed Aug 30, 2024
1 parent d5f89cc commit d9bb41d
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 53 deletions.
115 changes: 68 additions & 47 deletions src/components/page/meetingList/Advertisement/AdCarousel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback } from 'react';
import React, { useCallback, useMemo } from 'react';
import { EmblaOptionsType, EmblaCarouselType } from 'embla-carousel';
import { DotButton, useDotButton } from './AdCarouselDotBtn';
import { PrevButton, NextButton, usePrevNextButtons } from './AdCarouselArrowBtn';
Expand All @@ -10,13 +10,25 @@ import Link from 'next/link';
import { useDisplay } from '@hooks/useDisplay';

type PropType = {
slides: paths['/advertisement/v2']['get']['responses']['200']['content']['application/json;charset=UTF-8']['advertisementImages'];
link: paths['/advertisement/v2']['get']['responses']['200']['content']['application/json;charset=UTF-8']['advertisementLink'];
slides: paths['/advertisement/v2']['get']['responses']['200']['content']['application/json;charset=UTF-8']['advertisements'];
options?: EmblaOptionsType;
};

const AdCarousel: React.FC<PropType> = props => {
const { slides, link, options } = props;
const { slides, options } = props;

const shuffledSlides = useMemo(() => {
const shuffleArray = (array: typeof slides) => {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
};

return shuffleArray([...slides]);
}, [slides]);

const { isDesktop } = useDisplay();
const [emblaRef, emblaApi] = useEmblaCarousel(options, [Autoplay()]);

Expand All @@ -37,51 +49,51 @@ const AdCarousel: React.FC<PropType> = props => {
);

return (
<Link href={link} target="_blank">
<div style={{ display: 'flex', justifyContent: 'center' }}>
<Embla>
<EmblaViewport ref={emblaRef}>
<EmblaContainer>
{slides?.map((slide, index) => (
<div style={{ display: 'flex', justifyContent: 'center' }}>
<Embla>
<EmblaViewport ref={emblaRef}>
<EmblaContainer>
{shuffledSlides?.map((slide, index) => (
<Link href={slide?.advertisementLink} target="_blank">
<EmblaSlide key={index}>
<EmblaSlideImage src={slide.imageUrl}></EmblaSlideImage>
<EmblaSlideImage src={slide?.mobileImageUrl}></EmblaSlideImage>
</EmblaSlide>
</Link>
))}
</EmblaContainer>
</EmblaViewport>

{isDesktop ? (
<>
<EmblaButtons onClick={e => e.preventDefault()}>
<PrevButton onClick={onPrevButtonClick} disabled={prevBtnDisabled} />
<NextButton onClick={onNextButtonClick} disabled={nextBtnDisabled} />
</EmblaButtons>
<EmblaDots onClick={e => e.preventDefault()}>
{scrollSnaps.map((_, index) => (
<DotButton
key={index}
onClick={() => onDotButtonClick(index)}
className={'embla__dot'.concat(index === selectedIndex ? ' embla__dot--selected' : '')}
/>
))}
</EmblaContainer>
</EmblaViewport>

{isDesktop ? (
<>
<EmblaButtons onClick={e => e.preventDefault()}>
<PrevButton onClick={onPrevButtonClick} disabled={prevBtnDisabled} />
<NextButton onClick={onNextButtonClick} disabled={nextBtnDisabled} />
</EmblaButtons>
<EmblaDots onClick={e => e.preventDefault()}>
{scrollSnaps.map((_, index) => (
<DotButton
key={index}
onClick={() => onDotButtonClick(index)}
className={'embla__dot'.concat(index === selectedIndex ? ' embla__dot--selected' : '')}
/>
))}
</EmblaDots>
</>
) : (
<div style={{ position: 'relative' }}>
<EmblaDots onClick={e => e.preventDefault()}>
{scrollSnaps.map((_, index) => (
<DotButton
key={index}
onClick={() => onDotButtonClick(index)}
className={'embla__dot'.concat(index === selectedIndex ? ' embla__dot--selected' : '')}
/>
))}
</EmblaDots>
</div>
)}
</Embla>
</div>
</Link>
</EmblaDots>
</>
) : (
<div style={{ position: 'relative' }}>
<EmblaDots onClick={e => e.preventDefault()}>
{scrollSnaps.map((_, index) => (
<DotButton
key={index}
onClick={() => onDotButtonClick(index)}
className={'embla__dot'.concat(index === selectedIndex ? ' embla__dot--selected' : '')}
/>
))}
</EmblaDots>
</div>
)}
</Embla>
</div>
);
};

Expand All @@ -90,6 +102,7 @@ export default AdCarousel;
export const Embla = styled('div', {
width: '380px',
height: '380px',

'@mobile': {
width: '320px',
height: '320px',
Expand All @@ -98,11 +111,18 @@ export const Embla = styled('div', {
width: '280px',
height: '280px',
},

transition: 'transform 0.3s ease',
'&:hover': {
transform: 'translateY(-10px)',
},
});

export const EmblaViewport = styled('div', {
overflow: 'hidden',
borderRadius: '12px',
overflow: 'hidden',
'-webkit-backface-visibility': 'hidden',
'-webkit-transform': 'translate3d(0, 0, 0)',
});

export const EmblaContainer = styled('div', {
Expand All @@ -121,6 +141,7 @@ export const EmblaSlideImage = styled('img', {
userSelect: 'none',
width: '380px',
height: '380px',

'@mobile': {
width: '320px',
height: '320px',
Expand Down
8 changes: 2 additions & 6 deletions src/components/page/meetingList/Advertisement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@ const RenderPostsWithAds = () => {
</Link>
);
})}
{postAds && (
<AdCarousel slides={postAds.advertisementImages} link={postAds.advertisementLink} options={OPTIONS} />
)}
{postAds && <AdCarousel slides={postAds.advertisements} options={OPTIONS} />}
{postsData?.pages.slice(3).map(post => {
if (!post) return;
return (
Expand Down Expand Up @@ -142,9 +140,7 @@ const RenderPostsWithAds = () => {
</Link>
);
})}
{postAds && (
<AdCarousel slides={postAds.advertisementImages} link={postAds.advertisementLink} options={OPTIONS} />
)}
{postAds && <AdCarousel slides={postAds.advertisements} options={OPTIONS} />}

{postsData?.pages.slice(3).map(post => {
if (!post) return;
Expand Down

0 comments on commit d9bb41d

Please sign in to comment.