mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-23 04:26:57 +00:00
Persist manual ELO form to local storage
Persist manual ELO form to local storage
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { last } from "lodash";
|
||||
import { isEmpty, isNil, last } from "lodash";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { FormProvider, useFieldArray, useForm } from "react-hook-form";
|
||||
import { IoAdd, IoCloseOutline } from "react-icons/io5";
|
||||
@@ -11,12 +11,13 @@ import { z } from "zod";
|
||||
import { RadioGroupField } from "@/components/form/RadioGroupField";
|
||||
import { SelectField } from "@/components/form/SelectField";
|
||||
import { TextField } from "@/components/form/TextField";
|
||||
import useFormPersist from "@/hooks/useFormPersist";
|
||||
import { getNewRating } from "@/utils/eloCalculator";
|
||||
|
||||
import { KFactor } from "./KFactor";
|
||||
|
||||
const resultsSchema = z.object({
|
||||
currentElo: z.number().int().positive(),
|
||||
currentElo: z.number().int().positive().nullish(),
|
||||
kFactor: z.enum(["40", "30", "20", "15", "10"]),
|
||||
games: z.array(
|
||||
z.object({
|
||||
@@ -40,6 +41,7 @@ export const ManualEloForm = () => {
|
||||
const form = useForm<EloFormValues>({
|
||||
resolver: zodResolver(resultsSchema),
|
||||
defaultValues: {
|
||||
currentElo: null,
|
||||
kFactor: "20",
|
||||
games: [{}],
|
||||
},
|
||||
@@ -54,6 +56,12 @@ export const ManualEloForm = () => {
|
||||
name: "games",
|
||||
});
|
||||
|
||||
useFormPersist("manualElo", {
|
||||
watch: form.watch,
|
||||
setValue: form.setValue,
|
||||
storage: window.localStorage,
|
||||
});
|
||||
|
||||
const onSubmit = async (data: EloFormValues) => {};
|
||||
|
||||
const [currentElo, kFactor, games] = form.watch([
|
||||
@@ -62,6 +70,13 @@ export const ManualEloForm = () => {
|
||||
"games",
|
||||
]);
|
||||
|
||||
const isDefault =
|
||||
isEmpty(currentElo) &&
|
||||
kFactor === "20" &&
|
||||
games?.length === 1 &&
|
||||
(isEmpty(games[0]) ||
|
||||
(isEmpty(games[0]?.opponentElo) && isEmpty(games[0]?.result)));
|
||||
|
||||
type Deltas = {
|
||||
rating: number;
|
||||
deltas: { rating: number; delta: number | undefined }[];
|
||||
@@ -70,7 +85,11 @@ export const ManualEloForm = () => {
|
||||
const calculations = !Number.isNaN(currentElo)
|
||||
? (games ?? []).reduce<Deltas>(
|
||||
(acc, game) => {
|
||||
if (!Number.isNaN(game?.opponentElo) && game?.result) {
|
||||
if (
|
||||
!isNil(game?.opponentElo) &&
|
||||
!Number.isNaN(game?.opponentElo) &&
|
||||
game?.result
|
||||
) {
|
||||
const result =
|
||||
game?.result === "win" ? 1 : game?.result === "loss" ? 0 : 0.5;
|
||||
|
||||
@@ -136,8 +155,8 @@ export const ManualEloForm = () => {
|
||||
<div className="flex w-full flex-col gap-6 sm:gap-2">
|
||||
{gameFields.map((game, i) => {
|
||||
return (
|
||||
<div key={i} className="flex w-full flex-col">
|
||||
<div key={i} className="flex w-full items-center space-x-2">
|
||||
<div key={game.id} className="flex w-full flex-col">
|
||||
<div className="flex w-full items-center space-x-2">
|
||||
<div className="grid w-full grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<TextField
|
||||
name={`games.${i}.opponentElo`}
|
||||
@@ -223,7 +242,18 @@ export const ManualEloForm = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-8 flex justify-end">
|
||||
<div className="mt-8 flex justify-end gap-4">
|
||||
{!isDefault && (
|
||||
<button
|
||||
onClick={() => {
|
||||
form.reset();
|
||||
}}
|
||||
type="button"
|
||||
className="px-5 py-3 text-center text-sm font-medium text-primary-600 hover:text-primary-800 focus:outline-none focus:ring-4 focus:ring-primary-300 disabled:opacity-25 dark:text-white dark:hover:text-primary-700 dark:focus:ring-primary-800 sm:w-fit"
|
||||
>
|
||||
{t("clearButton")}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={() => {
|
||||
appendGame({});
|
||||
|
||||
Reference in New Issue
Block a user