import { ButtonHTMLAttributes, Fragment, ReactNode, useEffect, useRef, useState, } from "react"; import { ReactSortable, ReactSortableProps } from "react-sortablejs"; import { apiAuth, User } from "./api"; import { useSession } from "./Session"; import { Chemistry, MVPRanking } from "./types"; import TabController from "./TabController"; type PlayerListProps = Partial> & { orderedList?: boolean; }; function PlayerList(props: PlayerListProps) { return ( {props.list?.map((item, index) => ( {props.orderedList ? index + 1 + ". " + item.display_name : item.display_name} ))} ); } const LoadButton = (props: ButtonHTMLAttributes) => { return ( ๐๏ธ restore previous ); }; const ClearButton = (props: ButtonHTMLAttributes) => { return ( ๐๏ธ start over ); }; function filterSort(list: User[], ids: number[]): User[] { const objectMap = new Map(list.map((obj) => [obj.id, obj])); const filteredAndSortedObjects = ids .map((id) => objectMap.get(id)) .filter((obj) => obj !== undefined); return filteredAndSortedObjects; } interface PlayerInfoProps { user: User; players: User[]; } function ChemistryDnD({ user, players }: PlayerInfoProps) { var otherPlayers = players.filter((player) => player.id !== user.id); const [playersLeft, setPlayersLeft] = useState([]); const [playersMiddle, setPlayersMiddle] = useState(otherPlayers); const [playersRight, setPlayersRight] = useState([]); useEffect(() => { setPlayersMiddle(otherPlayers); }, [players]); const [dialog, setDialog] = useState("dialog"); const dialogRef = useRef(null); async function handleSubmit() { if (dialogRef.current) dialogRef.current.showModal(); setDialog("sending..."); let left = playersLeft.map(({ id }) => id); let middle = playersMiddle.map(({ id }) => id); let right = playersRight.map(({ id }) => id); const data = { user: user.id, hate: left, undecided: middle, love: right }; const response = await apiAuth("chemistry", data, "PUT"); setDialog(response || "try sending again"); } async function handleGet() { const chemistry = (await apiAuth("chemistry", null, "GET")) as Chemistry; setPlayersLeft(filterSort(otherPlayers, chemistry.hate)); setPlayersMiddle( otherPlayers.filter( (player) => !chemistry.hate.includes(player.id) && !chemistry.love.includes(player.id) ) ); setPlayersRight(filterSort(otherPlayers, chemistry.love)); } return ( <> { setPlayersRight([]); setPlayersMiddle(otherPlayers); setPlayersLeft([]); }} /> ๐ฌ {playersLeft.length < 1 && ( drag people here that you'd rather not play with )} ๐คท ๐ {playersRight.length < 1 && ( drag people here that you love playing with from best to ... ok )} handleSubmit()}> ๐พ submit { event.currentTarget.close(); }} > {dialog} > ); } function MVPDnD({ user, players }: PlayerInfoProps) { const [availablePlayers, setAvailablePlayers] = useState(players); const [rankedPlayers, setRankedPlayers] = useState([]); useEffect(() => { setAvailablePlayers(players); }, [players]); const [dialog, setDialog] = useState("dialog"); const dialogRef = useRef(null); async function handleSubmit() { if (dialogRef.current) dialogRef.current.showModal(); setDialog("sending..."); let mvps = rankedPlayers.map(({ id }) => id); const data = { user: user.id, mvps: mvps }; const response = await apiAuth("mvps", data, "PUT"); response ? setDialog(response) : setDialog("try sending again"); } async function handleGet() { const mvps = (await apiAuth("mvps", null, "GET")) as MVPRanking; setRankedPlayers(filterSort(players, mvps.mvps)); setAvailablePlayers(players.filter((user) => !mvps.mvps.includes(user.id))); } return ( <> { setAvailablePlayers(players); setRankedPlayers([]); }} /> ๐ฅ๐ {availablePlayers.length < 1 && ( all sorted ๐ )} ๐ {rankedPlayers.length < 1 && ( carefully place as many of the Most Valuable Players{" "} (according to your humble opinion) in this box )} handleSubmit()}> ๐พ submit { event.currentTarget.close(); }} > {dialog} > ); } interface HeaderControlProps { onLoad: () => void; onClear: () => void; } function HeaderControl({ onLoad, onClear }: HeaderControlProps) { return ( <> assign as many or as few players as you want and don't forget to{" "} submit ๐พ when you're done :) > ); } export default function Rankings() { const { user } = useSession(); const [players, setPlayers] = useState(null); async function loadPlayers() { try { const data = await apiAuth("player/list", null, "GET"); setPlayers(data as User[]); } catch (error) { console.error(error); } } useEffect(() => { loadPlayers(); }, [user]); const tabs = [ { id: "Chemistry", label: "๐งช Chemistry" }, { id: "MVP", label: "๐ MVP" }, ]; return ( <> {user && players ? ( ) : ( )} > ); }