import { m } from "framer-motion"; import Head from "next/head"; import { useRouter } from "next/router"; import { ReactElement, useEffect, useState } from "react"; import DashLayout from "../../../layouts/DashLayout"; import Image from "next/image"; import Loading from "../../../components/common/Loading"; // TODO: Animations function UserPage() { const [channelEmotes, setChannelEmotes] = useState<{ [key: string]: { [key: string]: string }; }>({}); const [userData, setUserData] = useState<{ [key: string]: any }>({}); const [errorCode, setErrorCode] = useState(null); const router = useRouter(); const { username } = router.query; const title = username ? `${username} - toffee` : "toffee"; useEffect(() => { if (!router.isReady) return; fetch("/api/7tv/emotes?c=61ad997effa9aba101bcfddf") .then((res) => res.json()) .then((data) => { // if error, return if (data.error) { setErrorCode(data.error.code); return; } // construct js object with emote names as keys and emote urls as values let emotes: { [key: string]: string } = {}; data.channel.user.emote_sets[0].emotes.forEach((emote: any) => { let base_url = emote.data.host.url; // get the largest emote size, append it to the base url let largest = emote.data.host.files[emote.data.host.files.length - 1]; emotes[emote.data.name] = `https:${base_url}/${largest.name}`; }); // same for global emotes data.global.namedEmoteSet.emotes.forEach((emote: any) => { let base_url = emote.data.host.url; let largest = emote.data.host.files[emote.data.host.files.length - 1]; emotes[emote.data.name] = `https:${base_url}/${largest.name}`; }); // set 7tv key to channelEmotes setChannelEmotes((prev) => ({ ...prev, "7tv": emotes })); }); fetch("/api/bttv/emotes?c=56418014") .then((res) => res.json()) .then((data) => { if (data.error) { setErrorCode(data.error.code); return; } let emotes: { [key: string]: string } = {}; data.channel.forEach((emote: any) => { emotes[emote.code] = `https://cdn.betterttv.net/emote/${emote.id}/3x`; }); data.global.forEach((emote: any) => { emotes[emote.code] = `https://cdn.betterttv.net/emote/${emote.id}/3x`; }); // add as bttv key to channelEmotes setChannelEmotes((prev) => ({ ...prev, bttv: emotes })); }); fetch("/api/ffz/emotes?s=341402") .then((res) => res.json()) .then((data) => { if (data.error) { setErrorCode(data.error.code); return; } let emotes: { [key: string]: string } = {}; data.channel.forEach((emote: any) => { // ffz emotes don't have all sizes available, so we need to get the largest one by taking the largest key in the urls object emotes[emote.name] = `https:${ emote.urls[ Math.max(...Object.keys(emote.urls).map((k) => parseInt(k))) ] }`; }); data.global.forEach((emote: any) => { emotes[emote.name] = `https:${ emote.urls[ Math.max(...Object.keys(emote.urls).map((k) => parseInt(k))) ] }`; }); // add as ffz key to channelEmotes setChannelEmotes((prev) => ({ ...prev, ffz: emotes })); }); fetch("/api/twitch/emotes?c=56418014") .then((res) => res.json()) .then((data) => { if (data.error) { setErrorCode(data.error.code); return; } let emotes: { [key: string]: string } = {}; data.channel.forEach((emote: any) => { emotes[emote.name] = emote.images["url_4x"]; }); data.global.forEach((emote: any) => { emotes[emote.name] = emote.images["url_4x"]; }); // add as twitch key to channelEmotes setChannelEmotes((prev) => ({ ...prev, ttv: emotes })); }); fetch(`/api/fakeUsers?u=${username}`) .then((res) => res.json()) .then((data) => { if (data.error) { setErrorCode(data.error.code); } setUserData(data.data); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [router.isReady]); if (errorCode !== null) { // 20000 = user not found // 10000 = 7tv api error // 10100 = Twitch api error // 10200 = BTTV api error // 10300 = FFZ api error const errorMsg = errorCode === 20000 ? "User not found" : "API error"; return (

{errorMsg}

); } // if json is empty, and if channelEmotes is incomplete, show loading screen if ( Object.keys(channelEmotes).length < 4 || !userData || Object.keys(userData).length === 0 ) { return (
); } console.log(channelEmotes); return ( <> {title}
{/* User "banner" */}
User avatar

{userData.name}

{/* User's badges */}
{userData.badges ? ( userData.badges.map( (badge: { name: string; color: string; priority: number; }) => { return (
{badge.name}
); } ) ) : ( <> )}

$ {userData.net_worth.toLocaleString("en-US")}

{/* Main Container */}
{/* User's Rank/Graph */}

Global Rank

# {userData.rank.toLocaleString("en-US")}
Rank chart

$ {userData.net_worth.toLocaleString("en-US")}

{/* User's Assets */}
{/* User's Assets Header */}

Top Assets

{/* User's Assets Body */}
{errorCode === 20000 ? (

{`Could not load assets`}

) : ( userData.assets.map( (asset: { name: string; count: number; provider: string; }) => (
{ // if error code is 10000 or emote does not exist, show placeholder image errorCode === 10000 || channelEmotes[asset.provider] === undefined || channelEmotes[asset.provider][asset.name] === undefined ? (

{`404 :(`}

) : ( {asset.name} ) } {/* Fix asset count to bottom right of image */}

x{asset.count}

{ // show provider logo (7tv, bttv, ffz, ttv) asset.provider === "7tv" ? (
) : asset.provider === "bttv" ? (
) : asset.provider === "ffz" ? (
) : (
) }

{asset.name}

) ) )}
{/* Sidebar */}
{/* User's Stats, left side is label, right side is value */}

Points

{userData.points.toLocaleString("en-US")}

Shares

{userData.shares.toLocaleString("en-US")}

Trades

{(userData.trades ?? 0).toLocaleString("en-US")}

Peak rank

{(userData.peak_rank ?? 0).toLocaleString("en-US")}

Joined

{new Date(userData.joined ?? 0).toLocaleDateString("en-US", { year: "numeric", month: "short", })}

{/* User's Favorite Emote */}

Favorite Emote

This user has not yet set a favorite emote.

); } const SevenTVLogo = () => { return ( ); }; const FFZLogo = () => { return ( ); }; const BTTVLogo = () => { return ( ); }; const TwitchLogo = () => { return ( ); }; UserPage.getLayout = function getLayout(page: ReactElement) { return {page}; }; export default UserPage;