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

Quiz Module:Modify Directory Structure and Optimize requests #143

Merged
merged 8 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 0 additions & 54 deletions src/app/quiz/Search.js

This file was deleted.

5 changes: 2 additions & 3 deletions src/app/quiz/[id]/RankListModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ import { Modal } from '@/components/Modal';
import useMounted from '@/hooks/useMounted';

import { fetchRankList } from '#/domain/quiz/repository';

import RankList from './RankList';
import RankListView from '#/domain/quiz/views/rank-list-view';

export function RankListModal({ quizId, shown, onClose, rank }) {
const [data, setData] = useState(null);
Expand All @@ -48,7 +47,7 @@ export function RankListModal({ quizId, shown, onClose, rank }) {
/>
<div className="md:h-[600px] h-[400px] flex flex-col overflow-y-auto rounded-inherit overflow-hidden">
{loading && <Loader classname="mr-2" />}
<RankList rank={rank} list={data} />
<RankListView rank={rank} list={data} />
</div>
</Modal>
);
Expand Down
53 changes: 2 additions & 51 deletions src/app/quiz/[id]/Record.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,15 @@
* limitations under the License.
*/

import Image from 'next/image';
import Link from 'next/link';
import useSWR from 'swr';

import { ModalCloseIcon } from '@/components/Icons';
import { Modal } from '@/components/Modal';
// import clsx from 'clsx'
import { NoData } from '@/components/NoData';
import { formatTime, fromUtcOffset, formatTimeMeridiem } from '@/utils/date';
import { fetcher } from '@/utils/request';

import RecordListView from '#/domain/quiz/views/record-list-view';
import { useMediaUrl } from '#/state/application/hooks';

export function Record({quizId, shown, onClose}) {
Expand All @@ -39,54 +37,7 @@ export function Record({quizId, shown, onClose}) {
<h3 className="text-center py-4 border-b border-gray-600">
Challenge Record
</h3>
<div className="px-6 py-4">
<ul className="hidden md:grid grid-cols-4 gap-4 text-xs opacity-60">
<li className="col-span-2">Quiz</li>
<li className="text-right">Time</li>
<li className="text-right">Score</li>
</ul>
<div className="max-h-[300px] mt-2 md:mt-4 overflow-y-auto">
{data?.map((i, k) => (
<div key={`challenge-record-${k}`} className=" mb-4 ">
<ul className="grid md:grid-cols-4 max-md:gap-y-4 md:gap-x-4 items-center">
<li className="md:col-span-2">
<Link href={`/quiz/${i.quiz_id}/questions/${i.id}`} className="text-sm font-bold hover:underline">{i.quiz_info.title}</Link>
<div className="flex items-center mt-1">
{mediaUrl && <Image
className="h-[18px] w-[18px] rounded object-cover mr-2"
height={18}
width={18}
alt={'user_avatar'}
src={mediaUrl + i.quiz_user?.user_avatar}
/>}
<p className="opacity-90 text-xs">by <a href={`/u/${i.quiz_user?.user_handle}`}><strong>{i.quiz_user?.user_nick_name}</strong></a> </p>
</div>
</li>
<li className="flex md:block justify-between md:text-right text-xs">
<div>
<p className="md:hidden opacity-60 mb-1">Time</p>
<p>{formatTime(i.created_at * 1000, 'YYYY-MM-DD hh:mm:ss')}&nbsp;
<span className="max-md:hidden">{formatTimeMeridiem(i.created_at * 1000)}
<span className="text-xs">
(UTC+{fromUtcOffset()})
</span>
</span>
</p>
</div>
<div className="md:hidden">
<p className="opacity-60 mb-1">Score</p>
<p className="text-right"><strong>{i.score}</strong></p>
</div>
</li>
<li className="max-md:hidden text-right">
<strong>{i.score}</strong>
</li>
</ul>
<hr className="border-t border-gray-600 mt-4" />
</div>
))}
</div>
</div>
<RecordListView data={data} mediaUrl={mediaUrl}/>
{(!data|| data?.length === 0) && <div className="pb-12"><NoData /></div>}
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/app/quiz/[id]/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ import { OViewer } from '@/components/MarkDown';
import { fetcher } from '@/utils/request';

import { CourseListViewWidget } from '#/domain/course';
import RankListView from '#/domain/quiz/views/rank-list-view';
import QuizLimiterWidget from '#/domain/quiz/widgets/quiz-limiter';
import { useMediaUrl } from '#/state/application/hooks';

import RankList from './RankList';
import { RankListModal } from './RankListModal';
import { Record } from './Record';

Expand Down Expand Up @@ -94,7 +94,7 @@ export default function Quiz({params}) {
className="mt-4 md:mt-6 mb-9 md:mb-10 !font-bold px-[64px] !text-base max-md:w-full">
Challenge now
</Button>
<RankList rank={data?.my_rank} list={data?.rank}/>
<RankListView rank={data?.my_rank} list={data?.rank}/>
<p className="text-sm text-center mt-6 cursor-pointer" onClick={()=>{setOpenRankList(true);}}><strong>{data?.user_num}</strong> builders have participated</p>
</div>
{
Expand Down
2 changes: 1 addition & 1 deletion src/app/quiz/[id]/questions/[version]/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import QuizQuestionListView from '#/domain/quiz/views/quiz-question-list';

export default function QuizDetails({ params }) {
export default function QuizVersion({ params }) {
return (
<QuizQuestionListView id={params.id} version={params.version} />
);
Expand Down
2 changes: 1 addition & 1 deletion src/app/quiz/[id]/questions/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import QuizQuestionListView from '#/domain/quiz/views/quiz-question-list';

export default function QuizDetails({ params }) {
export default function QuizQuestions({ params }) {
return (
<QuizQuestionListView id={params.id} />
);
Expand Down
52 changes: 32 additions & 20 deletions src/app/quiz/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ import QuizBannerPic from 'public/images/quiz-banner.svg';
import QuizS1 from 'public/images/quiz-s-1.svg';
import QuizS2 from 'public/images/quiz-s-2.svg';
import QuizS3 from 'public/images/quiz-s-3.svg';
import { useEffect,useState } from 'react';
import { useState } from 'react';

import { ArrowRightIcon } from '@/components/Icons';

import QuizListView from '#/domain/quiz/views/quiz-list-view';
import StartOnOpenBuild from '#/entry/components/StartOnOpenBuild';

import { QuizList } from './List';
import useMounted from '#/shared/hooks/useMounted';

const Steps = [
{
Expand All @@ -48,24 +48,32 @@ const Steps = [
export default function Quiz() {
const [activeStep, setActiveStep] = useState(0);

useEffect(() => {
useMounted(() => {
Aos.init({
delay: 100, // values from 0 to 3000, with step 50ms
duration: 800, // values from 0 to 3000, with step 50ms
});
}, []);
});
return (
<div>
<div className="md:flex bg-white md:justify-center pb-14">
<div className="md:w-[1200px] md:flex md:justify-between md:pr-[120px] py-6" data-aos="fade-left">
<div className="md:pt-[58px] md:max-w-[420px]" data-aos="fade-right">
<h1 className="text-[32px] md:text-[48px] leading-[42px] md:leading-[64px] max-md:text-center mb-3 md:mb-4">Learn & Earn</h1>
<p className="max-md:px-6 mx-auto max-md:mb-6 max-md:text-center text-[20px] md:text-[22px] leading-[26px] md:leading-8 font-normal">Discover cutting-edge protocols and ecosystems, <strong>earn prizes</strong> and <strong>thrive</strong> in the crypto space!</p>
<h1 className="text-[32px] md:text-[48px] leading-[42px] md:leading-[64px] max-md:text-center mb-3 md:mb-4">
Learn & Earn
</h1>
<p className="max-md:px-6 mx-auto max-md:mb-6 max-md:text-center text-[20px] md:text-[22px] leading-[26px] md:leading-8 font-normal">
Discover cutting-edge protocols and ecosystems, <strong>earn prizes</strong> and <strong>thrive</strong>{' '}
in the crypto space!
</p>
</div>
<Image className="max-md:w-[360px] max-md:mx-auto" src={QuizBannerPic} alt="" />
</div>
</div>
<div data-aos="fade-bottom" className="w-[1200px] h-[110px] mx-auto shadow-[0_4px_24px_rgba(0,0,0,0.08)] bg-white !translate-y-[-50%] rounded-xl hidden md:flex justify-center items-center gap-[96px]">
<div
data-aos="fade-bottom"
className="w-[1200px] h-[110px] mx-auto shadow-[0_4px_24px_rgba(0,0,0,0.08)] bg-white !translate-y-[-50%] rounded-xl hidden md:flex justify-center items-center gap-[96px]"
>
{Steps.map((i, k) => (
<div key={`quiz-step-${k}`} className="flex gap-[96px] items-center">
<div className="flex">
Expand All @@ -87,25 +95,25 @@ export default function Quiz() {
return (
<div key={`quiz-step-${k}`} className={`${activeStep === k ? 'flex' : 'hidden'} gap-[20px] items-center`}>
<ArrowRightIcon
className={`w-5 h-5 rotate-180 flex-shrink-0 ${isFirst ? 'opacity-[.2]':''}`}
className={`w-5 h-5 rotate-180 flex-shrink-0 ${isFirst ? 'opacity-[.2]' : ''}`}
onClick={() => {
if(k > 0){
setActiveStep(k-1);
if (k > 0) {
setActiveStep(k - 1);
}
}}
/>
<div className="flex flex-1">
<Image src={i.icon} alt="" className="h-[60px]"/>
<Image src={i.icon} alt="" className="h-[60px]" />
<div className="ml-4">
<p>Step {k + 1}</p>
<h3>{i.name}</h3>
</div>
</div>
<ArrowRightIcon
className={`w-5 h-5 flex-shrink-0 ${isNotLast ? '' : 'opacity-[.2]'}`}
onClick={()=>{
if(isNotLast){
setActiveStep(k+1);
onClick={() => {
if (isNotLast) {
setActiveStep(k + 1);
}
}}
/>
Expand All @@ -114,17 +122,19 @@ export default function Quiz() {
})}
</div>
<div className="md:w-[1200px] mx-6 md:mx-auto mb-14 md:mb-[110px]">
<QuizList />
<QuizListView />
<div className="md:flex mt-14">
<h3 className="md:flex-1 text-[24px] md:text-[32px] max-md:leading-10 max-md:pb-4">Quiz FAQ</h3>
<div className="md:w-[640px]">
<div className="collapse rounded-none collapse-plus border-t border-gray-1100">
<input type="radio" name="my-accordion-3" defaultChecked />
<div className="collapse-title font-bold h-[80px] flex items-center text-xl">
Who is able to participate in Quiz?
Who is able to participate in Quiz?
</div>
<div className="collapse-content pl-0 opacity-80">
<p>Anyone can participate in Quiz, and to claim the prize, users must connect their Github account first.</p>
<p>
Anyone can participate in Quiz, and to claim the prize, users must connect their Github account first.
</p>
</div>
</div>
<div className="collapse rounded-none collapse-plus border-t border-gray-1100">
Expand Down Expand Up @@ -154,10 +164,12 @@ export default function Quiz() {
Can I take the Quiz if it has ended?
</div>
<div className="collapse-content pl-0 opacity-80">
<p>You can always take the Quiz whenever you want. However, the prize is available only when the quiz status is Ongoing. </p>
<p>
You can always take the Quiz whenever you want. However, the prize is available only when the quiz
status is Ongoing.{' '}
</p>
</div>
</div>

</div>
</div>
</div>
Expand Down
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

搞错了,不是把 widgets/quiz-item 弄过来,是 widgets/quiz-list-item

Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ function QuizItem({ data, children }) {
<div suppressHydrationWarning className="flex [&>img]:ml-[-8px] [&>img]:rounded-full [&>img]:border [&>img]:border-white [&>img:first-child]:ml-0">
{data?.user_list?.slice(0, 10).map(i => (
<Image
key={`courses-enrool-users-${i.user_nick_name}`}
key={`courses-enrool-users-${i?.user_nick_name}`}
width={24}
height={24}
src={i.user_avatar}
src={i?.user_avatar}
alt=""
className="h-6 w-6 object-cover"
/>
Expand Down
Loading
Loading