From 913f28e2f27830192a1c80270612d8314eed3353 Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Tue, 6 May 2025 00:05:25 -0700 Subject: phase_tracker_only: implement the twitch table --- src/components/SubscriberTable/TwitchDataTable.tsx | 182 +++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 src/components/SubscriberTable/TwitchDataTable.tsx (limited to 'src/components/SubscriberTable/TwitchDataTable.tsx') diff --git a/src/components/SubscriberTable/TwitchDataTable.tsx b/src/components/SubscriberTable/TwitchDataTable.tsx new file mode 100644 index 0000000..3c0680c --- /dev/null +++ b/src/components/SubscriberTable/TwitchDataTable.tsx @@ -0,0 +1,182 @@ +"use client"; +import React, { useState } from "react"; +import ChannelRow from "./TwitchTableRow"; + +interface TwitchChannelDataProp { + channel_name: string; + profile_pic: string; + subscribers: number; + sub_org: string; + twitch_followers: number; + total_sum: number; + max_following?: number; +} + + +interface TwitchDataTableProp { + channel_data: TwitchChannelDataProp[]; + timestamp: string; +} + +type SortKey = keyof TwitchChannelDataProp | "rank" | "max_following"; + +const TwitchDataTable = ({ channel_data, timestamp }: TwitchDataTableProp) => { + const [sortKey, setSortKey] = useState("twitch_followers"); + const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc"); + const [indexName, setIndexName] = useState("RANK"); + + const handleSort = (key: SortKey) => { + if (sortKey === key) { + setSortOrder(sortOrder === "asc" ? "desc" : "asc"); + } else { + setSortKey(key); + setSortOrder("desc"); + } + setIndexName(key === "sub_org" ? "INDEX" : "RANK"); + }; + + const dataWithMax = channel_data.map((channel) => ({ + ...channel, + max_following: Math.max( + channel.subscribers || 0, + channel.twitch_followers || 0 + ), + })); + + const sortedData = [...dataWithMax].sort((a, b) => { + let aValue: any, bValue: any; + if (sortKey === "rank") { + aValue = dataWithMax.indexOf(a) + 1; + bValue = dataWithMax.indexOf(b) + 1; + } else { + aValue = a[sortKey]; + bValue = b[sortKey]; + } + if (typeof aValue === "string") { + return sortOrder === "asc" + ? aValue.localeCompare(bValue) + : bValue.localeCompare(aValue); + } + return sortOrder === "asc" ? aValue - bValue : bValue - aValue; + }); + + return ( + <> +
+ Limited data shown on mobile view! +
+
+

The Twitch Table

+

Updated Hourly. Retrieved at: {timestamp}

+
+ +
+
+ {/* Legend wrapper - stacked sections on all screen sizes */} +
+ + {/* Column explanations */} +
+

Column Explanations

+
+
+ SUM(YT+TTV): + Total combined followers across both platforms +
+
+ MAX(YT,TTV): + Highest follower count between platforms +
+
+
+ + {/* Horizontal divider */} +
+ + {/* Color key */} +
+

MAX Column Color Key

+
+
+
+ YouTube subscriber count is higher +
+
+
+ Twitch follower count is higher +
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + {sortedData.map((channel, index) => ( + + ))} + +
{indexName}CHANNEL handleSort("sub_org")} + > + GROUP + {sortKey === "sub_org" && ( + {sortOrder === "asc" ? "▲" : "▼"} + )} + handleSort("subscribers")} + > + YOUTUBE SUBS + {sortKey === "subscribers" && ( + {sortOrder === "asc" ? "▲" : "▼"} + )} + handleSort("twitch_followers")} + > + TWITCH FOLLOWS + {sortKey === "twitch_followers" && ( + {sortOrder === "asc" ? "▲" : "▼"} + )} + handleSort("total_sum")} + > + SUM(YT+TTV) + {sortKey === "total_sum" && ( + {sortOrder === "asc" ? "▲" : "▼"} + )} + handleSort("max_following")} + > + MAX(YT, TTV) + {sortKey === "max_following" && ( + {sortOrder === "asc" ? "▲" : "▼"} + )} +
+
+ + ); +}; + +export default TwitchDataTable; +export type { TwitchDataTableProp, TwitchChannelDataProp }; -- cgit v1.2.3