feat: slicing page ranking
This commit is contained in:
parent
1c1e828315
commit
ae17e2d0ba
|
@ -16,6 +16,7 @@
|
|||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-icons": "^5.3.0",
|
||||
"react-nice-avatar": "^1.5.0",
|
||||
"react-router-dom": "^6.26.1",
|
||||
"react-virtualized-auto-sizer": "^1.0.24",
|
||||
"react-window": "^1.8.10",
|
||||
|
@ -2069,6 +2070,12 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/chroma-js": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.6.0.tgz",
|
||||
"integrity": "sha512-BLHvCB9s8Z1EV4ethr6xnkl/P2YRFOGqfgvuMG/MyCbZPrTA+NeiByY6XvgF0zP4/2deU2CXnWyMa3zu1LqQ3A==",
|
||||
"license": "(BSD-3-Clause AND Apache-2.0)"
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
|
@ -3475,7 +3482,6 @@
|
|||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
@ -3809,6 +3815,17 @@
|
|||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
|
@ -3869,6 +3886,26 @@
|
|||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-nice-avatar": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/react-nice-avatar/-/react-nice-avatar-1.5.0.tgz",
|
||||
"integrity": "sha512-sGusqbgWIA4Il6Y0zHEfs4XF+a06etNljhwFYiHIGATDmVVf53Nez7U7GY5EwEz5/xGuUhs6uel5AC5NN/2UPg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.14.3",
|
||||
"chroma-js": "^2.1.2",
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.14.2",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-icons": "^5.3.0",
|
||||
"react-nice-avatar": "^1.5.0",
|
||||
"react-router-dom": "^6.26.1",
|
||||
"react-virtualized-auto-sizer": "^1.0.24",
|
||||
"react-window": "^1.8.10",
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
import { useState } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
|
||||
const slides = [
|
||||
{
|
||||
title: "Nama",
|
||||
description:
|
||||
"Masukkan nama Anda untuk memulai. Nama Anda akan digunakan untuk personalisasi pengalaman Anda selama menggunakan aplikasi ini.",
|
||||
image: "/assets/images/susun_1.svg",
|
||||
button: "Next",
|
||||
},
|
||||
{
|
||||
title: "Tebak Huruf",
|
||||
description:
|
||||
"Tebak huruf sesuai soal yang ditampilkan. Ini adalah latihan untuk meningkatkan keterampilan kognitif dan kecepatan berpikir Anda.",
|
||||
image: "/assets/images/susun_2.svg",
|
||||
button: "Next",
|
||||
},
|
||||
{
|
||||
title: "Proses Jawaban",
|
||||
description:
|
||||
"Tahan tangan Anda di depan kamera sampai proses selesai dan tampil dialog benar atau tidaknya jawaban.",
|
||||
image: "/assets/images/susun_3.svg",
|
||||
button: "Next",
|
||||
},
|
||||
{
|
||||
title: "Score",
|
||||
description:
|
||||
"Raih skor tertinggimu dengan menyelesaikan tugas dengan cepat dan tepat. Skor Anda akan dibandingkan dengan pengguna lain di papan peringkat.",
|
||||
image: "/assets/images/susun_4.svg",
|
||||
button: "Get Started",
|
||||
},
|
||||
];
|
||||
|
||||
export default function Carousel() {
|
||||
const [current, setCurrent] = useState(0);
|
||||
|
||||
const nextSlide = () => {
|
||||
setCurrent((prev) => (prev === slides.length - 1 ? 0 : prev + 1));
|
||||
};
|
||||
|
||||
const prevSlide = () => {
|
||||
setCurrent((prev) => (prev === 0 ? slides.length - 1 : prev - 1));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative w-full max-w-lg mx-auto p-6 pb-20 bg-white rounded-xl shadow-lg">
|
||||
<AnimatePresence mode="wait">
|
||||
{slides.map(
|
||||
(slide, index) =>
|
||||
index === current && (
|
||||
<motion.div
|
||||
key={index}
|
||||
className="flex flex-col items-center text-center"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
>
|
||||
<img src={slide.image} alt={slide.title} className="h-60" />
|
||||
{/* <h2 className="mt-4 text-xl font-bold">{slide.title}</h2> */}
|
||||
<p className="mt-8 text-gray-500 text-sm">
|
||||
{slide.description}
|
||||
</p>
|
||||
{/* <button
|
||||
onClick={nextSlide}
|
||||
className="mt-4 bg-blue-500 text-white py-2 px-4 rounded-full shadow-md"
|
||||
>
|
||||
{slide.button}
|
||||
</button> */}
|
||||
</motion.div>
|
||||
)
|
||||
)}
|
||||
</AnimatePresence>
|
||||
<div className="absolute bottom-4 left-1/2 -translate-x-1/2 flex gap-2">
|
||||
{slides.map((_, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => setCurrent(index)}
|
||||
className={`h-2 w-2 rounded-full ${
|
||||
index === current ? "bg-blue-500" : "bg-gray-300"
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<button
|
||||
onClick={prevSlide}
|
||||
className="absolute left-0 top-1/2 -translate-y-1/2 bg-base-100 text-gray-600 p-1 rounded-full"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-4 w-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M15 19l-7-7 7-7"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
onClick={nextSlide}
|
||||
className="absolute right-0 top-1/2 -translate-y-1/2 bg-base-100 text-gray-600 p-1 rounded-full"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-4 w-4"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M9 5l7 7-7 7"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -4,7 +4,11 @@ const FooterPage = () => {
|
|||
<div className="flex flex-row justify-center py-2 bg-white">
|
||||
<p className="text-xs text-center">
|
||||
© 2024 <span className="font-medium">Kedai Susu Tuli</span> &
|
||||
Developed by <span className="font-medium">Mphstar</span> ❤️
|
||||
Developed by{" "}
|
||||
<a href="https://mphstar.me" target="_blank" rel="noopener noreferrer">
|
||||
<span className="underline font-semibold">Mphstar</span>
|
||||
</a>{" "}
|
||||
❤️
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
|
|
@ -22,7 +22,7 @@ const HeaderPage = () => {
|
|||
</div>
|
||||
<ul
|
||||
className={cn(
|
||||
"flex md:flex-row flex-col items-center justify-center fixed md:static min-h-svh md:min-h-0 w-full md:w-fit bg-white/50 md:bg-transparent md:backdrop-blur-none backdrop-blur-md z-[999] top-0 left-0",
|
||||
"flex md:flex-row flex-col items-center justify-center fixed md:static min-h-svh md:min-h-0 w-full md:w-fit bg-white/50 md:bg-transparent z-[999] top-0 left-0",
|
||||
navStore.isOpen ? "translate-y-0" : "-translate-y-full",
|
||||
"duration-300 ease-in-out md:translate-y-0"
|
||||
)}
|
||||
|
|
|
@ -19,15 +19,29 @@ const Kamus = () => {
|
|||
<h1 className="font-semibold">Kamus SIBI</h1>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-6 mt-6">
|
||||
{constantKamus.map((item, index) => (
|
||||
<CardKamus
|
||||
handleClick={() => {
|
||||
setSelectedKamus(item);
|
||||
setShowDialog(true);
|
||||
}}
|
||||
<motion.div
|
||||
key={index}
|
||||
title={`Abjad ${item.abjad.toUpperCase()}`}
|
||||
image={`/assets/kamus/${item.abjad}.jpg`}
|
||||
/>
|
||||
initial={{
|
||||
scale: 0,
|
||||
opacity: 0,
|
||||
}}
|
||||
animate={{
|
||||
scale: 1,
|
||||
opacity: 1,
|
||||
}}
|
||||
transition={{
|
||||
delay: index * 0.1,
|
||||
}}
|
||||
>
|
||||
<CardKamus
|
||||
handleClick={() => {
|
||||
setSelectedKamus(item);
|
||||
setShowDialog(true);
|
||||
}}
|
||||
title={`Abjad ${item.abjad.toUpperCase()}`}
|
||||
image={`/assets/kamus/${item.abjad}.jpg`}
|
||||
/>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,6 +2,7 @@ import LayoutPage from "@/components/templates/LayoutPage";
|
|||
import useNavbarStore from "@/stores/NavbarStore";
|
||||
import { useEffect } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
const Kuis = () => {
|
||||
const store = useNavbarStore();
|
||||
|
@ -16,7 +17,20 @@ const Kuis = () => {
|
|||
<p>Be the first!</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-24 md:gap-6 mt-24 md:mt-52 h-full mb-12">
|
||||
<Link to="/kuis/tebak-huruf">
|
||||
<div className="relative ">
|
||||
<motion.div
|
||||
initial={{
|
||||
scale: 0,
|
||||
opacity: 0,
|
||||
}}
|
||||
animate={{
|
||||
scale: 1,
|
||||
opacity: 1,
|
||||
}}
|
||||
transition={{
|
||||
delay: 0.1,
|
||||
}}
|
||||
className="relative "
|
||||
>
|
||||
<img
|
||||
className="absolute w-24 -top-12 left-4 md:left-12"
|
||||
src="/assets/images/tebak-huruf.png"
|
||||
|
@ -28,10 +42,23 @@ const Kuis = () => {
|
|||
</h1>
|
||||
<p>Tebak huruf dan coba simulasikan</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</Link>
|
||||
<Link to="/kuis/menyusun-huruf">
|
||||
<div className="relative ">
|
||||
<motion.div
|
||||
initial={{
|
||||
scale: 0,
|
||||
opacity: 0,
|
||||
}}
|
||||
animate={{
|
||||
scale: 1,
|
||||
opacity: 1,
|
||||
}}
|
||||
transition={{
|
||||
delay: 0.2,
|
||||
}}
|
||||
className="relative "
|
||||
>
|
||||
<img
|
||||
className="absolute w-42 -top-12 left-4 md:left-12"
|
||||
src="/assets/images/menyusun-huruf.png"
|
||||
|
@ -43,7 +70,7 @@ const Kuis = () => {
|
|||
</h1>
|
||||
<p>Susun huruf jadi kata yang tepat</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import Carousel from "@/components/organisms/Carousel";
|
||||
import Carousel from "@/components/organisms/CarouselSusunHuruf";
|
||||
import LayoutPage from "@/components/templates/LayoutPage";
|
||||
import useMenyusunHurufStore from "@/stores/MenyusunHurufStore";
|
||||
import useNavbarStore from "@/stores/NavbarStore";
|
||||
import { AnimatePresence, motion } from "motion/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { HiOutlineHome } from "react-icons/hi";
|
||||
import { IoCloseOutline } from "react-icons/io5";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import Swal from "sweetalert2";
|
||||
|
@ -121,7 +122,10 @@ const MenyusunHuruf = () => {
|
|||
</AnimatePresence>
|
||||
<div className="flex flex-col flex-1 py-4 relative">
|
||||
<ul className="flex gap-3 mt-4">
|
||||
<li className="hover:text-primary cursor-default">Home</li>
|
||||
<li className="hover:text-primary cursor-default flex gap-2 items-center">
|
||||
<HiOutlineHome />
|
||||
<p>Home</p>
|
||||
</li>
|
||||
<li>{">"}</li>
|
||||
<Link to="/kuis" className="hover:text-primary">
|
||||
Kuis
|
||||
|
@ -131,10 +135,33 @@ const MenyusunHuruf = () => {
|
|||
</ul>
|
||||
|
||||
<div className="flex-1 flex flex-col mt-12 md:mt-24 w-full md:w-[500px]">
|
||||
<h1 className="text-5xl font-semibold">
|
||||
<motion.h1
|
||||
initial={{
|
||||
scale: 0,
|
||||
opacity: 0,
|
||||
}}
|
||||
animate={{
|
||||
scale: 1,
|
||||
opacity: 1,
|
||||
}}
|
||||
transition={{
|
||||
delay: 0.2,
|
||||
}}
|
||||
className="text-4xl md:text-5xl font-semibold"
|
||||
>
|
||||
Start Your <span className="text-primary">Quiz!</span>
|
||||
</h1>
|
||||
<div className="flex flex-col gap-3 w-full mt-24 md:mt-36">
|
||||
</motion.h1>
|
||||
<motion.div
|
||||
initial={{
|
||||
scale: 0,
|
||||
opacity: 0,
|
||||
}}
|
||||
animate={{
|
||||
scale: 1,
|
||||
opacity: 1,
|
||||
}}
|
||||
className="flex flex-col gap-3 w-full mt-24 md:mt-36"
|
||||
>
|
||||
<h1 className="font-semibold text-xl">Masukkan Nama</h1>
|
||||
<div className="bg-[#F2F2F2] rounded-full pr-4 flex py-2 items-center">
|
||||
<input
|
||||
|
@ -154,13 +181,22 @@ const MenyusunHuruf = () => {
|
|||
</button>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span onClick={() => {
|
||||
setShowDialog(true);
|
||||
}} className="text-primary btn btn-link px-0">Cara Bermain</span>
|
||||
<span
|
||||
onClick={() => {
|
||||
setShowDialog(true);
|
||||
}}
|
||||
className="text-primary btn btn-link px-0"
|
||||
>
|
||||
Cara Bermain
|
||||
</span>
|
||||
<span className="text-gray-400">|</span>
|
||||
<span className="text-primary btn btn-link px-0">Lihat Ranking</span>
|
||||
<Link to="/kuis/ranking" className="text-primary">
|
||||
<span className="text-primary btn btn-link px-0">
|
||||
Lihat Ranking
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
<img
|
||||
className="absolute right-0 md:top-36 bottom-0 pointer-events-none"
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import LayoutPage from "@/components/templates/LayoutPage";
|
||||
import useNavbarStore from "@/stores/NavbarStore";
|
||||
import useTebakHurufStore from "@/stores/TebakHurufStore";
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { HiOutlineHome } from "react-icons/hi";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import Swal from "sweetalert2";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import Carousel from "@/components/organisms/CarouselTebakHuruf";
|
||||
import { IoCloseOutline } from "react-icons/io5";
|
||||
|
||||
const TebakHuruf = () => {
|
||||
const quizStore = useTebakHurufStore();
|
||||
|
@ -123,11 +127,53 @@ const TebakHuruf = () => {
|
|||
};
|
||||
}, [quizStore.isFinish]);
|
||||
|
||||
const [showDialog, setShowDialog] = useState(false);
|
||||
|
||||
return (
|
||||
<LayoutPage>
|
||||
<AnimatePresence>
|
||||
{showDialog && (
|
||||
<motion.div
|
||||
className="fixed inset-0 bg-black bg-opacity-50 flex items-center z-[999] justify-center"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
onClick={(e) => {
|
||||
if (e.target === e.currentTarget) {
|
||||
setShowDialog(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<motion.div
|
||||
className="bg-white max-h-[90%] px-8 py-6 rounded-md flex flex-col max-w-[90%] md:min-w-[400px] md:max-w-[400px] w-full"
|
||||
initial={{ scale: 0.5 }}
|
||||
animate={{ scale: 1 }}
|
||||
exit={{ scale: 0.8 }}
|
||||
>
|
||||
<div className="flex gap-2 justify-between items-center pb-8">
|
||||
<h1 className="font-semibold">Cara Bermain</h1>
|
||||
<button
|
||||
onClick={() => setShowDialog(false)}
|
||||
className="hover:bg-base-100 p-3 rounded-md"
|
||||
>
|
||||
<IoCloseOutline />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col md:flex-row gap-6 overflow-y-auto flex-1">
|
||||
<Carousel />
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
<div className="flex flex-col flex-1 py-4 relative">
|
||||
<ul className="flex gap-3 mt-4">
|
||||
<li className="hover:text-primary cursor-default">Home</li>
|
||||
<li className="hover:text-primary cursor-default flex gap-2 items-center">
|
||||
<HiOutlineHome />
|
||||
<p>Home</p>
|
||||
</li>
|
||||
<li>{">"}</li>
|
||||
<Link to="/kuis" className="hover:text-primary">
|
||||
Kuis
|
||||
|
@ -137,10 +183,33 @@ const TebakHuruf = () => {
|
|||
</ul>
|
||||
|
||||
<div className="flex-1 flex flex-col mt-12 md:mt-24 w-full md:w-[500px]">
|
||||
<h1 className="text-5xl font-semibold">
|
||||
<motion.h1
|
||||
initial={{
|
||||
scale: 0,
|
||||
opacity: 0,
|
||||
}}
|
||||
animate={{
|
||||
scale: 1,
|
||||
opacity: 1,
|
||||
}}
|
||||
transition={{
|
||||
delay: 0.2,
|
||||
}}
|
||||
className="text-4xl md:text-5xl font-semibold"
|
||||
>
|
||||
Start Your <span className="text-primary">Quiz!</span>
|
||||
</h1>
|
||||
<div className="flex flex-col gap-3 w-full mt-24 md:mt-36">
|
||||
</motion.h1>
|
||||
<motion.div
|
||||
initial={{
|
||||
scale: 0,
|
||||
opacity: 0,
|
||||
}}
|
||||
animate={{
|
||||
scale: 1,
|
||||
opacity: 1,
|
||||
}}
|
||||
className="flex flex-col gap-3 w-full mt-24 md:mt-36"
|
||||
>
|
||||
<h1 className="font-semibold text-xl">Masukkan Nama</h1>
|
||||
<div className="bg-[#F2F2F2] rounded-full pr-4 flex py-2 items-center">
|
||||
<input
|
||||
|
@ -159,8 +228,23 @@ const TebakHuruf = () => {
|
|||
Mulai Kuis
|
||||
</button>
|
||||
</div>
|
||||
<span className="text-primary">Lihat Ranking</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span
|
||||
onClick={() => {
|
||||
setShowDialog(true);
|
||||
}}
|
||||
className="text-primary btn btn-link px-0"
|
||||
>
|
||||
Cara Bermain
|
||||
</span>
|
||||
<span className="text-gray-400">|</span>
|
||||
<Link to="/kuis/ranking" className="text-primary">
|
||||
<span className="text-primary btn btn-link px-0">
|
||||
Lihat Ranking
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
<img
|
||||
className="absolute right-0 md:top-36 bottom-0 pointer-events-none"
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
import LayoutPage from "@/components/templates/LayoutPage";
|
||||
import useNavbarStore from "@/stores/NavbarStore";
|
||||
import { useEffect, useState } from "react";
|
||||
import { HiOutlineHome } from "react-icons/hi";
|
||||
import { Link } from "react-router-dom";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
const data = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Asep",
|
||||
score: 100,
|
||||
time: "15-08-2021 12:40",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Budi",
|
||||
score: 90,
|
||||
time: "15-08-2021 12:40",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Cecep",
|
||||
score: 80,
|
||||
time: "15-08-2021 12:40",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Dedi",
|
||||
score: 70,
|
||||
time: "15-08-2021 12:40",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "Euis",
|
||||
score: 60,
|
||||
time: "15-08-2021 12:40",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "Fafa",
|
||||
score: 50,
|
||||
time: "15-08-2021 12:40",
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: "Gaga",
|
||||
score: 40,
|
||||
time: "15-08-2021 12:40",
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: "Haha",
|
||||
score: 30,
|
||||
time: "15-08-2021 12:40",
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: "Ii",
|
||||
score: 20,
|
||||
time: "15-08-2021 12:40",
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: "Jaja",
|
||||
score: 10,
|
||||
time: "15-08-2021 12:40",
|
||||
},
|
||||
];
|
||||
|
||||
const Ranking = () => {
|
||||
const store = useNavbarStore();
|
||||
|
||||
const [tabSelected, setTabSelected] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
store.setNavSelected("kuis");
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<LayoutPage>
|
||||
<div className="flex flex-col flex-1 py-4 relative items-center">
|
||||
<ul className="flex gap-3 mt-4 w-full">
|
||||
<li className="hover:text-primary cursor-default flex gap-2 items-center">
|
||||
<HiOutlineHome />
|
||||
<p>Home</p>
|
||||
</li>
|
||||
<li>{">"}</li>
|
||||
<Link to="/kuis" className="hover:text-primary">
|
||||
Kuis
|
||||
</Link>
|
||||
<li>{">"}</li>
|
||||
<li className="font-medium text-gray-500">Ranking</li>
|
||||
</ul>
|
||||
|
||||
<div className="md:max-w-[500px] w-full flex flex-col mt-6 items-center">
|
||||
<div className="flex items-center">
|
||||
<button
|
||||
onClick={() => setTabSelected(0)}
|
||||
className={`btn btn-link ${
|
||||
tabSelected === 0 ? "" : "no-underline text-gray-500"
|
||||
}`}
|
||||
>
|
||||
Tebak Huruf
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setTabSelected(1)}
|
||||
className={`btn btn-link ${
|
||||
tabSelected === 1 ? "" : "no-underline text-gray-500"
|
||||
}`}
|
||||
>
|
||||
Menyusun Huruf
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<label className="input input-bordered flex items-center gap-2 w-full mt-6 mb-4">
|
||||
<input type="text" className="grow" placeholder="Search" />
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
fill="currentColor"
|
||||
className="h-4 w-4 opacity-70"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M9.965 11.026a5 5 0 1 1 1.06-1.06l2.755 2.754a.75.75 0 1 1-1.06 1.06l-2.755-2.754ZM10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</label>
|
||||
|
||||
{data.map((item, index) => (
|
||||
<motion.div
|
||||
initial={{
|
||||
scale: 0,
|
||||
opacity: 0,
|
||||
}}
|
||||
whileInView={{
|
||||
scale: 1,
|
||||
opacity: 1,
|
||||
transition: { duration: 0.1, delay: index * 0.1 },
|
||||
}}
|
||||
key={item.id}
|
||||
className="flex justify-between mt-4 bg-base-100 hover:bg-base-200 duration-300 ease-in-out px-6 py-4 rounded-md w-full items-center gap-4"
|
||||
>
|
||||
<img
|
||||
className="bg-green-400 rounded-full h-14 w-14 object-cover"
|
||||
src={`https://api.dicebear.com/9.x/miniavs/svg?seed=${item.name}&backgroundColor=b6e3f4,c0aede,d1d4f9`}
|
||||
alt=""
|
||||
/>
|
||||
<div className="flex flex-col flex-1">
|
||||
<p className="font-semibold">{item.name}</p>
|
||||
<p>{item.score} Poin</p>
|
||||
<p className="text-xs text-gray-500">{item.time}</p>
|
||||
</div>
|
||||
<div
|
||||
className={`w-6 h-6 rounded-full flex justify-center items-center p-5 `}
|
||||
style={{
|
||||
backgroundColor: ["#b6e3f4", "#c0aede", "#d1d4f9"][
|
||||
Math.floor(Math.random() * 3)
|
||||
],
|
||||
}}
|
||||
>
|
||||
{index + 1}
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</LayoutPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default Ranking;
|
|
@ -36,6 +36,11 @@ const myRoute = [
|
|||
path: "/kuis/menyusun-huruf/app",
|
||||
component: lazy(() => import("@/pages/Kuis/MenyusunHuruf/Quiz")),
|
||||
},
|
||||
{
|
||||
title: "Ranking",
|
||||
path: "/kuis/ranking",
|
||||
component: lazy(() => import("@/pages/Ranking/Ranking")),
|
||||
},
|
||||
];
|
||||
|
||||
export default myRoute;
|
||||
|
|
Loading…
Reference in New Issue