add both fantasy teams

This commit is contained in:
2025-09-07 20:14:57 -04:00
parent d7ab2b4b06
commit 5031e9e5a4
4 changed files with 123 additions and 137 deletions
+111 -54
View File
@@ -1,80 +1,137 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import PlayerCell from "./fantasy/PlayerCell"; import PlayerCell from "./fantasy/PlayerCell";
import { import {
type NFLRosterState,
type NFLPlayer,
NFLState,
NFLMatchupState, NFLMatchupState,
NFLPlayer,
SleeperUsers,
type NFLRosterState,
type NFLState,
} from "../utils/types"; } from "../utils/types";
export default function FantasyStatus() { export default function FantasyStatus() {
const USER_ID = "1263620186439696384"; const USER_ID = "1263620186439696384";
const OPP_USER_ID = "1032518341627600896";
const LEAGUE_BASE_URL = const LEAGUE_BASE_URL =
"https://api.sleeper.app/v1/league/1263620000418119680/rosters"; "https://api.sleeper.app/v1/league/1263620000418119680/rosters";
const NFL_STATE_URL = "https://api.sleeper.app/v1/state/nfl"; const NFL_STATE_URL = "https://api.sleeper.app/v1/state/nfl";
const MATCHUPS_URL = const MATCHUPS_URL =
"https://api.sleeper.app/v1/league/1263620000418119680/matchups/"; "https://api.sleeper.app/v1/league/1263620000418119680/matchups/";
const LEAGUE_USERS =
"https://api.sleeper.app/v1/league/1263620000418119680/users";
const PLAYERS_URL = "https://api.alexav.gg/v4/football/players";
const [roster, setRoster] = useState<NFLRosterState | null>(null); const [personalRoster, setPersonalRoster] = useState<NFLRosterState | null>(
const [players, setPlayers] = useState<NFLPlayer[] | null>(null); null
);
const [opposingRoster, setOpposingRoster] = useState<NFLRosterState | null>(
null
);
const [nflState, setNflState] = useState<NFLState | null>(null); const [nflState, setNflState] = useState<NFLState | null>(null);
const [matchup, setMatchup] = useState<NFLMatchupState | null>(null); // const [roster, setRoster] = useState<NFLRosterState | null>(null);
// const [players, setPlayers] = useState<NFLPlayer[] | null>(null);
// const [matchup, setMatchup] = useState<NFLMatchupState | null>(null);
// fetch roster information
useEffect(() => { useEffect(() => {
fetch(NFL_STATE_URL).then(async (res) => { async function fetchData() {
if (res.ok) { const nflState = (await fetch(NFL_STATE_URL).then((res) =>
const data = await res.json(); res.json()
setNflState(data); )) as NFLState;
} const rosters = (await fetch(LEAGUE_BASE_URL).then((res) =>
}); res.json()
fetch(LEAGUE_BASE_URL).then(async (res) => { )) as NFLRosterState[];
if (res.ok) { const matchups = (await fetch(MATCHUPS_URL + nflState.week).then((res) =>
const data = await res.json(); res.json()
setRoster( )) as NFLMatchupState[];
data.filter((v: NFLRosterState) => v.owner_id === USER_ID)[0] const users = (await fetch(LEAGUE_USERS).then((res) =>
); res.json()
} )) as SleeperUser[];
});
// rosters
const ownMatchup = matchups[1];
const oppMatchup = matchups[0];
const ownMatchupPlayers = await fetch(
PLAYERS_URL + "?players=" + ownMatchup.starters
).then((res) => res.json());
const oppMatchupPlayers = await fetch(
PLAYERS_URL + "?players=" + oppMatchup.starters
).then((res) => res.json());
setNflState(nflState);
setPersonalRoster({
...rosters.filter((v) => v.owner_id === USER_ID)[0],
matchup: matchups[1],
players: ownMatchupPlayers.playerInfo,
user: users[1],
});
setOpposingRoster({
...rosters.filter((v) => v.owner_id === OPP_USER_ID)[0],
matchup: matchups[0],
players: oppMatchupPlayers.playerInfo,
user: users[0],
});
}
fetchData();
}, []); }, []);
useEffect(() => { useEffect(() => {
if (roster) { console.log(personalRoster, opposingRoster);
const players = roster.starters.join(","); }, [personalRoster, opposingRoster]);
fetch(
"https://api.alexav.gg/v4/football/players?players=" + players
).then(async (res) => {
if (res.ok) {
const data = await res.json();
setPlayers(data.playerInfo);
}
});
}
}, [roster]);
useEffect(() => {
if (nflState && !matchup) {
fetch(MATCHUPS_URL + nflState.display_week).then(async (res) => {
if (res.ok) {
const data = await res.json();
setMatchup(data[1]);
}
});
}
}, [nflState]);
return ( return (
<div className="border border-white border-solid rounded-lg w-full sm:w-[500px] mb-4 p-2"> <div className="border border-white border-solid rounded-lg w-full sm:w-[500px] mb-4 p-2">
<a href="https://sleeper.com/leagues/1263620000418119680" target="_blank"> <div className="mb-4 space-y-4">
<h1 className="text-2xl font-bold underline">Fantasy</h1> <a
</a> href="https://sleeper.com/leagues/1263620000418119680/matchup"
target="_blank"
className="underline"
>
<h1 className="font-semibold text-2xl mb-2">Fantasy</h1>
</a>
<div className="flex flex-wrap mb-2">
<img
width="30"
className="rounded-lg"
src={personalRoster?.user.metadata.avatar}
/>
<h1 className="flex justify-center items-center mx-2 font-semibold">
{personalRoster?.user.metadata.team_name} |{" "}
{personalRoster?.matchup.points}
</h1>
</div>
<div className="space-y-2 space-x-2 whitespace-nowrap overflow-x-scroll"> <div className="space-y-2 space-x-2 whitespace-nowrap overflow-x-scroll">
{players?.map((v, k) => { {personalRoster?.players?.map((v, k) => {
return ( return (
<div className="inline-block" key={k}> <div className="inline-block" key={k}>
<PlayerCell matchupData={matchup} player={v} /> <PlayerCell matchupData={personalRoster.matchup} player={v} />
</div> </div>
); );
})} })}
</div>
<div className="flex flex-wrap mb-2">
<img
width="30"
className="rounded-lg"
src={opposingRoster?.user.metadata.avatar}
/>
<h1 className="flex justify-center items-center mx-2 font-semibold">
{opposingRoster?.user.metadata.team_name} |{" "}
{opposingRoster?.matchup.points}
</h1>
</div>
<div className="space-y-2 space-x-2 whitespace-nowrap overflow-x-scroll">
{opposingRoster?.players?.map((v, k) => {
return (
<div className="inline-block" key={k}>
<PlayerCell matchupData={opposingRoster.matchup} player={v} />
</div>
);
})}
</div>
</div> </div>
</div> </div>
); );
-77
View File
@@ -1,77 +0,0 @@
import { useState, useEffect } from "react";
type GameObject = {
game: string;
startedOn: number;
finishedAt?: number;
finished: boolean;
};
export default function GameComponent() {
const [game, setGame] = useState<GameObject | null>(null);
const [failedFetch, setFailedFetch] = useState(false);
useEffect(() => {
async function fetchGame() {
const response = await fetch(
"https://api.alexav.gg/v4/tracker/latestGame"
);
if (response.ok) {
const data = await response.json();
if (data.data && data.data.game) {
setGame(data.data as GameObject);
} else setFailedFetch(true);
} else setFailedFetch(true);
}
setTimeout(() => {
fetchGame();
}, 60000);
fetchGame();
}, []);
if (game) {
const dateOrTime = () => {
if (game.finished && game.finishedAt) {
const currentDate = new Date();
const finishedDate = new Date(game.finishedAt);
if (
currentDate.toLocaleDateString() === finishedDate.toLocaleDateString()
) {
return `last played ${game.game} at ${finishedDate.toLocaleTimeString()}`;
} else {
return `last played ${game.game} on ${finishedDate.toLocaleDateString()}`;
}
} else {
return `playing ${game.game}`;
}
};
return (
<div className="flex align-middle">
<a
className="hover:underline"
href={`https://medal.tv/u/alexav`}
target="_blank"
>
<h1 className="lowercase">{dateOrTime()}</h1>
</a>
</div>
);
} else {
if (failedFetch) {
return (
<div>
<p>not playing anything</p>
</div>
);
} else {
return (
<div>
<p>loading game..</p>
</div>
);
}
}
}
-4
View File
@@ -1,15 +1,12 @@
import Layout from "../components/Layout"; import Layout from "../components/Layout";
import MusicComponent from "../components/MusicComponent"; import MusicComponent from "../components/MusicComponent";
import TVComponent from "../components/TVComponent"; import TVComponent from "../components/TVComponent";
import GameComponent from "../components/GameComponent";
import RandomLyric from "../components/RandomLyric"; import RandomLyric from "../components/RandomLyric";
import FantasyStatus from "../components/FantasyStatus"; import FantasyStatus from "../components/FantasyStatus";
import Countdown from "../components/Countdown";
export default function App() { export default function App() {
return ( return (
<Layout> <Layout>
<Countdown />
<FantasyStatus /> <FantasyStatus />
<div className="border border-white border-solid rounded-lg w-full sm:w-[500px] p-2"> <div className="border border-white border-solid rounded-lg w-full sm:w-[500px] p-2">
<div className="grid grid-cols-1 xs:grid-cols-2"> <div className="grid grid-cols-1 xs:grid-cols-2">
@@ -57,7 +54,6 @@ export default function App() {
<h1 className="font-bold text-2xl italic">status</h1> <h1 className="font-bold text-2xl italic">status</h1>
<TVComponent /> <TVComponent />
<GameComponent />
<h1 className="font-bold text-2xl italic">reach me</h1> <h1 className="font-bold text-2xl italic">reach me</h1>
<a href="mailto:alex@vierfrantz.com"> <a href="mailto:alex@vierfrantz.com">
+12 -2
View File
@@ -21,8 +21,9 @@ interface NFLState {
interface NFLRosterState { interface NFLRosterState {
league_id: string; league_id: string;
owner_id: string; owner_id: string;
players: string[]; matchup: NFLMatchupState;
starters: string[]; players: NFLPlayer[];
user: SleeperUser;
} }
interface NFLMatchupState { interface NFLMatchupState {
points: number; points: number;
@@ -39,6 +40,14 @@ interface NFLPlayer {
team: string; team: string;
player_id: string; player_id: string;
} }
interface SleeperUser {
avatar: string;
name: string;
metadata: {
team_name: string;
avatar: string;
};
}
export type { export type {
LastFMMusicObject, LastFMMusicObject,
@@ -47,4 +56,5 @@ export type {
NFLRosterState, NFLRosterState,
NFLPlayer, NFLPlayer,
NFLMatchupState, NFLMatchupState,
SleeperUser,
}; };