Skip to content

Commit

Permalink
wip(web/players): separated callout row + animated it
Browse files Browse the repository at this point in the history
  • Loading branch information
tabarra committed Mar 14, 2024
1 parent 6bfa522 commit 592067f
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 50 deletions.
108 changes: 108 additions & 0 deletions panel/src/components/PageCalloutRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import React, { useEffect, useState } from 'react';

const easeOutQuart = (t: number) => 1 - (--t) * t * t * t;
const frameDuration = 1000 / 60;

type CountUpAnimationProps = {
countTo: number;
duration?: number;
};

//Snippet from: https://jshakespeare.com/simple-count-up-number-animation-javascript-react/
const CountUpAnimation = ({ countTo, duration = 1250 }: CountUpAnimationProps) => {
const [count, setCount] = useState(0);

useEffect(() => {
let frame = 0;
const totalFrames = Math.round(duration / frameDuration);
const counter = setInterval(() => {
frame++;
const progress = easeOutQuart(frame / totalFrames);
setCount(countTo * progress);

if (frame === totalFrames) {
clearInterval(counter);
}
}, frameDuration);
}, []);

return Math.floor(count).toLocaleString("en-US");
};

function NumberLoading() {
return (
<div className="h-7 w-28 animate-pulse rounded-md bg-muted" />
)
}


export type PageCalloutProps = {
label: string;
icon: React.ReactNode;
value: number | false;
prefix?: string;
}

export type PageCalloutRowProps = {
callouts: PageCalloutProps[];
};
export default function PageCalloutRow({ callouts }: PageCalloutRowProps) {
if (callouts.length !== 4) return null;

return (
<div className="grid px-2 md:px-0 gap-2 xs:gap-4 grid-cols-2 lg:grid-cols-4 mb-4 md:mb-6">
<div className="py-2 px-4 rounded-lg border shadow-sm">
<div className="flex flex-row items-center justify-between space-y-0 pb-2 text-muted-foreground">
<h3 className="tracking-tight text-sm font-medium line-clamp-1">{callouts[0].label}</h3>
<div className='hidden xs:block'>{callouts[0].icon}</div>
</div>
{callouts[0].value === false ? (
<NumberLoading />
) : (
<div className="text-xl xs:text-2xl font-bold">
{callouts[0].prefix}<CountUpAnimation countTo={callouts[0].value} />
</div>
)}
</div>
<div className="py-2 px-4 rounded-lg border shadow-sm">
<div className="flex flex-row items-center justify-between space-y-0 pb-2 text-muted-foreground">
<h3 className="tracking-tight text-sm font-medium line-clamp-1">{callouts[1].label}</h3>
<div className='hidden xs:block'>{callouts[1].icon}</div>
</div>
{callouts[1].value === false ? (
<NumberLoading />
) : (
<div className="text-xl xs:text-2xl font-bold">
{callouts[1].prefix}<CountUpAnimation countTo={callouts[1].value} />
</div>
)}
</div>
<div className="py-2 px-4 rounded-lg border shadow-sm">
<div className="flex flex-row items-center justify-between space-y-0 pb-2 text-muted-foreground">
<h3 className="tracking-tight text-sm font-medium line-clamp-1">{callouts[2].label}</h3>
<div className='hidden xs:block'>{callouts[2].icon}</div>
</div>
{callouts[2].value === false ? (
<NumberLoading />
) : (
<div className="text-xl xs:text-2xl font-bold">
{callouts[2].prefix}<CountUpAnimation countTo={callouts[2].value} />
</div>
)}
</div>
<div className="py-2 px-4 rounded-lg border shadow-sm">
<div className="flex flex-row items-center justify-between space-y-0 pb-2 text-muted-foreground">
<h3 className="tracking-tight text-sm font-medium line-clamp-1">{callouts[3].label}</h3>
<div className='hidden xs:block'>{callouts[3].icon}</div>
</div>
{callouts[3].value === false ? (
<NumberLoading />
) : (
<div className="text-xl xs:text-2xl font-bold">
{callouts[3].prefix}<CountUpAnimation countTo={callouts[3].value} />
</div>
)}
</div>
</div >
)
}
80 changes: 30 additions & 50 deletions panel/src/pages/TestingPage/TmpTestTables.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
DropdownMenuSeparator, DropdownMenuTrigger
} from "@/components/ui/dropdown-menu";
import InlineCode from '@/components/InlineCode';
import PageCalloutRow, { PageCalloutProps } from '@/components/PageCalloutRow';



