From f9e436ea12ecb7a984b5fe494f53793eadc23aa4 Mon Sep 17 00:00:00 2001 From: maxime Date: Tue, 26 Mar 2024 21:40:56 +0100 Subject: [PATCH] Apply suggestion --- src/App.tsx | 5 +- src/app/Fetcher.ts | 9 +++- src/components/Visualizer.tsx | 62 +++++++++++++-------- src/components/editor/BasketCourt.tsx | 28 +++++----- src/components/editor/StepsTree.tsx | 48 ++++++++--------- src/domains/TacticContentDomains.ts | 2 - src/pages/Editor.tsx | 2 +- src/pages/Settings.tsx | 69 +++++++++++++----------- src/pages/VisualizerPage.tsx | 58 ++++++++++++-------- src/service/APITacticService.ts | 4 +- src/service/LocalStorageTacticService.ts | 2 +- src/visualizer/VisualizerState.ts | 9 +++- 12 files changed, 172 insertions(+), 126 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 489a9fc..f1ab122 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -147,8 +147,9 @@ export default function App() { path={"/tactic/:tacticId/view"} element={suspense( - , - + + , + , )} /> () const [stepsTree, setStepsTree] = useState() const fetcher = useAppFetcher() - const service = useMemo(() => new APITacticService(fetcher, tacticId), [tacticId]) + const service = useMemo( + () => new APITacticService(fetcher, tacticId), + [tacticId], + ) const isNotInit = !stepsTree || !courtType @@ -35,13 +52,11 @@ export function Visualizer({ tacticId, stepId }: VisualizerProps) { return } - const rootStep = contextResult.stepsTree setStepsTree(rootStep) setCourtType(contextResult.courtType) } - if (isNotInit) - init() + if (isNotInit) init() }, [isNotInit, service]) if (panicMessage) { @@ -51,12 +66,14 @@ export function Visualizer({ tacticId, stepId }: VisualizerProps) { return

Loading...

} - return + return ( + + ) } export interface StepVisualizerProps { @@ -66,7 +83,12 @@ export interface StepVisualizerProps { service: TacticService } -export function StepVisualizer({stepId, stepsTree, courtType, service}: StepVisualizerProps) { +export function StepVisualizer({ + stepId, + stepsTree, + courtType, + service, +}: StepVisualizerProps) { const [panicMessage, setPanicMessage] = useState(null) const [content, setContent] = useState(null) const [parentContent, setParentContent] = useState() @@ -75,7 +97,6 @@ export function StepVisualizer({stepId, stepsTree, courtType, service}: StepVisu useEffect(() => { async function init() { - const contentStepId = stepId ?? stepsTree.id const contentResult = await service.getContent(contentStepId) @@ -126,11 +147,10 @@ export interface VisualizerFrameProps { } export function VisualizerFrame({ - content, - parentContent, - courtType, - }: VisualizerFrameProps) { - + content, + parentContent, + courtType, +}: VisualizerFrameProps) { const courtRef = useRef(null) const courtBounds = useCallback( diff --git a/src/components/editor/BasketCourt.tsx b/src/components/editor/BasketCourt.tsx index 7c69d6d..903767f 100644 --- a/src/components/editor/BasketCourt.tsx +++ b/src/components/editor/BasketCourt.tsx @@ -2,7 +2,11 @@ import { ReactElement, ReactNode, RefObject, useEffect, useState } from "react" import { Action } from "../../model/tactic/Action" import { CourtAction } from "./CourtAction" -import { ComponentId, TacticComponent } from "../../model/tactic/Tactic" +import { + ComponentId, + CourtType, + TacticComponent, +} from "../../model/tactic/Tactic" import PlainCourt from "../../assets/court/full_court.svg?react" import HalfCourt from "../../assets/court/half_court.svg?react" @@ -34,7 +38,6 @@ export function BasketCourt({ courtImage, courtRef, }: BasketCourtProps) { - const [court, setCourt] = useState(courtRef.current) //force update once the court reference is set @@ -49,15 +52,11 @@ export function BasketCourt({ style={{ position: "relative" }}> {courtImage} - {court && - parentComponents?.map((i) => renderComponent(i, true))} - {court && - parentComponents?.flatMap((i) => renderActions(i, true))} + {court && parentComponents?.map((i) => renderComponent(i, true))} + {court && parentComponents?.flatMap((i) => renderActions(i, true))} - {court && - components.map((i) => renderComponent(i, false))} - {court && - components.flatMap((i) => renderActions(i, false))} + {court && components.map((i) => renderComponent(i, false))} + {court && components.flatMap((i) => renderActions(i, false))} {previewAction && ( - {courtType == "PLAIN" ? ( - - ) : ( - - )} + ) } diff --git a/src/components/editor/StepsTree.tsx b/src/components/editor/StepsTree.tsx index ddb19ee..0029a5c 100644 --- a/src/components/editor/StepsTree.tsx +++ b/src/components/editor/StepsTree.tsx @@ -15,12 +15,12 @@ export interface StepsTreeProps { } export default function StepsTree({ - root, - selectedStepId, - onAddChildren, - onRemoveNode, - onStepSelected, - }: StepsTreeProps) { + root, + selectedStepId, + onAddChildren, + onRemoveNode, + onStepSelected, +}: StepsTreeProps) { return (
(null) return ( @@ -67,8 +67,7 @@ function StepsTreeNode({ next: "step-piece-" + child.id, }, ]} - onSegmentsChanges={() => { - }} + onSegmentsChanges={() => {}} forceStraight={true} wavy={false} readOnly={true} @@ -80,9 +79,8 @@ function StepsTreeNode({ onAddChildren(node) - : undefined + onAddButtonClicked={ + onAddChildren ? () => onAddChildren(node) : undefined } onRemoveButtonClicked={ rootNode.id === node.id || !onRemoveNode @@ -126,13 +124,13 @@ interface StepPieceProps { } function StepPiece({ - id, - isSelected, - onAddButtonClicked, - onRemoveButtonClicked, - onSelected, - children, - }: StepPieceProps) { + id, + isSelected, + onAddButtonClicked, + onRemoveButtonClicked, + onSelected, + children, +}: StepPieceProps) { return (
-
+
{ passwordConfirmRef.current!.setCustomValidity( - password === confirmPassword ? "" : "Les mots de passe ne correspondent pas !" + password === confirmPassword + ? "" + : "Les mots de passe ne correspondent pas !", ) }, [confirmPassword, password]) @@ -110,9 +112,8 @@ export default function ProfileSettings() { autoComplete="username" required placeholder="Nom d'utilisateur" - value={name} - onChange={e => setName(e.target.value)} + onChange={(e) => setName(e.target.value)} /> @@ -124,9 +125,8 @@ export default function ProfileSettings() { placeholder={"Adresse email"} autoComplete="email" required - value={email} - onChange={e => setEmail(e.target.value)} + onChange={(e) => setEmail(e.target.value)} /> @@ -137,12 +137,13 @@ export default function ProfileSettings() { type="password" placeholder={"Mot de passe"} autoComplete="new-password" - value={password} - onChange={e => setPassword(e.target.value)} + onChange={(e) => setPassword(e.target.value)} /> - + setConfirmPassword(e.target.value)} + onChange={(e) => + setConfirmPassword(e.target.value) + } /> - @@ -207,25 +207,28 @@ function ProfileImageInputPopup({ show, onHide }: ProfileImageInputPopupProps) { if (e.key === "Escape") onHide() } - window.addEventListener('keyup', onKeyUp) - return () => window.removeEventListener('keyup', onKeyUp) + window.addEventListener("keyup", onKeyUp) + return () => window.removeEventListener("keyup", onKeyUp) }, [onHide]) - const handleForm = useCallback(async (e: FormEvent) => { - e.preventDefault() + const handleForm = useCallback( + async (e: FormEvent) => { + e.preventDefault() - const url = urlRef.current!.value - const errors = await updateAccount(fetcher, { - profilePicture: url, - }) - if (errors.length !== 0) { - setErrorMessages(errors) - return - } - setUser({ ...user!, profilePicture: url }) - setErrorMessages([]) - onHide() - }, [fetcher, onHide, setUser, user]) + const url = urlRef.current!.value + const errors = await updateAccount(fetcher, { + profilePicture: url, + }) + if (errors.length !== 0) { + setErrorMessages(errors) + return + } + setUser({ ...user!, profilePicture: url }) + setErrorMessages([]) + onHide() + }, + [fetcher, onHide, setUser, user], + ) if (!show) return <> @@ -243,7 +246,9 @@ function ProfileImageInputPopup({ show, onHide }: ProfileImageInputPopupProps) { {msg}
))} -
-
diff --git a/src/service/APITacticService.ts b/src/service/APITacticService.ts index 0e6ba05..718c22c 100644 --- a/src/service/APITacticService.ts +++ b/src/service/APITacticService.ts @@ -16,7 +16,9 @@ export class APITacticService implements MutableTacticService { } async canBeEdited(): Promise { - const response = await this.fetcher.fetchAPIGet(`tactics/${this.tacticId}/can-edit`) + const response = await this.fetcher.fetchAPIGet( + `tactics/${this.tacticId}/can-edit`, + ) const { canEdit } = await response.json() return canEdit } diff --git a/src/service/LocalStorageTacticService.ts b/src/service/LocalStorageTacticService.ts index 7e2b009..32b14c2 100644 --- a/src/service/LocalStorageTacticService.ts +++ b/src/service/LocalStorageTacticService.ts @@ -33,7 +33,7 @@ export class LocalStorageTacticService implements MutableTacticService { ) localStorage.setItem( GUEST_MODE_STEP_CONTENT_STORAGE_KEY + 1, - JSON.stringify({components: []}) + JSON.stringify({ components: [] }), ) } diff --git a/src/visualizer/VisualizerState.ts b/src/visualizer/VisualizerState.ts index cea3fc2..6c80d20 100644 --- a/src/visualizer/VisualizerState.ts +++ b/src/visualizer/VisualizerState.ts @@ -1,4 +1,5 @@ import { CourtType, StepContent, StepInfoNode } from "../model/tactic/Tactic.ts" +import { useReducer } from "react" export interface VisualizerState { stepId: number @@ -9,7 +10,7 @@ export interface VisualizerState { parentContent: StepContent | null } -export enum VisualizerStateActionKind { +export const enum VisualizerStateActionKind { INIT, SET_CONTENTS, } @@ -26,7 +27,11 @@ export type VisualizerStateAction = stepId: number } -export function visualizerStateReducer( +export function useVisualizer(initialState: VisualizerState | null) { + return useReducer(visualizerStateReducer, initialState) +} + +function visualizerStateReducer( state: VisualizerState | null, action: VisualizerStateAction, ): VisualizerState | null {