Skip to content

Commit

Permalink
feat: 리뷰 슬라이드 추가 #229
Browse files Browse the repository at this point in the history
  • Loading branch information
imdaxsz committed Oct 24, 2024
1 parent bddfbda commit ea33083
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 32 deletions.
35 changes: 3 additions & 32 deletions src/pages/Home/components/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import HeroImage from '@/assets/images/hero-img.svg?react';

import { reviews } from '../constants';
import Reviews from './Reviews';

export default function Hero() {
return (
<div
id='hero'
className='bg-white min-h-[813px] flex flex-col leading-[1.4]
hero-gradient pt-135 lg:pb-40 pb-72'
hero-gradient pt-135 lg:pb-70 pb-72'
>
<div className='lg:mb-24 mb-100'>
<h1 className='text-center text-primary-400 leading-[1.4]'>
Expand All @@ -26,36 +26,7 @@ export default function Hero() {
<div className='w-full max-w-[1215px] mx-auto'>
<HeroImage className='hidden lg:block w-180 h-196 ml-32' />
</div>
<div className='flex-col-center lg:flex-row-center gap-30 lg:-mt-13'>
{reviews.map(review => (
<div
key={review.keyword}
className='relative max-w-[385px] min-h-220 rounded-[20px] bg-white
px-32 py-36 shadow-card-md max-xs:w-240'
>
<span
className='absolute text-primary-400/60 font-HakgyoansimGaeulsopungB
text-26 top-12 right-18 max-xs:text-16'
>
{review.keyword}
</span>
<div className='font-semibold flex items-center gap-14 pt-4 pb-20'>
<span className='text-20'>{review.school}</span>
<span
className='text-primary-400 text-12 block min-h-22 px-8 flex-row-center
bg-primary-400/15 rounded-[10px] border-1 border-primary-400'
>
{review.grade}
</span>
</div>
<p
className='text-neutral-300 [&>strong]:text-primary-400
[&>strong]:font-medium max-xs:text-11'
dangerouslySetInnerHTML={{ __html: review.content }}
/>
</div>
))}
</div>
<Reviews />
</div>
);
}
32 changes: 32 additions & 0 deletions src/pages/Home/components/Reviews/ReivewCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Review } from '../../types';

export default function ReivewCard({ review }: { review: Review }) {
return (
<div
className='relative max-w-[385px] min-h-220 flex-grow rounded-[20px] bg-white
shrink-0 flex-1 px-32 py-36 shadow-card-md max-xs:w-240'
>
{review.keyword && (
<span
className='absolute text-primary-400/60 font-HakgyoansimGaeulsopungB
text-26 top-12 right-18 max-xs:text-16'
>
{review.keyword}
</span>
)}
<div className='font-semibold flex items-center gap-14 pt-4 pb-20'>
<span className='text-20'>{review.school}</span>
<span
className='text-primary-400 text-12 block min-h-22 px-8 flex-row-center
bg-primary-400/15 rounded-[10px] border-1 border-primary-400'
>
{review.grade}
</span>
</div>
<p
className='text-neutral-300 [&>strong]:text-primary-400 [&>strong]:font-medium max-xs:text-11'
dangerouslySetInnerHTML={{ __html: review.content }}
/>
</div>
);
}
41 changes: 41 additions & 0 deletions src/pages/Home/components/Reviews/ReviewSlide.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { animate, motion, useMotionValue } from 'framer-motion';
import { useEffect, useRef } from 'react';

import { Review } from '../../types';

import ReivewCard from './ReivewCard';

export default function ReviewSlide({ reviews }: { reviews: Review[] }) {
const ref = useRef<HTMLDivElement | null>(null);
const xTranslation = useMotionValue(0);

useEffect(() => {
if (!ref.current) return;
const x = ref.current.offsetWidth;
const finalPosition = -x / 2 - 16;

const controls = animate(xTranslation, [0, finalPosition], {
ease: 'linear',
duration: 60,
repeat: Infinity,
repeatType: 'loop',
repeatDelay: 0,
});

return controls.stop;
}, [xTranslation]);

return (
<div id='slide-container' className='w-full overflow-hidden pb-40'>
<motion.div
className='w-[max-content] flex flex-nowrap gap-32 items-center'
ref={ref}
style={{ x: xTranslation }}
>
{[...reviews, ...reviews].map((review, index) => (
<ReivewCard key={index} review={review} />
))}
</motion.div>
</div>
);
}
28 changes: 28 additions & 0 deletions src/pages/Home/components/Reviews/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useState } from 'react';

import { reviews } from '../../constants';

import ReivewCard from './ReivewCard';
import ReviewSlide from './ReviewSlide';

export default function Reviews() {
const [isSlideOpen, setIsSlideOpen] = useState(false);
const toggleSlide = () => setIsSlideOpen(prev => !prev);

return (
<div className='flex-col-center gap-48'>
<div className='flex-col-center lg:flex-row-center gap-30 lg:-mt-13'>
{reviews.slice(0, 3).map(review => (
<ReivewCard key={review.school} review={review} />
))}
</div>
{isSlideOpen && <ReviewSlide reviews={reviews.slice(3)} />}
<button
className='bg-white px-12 py-8 border-1 lg:hover:bg-primary-200/5 rounded-xl text-primary-400/60 shadow-btn-light transition-colors duration-200 font-medium'
onClick={toggleSlide}
>
{isSlideOpen ? '리뷰 접기' : '리뷰 더보기'}
</button>
</div>
);
}

0 comments on commit ea33083

Please sign in to comment.