Skip to content

Commit

Permalink
[SWM-363] Refactor : split recommendations into 2 components
Browse files Browse the repository at this point in the history
  • Loading branch information
oikkoikk committed Oct 25, 2023
1 parent b017e8b commit cdbd5e6
Show file tree
Hide file tree
Showing 4 changed files with 232 additions and 100 deletions.
5 changes: 0 additions & 5 deletions src/components/recommendations/LectureRecommendationsCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ export default function LectureRecommendationsCard({ lecture }: Props) {
{channel}
</p>
</div>
<div className='mb-2 min-h-[3.5rem]'>
<p className='text-sm break-all whitespace-normal text-sroom-black-200 line-clamp-3'>
{description}
</p>
</div>
{review_count > 0 && (
<StarRatingWithReviewCount
rating={rating}
Expand Down
101 changes: 6 additions & 95 deletions src/components/recommendations/LectureRecommendationsList.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,12 @@
'use client';
import { Swiper, SwiperSlide } from 'swiper/react';
import SwiperCore from 'swiper';
import 'swiper/css';
import 'swiper/css/mousewheel';
import SectionHeading from '../ui/SectionHeading';
import LectureRecommendationsCard from './LectureRecommendationsCard';
import useWindowSize from '@/src/hooks/useWindowSize';
import SwiperNavigationButton from '../ui/button/SwiperNavigationButton';
import { useEffect, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useQuery } from '@tanstack/react-query';
import { QueryKeys } from '@/src/api/queryKeys';
import { fetchLectureRecommendations } from '@/src/api/lectures/search';
import { CACHE_TIME, STALE_TIME } from '@/src/constants/query/query';
import { RECOMMENDATION_BREAKPOINT_LG, RECOMMENDATION_BREAKPOINT_SM } from '@/src/constants/window/window';
import ChannelRecommendationsList from './channel/ChannelRecommendationsList';
import GeneralRecommendationsList from './general/GeneralRecommendationsList';

export default function LectureRecommendationsList() {
const windowSize = useWindowSize();
const router = useRouter();
const prevRef = useRef<HTMLButtonElement>(null);
const nextRef = useRef<HTMLButtonElement>(null);
const [swiper, setSwiper] = useState<SwiperCore>();
const [currPageIdx, setCurrPageIdx] = useState(1);
const [isFirstSlide, setIsFirstSlide] = useState<boolean>(true);
const [isLastSlide, setIsLastSlide] = useState<boolean>(false);

const { data } = useQuery(
[QueryKeys.RECCOMENDATION],
fetchLectureRecommendations,
Expand All @@ -36,84 +18,13 @@ export default function LectureRecommendationsList() {
}
);

const { recommendations } = data || { recommendations: [] };

const slidesPerView =
windowSize.width < RECOMMENDATION_BREAKPOINT_SM ? 1 : windowSize.width < RECOMMENDATION_BREAKPOINT_LG ? 2 : 3;
const totalPage =
recommendations.length - (slidesPerView - 1) > 0
? recommendations.length - (slidesPerView - 1)
: 1;

useEffect(() => {
if (currPageIdx === totalPage) {
setIsLastSlide(true);
} else {
setIsLastSlide(false);
}
if (currPageIdx === 1) {
setIsFirstSlide(true);
} else {
setIsFirstSlide(false);
}
}, [totalPage, currPageIdx]);
const general_recommendations = data?.general_recommendations ?? [];
const channel_recommendations = data?.channel_recommendations ?? [];

return (
<>
{recommendations.length > 0 && (
<section className='max-w-screen-xl px-4 mx-auto my-20 lg:px-24 min-h-12'>
<SectionHeading title='이런 강의는 어때요?' />
<div className='relative'>
<Swiper
className='!py-2'
slidesPerView={slidesPerView}
navigation={{
prevEl: prevRef.current,
nextEl: nextRef.current
}}
onBeforeInit={(swiper) => {
setSwiper(swiper);
}}
onSlideChange={(swiper) => {
setCurrPageIdx(() => swiper.activeIndex + 1);
}}
>
{recommendations.map((lecture) => (
<SwiperSlide
key={lecture.lecture_code}
className='!flex justify-between'
>
<div
onClick={() => {
router.refresh();
router.push(`/search/${lecture.lecture_code}`);
}}
>
<LectureRecommendationsCard lecture={lecture} />
</div>
</SwiperSlide>
))}
</Swiper>
<div className='flex items-center justify-center gap-10 mt-3'>
<SwiperNavigationButton
onClick={() => swiper?.slidePrev()}
disabled={isFirstSlide}
navigation='prev'
/>
<div>
<span>
{currPageIdx} / {totalPage}
</span>
</div>
<SwiperNavigationButton
disabled={isLastSlide}
onClick={() => swiper?.slideNext()}
navigation='next'
/>
</div>
</div>
</section>
)}
<ChannelRecommendationsList recommendations={channel_recommendations} />
<GeneralRecommendationsList recommendations={general_recommendations} />
</>
);
}
113 changes: 113 additions & 0 deletions src/components/recommendations/channel/ChannelRecommendationsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
'use client';
import { Swiper, SwiperSlide } from 'swiper/react';
import SwiperCore from 'swiper';
import 'swiper/css';
import 'swiper/css/mousewheel';
import SectionHeading from '../../ui/SectionHeading';
import LectureRecommendationsCard from './../LectureRecommendationsCard';
import useWindowSize from '@/src/hooks/useWindowSize';
import SwiperNavigationButton from '../../ui/button/SwiperNavigationButton';
import { useEffect, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import {
RECOMMENDATION_BREAKPOINT_LG,
RECOMMENDATION_BREAKPOINT_SM
} from '@/src/constants/window/window';

type Props= {
recommendations: PersonalizedLecture[];
}
export default function ChannelRecommendationsList({recommendations}: Props) {
const windowSize = useWindowSize();
const router = useRouter();
const prevRef = useRef<HTMLButtonElement>(null);
const nextRef = useRef<HTMLButtonElement>(null);
const [swiper, setSwiper] = useState<SwiperCore>();
const [currPageIdx, setCurrPageIdx] = useState(1);
const [isFirstSlide, setIsFirstSlide] = useState<boolean>(true);
const [isLastSlide, setIsLastSlide] = useState<boolean>(false);

const slidesPerView =
windowSize.width < RECOMMENDATION_BREAKPOINT_SM
? 1
: windowSize.width < RECOMMENDATION_BREAKPOINT_LG
? 2
: 3;

const totalPage =
recommendations.length - (slidesPerView - 1) > 0
? recommendations.length - (slidesPerView - 1)
: 1;

useEffect(() => {
if (currPageIdx === totalPage) {
setIsLastSlide(true);
} else {
setIsLastSlide(false);
}
if (currPageIdx === 1) {
setIsFirstSlide(true);
} else {
setIsFirstSlide(false);
}
}, [totalPage, currPageIdx]);

return (
<>
{recommendations.length > 0 && (
<section className='max-w-screen-xl px-4 mx-auto my-20 lg:px-24 min-h-12'>
<SectionHeading title='이런 강의는 어때요?' />
<div className='relative'>
<Swiper
className='!py-2'
slidesPerView={slidesPerView}
navigation={{
prevEl: prevRef.current,
nextEl: nextRef.current
}}
onBeforeInit={(swiper) => {
setSwiper(swiper);
}}
onSlideChange={(swiper) => {
setCurrPageIdx(() => swiper.activeIndex + 1);
}}
>
{recommendations.map((lecture) => (
<SwiperSlide
key={lecture.lecture_code}
className='!flex justify-between'
>
<div
onClick={() => {
router.refresh();
router.push(`/search/${lecture.lecture_code}`);
}}
>
<LectureRecommendationsCard lecture={lecture} />
</div>
</SwiperSlide>
))}
</Swiper>
<div className='flex items-center justify-center gap-10 mt-3'>
<SwiperNavigationButton
onClick={() => swiper?.slidePrev()}
disabled={isFirstSlide}
navigation='prev'
/>
<div>
<span>
{currPageIdx} / {totalPage}
</span>
</div>
<SwiperNavigationButton
disabled={isLastSlide}
onClick={() => swiper?.slideNext()}
navigation='next'
/>
</div>
</div>
</section>
)}
</>
);
}
113 changes: 113 additions & 0 deletions src/components/recommendations/general/GeneralRecommendationsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
'use client';
import { Swiper, SwiperSlide } from 'swiper/react';
import SwiperCore from 'swiper';
import 'swiper/css';
import 'swiper/css/mousewheel';
import SectionHeading from '../../ui/SectionHeading';
import LectureRecommendationsCard from './../LectureRecommendationsCard';
import useWindowSize from '@/src/hooks/useWindowSize';
import SwiperNavigationButton from '../../ui/button/SwiperNavigationButton';
import { useEffect, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import {
RECOMMENDATION_BREAKPOINT_LG,
RECOMMENDATION_BREAKPOINT_SM
} from '@/src/constants/window/window';

type Props = {
recommendations: PersonalizedLecture[];
};
export default function GeneralRecommendationsList({ recommendations }: Props) {
const windowSize = useWindowSize();
const router = useRouter();
const prevRef = useRef<HTMLButtonElement>(null);
const nextRef = useRef<HTMLButtonElement>(null);
const [swiper, setSwiper] = useState<SwiperCore>();
const [currPageIdx, setCurrPageIdx] = useState(1);
const [isFirstSlide, setIsFirstSlide] = useState<boolean>(true);
const [isLastSlide, setIsLastSlide] = useState<boolean>(false);

const slidesPerView =
windowSize.width < RECOMMENDATION_BREAKPOINT_SM
? 1
: windowSize.width < RECOMMENDATION_BREAKPOINT_LG
? 2
: 3;

const totalPage =
recommendations.length - (slidesPerView - 1) > 0
? recommendations.length - (slidesPerView - 1)
: 1;

useEffect(() => {
if (currPageIdx === totalPage) {
setIsLastSlide(true);
} else {
setIsLastSlide(false);
}
if (currPageIdx === 1) {
setIsFirstSlide(true);
} else {
setIsFirstSlide(false);
}
}, [totalPage, currPageIdx]);

return (
<>
{recommendations.length > 0 && (
<section className='max-w-screen-xl px-4 mx-auto my-20 lg:px-24 min-h-12'>
<SectionHeading title='스룸에서 인기 폭발한🔥 강의를 만나보세요!' />
<div className='relative'>
<Swiper
className='!py-2'
slidesPerView={slidesPerView}
navigation={{
prevEl: prevRef.current,
nextEl: nextRef.current
}}
onBeforeInit={(swiper) => {
setSwiper(swiper);
}}
onSlideChange={(swiper) => {
setCurrPageIdx(() => swiper.activeIndex + 1);
}}
>
{recommendations.map((lecture) => (
<SwiperSlide
key={lecture.lecture_code}
className='!flex justify-between'
>
<div
onClick={() => {
router.refresh();
router.push(`/search/${lecture.lecture_code}`);
}}
>
<LectureRecommendationsCard lecture={lecture} />
</div>
</SwiperSlide>
))}
</Swiper>
<div className='flex items-center justify-center gap-10 mt-3'>
<SwiperNavigationButton
onClick={() => swiper?.slidePrev()}
disabled={isFirstSlide}
navigation='prev'
/>
<div>
<span>
{currPageIdx} / {totalPage}
</span>
</div>
<SwiperNavigationButton
disabled={isLastSlide}
onClick={() => swiper?.slideNext()}
navigation='next'
/>
</div>
</div>
</section>
)}
</>
);
}

0 comments on commit cdbd5e6

Please sign in to comment.