route changes
This commit is contained in:
parent
35fa202f61
commit
3cbbdf21c4
|
|
@ -191,6 +191,12 @@ export class Queries {
|
||||||
}).then((res) => res.json().then((res) => res as IQuizQuestions));
|
}).then((res) => res.json().then((res) => res as IQuizQuestions));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async getQuizByUUID(quiz_id: string): Promise<IQuizQuestions> {
|
||||||
|
return await fetch(`${baseUrl.QUIZ_SRC}${routes.getQuizUUID(quiz_id)}`, {
|
||||||
|
next: { revalidate: 3600 },
|
||||||
|
}).then((res) => res.json().then((res) => res as IQuizQuestions));
|
||||||
|
}
|
||||||
|
|
||||||
public static async getQuizById(quiz_id: string) {
|
public static async getQuizById(quiz_id: string) {
|
||||||
return await fetch(`${baseUrl.QUIZ_SRC}${routes.getQuiz(quiz_id)}`, {
|
return await fetch(`${baseUrl.QUIZ_SRC}${routes.getQuiz(quiz_id)}`, {
|
||||||
next: { revalidate: 3600 },
|
next: { revalidate: 3600 },
|
||||||
|
|
@ -234,6 +240,12 @@ export class Queries {
|
||||||
}).then((res) => res.json().then((res) => res as IVote));
|
}).then((res) => res.json().then((res) => res as IVote));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async getVoteByUUID(vote_id: string): Promise<IVote> {
|
||||||
|
return await fetch(`${baseUrl.QUIZ_SRC}${routes.voteUUID(vote_id)}`, {
|
||||||
|
next: { revalidate: 3600 },
|
||||||
|
}).then((res) => res.json().then((res) => res as IVote));
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================================
|
// ============================================================================================
|
||||||
|
|
||||||
// Sms ========================================================================================
|
// Sms ========================================================================================
|
||||||
|
|
|
||||||
|
|
@ -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 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 (
|
||||||
|
<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 page;
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import ParticipantsList from "@/components/vote/ParticipantsList";
|
||||||
|
import VoteProvider from "@/providers/VoteProvider";
|
||||||
|
|
||||||
|
const page = () => {
|
||||||
|
return (
|
||||||
|
<main className="pt-[60px] pb-[120px]">
|
||||||
|
<div className="container">
|
||||||
|
<VoteProvider>
|
||||||
|
<div className="flex flex-col items-center w-full">
|
||||||
|
<ParticipantsList />
|
||||||
|
</div>
|
||||||
|
</VoteProvider>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default page;
|
||||||
|
|
@ -1,23 +1,19 @@
|
||||||
'use client';
|
"use client";
|
||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
import GradientTitle from './GradientTitle';
|
import GradientTitle from "./GradientTitle";
|
||||||
import ParticipantCard from './ParticipantCard';
|
import ParticipantCard from "./ParticipantCard";
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from "uuid";
|
||||||
import { IAllVotes, VotingItem } from '@/models/allVotes.model';
|
import { IAllVotes, VotingItem } from "@/models/allVotes.model";
|
||||||
import { Queries } from '@/api/queries';
|
import { Queries } from "@/api/queries";
|
||||||
import Loader from '../Loader';
|
import Loader from "../Loader";
|
||||||
import VoteContext from '@/context/VoteContext';
|
import VoteContext from "@/context/VoteContext";
|
||||||
import PageBage from './PageBage';
|
import PageBage from "./PageBage";
|
||||||
import Image from 'next/image';
|
import Image from "next/image";
|
||||||
import { useMediaQuery } from 'usehooks-ts';
|
import { useMediaQuery } from "usehooks-ts";
|
||||||
import Countdown from './Countdown';
|
import Countdown from "./Countdown";
|
||||||
import Link from 'next/link';
|
import Link from "next/link";
|
||||||
import { useWindowSize } from 'react-use';
|
import Confetti from "../common/Confetti";
|
||||||
import Confetti from '../common/Confetti';
|
import { useRouter, useSearchParams } from "next/navigation";
|
||||||
|
|
||||||
interface IParams {
|
|
||||||
vote_id?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ISocketMessage {
|
interface ISocketMessage {
|
||||||
voting_id: number;
|
voting_id: number;
|
||||||
|
|
@ -27,11 +23,13 @@ interface ISocketMessage {
|
||||||
date: string;
|
date: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ParticipantsList = ({ vote_id }: IParams) => {
|
const ParticipantsList = () => {
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const router = useRouter();
|
||||||
const [data, setData] = useState<IAllVotes>();
|
const [data, setData] = useState<IAllVotes>();
|
||||||
const [participantsData, setParticipantsData] = useState<VotingItem[]>([]);
|
const [participantsData, setParticipantsData] = useState<VotingItem[]>([]);
|
||||||
const [voteStatus, setVoteStatus] = useState<string>();
|
const [voteStatus, setVoteStatus] = useState<string>();
|
||||||
const [eventStatus, setEventStatus] = useState<string>('Not started');
|
const [eventStatus, setEventStatus] = useState<string>("Not started");
|
||||||
const [manualClose, setManualClose] = useState(false); // Track manual closure
|
const [manualClose, setManualClose] = useState(false); // Track manual closure
|
||||||
|
|
||||||
const [winnersCount, setWinnersCount] = useState<number>(0);
|
const [winnersCount, setWinnersCount] = useState<number>(0);
|
||||||
|
|
@ -41,28 +39,22 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
const [socket, setSocket] = useState<WebSocket | null>(null);
|
const [socket, setSocket] = useState<WebSocket | null>(null);
|
||||||
const [isConnected, setIsConnected] = useState(false);
|
const [isConnected, setIsConnected] = useState(false);
|
||||||
|
|
||||||
const mobile = useMediaQuery('(max-width: 768px)');
|
const mobile = useMediaQuery("(max-width: 768px)");
|
||||||
const { width, height } = useWindowSize();
|
|
||||||
|
|
||||||
const { setVoteDescription } = useContext(VoteContext).voteDescriptionContext;
|
const { setVoteDescription } = useContext(VoteContext).voteDescriptionContext;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!vote_id) {
|
const id = searchParams.get("d")
|
||||||
Queries.getAllVotes().then((res) => {
|
if (id) {
|
||||||
setData(res);
|
Queries.getVote(id).then((res) => {
|
||||||
setParticipantsData([...res.data.voting_items]);
|
|
||||||
setVoteDescription(res.data.description);
|
|
||||||
setVoteStatus(res.data.status);
|
|
||||||
setSmsNumber(res.data.sms_number);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Queries.getVote(vote_id).then((res) => {
|
|
||||||
setData(res);
|
setData(res);
|
||||||
setParticipantsData(res.data.voting_items);
|
setParticipantsData(res.data.voting_items);
|
||||||
setVoteDescription(res.data.description);
|
setVoteDescription(res.data.description);
|
||||||
setVoteStatus(res.data.status);
|
setVoteStatus(res.data.status);
|
||||||
setSmsNumber(res.data.sms_number);
|
setSmsNumber(res.data.sms_number);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
router.push('/vote/active')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (participantsData) {
|
if (participantsData) {
|
||||||
|
|
@ -79,19 +71,21 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
try {
|
try {
|
||||||
// Only connect if manualClose is false
|
// Only connect if manualClose is false
|
||||||
if (!manualClose) {
|
if (!manualClose) {
|
||||||
socket = new WebSocket(`wss://sms.turkmentv.gov.tm/ws/voting?dst=${smsNumber}`);
|
socket = new WebSocket(
|
||||||
|
`wss://sms.turkmentv.gov.tm/ws/voting?dst=${smsNumber}`
|
||||||
|
);
|
||||||
setSocket(socket);
|
setSocket(socket);
|
||||||
|
|
||||||
socket.onopen = () => {
|
socket.onopen = () => {
|
||||||
console.log('WebSocket is connected');
|
console.log("WebSocket is connected");
|
||||||
setIsConnected(true);
|
setIsConnected(true);
|
||||||
|
|
||||||
pingInterval = setInterval(() => {
|
pingInterval = setInterval(() => {
|
||||||
if (socket?.readyState === WebSocket.OPEN) {
|
if (socket?.readyState === WebSocket.OPEN) {
|
||||||
try {
|
try {
|
||||||
socket.send(JSON.stringify({ type: 'ping' }));
|
socket.send(JSON.stringify({ type: "ping" }));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error sending ping:', error);
|
console.error("Error sending ping:", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 25000); // Ping every 25 seconds
|
}, 25000); // Ping every 25 seconds
|
||||||
|
|
@ -102,23 +96,23 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
const message = JSON.parse(event.data);
|
const message = JSON.parse(event.data);
|
||||||
handleWebSocketMessage(message);
|
handleWebSocketMessage(message);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error processing message:', error);
|
console.error("Error processing message:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onerror = (error) => {
|
socket.onerror = (error) => {
|
||||||
console.error('WebSocket error:', error);
|
console.error("WebSocket error:", error);
|
||||||
|
|
||||||
if (!manualClose && !reconnectTimeout) {
|
if (!manualClose && !reconnectTimeout) {
|
||||||
reconnectTimeout = setTimeout(() => {
|
reconnectTimeout = setTimeout(() => {
|
||||||
console.log('Attempting to reconnect WebSocket after error...');
|
console.log("Attempting to reconnect WebSocket after error...");
|
||||||
connectWebSocket();
|
connectWebSocket();
|
||||||
}, 5000); // Reconnect after 5 seconds
|
}, 5000); // Reconnect after 5 seconds
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onclose = () => {
|
socket.onclose = () => {
|
||||||
console.log('WebSocket is closed');
|
console.log("WebSocket is closed");
|
||||||
setIsConnected(false);
|
setIsConnected(false);
|
||||||
|
|
||||||
if (pingInterval) {
|
if (pingInterval) {
|
||||||
|
|
@ -132,12 +126,12 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('WebSocket connection error:', error);
|
console.error("WebSocket connection error:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// WebSocket connection only if eventStatus is 'Started'
|
// WebSocket connection only if eventStatus is 'Started'
|
||||||
if (smsNumber && eventStatus === 'Started' && !manualClose) {
|
if (smsNumber && eventStatus === "Started" && !manualClose) {
|
||||||
connectWebSocket();
|
connectWebSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,7 +155,9 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
|
|
||||||
// Update the corresponding voting item
|
// Update the corresponding voting item
|
||||||
const updatedItems = prevVotingItems.map((item, index) =>
|
const updatedItems = prevVotingItems.map((item, index) =>
|
||||||
item.id === message.voting_item_id ? { ...item, votes_count: item.votes_count + 1 } : item,
|
item.id === message.voting_item_id
|
||||||
|
? { ...item, votes_count: item.votes_count + 1 }
|
||||||
|
: item
|
||||||
);
|
);
|
||||||
|
|
||||||
// Sort the updated items array by votes_count in descending order
|
// Sort the updated items array by votes_count in descending order
|
||||||
|
|
@ -175,10 +171,10 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
|
|
||||||
// Update the corresponding voting item
|
// Update the corresponding voting item
|
||||||
const updatedItems = prevVotingItems.map((item, index) =>
|
const updatedItems = prevVotingItems.map((item, index) =>
|
||||||
index === 1 ? { ...item, votes_count: item.votes_count + 1 } : item,
|
index === 1 ? { ...item, votes_count: item.votes_count + 1 } : item
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log('votes updated');
|
console.log("votes updated");
|
||||||
console.log(updatedItems.sort((a, b) => b.votes_count - a.votes_count));
|
console.log(updatedItems.sort((a, b) => b.votes_count - a.votes_count));
|
||||||
// Sort the updated items array by votes_count in descending order
|
// Sort the updated items array by votes_count in descending order
|
||||||
return updatedItems.sort((a, b) => b.votes_count - a.votes_count);
|
return updatedItems.sort((a, b) => b.votes_count - a.votes_count);
|
||||||
|
|
@ -188,7 +184,10 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
const winnersCountHandle = (winners: VotingItem[]) => {
|
const winnersCountHandle = (winners: VotingItem[]) => {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
winners.map((winner) => {
|
winners.map((winner) => {
|
||||||
if (winner.votes_percents === 100 && winner.votes_count === winners[0].votes_count) {
|
if (
|
||||||
|
winner.votes_percents === 100 &&
|
||||||
|
winner.votes_count === winners[0].votes_count
|
||||||
|
) {
|
||||||
count++;
|
count++;
|
||||||
setWinnersCount(count);
|
setWinnersCount(count);
|
||||||
}
|
}
|
||||||
|
|
@ -202,23 +201,29 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
if (!data?.data) {
|
if (!data?.data) {
|
||||||
return (
|
return (
|
||||||
<div className="py-12">
|
<div className="py-12">
|
||||||
<GradientTitle title={'No voting to show on the site'} size="big" />
|
<GradientTitle title={"No voting to show on the site"} size="big" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-[20px] sm:gap-[40px] w-full items-center">
|
<div className="flex flex-col gap-[20px] sm:gap-[40px] w-full items-center">
|
||||||
{data.data.description ? <PageBage title={data.data.description} /> : null}
|
{data.data.description ? (
|
||||||
|
<PageBage title={data.data.description} />
|
||||||
|
) : null}
|
||||||
|
|
||||||
{eventStatus === 'Finished' && <Confetti />}
|
{eventStatus === "Finished" && <Confetti />}
|
||||||
|
|
||||||
{data.data.banner ? (
|
{data.data.banner ? (
|
||||||
<div className="relative w-full md:min-h-[150px] md:h-auto h-[100px] ">
|
<div className="relative w-full md:min-h-[150px] md:h-auto h-[100px] ">
|
||||||
{mobile ? (
|
{mobile ? (
|
||||||
<Image
|
<Image
|
||||||
fill
|
fill
|
||||||
src={data.data.banner_mobile !== null ? data.data.banner_mobile : data.data.banner}
|
src={
|
||||||
|
data.data.banner_mobile !== null
|
||||||
|
? data.data.banner_mobile
|
||||||
|
: data.data.banner
|
||||||
|
}
|
||||||
alt={data.data.title}
|
alt={data.data.title}
|
||||||
unselectable="off"
|
unselectable="off"
|
||||||
unoptimized
|
unoptimized
|
||||||
|
|
@ -251,22 +256,26 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<div className="flex w-full flex-col items-center gap-[10px] sm:gap-[20px]">
|
<div className="flex w-full flex-col items-center gap-[10px] sm:gap-[20px]">
|
||||||
{winnersCount > 1 ? <GradientTitle title="победители" size="small" /> : null}
|
{winnersCount > 1 ? (
|
||||||
|
<GradientTitle title="победители" size="small" />
|
||||||
|
) : null}
|
||||||
|
|
||||||
{participantsData && participantsData[0].votes_count > 0 ? (
|
{participantsData && participantsData[0].votes_count > 0 ? (
|
||||||
<div className="flex flex-col items-center overflow-hidden bg-fillNavyBlue rounded-[10px] sm:rounded-[30px] max-w-[940px] w-full px-[5px] py-[20px] sm:p-[20px] sm:gap-[20px] gap-[10px]">
|
<div className="flex flex-col items-center overflow-hidden bg-fillNavyBlue rounded-[10px] sm:rounded-[30px] max-w-[940px] w-full px-[5px] py-[20px] sm:p-[20px] sm:gap-[20px] gap-[10px]">
|
||||||
{participantsData.map((participant, index) =>
|
{participantsData.map((participant, index) =>
|
||||||
participant.votes_count === participantsData[0].votes_count ? (
|
participant.votes_count ===
|
||||||
|
participantsData[0].votes_count ? (
|
||||||
participant.url ? (
|
participant.url ? (
|
||||||
<Link
|
<Link
|
||||||
href={participant.url ? participant.url : ''}
|
href={participant.url ? participant.url : ""}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className="w-full"
|
className="w-full"
|
||||||
key={v4()}>
|
key={v4()}
|
||||||
|
>
|
||||||
<ParticipantCard
|
<ParticipantCard
|
||||||
index={index}
|
index={index}
|
||||||
hasUrl={true}
|
hasUrl={true}
|
||||||
voteStatus={voteStatus ? voteStatus : ''}
|
voteStatus={voteStatus ? voteStatus : ""}
|
||||||
isFirst={index === 0 ? true : false}
|
isFirst={index === 0 ? true : false}
|
||||||
name={participant.title}
|
name={participant.title}
|
||||||
progress={participant.votes_percents}
|
progress={participant.votes_percents}
|
||||||
|
|
@ -283,7 +292,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
key={v4()}
|
key={v4()}
|
||||||
index={index}
|
index={index}
|
||||||
hasUrl={false}
|
hasUrl={false}
|
||||||
voteStatus={voteStatus ? voteStatus : ''}
|
voteStatus={voteStatus ? voteStatus : ""}
|
||||||
isFirst={index === 0 ? true : false}
|
isFirst={index === 0 ? true : false}
|
||||||
name={participant.title}
|
name={participant.title}
|
||||||
progress={participant.votes_percents}
|
progress={participant.votes_percents}
|
||||||
|
|
@ -295,12 +304,14 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
winner={true}
|
winner={true}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
) : null,
|
) : null
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{winnersCount > 1 ? <div className="w-full h-[1px] bg-[#3636A3]"></div> : null}
|
{winnersCount > 1 ? (
|
||||||
|
<div className="w-full h-[1px] bg-[#3636A3]"></div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col items-center max-w-[940px] w-full gap-5 justify-center mx-auto">
|
<div className="flex flex-col items-center max-w-[940px] w-full gap-5 justify-center mx-auto">
|
||||||
|
|
@ -309,14 +320,15 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
!hasVotes ? (
|
!hasVotes ? (
|
||||||
participant.url ? (
|
participant.url ? (
|
||||||
<Link
|
<Link
|
||||||
href={participant.url ? participant.url : ''}
|
href={participant.url ? participant.url : ""}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className="w-full mx-auto"
|
className="w-full mx-auto"
|
||||||
key={v4()}>
|
key={v4()}
|
||||||
|
>
|
||||||
<ParticipantCard
|
<ParticipantCard
|
||||||
index={index}
|
index={index}
|
||||||
hasUrl={true}
|
hasUrl={true}
|
||||||
voteStatus={voteStatus ? voteStatus : ''}
|
voteStatus={voteStatus ? voteStatus : ""}
|
||||||
isFirst={index === 0 ? true : false}
|
isFirst={index === 0 ? true : false}
|
||||||
name={participant.title}
|
name={participant.title}
|
||||||
progress={participant.votes_percents}
|
progress={participant.votes_percents}
|
||||||
|
|
@ -333,7 +345,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
hasUrl={false}
|
hasUrl={false}
|
||||||
key={v4()}
|
key={v4()}
|
||||||
index={index}
|
index={index}
|
||||||
voteStatus={voteStatus ? voteStatus : ''}
|
voteStatus={voteStatus ? voteStatus : ""}
|
||||||
isFirst={index === 0 ? true : false}
|
isFirst={index === 0 ? true : false}
|
||||||
name={participant.title}
|
name={participant.title}
|
||||||
progress={participant.votes_percents}
|
progress={participant.votes_percents}
|
||||||
|
|
@ -346,17 +358,19 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
participant.votes_count !== participantsData[0].votes_count &&
|
participant.votes_count !==
|
||||||
|
participantsData[0].votes_count &&
|
||||||
(participant.url ? (
|
(participant.url ? (
|
||||||
<Link
|
<Link
|
||||||
href={participant.url ? participant.url : ''}
|
href={participant.url ? participant.url : ""}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className="w-full mx-auto"
|
className="w-full mx-auto"
|
||||||
key={v4()}>
|
key={v4()}
|
||||||
|
>
|
||||||
<ParticipantCard
|
<ParticipantCard
|
||||||
index={index}
|
index={index}
|
||||||
hasUrl={true}
|
hasUrl={true}
|
||||||
voteStatus={voteStatus ? voteStatus : ''}
|
voteStatus={voteStatus ? voteStatus : ""}
|
||||||
isFirst={index === 0 ? true : false}
|
isFirst={index === 0 ? true : false}
|
||||||
name={participant.title}
|
name={participant.title}
|
||||||
progress={participant.votes_percents}
|
progress={participant.votes_percents}
|
||||||
|
|
@ -373,7 +387,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
hasUrl={false}
|
hasUrl={false}
|
||||||
key={v4()}
|
key={v4()}
|
||||||
index={index}
|
index={index}
|
||||||
voteStatus={voteStatus ? voteStatus : ''}
|
voteStatus={voteStatus ? voteStatus : ""}
|
||||||
isFirst={index === 0 ? true : false}
|
isFirst={index === 0 ? true : false}
|
||||||
name={participant.title}
|
name={participant.title}
|
||||||
progress={participant.votes_percents}
|
progress={participant.votes_percents}
|
||||||
|
|
@ -385,7 +399,7 @@ const ParticipantsList = ({ vote_id }: IParams) => {
|
||||||
winner={false}
|
winner={false}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
: null}
|
: null}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ export default {
|
||||||
// Quiz ==============================================================
|
// Quiz ==============================================================
|
||||||
getQuizQuestions: `/quiz/active`,
|
getQuizQuestions: `/quiz/active`,
|
||||||
getQuiz: (quiz_id: string) => `/quiz/${quiz_id}`,
|
getQuiz: (quiz_id: string) => `/quiz/${quiz_id}`,
|
||||||
|
getQuizUUID: (quiz_id: string) => `/quiz/uuid/${quiz_id}`,
|
||||||
getQuizQuestionsWinners: (id: number) => `/quiz/${id}/winners`,
|
getQuizQuestionsWinners: (id: number) => `/quiz/${id}/winners`,
|
||||||
getQuizNetijeWinners: (id: string) => `/quiz/${id}/netije`,
|
getQuizNetijeWinners: (id: string) => `/quiz/${id}/netije`,
|
||||||
getQuizQuestionHistory: (id: number) => `/question/${id}/history`,
|
getQuizQuestionHistory: (id: number) => `/question/${id}/history`,
|
||||||
|
|
@ -19,6 +20,7 @@ export default {
|
||||||
// Votes ================================================================
|
// Votes ================================================================
|
||||||
allVotes: "/voting/show_on_site",
|
allVotes: "/voting/show_on_site",
|
||||||
vote: (vote_id: string) => `/voting/${vote_id}`,
|
vote: (vote_id: string) => `/voting/${vote_id}`,
|
||||||
|
voteUUID: (vote_id: string) => `/voting/uuid/${vote_id}`,
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
// Lottery ================================================================
|
// Lottery ================================================================
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue