diff --git a/app/league/[slug]/layout.tsx b/app/league/[slug]/layout.tsx index f5cc9b6..ddcba88 100644 --- a/app/league/[slug]/layout.tsx +++ b/app/league/[slug]/layout.tsx @@ -1,46 +1,37 @@ 'use client' import {Box, Button, Center, Grid, GridItem, Heading} from '@chakra-ui/react' import axios from 'axios' -import {enableMapSet} from "immer" +import {enableMapSet} from 'immer' import Link from 'next/link' import React, {useContext, useEffect} from 'react' import useSWR from 'swr' import {Draft} from '../../../classes/custom/Draft' import League from '../../../classes/custom/League' -import { DatabasePlayer, PlayerScores, SleeperPlayerDetails } from '../../../classes/custom/Player' +import {DatabasePlayer, PlayerScores, SleeperPlayerDetails} from '../../../classes/custom/Player' import Footer from '../../../components/Footer' import Navbar from '../../../components/nav/Navbar' import {LeagueContext} from '../../../contexts/LeagueContext' import {PlayerScoresContext} from '../../../contexts/PlayerScoresContext' import {PlayerDetailsContext} from '../../../contexts/PlayerDetailsContext' import styles from '../../../styles/Home.module.css' -import { LeagueSettings } from '../../../classes/sleeper/LeagueSettings' -import { SleeperRoster } from '../../../classes/sleeper/SleeperRoster' -import { SleeperUser, UserData } from '../../../classes/sleeper/SleeperUser' -const LeagueLayout = ({ - children, - params, -}: { - children: React.ReactNode - params: {slug: string} -}) => { +import {LeagueSettings} from '../../../classes/sleeper/LeagueSettings' +import {SleeperRoster} from '../../../classes/sleeper/SleeperRoster' +import {BlankUserData, SleeperUser, UserData} from '../../../classes/sleeper/SleeperUser' +const LeagueLayout = ({children, params}: {children: React.ReactNode; params: {slug: string}}) => { enableMapSet() const [leagueContext, setLeagueContext] = useContext(LeagueContext) const [playerDetailsContext, setPlayerDetailsContext] = useContext(PlayerDetailsContext) const [playerScoresContext, setPlayerScoresContext] = useContext(PlayerScoresContext) - const fetcher = (url: string) => axios.get(url).then((res) => res.data) const disableValidation = { revalidateIfStale: false, revalidateOnFocus: false, - revalidateOnReconnect: false - } + revalidateOnReconnect: false, + } const {data: sleeperLeagueData, error: sleeperLeagueError} = useSWR( - params.slug != undefined - ? `https://api.sleeper.app/v1/league/${params.slug}` - : null, + params.slug != undefined ? `https://api.sleeper.app/v1/league/${params.slug}` : null, fetcher, disableValidation ) @@ -62,9 +53,7 @@ const LeagueLayout = ({ ) const {data: leagueData, error: leagueError} = useSWR( - params.slug != undefined && - sleeperLeagueError == undefined && - sleeperLeagueData + params.slug != undefined && sleeperLeagueError == undefined && sleeperLeagueData ? `/api/league/${params.slug}` : null, fetcher, @@ -83,7 +72,12 @@ const LeagueLayout = ({ let playerDetails = new Map() leagueData.league.player_details.forEach((player: DatabasePlayer) => { let settings = leagueData.league.sleeperDetails as LeagueSettings - let playerObj = new PlayerScores(player, settings.scoring_settings, settings.settings.start_week, settings.settings.last_scored_leg) + let playerObj = new PlayerScores( + player, + settings.scoring_settings, + settings.settings.start_week, + settings.settings.last_scored_leg + ) playerDetails.set(player._id, player) playerScores.set(player._id, playerObj) }) @@ -93,10 +87,15 @@ const LeagueLayout = ({ setPlayerDetailsContext(playerDetails) let users: UserData[] = [] leagueData.league.rosters.forEach((roster: SleeperRoster) => { - users.push(new UserData(leagueData.league.users.find((user: SleeperUser) => { + let user = leagueData.league.users.find((user: SleeperUser) => { return user.user_id == roster.owner_id - }), roster)) - }); + }) + if (user == undefined) { + users.push(new BlankUserData(leagueData.league.league_id, roster.owner_id, roster)) + } else { + users.push(new UserData(user, roster)) + } + }) let league = new League( users, leagueData.league.matchups, @@ -139,8 +138,7 @@ const LeagueLayout = ({ + }> @@ -153,8 +151,7 @@ const LeagueLayout = ({ ) } - if (leagueError || tradeError) - return Failed to load + if (leagueError || tradeError) return Failed to load return ( + fontWeight='bold'> diff --git a/classes/custom/Matchup.ts b/classes/custom/Matchup.ts index a759ced..3dcdafc 100644 --- a/classes/custom/Matchup.ts +++ b/classes/custom/Matchup.ts @@ -67,7 +67,7 @@ export default class Matchup implements MatchupInterface { return Math.abs(this.homeTeam.pf - (this.awayTeam?.pf ?? this.homeTeam.pf)) } - public getWinner() { + public getWinner(): MatchupSide | undefined { let winner if (!this.isTie) { if (this.homeTeam.roster_id == this.winnerRosterId) { @@ -75,6 +75,8 @@ export default class Matchup implements MatchupInterface { } else { winner = this.awayTeam } + } else { + winner = undefined } return winner diff --git a/classes/sleeper/SleeperUser.ts b/classes/sleeper/SleeperUser.ts index 2d3f1a1..f8fa206 100644 --- a/classes/sleeper/SleeperUser.ts +++ b/classes/sleeper/SleeperUser.ts @@ -1,80 +1,145 @@ -import { SleeperRoster } from "./SleeperRoster"; +import {SleeperRoster} from './SleeperRoster' export class UserData { - user_id: string; - settings?: null; - metadata: Metadata; - league_id: string; - is_owner: boolean; - is_bot?: boolean | null; - display_name: string; - avatar: string; - roster: SleeperRoster; + user_id: string + settings?: null + metadata: Metadata + league_id: string + is_owner: boolean + is_bot?: boolean | null + display_name: string + avatar: string + roster: SleeperRoster - constructor(sleeperUser: SleeperUser, roster: SleeperRoster) { - this.user_id = sleeperUser.user_id; - this.settings = sleeperUser.settings; - this.metadata = sleeperUser.metadata; - this.league_id = sleeperUser.league_id; - this.is_owner = sleeperUser.is_owner; - this.display_name = sleeperUser.display_name; - this.avatar = sleeperUser.avatar; - this.roster = roster; - } + constructor(sleeperUser: SleeperUser, roster: SleeperRoster) { + this.user_id = sleeperUser.user_id + this.settings = sleeperUser.settings + this.metadata = sleeperUser.metadata + this.league_id = sleeperUser.league_id + this.is_owner = sleeperUser.is_owner + this.display_name = sleeperUser.display_name + this.avatar = sleeperUser.avatar + this.roster = roster + } } - export interface SleeperUser { - user_id: string; - settings?: null; - metadata: Metadata; - league_id: string; - is_owner: boolean; - is_bot?: boolean | null; - display_name: string; - avatar: string; - } - export interface Metadata { - user_message_pn?: string | null; - transaction_waiver?: string | null; - transaction_trade?: string | null; - transaction_free_agent?: string | null; - transaction_commissioner?: string | null; - trade_block_pn?: string | null; - team_name_update?: string | null; - player_nickname_update?: string | null; - player_like_pn?: string | null; - mention_pn: string; - mascot_message_emotion_leg_9?: string | null; - mascot_message?: string | null; - mascot_item_type_id_leg_9?: string | null; - mascot_item_type_id_leg_18?: string | null; - mascot_item_type_id_leg_17?: string | null; - mascot_item_type_id_leg_16?: string | null; - mascot_item_type_id_leg_15?: string | null; - mascot_item_type_id_leg_14?: string | null; - mascot_item_type_id_leg_13?: string | null; - mascot_item_type_id_leg_12?: string | null; - mascot_item_type_id_leg_11?: string | null; - mascot_item_type_id_leg_10?: string | null; - join_voice_pn?: string | null; - archived?: string | null; - allow_pn: string; - team_name?: string | null; - mascot_message_leg_3?: string | null; - mascot_message_emotion_leg_3?: string | null; - mascot_item_type_id_leg_8?: string | null; - mascot_item_type_id_leg_7?: string | null; - mascot_item_type_id_leg_6?: string | null; - mascot_item_type_id_leg_5?: string | null; - mascot_item_type_id_leg_4?: string | null; - mascot_item_type_id_leg_3?: string | null; - avatar?: string | null; - allow_sms?: string | null; - mascot_message_emotion_leg_6?: string | null; - mascot_message_emotion_leg_1?: string | null; - mascot_item_type_id_leg_1?: string | null; - mascot_item_type_id_leg_2?: string | null; - show_mascots?: string | null; - } - \ No newline at end of file + user_id: string + settings?: null + metadata: Metadata + league_id: string + is_owner: boolean + is_bot?: boolean | null + display_name: string + avatar: string +} + +export class BlankUserData implements UserData { + user_id: string + settings?: null = null + metadata: Metadata = new BlankMetadata() + league_id: string + is_owner: boolean = false + is_bot?: boolean | null | undefined + display_name: string = 'Missing Member' + avatar: string = 'https://sleepercdn.com/images/v2/icons/player_default.webp' + roster: SleeperRoster + + constructor(rosterId: string, leagueId: string, roster: SleeperRoster) { + this.user_id = rosterId + this.league_id = leagueId + this.roster = roster + } +} +export interface Metadata { + user_message_pn?: string | null + transaction_waiver?: string | null + transaction_trade?: string | null + transaction_free_agent?: string | null + transaction_commissioner?: string | null + trade_block_pn?: string | null + team_name_update?: string | null + player_nickname_update?: string | null + player_like_pn?: string | null + mention_pn: string + mascot_message_emotion_leg_9?: string | null + mascot_message?: string | null + mascot_item_type_id_leg_9?: string | null + mascot_item_type_id_leg_18?: string | null + mascot_item_type_id_leg_17?: string | null + mascot_item_type_id_leg_16?: string | null + mascot_item_type_id_leg_15?: string | null + mascot_item_type_id_leg_14?: string | null + mascot_item_type_id_leg_13?: string | null + mascot_item_type_id_leg_12?: string | null + mascot_item_type_id_leg_11?: string | null + mascot_item_type_id_leg_10?: string | null + join_voice_pn?: string | null + archived?: string | null + allow_pn: string + team_name?: string | null + mascot_message_leg_3?: string | null + mascot_message_emotion_leg_3?: string | null + mascot_item_type_id_leg_8?: string | null + mascot_item_type_id_leg_7?: string | null + mascot_item_type_id_leg_6?: string | null + mascot_item_type_id_leg_5?: string | null + mascot_item_type_id_leg_4?: string | null + mascot_item_type_id_leg_3?: string | null + avatar?: string | null + allow_sms?: string | null + mascot_message_emotion_leg_6?: string | null + mascot_message_emotion_leg_1?: string | null + mascot_item_type_id_leg_1?: string | null + mascot_item_type_id_leg_2?: string | null + show_mascots?: string | null +} + +class BlankMetadata implements Metadata { + user_message_pn?: string | null + transaction_waiver?: string | null + transaction_trade?: string | null + transaction_free_agent?: string | null + transaction_commissioner?: string | null + trade_block_pn?: string | null + team_name_update?: string | null + player_nickname_update?: string | null + player_like_pn?: string | null + mention_pn: string + mascot_message_emotion_leg_9?: string | null + mascot_message?: string | null + mascot_item_type_id_leg_9?: string | null + mascot_item_type_id_leg_18?: string | null + mascot_item_type_id_leg_17?: string | null + mascot_item_type_id_leg_16?: string | null + mascot_item_type_id_leg_15?: string | null + mascot_item_type_id_leg_14?: string | null + mascot_item_type_id_leg_13?: string | null + mascot_item_type_id_leg_12?: string | null + mascot_item_type_id_leg_11?: string | null + mascot_item_type_id_leg_10?: string | null + join_voice_pn?: string | null + archived?: string | null + allow_pn: string + team_name?: string | null + mascot_message_leg_3?: string | null + mascot_message_emotion_leg_3?: string | null + mascot_item_type_id_leg_8?: string | null + mascot_item_type_id_leg_7?: string | null + mascot_item_type_id_leg_6?: string | null + mascot_item_type_id_leg_5?: string | null + mascot_item_type_id_leg_4?: string | null + mascot_item_type_id_leg_3?: string | null + avatar?: string | null + allow_sms?: string | null + mascot_message_emotion_leg_6?: string | null + mascot_message_emotion_leg_1?: string | null + mascot_item_type_id_leg_1?: string | null + mascot_item_type_id_leg_2?: string | null + show_mascots?: string | null + + constructor() { + this.mention_pn = '' + this.allow_pn = '' + } +} diff --git a/components/groups/stats/LeagueWeekGroup.tsx b/components/groups/stats/LeagueWeekGroup.tsx index 416bb82..2e1382e 100644 --- a/components/groups/stats/LeagueWeekGroup.tsx +++ b/components/groups/stats/LeagueWeekGroup.tsx @@ -2,6 +2,7 @@ import {HStack} from '@chakra-ui/react' import League from '../../../classes/custom/League' import Matchup from '../../../classes/custom/Matchup' +import { MatchupSide } from '../../../classes/custom/MatchupSide' import NotableMatchupStatCard from '../../cards/statcards/NotableMatchupStatCard' import WeekStatCard from '../../cards/statcards/WeekStatCard' @@ -9,10 +10,10 @@ interface MyProps { league: League | undefined } const LeagueNotableWeeksStatGroup = (props: MyProps) => { - let bestWeekTeam - let bestWeek - let worstWeekTeam - let worstWeek + let bestWeekTeam: MatchupSide | undefined = undefined + let bestWeek: Matchup | undefined = undefined + let worstWeekTeam: MatchupSide | undefined = undefined + let worstWeek: Matchup | undefined = undefined let closestGame: Matchup | undefined = undefined let furthestGame: Matchup | undefined = undefined let biggestShootout: Matchup | undefined = undefined //highest combined score @@ -22,9 +23,9 @@ const LeagueNotableWeeksStatGroup = (props: MyProps) => { let notableWeeks = props.league.getLeagueNotableWeeks() bestWeek = notableWeeks.matchupForBestTeam as unknown as Matchup - bestWeekTeam = bestWeek.getWinner() + bestWeekTeam = bestWeek?.getWinner() worstWeek = notableWeeks.matchupForWorstTeam as unknown as Matchup - worstWeekTeam = worstWeek.getLoser() + worstWeekTeam = worstWeek?.getLoser() closestGame = notableWeeks.closestGame as unknown as Matchup biggestShootout = notableWeeks.biggestShootout as unknown as Matchup @@ -52,35 +53,35 @@ const LeagueNotableWeeksStatGroup = (props: MyProps) => { subStat={ props.league?.members?.get(worstWeekTeam?.roster_id ?? 0)?.teamName } - isLoaded={bestWeekTeam != undefined} + isLoaded={worstWeekTeam != undefined} /> )