Skip to content

Commit

Permalink
[SWM-363] Feat : wrongQuizSlider
Browse files Browse the repository at this point in the history
  • Loading branch information
oikkoikk committed Oct 25, 2023
1 parent 352866e commit b017e8b
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 18 deletions.
7 changes: 4 additions & 3 deletions src/components/dashboard/main/MainDashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import SectionHeading from '../../ui/SectionHeading';
import CompletionRate from './completionRate/CompletionRate';
import CorrectnessRate from './correctnessRate/CorrectnessRate';
import Motivation from './motivation/Motivation';
import WrongQuizReviewSlider from './wrongQuizReview/WrongQuizReviewSlider';
import TotalLearningTime from './totalLearningTime/TotalLearningTime';
import WeeklyCalendar from './weeklyCalendar/WeeklyCalendar';

Expand All @@ -14,10 +14,11 @@ export default async function MainDashboard({ dashboardInfo }: Props) {
completion_rate,
correctness_rate,
motivation,
wrong_quizzes,
total_learning_time,
learning_histories
} = dashboardInfo;

return (
<section
id='dashboard-section'
Expand All @@ -28,7 +29,7 @@ export default async function MainDashboard({ dashboardInfo }: Props) {
<div className='relative pb-[32.90%] w-full'>
<div className='absolute w-full h-full'>
<div className='grid gap-2 grid-cols-3 grid-rows-[1fr_repeat(2,_minmax(0,_1.5fr))] w-full h-full'>
<Motivation text={motivation} />
<WrongQuizReviewSlider wrongQuizzes={wrong_quizzes} />
<TotalLearningTime time={total_learning_time} />
<CorrectnessRate value={correctness_rate} />
<CompletionRate value={completion_rate} />
Expand Down
13 changes: 0 additions & 13 deletions src/components/dashboard/main/motivation/Motivation.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use client';
import Button from '@/src/components/ui/button/Button';
import getRelativeTime from '@/src/util/time/getRelativeTime';
import { useState } from 'react';

type Props = {
wrongQuiz: WrongQuiz;
};

export default function WrongQuizReviewCard({ wrongQuiz }: Props) {
const [mode, setMode] = useState<'question' | 'answer'>('question');

const toggleModeHandler = () => {
setMode((prev) => (prev === 'question' ? 'answer' : 'question'));
};

return (
<div className='flex flex-col gap-2'>
{mode === 'question' ? (
<>
<div className='flex items-center justify-between border-b-2 border-b-sroom-white'>
<p className='text-xs text-sroom-gray-100'>
{wrongQuiz.video_title}
</p>
<Button
onClick={toggleModeHandler}
className='h-5 border !rounded-full w-16 bg-sroom-white text-sroom-brand
mb-1'
>
정답보기
</Button>
</div>
<p className='flex items-center text-xs font-medium break-keep md:text-sm xl:text-base text-sroom-white'>
{`Q. ${wrongQuiz.quiz_question}`}
</p>
</>
) : mode === 'answer' ? (
<>
<div className='flex items-center justify-between border-b-2 border-b-sroom-white'>
<p className='text-xs text-sroom-gray-100'>
{getRelativeTime(wrongQuiz.submitted_at)}
</p>
<Button
onClick={toggleModeHandler}
className='h-5 border !rounded-full w-16 bg-sroom-white text-sroom-brand
mb-1'
>
문제보기
</Button>
</div>
<p className='flex items-center text-xs font-medium break-keep md:text-sm xl:text-base text-sroom-white'>
{`A. ${wrongQuiz.quiz_answer}`}
</p>
</>
) : (
<></>
)}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use client';
import { useEffect, useRef, useState } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import SwiperCore from 'swiper';
import 'swiper/css';
import SwiperNavigationButton from '@/src/components/ui/button/SwiperNavigationButton';
import WrongQuizReviewCard from './WrongQuizReviewCard';

type Props = {
wrongQuizzes: WrongQuiz[];
};

export default function WrongQuizReviewSlider({ wrongQuizzes }: Props) {
const prevRef = useRef<HTMLButtonElement>(null);
const nextRef = useRef<HTMLButtonElement>(null);

const [swiper, setSwiper] = useState<SwiperCore>();
const [isFirstSlide, setIsFirstSlide] = useState<boolean>(true);
const [isLastSlide, setIsLastSlide] = useState<boolean>(false);
const [currPageIdx, setCurrPageIdx] = useState(1);

const totalPage = wrongQuizzes.length;

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

return (
<div className='flex items-center col-start-1 col-end-3 row-start-1 row-end-2 px-[5%] rounded-full bg-sroom-brand relative'>
<Swiper
className='!py-2 h-full'
slidesPerView={1}
navigation={{
prevEl: prevRef.current,
nextEl: nextRef.current
}}
onBeforeInit={(swiper) => {
setSwiper(swiper);
}}
onSlideChange={(swiper) => {
setCurrPageIdx(() => swiper.activeIndex + 1);
}}
>
{wrongQuizzes.map((wrongQuiz, idx) => (
<SwiperSlide key={idx} className='px-10'>
<WrongQuizReviewCard wrongQuiz={wrongQuiz} />
</SwiperSlide>
))}
</Swiper>
<div className='absolute left-0 z-20 flex items-center justify-between w-full px-5 -translate-y-1/2 top-1/2'>
<SwiperNavigationButton
className='rounded-full text-sroom-white'
onClick={() => swiper?.slidePrev()}
disabled={isFirstSlide}
navigation='prev'
/>
<SwiperNavigationButton
className='rounded-full text-sroom-white'
onClick={() => swiper?.slideNext()}
disabled={isLastSlide}
navigation='next'
/>
</div>
</div>
);
}
13 changes: 11 additions & 2 deletions types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,21 @@ interface LearningHistory {
lecture_count: number;
}

interface WrongQuiz {
quiz_question: string;
quiz_answer: string;
video_title: string;
submitted_at: string;
}

interface DashboardInfo {
correctness_rate: number;
completion_rate: number;
total_learning_time: number;
motivation: string;
latest_lectures: Course[];
learning_histories: LearningHistory[];
wrong_quizzes: WrongQuiz[];
}

interface WeekInfo {
Expand Down Expand Up @@ -268,7 +276,8 @@ interface LectureReviewParams extends Record<string, number | boolean> {
interface LectureDeatilParams extends LectureIndexParams, LectureReviewParams {}

interface LectureRecommendations {
recommendations: PersonalizedLecture[];
general_recommendations: PersonalizedLecture[];
channel_recommendations: PersonalizedLecture[];
}

/////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -454,4 +463,4 @@ interface CourseReviewResponse {
interface UpdateLectureReviewParams {
submitted_rating: number;
review_content: string;
}
}

0 comments on commit b017e8b

Please sign in to comment.