route changes
This commit is contained in:
parent
ce90ebeb50
commit
5fe9491f86
|
|
@ -1,197 +1,12 @@
|
||||||
"use client";
|
import QuizMainPage from "@/components/quiz/QuizMainPage";
|
||||||
|
import React, { Suspense } from "react";
|
||||||
|
|
||||||
import { Queries } from "@/api/queries";
|
function page() {
|
||||||
import Loader from "@/components/Loader";
|
|
||||||
import QuizQuestionList from "@/components/quiz/QuizQuestionList";
|
|
||||||
import QuizSearch from "@/components/quiz/QuizSearch";
|
|
||||||
import QuizTable from "@/components/quiz/QuizTable";
|
|
||||||
import QuizWinnerTable from "@/components/quiz/QuizWinnerTable";
|
|
||||||
import GradientTitle from "@/components/vote/GradientTitle";
|
|
||||||
import { IQuizQuestions } from "@/models/quizQuestions.model";
|
|
||||||
import QuizProvider from "@/providers/QuizProvider";
|
|
||||||
import { useQuizSearchActive, useSteps } from "@/store/store";
|
|
||||||
import { Validator } from "@/utils/validator";
|
|
||||||
import Image from "next/image";
|
|
||||||
import Link from "next/link";
|
|
||||||
import { useRouter, useSearchParams } from "next/navigation";
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { useMediaQuery } from "usehooks-ts";
|
|
||||||
|
|
||||||
const page = () => {
|
|
||||||
const searchParams = useSearchParams();
|
|
||||||
const router = useRouter();
|
|
||||||
const [quizFinished, setQuizFinished] = useState<boolean>(false);
|
|
||||||
const [data, setData] = useState<IQuizQuestions>();
|
|
||||||
const { active } = useQuizSearchActive();
|
|
||||||
const { step, setStep } = useSteps();
|
|
||||||
const id = searchParams.get("d");
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (id) {
|
|
||||||
Queries.getQuizByUUID(id).then((res) => {
|
|
||||||
setData(res);
|
|
||||||
if (res.data.questions) {
|
|
||||||
res.data.questions.map((question) =>
|
|
||||||
question.status === "active" || question.status === "new"
|
|
||||||
? setQuizFinished(false)
|
|
||||||
: setQuizFinished(true)
|
|
||||||
);
|
|
||||||
} else if (res.data.steps && res.data.steps?.length > 0) {
|
|
||||||
setStep(res.data.steps[0].tapgyr);
|
|
||||||
for (let i = 0; i < res.data.steps.length; i++) {
|
|
||||||
res.data.steps[i].questions.map((question) =>
|
|
||||||
question.status === "active" || question.status === "new"
|
|
||||||
? setQuizFinished(false)
|
|
||||||
: setQuizFinished(true)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
router.push("/quiz/active");
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const mobile = useMediaQuery("(max-width: 768px)");
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
if (!data.data) {
|
|
||||||
return (
|
return (
|
||||||
<main className="h-full py-[200px]">
|
<Suspense>
|
||||||
<div className="container">
|
<QuizMainPage />
|
||||||
<GradientTitle title={data?.message} size="big" />
|
</Suspense>
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
|
||||||
<main className="pt-[60px] pb-[200px]">
|
|
||||||
{typeof data !== "string" ? (
|
|
||||||
<div className="container flex flex-col md:gap-[200px] gap-[80px]">
|
|
||||||
<QuizProvider>
|
|
||||||
<div className="flex flex-col gap-[100px]">
|
|
||||||
<div className="flex flex-col gap-[45px]">
|
|
||||||
<div className="flex flex-col gap-[10px] md:gap-[5px]">
|
|
||||||
<h3 className="text-base md:text-[14px] text-textLight font-semibold md:font-normal">
|
|
||||||
{data ? Validator.reveseDate(data?.data.date) : null}
|
|
||||||
</h3>
|
|
||||||
<h1 className="text-textBlack text-[32px] md:text-[60px] leading-[100%] font-semibold">
|
|
||||||
{data?.data.title}
|
|
||||||
</h1>
|
|
||||||
<h3 className="text-base font-medium leading-[125%] md:text-[14px] text-textDarkt mt-[5px] max-w-[600px]">
|
|
||||||
{data?.data.description}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
{data?.data.banner ? (
|
|
||||||
<div className="relative w-full md:min-h-[150px] md:h-auto h-[100px]">
|
|
||||||
{mobile ? (
|
|
||||||
<Image
|
|
||||||
src={
|
|
||||||
data.data.banner_mobile !== null
|
|
||||||
? data.data.banner_mobile
|
|
||||||
: data.data.banner
|
|
||||||
}
|
|
||||||
alt={"banner"}
|
|
||||||
unoptimized
|
|
||||||
unselectable="off"
|
|
||||||
fill
|
|
||||||
className="rounded-[8px]"
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Image
|
|
||||||
src={data?.data.banner}
|
|
||||||
alt={"banner"}
|
|
||||||
unoptimized
|
|
||||||
unselectable="off"
|
|
||||||
fill
|
|
||||||
className="rounded-[8px]"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{data?.data.rules && data.data.notes ? (
|
|
||||||
<QuizTable
|
|
||||||
rules={data?.data.rules}
|
|
||||||
notes={data?.data.notes}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col md:gap-[160px] gap-[80px]">
|
|
||||||
{data.data.has_steps !== 0 &&
|
|
||||||
data.data.steps &&
|
|
||||||
data.data.steps?.length > 0 && (
|
|
||||||
<div className="flex flex-col gap-4 items-center w-full">
|
|
||||||
<h1 className="text-textBlack md:text-[60px] leading-[100%] font-semibold">
|
|
||||||
Tapgyr
|
|
||||||
</h1>
|
|
||||||
<div className="flex w-full md:w-1/2 gap-[10px]">
|
|
||||||
{data.data.steps.map((item) => (
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
setStep(item.tapgyr);
|
|
||||||
}}
|
|
||||||
key={item.tapgyr}
|
|
||||||
className={`flex-1 py-[5px] rounded-lg transition-all duration-300 ${
|
|
||||||
step === item.tapgyr
|
|
||||||
? "bg-lightPrimary text-white"
|
|
||||||
: "bg-lightPrimaryContainer text-textLight"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{item.tapgyr}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
<Link
|
|
||||||
href={`/quiz/${data.data.id}/results`}
|
|
||||||
className={`flex-1 py-[5px] rounded-lg transition-all duration-300 bg-lightPrimaryContainer text-center text-textLight`}
|
|
||||||
>
|
|
||||||
Netije
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{data?.data && !active ? (
|
|
||||||
<QuizQuestionList
|
|
||||||
paramsId={String(data.data.id)}
|
|
||||||
initialQuestionsData={data}
|
|
||||||
setQuizFinished={setQuizFinished}
|
|
||||||
quizFinished={quizFinished}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{data?.data.id && quizFinished && data.data.has_steps === 0 ? (
|
|
||||||
<QuizSearch quizId={data?.data.id} />
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{data?.data.id && data.data.has_steps === 0 && (
|
|
||||||
<QuizWinnerTable
|
|
||||||
quizId={data?.data.id}
|
|
||||||
questionsData={data.data.questions}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</QuizProvider>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="container text-[40px] flex items-center justify-center font-bold text-textLight min-h-[30vh]">
|
|
||||||
Непредвиденная ошибка. Нет активной викторины.
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<main className="h-full py-[200px]">
|
|
||||||
<div className="container">
|
|
||||||
<Loader />
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default page;
|
export default page;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import ParticipantsList from '@/components/vote/ParticipantsList';
|
import ParticipantsList from "@/components/vote/ParticipantsList";
|
||||||
import VoteProvider from '@/providers/VoteProvider';
|
import VoteProvider from "@/providers/VoteProvider";
|
||||||
|
import { Suspense } from "react";
|
||||||
|
|
||||||
const page = () => {
|
const page = () => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -7,7 +8,9 @@ const page = () => {
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<VoteProvider>
|
<VoteProvider>
|
||||||
<div className="flex flex-col items-center w-full">
|
<div className="flex flex-col items-center w-full">
|
||||||
<ParticipantsList />
|
<Suspense>
|
||||||
|
<ParticipantsList all />
|
||||||
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
</VoteProvider>
|
</VoteProvider>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
|
"use client";
|
||||||
import ParticipantsList from "@/components/vote/ParticipantsList";
|
import ParticipantsList from "@/components/vote/ParticipantsList";
|
||||||
import VoteProvider from "@/providers/VoteProvider";
|
import VoteProvider from "@/providers/VoteProvider";
|
||||||
|
import { Suspense } from "react";
|
||||||
|
|
||||||
const page = () => {
|
const page = () => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -7,7 +9,9 @@ const page = () => {
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<VoteProvider>
|
<VoteProvider>
|
||||||
<div className="flex flex-col items-center w-full">
|
<div className="flex flex-col items-center w-full">
|
||||||
|
<Suspense>
|
||||||
<ParticipantsList />
|
<ParticipantsList />
|
||||||
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
</VoteProvider>
|
</VoteProvider>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,197 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Queries } from "@/api/queries";
|
||||||
|
import Loader from "@/components/Loader";
|
||||||
|
import QuizQuestionList from "@/components/quiz/QuizQuestionList";
|
||||||
|
import QuizSearch from "@/components/quiz/QuizSearch";
|
||||||
|
import QuizTable from "@/components/quiz/QuizTable";
|
||||||
|
import QuizWinnerTable from "@/components/quiz/QuizWinnerTable";
|
||||||
|
import GradientTitle from "@/components/vote/GradientTitle";
|
||||||
|
import { IQuizQuestions } from "@/models/quizQuestions.model";
|
||||||
|
import QuizProvider from "@/providers/QuizProvider";
|
||||||
|
import { useQuizSearchActive, useSteps } from "@/store/store";
|
||||||
|
import { Validator } from "@/utils/validator";
|
||||||
|
import Image from "next/image";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useRouter, useSearchParams } from "next/navigation";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useMediaQuery } from "usehooks-ts";
|
||||||
|
|
||||||
|
const QuizMainPage = () => {
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const router = useRouter();
|
||||||
|
const [quizFinished, setQuizFinished] = useState<boolean>(false);
|
||||||
|
const [data, setData] = useState<IQuizQuestions>();
|
||||||
|
const { active } = useQuizSearchActive();
|
||||||
|
const { step, setStep } = useSteps();
|
||||||
|
const id = searchParams.get("d");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (id) {
|
||||||
|
Queries.getQuizByUUID(id).then((res) => {
|
||||||
|
setData(res);
|
||||||
|
if (res.data.questions) {
|
||||||
|
res.data.questions.map((question) =>
|
||||||
|
question.status === "active" || question.status === "new"
|
||||||
|
? setQuizFinished(false)
|
||||||
|
: setQuizFinished(true)
|
||||||
|
);
|
||||||
|
} else if (res.data.steps && res.data.steps?.length > 0) {
|
||||||
|
setStep(res.data.steps[0].tapgyr);
|
||||||
|
for (let i = 0; i < res.data.steps.length; i++) {
|
||||||
|
res.data.steps[i].questions.map((question) =>
|
||||||
|
question.status === "active" || question.status === "new"
|
||||||
|
? setQuizFinished(false)
|
||||||
|
: setQuizFinished(true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
router.push("/quiz/active");
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const mobile = useMediaQuery("(max-width: 768px)");
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
if (!data.data) {
|
||||||
|
return (
|
||||||
|
<main className="h-full py-[200px]">
|
||||||
|
<div className="container">
|
||||||
|
<GradientTitle title={data?.message} size="big" />
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className="pt-[60px] pb-[200px]">
|
||||||
|
{typeof data !== "string" ? (
|
||||||
|
<div className="container flex flex-col md:gap-[200px] gap-[80px]">
|
||||||
|
<QuizProvider>
|
||||||
|
<div className="flex flex-col gap-[100px]">
|
||||||
|
<div className="flex flex-col gap-[45px]">
|
||||||
|
<div className="flex flex-col gap-[10px] md:gap-[5px]">
|
||||||
|
<h3 className="text-base md:text-[14px] text-textLight font-semibold md:font-normal">
|
||||||
|
{data ? Validator.reveseDate(data?.data.date) : null}
|
||||||
|
</h3>
|
||||||
|
<h1 className="text-textBlack text-[32px] md:text-[60px] leading-[100%] font-semibold">
|
||||||
|
{data?.data.title}
|
||||||
|
</h1>
|
||||||
|
<h3 className="text-base font-medium leading-[125%] md:text-[14px] text-textDarkt mt-[5px] max-w-[600px]">
|
||||||
|
{data?.data.description}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
{data?.data.banner ? (
|
||||||
|
<div className="relative w-full md:min-h-[150px] md:h-auto h-[100px]">
|
||||||
|
{mobile ? (
|
||||||
|
<Image
|
||||||
|
src={
|
||||||
|
data.data.banner_mobile !== null
|
||||||
|
? data.data.banner_mobile
|
||||||
|
: data.data.banner
|
||||||
|
}
|
||||||
|
alt={"banner"}
|
||||||
|
unoptimized
|
||||||
|
unselectable="off"
|
||||||
|
fill
|
||||||
|
className="rounded-[8px]"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Image
|
||||||
|
src={data?.data.banner}
|
||||||
|
alt={"banner"}
|
||||||
|
unoptimized
|
||||||
|
unselectable="off"
|
||||||
|
fill
|
||||||
|
className="rounded-[8px]"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{data?.data.rules && data.data.notes ? (
|
||||||
|
<QuizTable
|
||||||
|
rules={data?.data.rules}
|
||||||
|
notes={data?.data.notes}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col md:gap-[160px] gap-[80px]">
|
||||||
|
{data.data.has_steps !== 0 &&
|
||||||
|
data.data.steps &&
|
||||||
|
data.data.steps?.length > 0 && (
|
||||||
|
<div className="flex flex-col gap-4 items-center w-full">
|
||||||
|
<h1 className="text-textBlack md:text-[60px] leading-[100%] font-semibold">
|
||||||
|
Tapgyr
|
||||||
|
</h1>
|
||||||
|
<div className="flex w-full md:w-1/2 gap-[10px]">
|
||||||
|
{data.data.steps.map((item) => (
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setStep(item.tapgyr);
|
||||||
|
}}
|
||||||
|
key={item.tapgyr}
|
||||||
|
className={`flex-1 py-[5px] rounded-lg transition-all duration-300 ${
|
||||||
|
step === item.tapgyr
|
||||||
|
? "bg-lightPrimary text-white"
|
||||||
|
: "bg-lightPrimaryContainer text-textLight"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{item.tapgyr}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
<Link
|
||||||
|
href={`/quiz/${data.data.id}/results`}
|
||||||
|
className={`flex-1 py-[5px] rounded-lg transition-all duration-300 bg-lightPrimaryContainer text-center text-textLight`}
|
||||||
|
>
|
||||||
|
Netije
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{data?.data && !active ? (
|
||||||
|
<QuizQuestionList
|
||||||
|
paramsId={String(data.data.id)}
|
||||||
|
initialQuestionsData={data}
|
||||||
|
setQuizFinished={setQuizFinished}
|
||||||
|
quizFinished={quizFinished}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{data?.data.id && quizFinished && data.data.has_steps === 0 ? (
|
||||||
|
<QuizSearch quizId={data?.data.id} />
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{data?.data.id && data.data.has_steps === 0 && (
|
||||||
|
<QuizWinnerTable
|
||||||
|
quizId={data?.data.id}
|
||||||
|
questionsData={data.data.questions}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</QuizProvider>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="container text-[40px] flex items-center justify-center font-bold text-textLight min-h-[30vh]">
|
||||||
|
Непредвиденная ошибка. Нет активной викторины.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<main className="h-full py-[200px]">
|
||||||
|
<div className="container">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default QuizMainPage;
|
||||||
|
|
@ -17,6 +17,7 @@ import { useRouter, useSearchParams } from "next/navigation";
|
||||||
|
|
||||||
interface IParams {
|
interface IParams {
|
||||||
vote_id?: string;
|
vote_id?: string;
|
||||||
|
all?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ISocketMessage {
|
interface ISocketMessage {
|
||||||
|
|
@ -27,7 +28,7 @@ interface ISocketMessage {
|
||||||
date: string;
|
date: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ParticipantsList = ({ vote_id }: IParams) => {
|
const ParticipantsList = ({ vote_id, all }: IParams) => {
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [data, setData] = useState<IAllVotes>();
|
const [data, setData] = useState<IAllVotes>();
|
||||||
|
|
@ -65,7 +66,16 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
setVoteStatus(res.data.status);
|
setVoteStatus(res.data.status);
|
||||||
setSmsNumber(res.data.sms_number);
|
setSmsNumber(res.data.sms_number);
|
||||||
});
|
});
|
||||||
} else {
|
} else if (all) {
|
||||||
|
Queries.getAllVotes().then((res) => {
|
||||||
|
setData(res);
|
||||||
|
setParticipantsData([...res.data.voting_items]);
|
||||||
|
setVoteDescription(res.data.description);
|
||||||
|
setVoteStatus(res.data.status);
|
||||||
|
setSmsNumber(res.data.sms_number);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
{
|
||||||
router.push("/vote/active");
|
router.push("/vote/active");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue