A decentralized music tracking and discovery platform built on AT Protocol 馃幍
at feat/feed-generator 135 lines 3.3 kB view raw
1import { LabelMedium } from "baseui/typography"; 2import dayjs from "dayjs"; 3import numeral from "numeral"; 4import { useEffect, useState } from "react"; 5import { useLocation, useParams } from "react-router"; 6import { Area, AreaChart, Tooltip, TooltipProps, XAxis } from "recharts"; 7import useChart from "../../hooks/useChart"; 8 9const CustomTooltip = ({ 10 active, 11 payload, 12 label, 13}: TooltipProps<number, string>) => { 14 if (active && payload && payload.length) { 15 return ( 16 <div 17 style={{ 18 backgroundColor: "white", 19 padding: "5px", 20 border: "1px solid #ccc", 21 }} 22 > 23 <span style={{ color: "#808080" }}> 24 {dayjs(label).format("dddd DD MMMM YYYY")}: 25 </span> 26 <span> {numeral(payload[0].value).format("0,0")}</span> 27 </div> 28 ); 29 } 30 31 return null; 32}; 33const formatXAxis = (tickItem: string) => dayjs(tickItem).format("MMM D"); 34 35function ScrobblesAreaChart() { 36 const { 37 getScrobblesChart, 38 getAlbumChart, 39 getArtistChart, 40 getSongChart, 41 getProfileChart, 42 } = useChart(); 43 const { pathname } = useLocation(); 44 const { did, rkey } = useParams<{ did: string; rkey: string }>(); 45 const [data, setData] = useState< 46 { 47 date: string; 48 count: number; 49 }[] 50 >([]); 51 52 useEffect(() => { 53 const fetchScrobblesChart = async () => { 54 if (pathname === "/") { 55 return; 56 } 57 58 if (pathname.startsWith("/profile")) { 59 const charts = await getProfileChart(did!); 60 setData(charts); 61 return; 62 } 63 64 if (pathname.includes("app.rocksky.artist")) { 65 const charts = await getArtistChart( 66 `at://${did}/app.rocksky.artist/${rkey}` 67 ); 68 setData(charts); 69 return; 70 } 71 72 if (pathname.includes("app.rocksky.album")) { 73 const charts = await getAlbumChart( 74 `at://${did}/app.rocksky.album/${rkey}` 75 ); 76 setData(charts); 77 return; 78 } 79 80 if (pathname.includes("app.rocksky.song")) { 81 const charts = await getSongChart( 82 `at://${did}/app.rocksky.song/${rkey}` 83 ); 84 setData(charts); 85 return; 86 } 87 88 if (pathname.includes("app.rocksky.scrobble")) { 89 const charts = await getSongChart( 90 `at://${did}/app.rocksky.scrobble/${rkey}` 91 ); 92 setData(charts); 93 return; 94 } 95 }; 96 fetchScrobblesChart(); 97 // eslint-disable-next-line react-hooks/exhaustive-deps 98 }, [pathname]); 99 100 return ( 101 <> 102 <LabelMedium marginBottom={"20px"}>Scrobble Stats</LabelMedium> 103 <AreaChart 104 width={300} 105 height={120} 106 data={pathname === "/" ? getScrobblesChart() : data} 107 margin={{ 108 top: 5, 109 right: 0, 110 left: 0, 111 bottom: 5, 112 }} 113 > 114 <XAxis 115 dataKey="date" 116 axisLine={{ stroke: "#ccc", strokeWidth: 1 }} 117 tick={{ fontSize: 10 }} 118 tickFormatter={formatXAxis} 119 /> 120 <Tooltip 121 content={<CustomTooltip />} 122 labelFormatter={(label) => dayjs(label).format("YYYY-MM-DD")} 123 /> 124 <Area 125 type="monotone" 126 dataKey="count" 127 stroke="#710de4" 128 fill="#9754e463" 129 /> 130 </AreaChart> 131 </> 132 ); 133} 134 135export default ScrobblesAreaChart;