basic concept ready

This commit is contained in:
Anthony Mineo 2020-04-12 14:47:23 -04:00
parent a57800e3a4
commit 74798d239b
10 changed files with 197 additions and 44 deletions

View file

@ -36,6 +36,7 @@ class PlayerController {
const playerStatData = await Database.from('games') const playerStatData = await Database.from('games')
.select('game_id', .select('game_id',
'gametype',
'stats') 'stats')
.where({ player_guid: request.params.player_guid }) .where({ player_guid: request.params.player_guid })

View file

@ -10,7 +10,7 @@ const returnTotalSumGames = (player) => {
const GameTypesPlayedBoxes = (props) => { const GameTypesPlayedBoxes = (props) => {
return ( return (
<div> <>
<h3 className="text-md leading-6 font-medium text-gray-900"> <h3 className="text-md leading-6 font-medium text-gray-900">
Games Played {returnTotalSumGames(props)} Games Played {returnTotalSumGames(props)}
</h3> </h3>
@ -64,7 +64,7 @@ const GameTypesPlayedBoxes = (props) => {
</div> </div>
</div> </div>
</div> </div>
</div> </>
); );
}; };

View file

@ -0,0 +1,58 @@
import React from 'react'
const returnTotalSumGames = (player) => {
let sum = Number(player.ctf) +
Number(player.dm) +
Number(player.lak) +
Number(player.spawnctf);
return sum
};
const GameTypesPlayedCols = (props) => {
return (
<>
<dl className="grid grid-cols-1 col-gap-4 row-gap-8 sm:grid-cols-4">
<div className="sm:col-span-1">
<dt className="text-sm leading-5 font-medium text-gray-500">
CTF
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900">
<span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium leading-4 bg-gray-100 text-gray-800">{props.ctf} </span>
</dd>
</div><div className="sm:col-span-1">
<dt className="text-sm leading-5 font-medium text-gray-500">
LAK Rabbit
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900">
<span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium leading-4 bg-gray-100 text-gray-800">{props.lak}</span>
</dd>
</div><div className="sm:col-span-1">
<dt className="text-sm leading-5 font-medium text-gray-500">
Spawn CTF
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900">
<span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium leading-4 bg-gray-100 text-gray-800">{props.spawnctf}</span>
</dd>
</div><div className="sm:col-span-1">
<dt className="text-sm leading-5 font-medium text-gray-500">
Deathmatch
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900">
<span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium leading-4 bg-gray-100 text-gray-800">{props.dm}</span>
</dd>
</div>
</dl>
<div className="mt-5">
<dt className="text-sm leading-5 font-medium text-gray-500">
Total
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900">
<span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium leading-4 bg-gray-100 text-gray-800">{returnTotalSumGames(props)}</span>
</dd>
</div>
</>
);
};
export default GameTypesPlayedCols;

View file

@ -0,0 +1 @@
export { default } from './GameTypesPlayedCols';

View file

@ -4,49 +4,33 @@ import { InertiaLink } from '@inertiajs/inertia-react'
const navItems = () => const navItems = () =>
<div className="ml-10 flex items-baseline"> <div className="ml-10 flex items-baseline">
<InertiaLink href="/" className="px-3 py-2 rounded-md text-sm font-medium text-white bg-gray-900 focus:outline-none focus:text-white focus:bg-gray-700">Home</InertiaLink> {/* <InertiaLink href="/" className="px-3 py-2 rounded-md text-sm font-medium text-white bg-gray-900 focus:outline-none focus:text-white focus:bg-gray-700">Home</InertiaLink> */}
<InertiaLink href="/games" className="ml-4 px-3 py-2 rounded-md text-sm font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Games</InertiaLink> <InertiaLink href="/games" className="ml-4 px-3 py-2 rounded-md text-sm font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Games</InertiaLink>
<InertiaLink href="/players" className="ml-4 px-3 py-2 rounded-md text-sm font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Players</InertiaLink> <InertiaLink href="/players" className="ml-4 px-3 py-2 rounded-md text-sm font-medium text-gray-300 hover:text-white hover:bg-gray-700 focus:outline-none focus:text-white focus:bg-gray-700">Players</InertiaLink>
</div>; </div>;
const TopNav = () => { const TopNav = () => {
return ( return (
<nav data-todo-x-data="{ open: false }" data-todo-at-keydown-window-escape="open = false" className="bg-gray-800"> <nav className="bg-gray-800">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-16"> <div className="flex items-center justify-between h-16">
<div className="flex items-center"> <div className="flex items-center">
<div className="flex-shrink-0"> <div className="flex-shrink-0">
<img className="h-8 w-8" src="https://tailwindui.com/img/logos/workflow-mark-on-dark.svg" alt="Workflow logo" /> <img className="h-8 w-8" src="https://d33wubrfki0l68.cloudfront.net/1699fc97aa9b1cb851a6c0039162a9241724e1fb/7289f/images/logo.png" alt="Tribes 2 Stats" />
</div> </div>
<div className="hidden md:block"> <div className="md:block">
{ navItems() } { navItems() }
</div> </div>
</div> </div>
<div className="hidden md:block"> <div className="md:block">
<div className="ml-4 flex items-center md:ml-6"> <div className="ml-4 flex items-center md:ml-6">
<div data-todo-at-click-away="open = false" className="ml-3 relative" data-todo-x-data="{ open: false }">
<span className="inline-flex rounded-md shadow-sm"> <span className="inline-flex rounded-md shadow-sm">
<button type="button" className="inline-flex items-center px-2.5 py-1.5 border border-gray-300 text-xs leading-4 font-medium rounded text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:text-gray-800 active:bg-gray-50 transition ease-in-out duration-150"> <a href="https://www.playt2.com/discord" className="inline-flex items-center px-2.5 py-1.5 border border-gray-300 text-xs leading-4 font-medium rounded text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:text-gray-800 active:bg-gray-50 transition ease-in-out duration-150">
Discord Join Discord
</button> </a>
</span> </span>
</div>
</div> </div>
</div> </div>
{/* {Mobile nav} */}
<div className="-mr-2 flex md:hidden">
<button data-todo-at-click="open = !open" className="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:bg-gray-700 focus:text-white" data-todo-x-bind-aria-label="open ? 'Close main menu' data-todo-colon- 'Main menu'" data-todo-x-bind-aria-expanded="open">
<svg className="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
<path data-todo-colon-className="{'hidden': open, 'inline-flex': !open }" className="inline-flex" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 6h16M4 12h16M4 18h16" />
<path data-todo-colon-className="{'hidden': !open, 'inline-flex': open }" className="hidden" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</div>
</div>
<div data-todo-colon-className="{'block': open, 'hidden': !open}" className="hidden md:hidden">
<div className="px-2 pt-2 pb-3 sm:px-3">
{ navItems() }
</div> </div>
</div> </div>
</nav> </nav>

View file

@ -105,7 +105,7 @@ const PlayerRow = (player, index) => {
{player.stats.score} {player.stats.score}
</dd> </dd>
</div> </div>
<div className="bg-gray-50"> <div className="bg-gray-50 flex items-center justify-center">
{ {
(player.gametype == "CTFGame" || player.gametype == "SCtFGame") ? <TwoLevelPieChart data={{ (player.gametype == "CTFGame" || player.gametype == "SCtFGame") ? <TwoLevelPieChart data={{
oScore: Number(player.stats.offenseScore[0]), oScore: Number(player.stats.offenseScore[0]),

View file

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import { InertiaLink } from '@inertiajs/inertia-react'
import Layout from '@/Shared/Layout' import Layout from '@/Shared/Layout'
import GameTypesPlayedBoxes from '@/Components/GameTypesPlayedBoxes' import GameTypesPlayedCols from '@/Components/GameTypesPlayedCols'
import {Radar, RadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis} from 'recharts' import {Radar, RadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis} from 'recharts'
@ -29,7 +29,72 @@ const returnWeaponTotals = (statTotals) => {
}; };
const GameCard = (player, index) => {
// only display card if player has score
if (Number(player.stats.score) <= 0){return}
return <div key={index} className="bg-white shadow overflow-hidden sm:rounded-lg mb-5">
<div className="px-4 py-5 border-b border-gray-200 sm:px-6">
<div className="-ml-4 -mt-4 flex justify-between items-center flex-wrap sm:flex-no-wrap">
<div className="ml-4 mt-4">
<h3 className="text-lg leading-6 font-medium text-gray-900">
<InertiaLink href={`/game/${player.game_id}`} className="text-indigo-600 hover:text-indigo-500 transition duration-150 ease-in-out">{player.stats.map}</InertiaLink>
</h3>
<p className="mt-1 max-w-2xl text-sm leading-5 text-gray-500">
<span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium leading-4 bg-gray-100 text-gray-800">{player.stats.dateStamp}</span>
</p>
</div>
<div className="ml-4 mt-4 flex-shrink-0">
<span className="inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium leading-5 bg-indigo-100 text-indigo-800">
{ player.gametype }
</span>
</div>
</div>
</div>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm leading-5 font-medium text-gray-500">
Total Score
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
{player.stats.score}
</dd>
</div>
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm leading-5 font-medium text-gray-500">
Kills / Assists
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
{player.stats.kills} / {player.stats.assist}
</dd>
</div>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm leading-5 font-medium text-gray-500">
MAs
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
{player.stats.totalMA}
</dd>
</div>
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm leading-5 font-medium text-gray-500">
Flag Grabs / Caps
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
{player.stats.flagGrabs} / {player.stats.flagCaps}
</dd>
</div>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm leading-5 font-medium text-gray-500">
Flag Defends / Carrier Kills / Returns
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
{player.stats.flagDefends} / {player.stats.carrierKills} / {player.stats.flagReturns}
</dd>
</div>
</div>;
}
@ -37,23 +102,65 @@ export default function Player(props) {
return ( return (
<Layout title={props.pageTitle}> <Layout title={props.pageTitle}>
<GameTypesPlayedBoxes ctf={props.playerData.player.total_games_ctfgame} <div className="md:grid md:grid-cols-4 md:gap-6">
<div className="md:col-span-1">
<div className="px-4 sm:px-0">
<h3 className="text-lg font-medium leading-6 text-gray-900">Aggregate</h3>
<p className="mt-1 text-sm leading-5 text-gray-500">
Stat Totals
</p>
</div>
</div>
<div className="mt-5 md:mt-0 md:col-span-3">
<div className="bg-white shadow overflow-hidden sm:rounded-lg">
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<div className="text-sm leading-5 font-medium text-gray-500">
Games Played
</div>
<div className="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
<GameTypesPlayedCols ctf={props.playerData.player.total_games_ctfgame}
dm={props.playerData.player.total_games_dmgame} dm={props.playerData.player.total_games_dmgame}
lak={props.playerData.player.total_games_lakrabbitgame} lak={props.playerData.player.total_games_lakrabbitgame}
spawnctf={props.playerData.player.total_games_sctfgame} spawnctf={props.playerData.player.total_games_sctfgame}/>
/> </div>
</div>
<div className="bg-gray-50 px-4 py-5">
<dt className="text-sm leading-5 font-medium text-gray-500">
Weapon Usage
</dt>
<dd className="mt-1 text-sm leading-5 text-gray-900 flex items-center justify-center">
<RadarChart cx={300} cy={250} outerRadius={150} width={600} height={500} data={ returnWeaponTotals(props.playerData.totals).length ? returnWeaponTotals(props.playerData.totals) : [{ weapon: 'No Data', val:1}]} className="text-xs">
<PolarGrid />
<PolarAngleAxis dataKey="weapon" />
<PolarRadiusAxis/>
<Radar name={props.playerData.player.player_name} dataKey="val" stroke="#8884d8" fill="#8884d8" fillOpacity={0.6}/>
</RadarChart>
</dd>
</div>
</div>
</div>
</div>
<RadarChart cx={300} cy={250} outerRadius={150} width={600} height={500} data={ returnWeaponTotals(props.playerData.totals).length ? returnWeaponTotals(props.playerData.totals) : [{ weapon: 'No Data', val:1}]} className="text-sm"> <div className="md:grid md:grid-cols-4 md:gap-6 mt-10">
<PolarGrid /> <div className="md:col-span-1">
<PolarAngleAxis dataKey="weapon" /> <div className="px-4 sm:px-0">
<PolarRadiusAxis/> <h3 className="text-lg font-medium leading-6 text-gray-900">Game History</h3>
<Radar name={props.playerData.player.player_name} dataKey="val" stroke="#8884d8" fill="#8884d8" fillOpacity={0.6}/> <p className="mt-1 text-sm leading-5 text-gray-500">
</RadarChart> Stats for past {props.playerData.stats.length} games
</p>
</div>
</div>
<div className="mt-5 md:mt-0 md:col-span-3">
{ props.playerData.stats.map((player, index) => GameCard(player, index)) }
</div>
</div>
{/*
<div className="bg-white shadow overflow-hidden sm:rounded-md"> <div className="bg-white shadow overflow-hidden sm:rounded-md">
<div className="py-10 px-10">{JSON.stringify(props.playerData.totals)}</div>
<div className="py-10 px-10"><code> {JSON.stringify(props.playerData.stats)}</code></div> <div className="py-10 px-10"><code> {JSON.stringify(props.playerData.stats)}</code></div>
</div> </div> */}
</Layout> </Layout>
) )
} }

View file

@ -5,7 +5,7 @@ import FrameHeading from '../Components/FrameHeading'
export default function Layout({ title, gametype, children }) { export default function Layout({ title, gametype, children }) {
useEffect(() => { useEffect(() => {
document.title = title; document.title = title + ' - Tribes 2 Stats';
}, [title]) }, [title])
return ( return (

View file

@ -4,7 +4,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ edgeVar }}</title> <title>Tribes 2 Stats</title>
<link rel="stylesheet" href="https://rsms.me/inter/inter.css"> <link rel="stylesheet" href="https://rsms.me/inter/inter.css">
@if(node_env().env === "production") @if(node_env().env === "production")
@ -15,7 +15,7 @@
</head> </head>
<body class="antialiased font-sans bg-gray-200"> <body class="antialiased font-sans bg-gray-200">
{{{ startTag }}} {{{ startTag }}}
{{ edgeVar }} {{-- {{ edgeVar }} --}}
@if(node_env().env === "production" || node_env().hmr === "false") @if(node_env().env === "production" || node_env().hmr === "false")
{{ script(versionjs('app')) }} {{ script(versionjs('app')) }}
@else @else

View file

@ -17,7 +17,9 @@
const Route = use('Route') const Route = use('Route')
// [ Routes ] // [ Routes ]
Route.get('/', 'IndexController.index').as('home') //Route.get('/', 'IndexController.index').as('home')
//temp set games as home
Route.get('/', 'GameController.index').as('home')
// [ player ] // [ player ]
Route.get('/players', 'PlayerController.index') Route.get('/players', 'PlayerController.index')