Expand Down Expand Up @@ -266,47 +267,37 @@ function PlayerSearchBox() {
const PlayerSearchBoxMemo = memo(PlayerSearchBox);


const callouts: PageCalloutProps[] = [
{
label: 'Total Players',
value: 123456,
// value: false,
icon: <UsersIcon />,
prefix: ''
},
{
label: 'Players Today',
value: 1234,
icon: <CalendarPlusIcon />,
prefix: ''
},
{
label: 'New Players Today',
value: 1234,
icon: <UserRoundPlusIcon />,
prefix: '+'
},
{
label: 'New Players This Week',
value: 12345,
icon: <UserRoundPlusIcon />,
prefix: '+'
}
]

function PlayerStats() {
return (
// <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4 mb-4 md:mb-6">
<div className="grid px-2 md:px-0 gap-2 xs:gap-4 grid-cols-2 lg:grid-cols-4 mb-4 md:mb-6">
<div className="py-2 px-4 rounded-lg border shadow-sm">
<div className="flex flex-row items-center justify-between space-y-0 pb-2 text-muted-foreground">
<h3 className="tracking-tight text-sm font-medium line-clamp-1">Total Players</h3>
<UsersIcon className='hidden xs:block' />
</div>
<div className="text-xl xs:text-2xl font-bold">
123,456
</div>
</div>
<div className="py-2 px-4 rounded-lg border shadow-sm">
<div className="flex flex-row items-center justify-between space-y-0 pb-2 text-muted-foreground">
<h3 className="tracking-tight text-sm font-medium line-clamp-1">Players Today</h3>
<CalendarPlusIcon className='hidden xs:block' />
</div>
<div className="text-xl xs:text-2xl font-bold">
1,234
</div>
</div>
<div className="py-2 px-4 rounded-lg border shadow-sm">
<div className="flex flex-row items-center justify-between space-y-0 pb-2 text-muted-foreground">
<h3 className="tracking-tight text-sm font-medium line-clamp-1">New Players Today</h3>
<UserRoundPlusIcon className='hidden xs:block' />
</div>
<div className="text-xl xs:text-2xl font-bold">
+1,234
</div>
</div>
<div className="py-2 px-4 rounded-lg border shadow-sm">
<div className="flex flex-row items-center justify-between space-y-0 pb-2 text-muted-foreground">
<h3 className="tracking-tight text-sm font-medium line-clamp-1">New Players This Week</h3>
<UserRoundPlusIcon className='hidden xs:block' />
</div>
<div className="text-xl xs:text-2xl font-bold">
+12,345
</div>
</div>
</div>
<PageCalloutRow callouts={callouts} />
)
}

Expand Down Expand Up @@ -416,17 +407,6 @@ export default function TmpTestTables() {
className='flex flex-col min-w-96 2xl:mx-8'
style={{ height: 'calc(100vh - 3.5rem - 1px - 2rem)' }}
>
{/* <div className="flex gap-3 items-center ">
<Button onClick={() => rowVirtualizer.scrollToIndex(0)}>Scroll to top</Button>
<Button onClick={() => fetchNextPage()}>fetchNextPage()</Button>
<Button onClick={() => setPlayers([])}>Wipe</Button>
</div> */}


{/* <h2 className='px-2 md:px-0 mb-4 md:mb-6 text-lg md:text-2xl'>
Players: {players.length}/{dbPlayerCount}
<span className='text-fuchsia-600 pl-3'>({virtualItems.length - 1} rendered)</span>
</h2> */}
<PlayerStatsMemo />

<PlayerSearchBoxMemo />
Expand Down

0 comments on commit 592067f

Please sign in to comment.