feat: quiz tebak huruf
This commit is contained in:
parent
3cde38dd5e
commit
7c37026804
|
@ -10,7 +10,7 @@ const NavLink = ({ href, name, isActive }: NavLinkProps) => {
|
||||||
<a href={href}>
|
<a href={href}>
|
||||||
<li
|
<li
|
||||||
className={cn(
|
className={cn(
|
||||||
"btn bg-transparent border-none",
|
"btn bg-transparent shadow-none border-none",
|
||||||
isActive ? "text-primary" : ""
|
isActive ? "text-primary" : ""
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,11 +1,49 @@
|
||||||
import LayoutPage from "@/components/templates/LayoutPage";
|
import LayoutPage from "@/components/templates/LayoutPage";
|
||||||
import useMenyusunHurufStore from "@/stores/MenyusunHurufStore";
|
import useMenyusunHurufStore from "@/stores/MenyusunHurufStore";
|
||||||
|
import useNavbarStore from "@/stores/NavbarStore";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import Swal from "sweetalert2";
|
import Swal from "sweetalert2";
|
||||||
|
|
||||||
const MenyusunHuruf = () => {
|
const MenyusunHuruf = () => {
|
||||||
const quizStore = useMenyusunHurufStore();
|
const quizStore = useMenyusunHurufStore();
|
||||||
|
const store = useNavbarStore();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
store.setNavSelected("kuis");
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const saveData = async () => {
|
||||||
|
try {
|
||||||
|
await fetch("https://ksuli-api.deno.dev/proses-kuis", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Bearer KSULI_TOKEN_321`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
kategori_id: "rec_cuum7c5qrj60bgubcjog",
|
||||||
|
person_name: quizStore.name,
|
||||||
|
score: parseInt(quizStore.time.toString()),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
Swal.close();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error saving data:", error);
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Oops...",
|
||||||
|
text: "Something went wrong while saving your data!",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
icon: "success",
|
||||||
|
title: "Kuis telah selesai",
|
||||||
|
text: `Anda menyelesaikan kuis dalam waktu ${quizStore.time} detik`,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const shuffleArray = (array: any[]) => {
|
const shuffleArray = (array: any[]) => {
|
||||||
for (let i = array.length - 1; i > 0; i--) {
|
for (let i = array.length - 1; i > 0; i--) {
|
||||||
|
@ -19,11 +57,7 @@ const MenyusunHuruf = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (quizStore.isFinish) {
|
if (quizStore.isFinish) {
|
||||||
Swal.fire({
|
saveData();
|
||||||
icon: "success",
|
|
||||||
title: "Kuis telah selesai",
|
|
||||||
text: `Anda menyelesaikan kuis dalam waktu ${quizStore.time} detik`,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, [quizStore.isFinish]);
|
}, [quizStore.isFinish]);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import calcLandmarkList from "@/utils/CalculateLandmark";
|
||||||
import preProcessLandmark from "@/utils/PreProcessLandmark";
|
import preProcessLandmark from "@/utils/PreProcessLandmark";
|
||||||
import { abjads } from "@/utils/ConvertResult";
|
import { abjads } from "@/utils/ConvertResult";
|
||||||
import useNavbarStore from "@/stores/NavbarStore";
|
import useNavbarStore from "@/stores/NavbarStore";
|
||||||
import ProgressBar from "@/components/molecules/ProgressBar";
|
|
||||||
import { MdOutlineQuiz } from "react-icons/md";
|
import { MdOutlineQuiz } from "react-icons/md";
|
||||||
import useMenyusunHurufStore from "@/stores/MenyusunHurufStore";
|
import useMenyusunHurufStore from "@/stores/MenyusunHurufStore";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
@ -94,7 +93,6 @@ const Quiz = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const [progress, setProgress] = useState(0);
|
|
||||||
const [answer, setAnswer] = useState("");
|
const [answer, setAnswer] = useState("");
|
||||||
|
|
||||||
let tempAnswer = "";
|
let tempAnswer = "";
|
||||||
|
@ -196,7 +194,6 @@ const Quiz = () => {
|
||||||
Swal.showLoading();
|
Swal.showLoading();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await saveData(parseInt(answerTime.toString()));
|
|
||||||
|
|
||||||
navigate("/kuis/menyusun-huruf/");
|
navigate("/kuis/menyusun-huruf/");
|
||||||
}
|
}
|
||||||
|
@ -204,32 +201,6 @@ const Quiz = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveData = async (time: number) => {
|
|
||||||
try {
|
|
||||||
await fetch("https://ksuli-api.deno.dev/proses-kuis", {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer KSULI_TOKEN_321`,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
kategori_id: "rec_cuum7c5qrj60bgubcjog",
|
|
||||||
person_name: quizStore.name,
|
|
||||||
score: time,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
Swal.close();
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error saving data:", error);
|
|
||||||
Swal.fire({
|
|
||||||
icon: "error",
|
|
||||||
title: "Oops...",
|
|
||||||
text: "Something went wrong while saving your data!",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const detectHands = async () => {
|
const detectHands = async () => {
|
||||||
if (showAnswer) {
|
if (showAnswer) {
|
||||||
return;
|
return;
|
||||||
|
@ -256,10 +227,8 @@ const Quiz = () => {
|
||||||
makePrediction(finalResult);
|
makePrediction(finalResult);
|
||||||
} else {
|
} else {
|
||||||
setHandPresence(false);
|
setHandPresence(false);
|
||||||
setProgress(0);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setProgress(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,13 +285,13 @@ const Quiz = () => {
|
||||||
{!showAnswer && (
|
{!showAnswer && (
|
||||||
<div className="top-6 left-6 absolute flex flex-col gap-2">
|
<div className="top-6 left-6 absolute flex flex-col gap-2">
|
||||||
<div className="flex gap-2 items-center bg-white text-black rounded-md drop-shadow px-3 py-2">
|
<div className="flex gap-2 items-center bg-white text-black rounded-md drop-shadow px-3 py-2">
|
||||||
<h1 className="text-2xl font-semibold text-center">
|
<h1 className="text-xs md:text-2xl font-semibold text-center">
|
||||||
Susun huruf "{quizStore.listSoal[quizStore.soalIndex]}"
|
Susun huruf "{quizStore.listSoal[quizStore.soalIndex]}"
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
{answer.length > 0 && (
|
{answer.length > 0 && (
|
||||||
<div className="flex gap-2 items-center bg-white text-black w-fit rounded-md drop-shadow px-3 py-2">
|
<div className="flex gap-2 items-center bg-white text-black w-fit rounded-md drop-shadow px-3 py-2">
|
||||||
<h1 className="text-2xl font-semibold text-center">
|
<h1 className="text-xs md:text-2xl font-semibold text-center">
|
||||||
{answer}
|
{answer}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
@ -334,9 +303,7 @@ const Quiz = () => {
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="loader"></span>
|
<span className="loader"></span>
|
||||||
<h1>Tahan Tangan..</h1>
|
|
||||||
</div>
|
</div>
|
||||||
<ProgressBar progress={progress} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -4,10 +4,13 @@ import * as tf from "@tensorflow/tfjs";
|
||||||
import { FilesetResolver, HandLandmarker } from "@mediapipe/tasks-vision";
|
import { FilesetResolver, HandLandmarker } from "@mediapipe/tasks-vision";
|
||||||
import calcLandmarkList from "@/utils/CalculateLandmark";
|
import calcLandmarkList from "@/utils/CalculateLandmark";
|
||||||
import preProcessLandmark from "@/utils/PreProcessLandmark";
|
import preProcessLandmark from "@/utils/PreProcessLandmark";
|
||||||
import ConvertResult from "@/utils/ConvertResult";
|
import ConvertResult, { abjads } from "@/utils/ConvertResult";
|
||||||
import useNavbarStore from "@/stores/NavbarStore";
|
import useNavbarStore from "@/stores/NavbarStore";
|
||||||
import ProgressBar from "@/components/molecules/ProgressBar";
|
import ProgressBar from "@/components/molecules/ProgressBar";
|
||||||
import { MdOutlineQuiz } from "react-icons/md";
|
import { MdOutlineQuiz } from "react-icons/md";
|
||||||
|
import useTebakHurufStore from "@/stores/TebakHurufStore";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import Swal from "sweetalert2";
|
||||||
|
|
||||||
// type PredictResult = {
|
// type PredictResult = {
|
||||||
// abjad: String;
|
// abjad: String;
|
||||||
|
@ -85,6 +88,9 @@ const Quiz = () => {
|
||||||
|
|
||||||
let previousResult: string[] = [];
|
let previousResult: string[] = [];
|
||||||
const [progress, setProgress] = useState(0);
|
const [progress, setProgress] = useState(0);
|
||||||
|
let noSoal = 0;
|
||||||
|
let isLoading = false;
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const makePrediction = async (finalResult: any) => {
|
const makePrediction = async (finalResult: any) => {
|
||||||
const input = tf.tensor2d([finalResult]);
|
const input = tf.tensor2d([finalResult]);
|
||||||
|
@ -127,13 +133,45 @@ const Quiz = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previousResult.length == 11) {
|
if (previousResult.length == 11) {
|
||||||
|
isLoading = true;
|
||||||
|
|
||||||
|
if (abjads[parseInt(maxKey)] === quizStore.listSoal[noSoal]) {
|
||||||
|
quizStore.addJawaban({
|
||||||
|
jawaban: abjads[parseInt(maxKey)],
|
||||||
|
isCorrect: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
quizStore.addJawaban({
|
||||||
|
jawaban: abjads[parseInt(maxKey)],
|
||||||
|
isCorrect: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setShowAnswer(true);
|
setShowAnswer(true);
|
||||||
|
|
||||||
previousResult = [];
|
|
||||||
setProgress(0);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
isLoading = false;
|
||||||
setShowAnswer(false);
|
setShowAnswer(false);
|
||||||
|
setProgress(0);
|
||||||
|
noSoal++;
|
||||||
|
previousResult = [];
|
||||||
|
quizStore.setSoalIndex(noSoal);
|
||||||
|
|
||||||
|
if (noSoal === quizStore.listSoal.length) {
|
||||||
|
quizStore.setSession(false);
|
||||||
|
quizStore.setIsFinish(true);
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: "Loading",
|
||||||
|
text: "Proses menyimpan data...",
|
||||||
|
allowOutsideClick: false,
|
||||||
|
didOpen: () => {
|
||||||
|
Swal.showLoading();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
navigate("/kuis/tebak-huruf");
|
||||||
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +201,9 @@ const Quiz = () => {
|
||||||
const calt = calcLandmarkList(videoRef.current, landm);
|
const calt = calcLandmarkList(videoRef.current, landm);
|
||||||
const finalResult = preProcessLandmark(calt);
|
const finalResult = preProcessLandmark(calt);
|
||||||
|
|
||||||
|
if (!isLoading) {
|
||||||
makePrediction(finalResult);
|
makePrediction(finalResult);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setHandPresence(false);
|
setHandPresence(false);
|
||||||
setProgress(0);
|
setProgress(0);
|
||||||
|
@ -179,6 +219,15 @@ const Quiz = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const store = useNavbarStore();
|
const store = useNavbarStore();
|
||||||
|
const quizStore = useTebakHurufStore();
|
||||||
|
|
||||||
|
console.log(quizStore.jawaban);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!quizStore.session) {
|
||||||
|
window.location.href = "/kuis/tebak-huruf";
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
store.setNavSelected("kuis");
|
store.setNavSelected("kuis");
|
||||||
|
@ -205,33 +254,48 @@ const Quiz = () => {
|
||||||
<div className="rounded-md px-3 py-2 text-white flex flex-col justify-center items-center gap-3">
|
<div className="rounded-md px-3 py-2 text-white flex flex-col justify-center items-center gap-3">
|
||||||
<img
|
<img
|
||||||
className="h-56"
|
className="h-56"
|
||||||
src="/assets/gif/salah.gif"
|
src={`/assets/gif/${
|
||||||
alt="Jawaban Salah"
|
quizStore.jawaban[quizStore.soalIndex]?.isCorrect
|
||||||
|
? "betul"
|
||||||
|
: "salah"
|
||||||
|
}.gif`}
|
||||||
|
alt={`Jawaban ${
|
||||||
|
quizStore.jawaban[quizStore.soalIndex]?.isCorrect
|
||||||
|
? "Benar"
|
||||||
|
: "Salah"
|
||||||
|
}`}
|
||||||
/>
|
/>
|
||||||
<p className="text-center text-6xl font-bold">A</p>
|
<p className="text-center text-6xl font-bold">
|
||||||
|
{quizStore.jawaban[quizStore.soalIndex]?.jawaban}
|
||||||
|
</p>
|
||||||
<h1 className="text-2xl font-semibold text-center">
|
<h1 className="text-2xl font-semibold text-center">
|
||||||
Jawaban kamu Salah
|
Jawaban kamu{" "}
|
||||||
|
{quizStore.jawaban[quizStore.soalIndex]?.isCorrect
|
||||||
|
? "Benar"
|
||||||
|
: "Salah"}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2 mt-4">
|
<div className="flex items-center gap-2 mt-4">
|
||||||
<MdOutlineQuiz size={18} />
|
<MdOutlineQuiz size={18} />
|
||||||
<h1 className="text-xl font-semibold">Soal: 1 / 10</h1>
|
<h1 className="text-xl font-semibold">
|
||||||
|
Soal: {quizStore.soalIndex + 1} / {quizStore.listSoal.length}
|
||||||
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col flex-1 py-4">
|
<div className="flex flex-col flex-1 py-4">
|
||||||
{loadCamera ? (
|
{loadCamera ? (
|
||||||
<div className="rounded-md overflow-hidden relative">
|
<div className="rounded-md overflow-hidden relative">
|
||||||
{!showAnswer && (
|
{!showAnswer && (
|
||||||
<div className="top-6 left-6 absolute flex gap-2 items-center bg-white text-black rounded-md drop-shadow px-3 py-2">
|
<div className="md:top-6 top-3 left-3 md:left-6 absolute flex gap-2 items-center bg-white text-black rounded-md drop-shadow px-3 py-2">
|
||||||
<h1 className="text-2xl font-semibold text-center">
|
<h1 className="md:text-2xl font-semibold text-center">
|
||||||
Tebak Huruf K
|
Tebak Huruf {quizStore.listSoal[quizStore.soalIndex]}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{handPresence && !showAnswer && (
|
{handPresence && !showAnswer && (
|
||||||
<div className="top-6 right-6 absolute flex gap-2 items-center bg-white text-black rounded-md drop-shadow px-3 py-2 w-fit">
|
<div className="bottom-3 md:bottom-auto md:top-6 right-3 md:right-6 absolute flex gap-2 items-center bg-white text-black rounded-md drop-shadow px-3 py-2 w-fit">
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="loader"></span>
|
<span className="loader"></span>
|
||||||
|
|
|
@ -1,7 +1,128 @@
|
||||||
import LayoutPage from "@/components/templates/LayoutPage";
|
import LayoutPage from "@/components/templates/LayoutPage";
|
||||||
import { Link } from "react-router-dom";
|
import useNavbarStore from "@/stores/NavbarStore";
|
||||||
|
import useTebakHurufStore from "@/stores/TebakHurufStore";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
import Swal from "sweetalert2";
|
||||||
|
|
||||||
const TebakHuruf = () => {
|
const TebakHuruf = () => {
|
||||||
|
const quizStore = useTebakHurufStore();
|
||||||
|
|
||||||
|
const store = useNavbarStore();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
store.setNavSelected("kuis");
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const shuffleSoal = () => {
|
||||||
|
const arr = [
|
||||||
|
"A",
|
||||||
|
"B",
|
||||||
|
"C",
|
||||||
|
"D",
|
||||||
|
"E",
|
||||||
|
"F",
|
||||||
|
"G",
|
||||||
|
"H",
|
||||||
|
"I",
|
||||||
|
"K",
|
||||||
|
"L",
|
||||||
|
"M",
|
||||||
|
"N",
|
||||||
|
"O",
|
||||||
|
"P",
|
||||||
|
"Q",
|
||||||
|
"R",
|
||||||
|
"S",
|
||||||
|
"T",
|
||||||
|
"U",
|
||||||
|
"V",
|
||||||
|
"W",
|
||||||
|
"X",
|
||||||
|
"Y",
|
||||||
|
];
|
||||||
|
|
||||||
|
const shuffledArr = arr.sort(() => 0.5 - Math.random()).slice(0, 10);
|
||||||
|
return shuffledArr;
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveData = async () => {
|
||||||
|
let score = 0;
|
||||||
|
let benar = 0;
|
||||||
|
let salah = 0;
|
||||||
|
try {
|
||||||
|
quizStore.jawaban.forEach((jawaban) => {
|
||||||
|
if (jawaban.isCorrect) {
|
||||||
|
score += 10;
|
||||||
|
benar += 1;
|
||||||
|
} else {
|
||||||
|
salah += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await fetch("https://ksuli-api.deno.dev/proses-kuis", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: `Bearer KSULI_TOKEN_321`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
kategori_id: "rec_cuum78tqrj678tmbcjh0",
|
||||||
|
person_name: quizStore.name,
|
||||||
|
score: score,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
Swal.close();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error saving data:", error);
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Oops...",
|
||||||
|
text: "Something went wrong while saving your data!",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
icon: "success",
|
||||||
|
title: "Kuis telah selesai",
|
||||||
|
html: `
|
||||||
|
<p>Anda menyelesaikan kuis dengan score: ${score}</p>
|
||||||
|
<p>Jawaban benar: ${benar}</p>
|
||||||
|
<p>Jawaban salah: ${salah}</p>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const router = useNavigate();
|
||||||
|
|
||||||
|
const ProsesKuis = () => {
|
||||||
|
if (quizStore.name === "") {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Oops...",
|
||||||
|
text: "Isi nama terlebih dahulu",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
quizStore.setSoalIndex(0);
|
||||||
|
quizStore.setSession(true);
|
||||||
|
quizStore.setListSoal(shuffleSoal());
|
||||||
|
|
||||||
|
router("/kuis/tebak-huruf/app");
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (quizStore.isFinish) {
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
quizStore.setIsFinish(false);
|
||||||
|
};
|
||||||
|
}, [quizStore.isFinish]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LayoutPage>
|
<LayoutPage>
|
||||||
<div className="flex flex-col flex-1 py-4 relative">
|
<div className="flex flex-col flex-1 py-4 relative">
|
||||||
|
@ -25,13 +146,18 @@ const TebakHuruf = () => {
|
||||||
<input
|
<input
|
||||||
placeholder="Name.."
|
placeholder="Name.."
|
||||||
type="text"
|
type="text"
|
||||||
|
value={quizStore.name}
|
||||||
|
onChange={(e) => quizStore.setName(e.target.value)}
|
||||||
className="bg-transparent outline-none p-2 px-8 flex-1 w-full"
|
className="bg-transparent outline-none p-2 px-8 flex-1 w-full"
|
||||||
/>
|
/>
|
||||||
<Link to="/kuis/tebak-huruf/app">
|
<button
|
||||||
<button className="bg-blue-500 hover:bg-blue-700 text-white px-3 py-2 rounded-full whitespace-nowrap">
|
onClick={() => {
|
||||||
|
ProsesKuis();
|
||||||
|
}}
|
||||||
|
className="bg-blue-500 hover:bg-blue-700 text-white px-3 py-2 rounded-full whitespace-nowrap"
|
||||||
|
>
|
||||||
Mulai Kuis
|
Mulai Kuis
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
<span className="text-primary">Lihat Ranking</span>
|
<span className="text-primary">Lihat Ranking</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,6 +15,12 @@ type TebakHurufType = {
|
||||||
jawaban: JawabanType[];
|
jawaban: JawabanType[];
|
||||||
setJawaban: (jawaban: JawabanType[]) => void;
|
setJawaban: (jawaban: JawabanType[]) => void;
|
||||||
addJawaban: (jawaban: JawabanType) => void;
|
addJawaban: (jawaban: JawabanType) => void;
|
||||||
|
session: boolean;
|
||||||
|
setSession: (session: boolean) => void;
|
||||||
|
name: string;
|
||||||
|
setName: (name: string) => void;
|
||||||
|
isFinish: boolean;
|
||||||
|
setIsFinish: (isFinish: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const useTebakHurufStore = create<TebakHurufType>((set) => ({
|
const useTebakHurufStore = create<TebakHurufType>((set) => ({
|
||||||
|
@ -28,6 +34,12 @@ const useTebakHurufStore = create<TebakHurufType>((set) => ({
|
||||||
setJawaban: (jawaban) => set({ jawaban: jawaban }),
|
setJawaban: (jawaban) => set({ jawaban: jawaban }),
|
||||||
addJawaban: (jawaban) =>
|
addJawaban: (jawaban) =>
|
||||||
set((state) => ({ jawaban: [...state.jawaban, jawaban] })),
|
set((state) => ({ jawaban: [...state.jawaban, jawaban] })),
|
||||||
|
session: false,
|
||||||
|
setSession: (session) => set({ session: session }),
|
||||||
|
name: "",
|
||||||
|
setName: (name) => set({ name: name }),
|
||||||
|
isFinish: false,
|
||||||
|
setIsFinish: (isFinish) => set({ isFinish: isFinish }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default useTebakHurufStore;
|
export default useTebakHurufStore;
|
||||||
|
|
Loading…
Reference in New Issue