import { resetTest } from "helpers/resetTest"; import { useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { setTheme, setTime, setType, setWordList, timerSet, } from "store/actions"; import { State } from "store/reducer"; import "stylesheets/Header.scss"; import "stylesheets/AnimatedTheme.scss"; export interface Options { time: number[]; theme: string[]; type: string[]; } interface AnimationProps { top: number; left: number; theme: string; } export const options: Options = { time: [15, 30, 45, 60, 120], theme: [ "khr1st", "classic-bw", "slate-grey", "ocean-breeze", "sunset-glow", "forest-green", "royal-purple", "coral-reef", "seafoam-green", ], type: [ "words", "hard-words", "sentences", "numbers", "got", "javascript", "python", ], }; export default function Header() { const { preferences: { timeLimit, theme, type }, time: { timerId }, } = useSelector((state: State) => state); const [animationProps, setAnimationProps] = useState(); const dispatch = useDispatch(); useEffect(() => { const theme = localStorage.getItem("theme") || "default"; const type = localStorage.getItem("type") || "words"; const time = parseInt(localStorage.getItem("time") || "60", 10); import(`wordlists/${type}.json`).then((words) => dispatch(setWordList(words.default)) ); dispatch(timerSet(time)); dispatch(setType(type)); dispatch(setTime(time)); dispatch(setTheme(theme)); }, [dispatch]); // Set Theme useEffect(() => { if (theme) { document.querySelector(".theme")?.childNodes.forEach((el) => { if (el instanceof HTMLButtonElement) el.classList.remove("selected"); }); document .querySelector(`button[value="${theme}"]`) ?.classList.add("selected"); document.body.children[1].classList.remove(...options.theme); document.body.children[1].classList.add(theme); localStorage.setItem("theme", theme); } }, [dispatch, theme]); // Set Time useEffect(() => { if (timeLimit !== 0) { document.querySelector(".time")?.childNodes.forEach((el) => { if (el instanceof HTMLButtonElement) el.classList.remove("selected"); }); document .querySelector(`button[value="${timeLimit}"]`) ?.classList.add("selected"); dispatch(setTime(timeLimit)); localStorage.setItem("time", `${timeLimit}`); resetTest(); } }, [dispatch, timeLimit]); // Set Type useEffect(() => { if (type !== "") { document.querySelector(".type")?.childNodes.forEach((el) => { if (el instanceof HTMLButtonElement) el.classList.remove("selected"); }); document .querySelector(`button[value="${type}"]`) ?.classList.add("selected"); dispatch(setType(type)); localStorage.setItem("type", type); resetTest(); } }, [dispatch, type]); const handleOptions = ({ target, clientX, clientY }: React.MouseEvent) => { if (target instanceof HTMLButtonElement && target.dataset.option) { if (target.value === theme || +target.value === timeLimit) { target.blur(); return; } switch (target.dataset.option) { case "theme": setTimeout(() => { dispatch(setTheme(target.value)); }, 750); setAnimationProps({ top: clientY, left: clientX, theme: target.value, }); break; case "time": dispatch(setTime(+target.value)); break; case "type": dispatch(setType(target.value)); break; } target.blur(); } }; return (
typix-test
{Object.entries(options).map(([option, choices]) => (
{option}: {choices.map((choice: string) => ( ))}
))}
{animationProps ? (
setAnimationProps(null)}>
) : null}
); }