Skip to content

Commit

Permalink
Added loading page logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephan Moerman committed Aug 24, 2023
1 parent 1809027 commit 65fef02
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 14 deletions.
35 changes: 35 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-toast": "^1.1.4",
Expand Down
Binary file added public/loading.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 29 additions & 14 deletions src/components/forms/quiz-creation.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
"use client";

import { useState } from "react";
import { useForm } from "react-hook-form";
import { quizCreationSchema } from "@/schemas/form/quiz";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation } from "@tanstack/react-query";
import axios from "axios";
import { useRouter } from "next/navigation";
import { BookOpen, CopyCheck, Loader2 } from "lucide-react";

import {
Card,
CardContent,
Expand All @@ -19,22 +29,16 @@ import {
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Separator } from "@/components/ui/separator";
import { BookOpen, CopyCheck, Loader2 } from "lucide-react";

import { useForm } from "react-hook-form";
import { quizCreationSchema } from "@/schemas/form/quiz";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation } from "@tanstack/react-query";
import axios from "axios";
import { useRouter } from "next/navigation";
import LoadingQuestions from "@/components/loading-questions";

type Props = {};

type Input = z.infer<typeof quizCreationSchema>;

const QuizCreation = (props: Props) => {
const router = useRouter();
const [showLoader, setShowLoader] = useState(false);
const [finished, setFinished] = useState(false);
const { mutate: getQuestions, isLoading } = useMutation({
mutationFn: async ({ amount, topic, type }: Input) => {
const response = await axios.post("/api/game", {
Expand All @@ -56,6 +60,7 @@ const QuizCreation = (props: Props) => {
});

function onSubmit(input: Input) {
setShowLoader(true);
getQuestions(
{
amount: input.amount,
Expand All @@ -64,18 +69,28 @@ const QuizCreation = (props: Props) => {
},
{
onSuccess: ({ gameId }) => {
if (form.getValues("type") === "open_ended") {
router.push(`/play/open-ended/${gameId}`);
} else {
router.push(`/play/mcq/${gameId}`);
}
setFinished(true);
setTimeout(() => {
if (form.getValues("type") === "open_ended") {
router.push(`/play/open-ended/${gameId}`);
} else {
router.push(`/play/mcq/${gameId}`);
}
}, 1000);
},
onError: () => {
setShowLoader(false);
},
}
);
}

form.watch();

if (showLoader) {
return <LoadingQuestions finished={finished} />;
}

return (
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
<Card>
Expand Down
62 changes: 62 additions & 0 deletions src/components/loading-questions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"use client";

import { useEffect, useState } from "react";
import Image from "next/image";

import { Progress } from "@/components/ui/progress";

type Props = {
finished: boolean;
};

const loadingTexts = [
"Generating questions...",
"Unleashing the power of curiosity...",
"Diving deep into the ocean of questions...",
"Harnessing the collective knowledge of the cosmos...",
"Igniting the flame of wonder and exploration...",
];

const LoadingQuestions = ({ finished }: Props) => {
const [progress, setProgress] = useState(0);
const [loadingText, setLoadingText] = useState(loadingTexts[0]);

useEffect(() => {
const interval = setInterval(() => {
const randomIndex = Math.floor(Math.random() * loadingTexts.length);
setLoadingText(loadingTexts[randomIndex]);
}, 2000);
return () => clearInterval(interval);
}, []);

useEffect(() => {
const interval = setInterval(() => {
setProgress((prev) => {
if (finished) return 100;
if (prev === 100) {
return 0;
}
if (Math.random() < 0.1) {
return prev + 2;
}
return prev + 0.5;
});
}, 100);
return () => clearInterval(interval);
}, [finished]);

return (
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[70vw] md:w-[60vw] flex flex-col items-center">
<Image
src="/loading.gif"
width={400}
height={400}
alt="Loading animation"
/>
<Progress value={progress} className="w-full mt-4" />
<h1 className="mt-2 text-xl">{loadingText}</h1>
</div>
);
};

export default LoadingQuestions;
1 change: 1 addition & 0 deletions src/components/mcq.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const MCQ = ({ game }: Props) => {
await axios.post("/api/end-game", { gameId: game.id });
return;
}
setSelectedChoice(0);
setQuestionIndex((prev) => prev + 1);
},
});
Expand Down
28 changes: 28 additions & 0 deletions src/components/ui/progress.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"use client"

import * as React from "react"
import * as ProgressPrimitive from "@radix-ui/react-progress"

import { cn } from "@/lib/utils"

const Progress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
>(({ className, value, ...props }, ref) => (
<ProgressPrimitive.Root
ref={ref}
className={cn(
"relative h-2 w-full overflow-hidden rounded-full bg-primary/20",
className
)}
{...props}
>
<ProgressPrimitive.Indicator
className="h-full w-full flex-1 bg-primary transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
))
Progress.displayName = ProgressPrimitive.Root.displayName

export { Progress }

0 comments on commit 65fef02

Please sign in to comment.