import {CSSProperties, useEffect, useRef, useState} from "react"; import "../style/editor.css"; import TitleInput from "../components/TitleInput"; import {BasketCourt} from "../components/editor/BasketCourt"; import {Rack} from "../components/Rack"; import {PlayerPiece} from "../components/editor/PlayerPiece"; import {Player} from "../tactic/Player"; import {Tactic, TacticContent} from "../tactic/Tactic"; import {fetchAPI} from "../Fetcher"; import {Team} from "../tactic/Team"; import {calculateRatio} from "../Utils"; const ERROR_STYLE: CSSProperties = { borderColor: "red", } export interface EditorViewProps { tactic: Tactic, onContentChange: (tactic: TacticContent) => Promise, onNameChange: (name: string) => Promise } /** * information about a player that is into a rack */ interface RackedPlayer { team: Team key: string } export default function Editor({tactic}: { tactic: Tactic }) { return ( fetchAPI(`tactic/${tactic.id}/save`, {content}) .then((r) => r.ok) )} onNameChange={(name: string) => ( fetchAPI(`tactic/${tactic.id}/edit/name`, {name}) .then((r) => r.ok) )}/> } function EditorView({tactic: {name, content}, onContentChange, onNameChange}: EditorViewProps) { const [style, setStyle] = useState({}); const positions = ["1", "2", "3", "4", "5"] const [allies, setAllies] = useState( positions.map((key) => ({ team: Team.Allies, key })), ) const [opponents, setOpponents] = useState( positions.map((key) => ({ team: Team.Opponents, key })), ) const [players, setPlayers] = useState(content.players); const courtDivContentRef = useRef(null); useEffect(() => { onContentChange({players}) .then(success => { if (!success) alert("error when saving changes.") }) }, [players]) const canDetach = (ref: HTMLDivElement) => { const refBounds = ref.getBoundingClientRect() const courtBounds = courtDivContentRef.current!.getBoundingClientRect() // check if refBounds overlaps courtBounds return !( refBounds.top > courtBounds.bottom || refBounds.right < courtBounds.left || refBounds.bottom < courtBounds.top || refBounds.left > courtBounds.right ) } const onPieceDetach = (ref: HTMLDivElement, element: RackedPlayer) => { const refBounds = ref.getBoundingClientRect() const courtBounds = courtDivContentRef.current!.getBoundingClientRect() const {x, y} = calculateRatio(refBounds, courtBounds) setPlayers(players => { return [...players, { id: players.length, team: element.team, role: element.key, rightRatio: x, bottomRatio: y }] }) } return (
LEFT
{ onNameChange(new_name).then(success => { if (success) { setStyle({}) } else { setStyle(ERROR_STYLE) } }) }}/>
RIGHT
( )} /> ( )} />
{ setPlayers(players => { const idx = players.indexOf(player) return players.toSpliced(idx, 1, player) }) }} onPlayerRemove={(player) => { setPlayers((players) => { const idx = players.indexOf(player) return players.toSpliced(idx, 1) }) switch (player.team) { case Team.Opponents: setOpponents((opponents) => [ ...opponents, { team: player.team, pos: player.role, key: player.role, }, ]) break case Team.Allies: setAllies((allies) => [ ...allies, { team: player.team, pos: player.role, key: player.role, }, ]) } }} />
) }