@@ -6,14 +6,15 @@ import useHeadlines from '../api/useHeadlines'
66import ErrorMessage from '../components/ErrorMessage'
77import HeadlineStat from '../components/HeadlineStat'
88import TimePeriodPicker from '../components/TimePeriodPicker'
9- import Title from '../components/Title '
9+ import Page from '../components/Page '
1010import routes from '../constants/routes'
1111import activeGameState from '../state/activeGameState'
1212import canViewPage from '../utils/canViewPage'
1313import useLocalStorage from '../utils/useLocalStorage'
1414import useTimePeriod from '../utils/useTimePeriod'
1515import Link from '../components/Link'
1616import userState from '../state/userState'
17+ import useStats from '../api/useStats'
1718
1819const Dashboard = ( ) => {
1920 const history = useHistory ( )
@@ -34,16 +35,17 @@ const Dashboard = () => {
3435 const activeGame = useRecoilValue ( activeGameState )
3536
3637 const timePeriods = [
37- { id : '7d' , label : '7 days' , titleSuffix : 'the last 7 days' } ,
38- { id : '30d' , label : '30 days' , titleSuffix : 'the last 30 days' } ,
39- { id : 'w' , label : 'This week' , titleSuffix : 'this week' } ,
40- { id : 'm' , label : 'This month' , titleSuffix : 'this month' } ,
41- { id : 'y' , label : 'This year' , titleSuffix : 'this year' }
38+ { id : '7d' , label : '7 days' , titlePrefix : 'Last 7 days' } ,
39+ { id : '30d' , label : '30 days' , titlePrefix : 'Last 30 days' } ,
40+ { id : 'w' , label : 'This week' , titlePrefix : 'This week' } ,
41+ { id : 'm' , label : 'This month' , titlePrefix : 'This month' } ,
42+ { id : 'y' , label : 'This year' , titlePrefix : 'This year' }
4243 ]
4344
44- const [ timePeriod , setTimePeriod ] = useLocalStorage ( 'headlinesTimePeriod' , timePeriods [ 1 ] )
45- const { startDate, endDate } = useTimePeriod ( timePeriod . id )
46- const { headlines, loading, error } = useHeadlines ( activeGame , startDate , endDate )
45+ const [ timePeriod , setTimePeriod ] = useLocalStorage ( 'headlinesTimePeriod' , timePeriods [ 1 ] . id )
46+ const { startDate, endDate } = useTimePeriod ( timePeriod )
47+ const { headlines, loading : headlinesLoading , error : headlinesError } = useHeadlines ( activeGame , startDate , endDate )
48+ const { stats, loading : statsLoading , error : statsError } = useStats ( activeGame )
4749
4850 if ( ! intendedRouteChecked ) return null
4951
@@ -56,45 +58,53 @@ const Dashboard = () => {
5658 )
5759 }
5860
59- return (
60- < div >
61- < Title > { activeGame . name } dashboard</ Title >
61+ const titlePrefix = timePeriods . find ( ( period ) => period . id === timePeriod ) . titlePrefix
6262
63- < div className = 'flex flex-col-reverse md:flex-row md:justify-between md:items-center mt-8' >
64- < h2 className = 'text-2xl mt-4 md:mt-0' > Stats for { timePeriod . titleSuffix } </ h2 >
63+ return (
64+ < Page title = { `${ activeGame . name } dashboard` } isLoading = { headlinesLoading || statsLoading } >
65+ < div className = 'flex flex-col-reverse md:flex-row md:justify-between md:items-center' >
66+ < h2 className = 'text-2xl mt-4 md:mt-0' > { titlePrefix } at a glance</ h2 >
6567 < TimePeriodPicker
6668 periods = { timePeriods }
67- onPick = { setTimePeriod }
68- selectedPeriod = { timePeriod . id }
69+ onPick = { ( period ) => setTimePeriod ( period . id ) }
70+ selectedPeriod = { timePeriod }
6971 />
7072 </ div >
7173
72- { error &&
73- < div className = 'mt-8' >
74- < ErrorMessage error = { { message : 'Couldn\'t fetch headlines' } } />
74+ { headlinesError &&
75+ < ErrorMessage error = { { message : 'Couldn\'t fetch headlines' } } />
76+ }
77+
78+ { ! headlinesLoading &&
79+ < div className = 'grid md:grid-cols-2 lg:grid-cols-4 gap-4' >
80+ < HeadlineStat title = 'New players' stat = { headlines . new_players . count } />
81+ < HeadlineStat title = 'Returning players' stat = { headlines . returning_players . count } />
82+ < HeadlineStat title = 'New events' stat = { headlines . events . count } />
83+ < HeadlineStat title = 'Unique event submitters' stat = { headlines . unique_event_submitters . count } />
7584 </ div >
7685 }
7786
78- { ! loading && ! error &&
79- < div className = 'lg:flex' >
80- < div className = 'md:flex md:space-x-4 lg:w-1/2' >
81- < HeadlineStat title = 'New players' stat = { headlines . new_players . count } />
82- < HeadlineStat title = 'Returning players' stat = { headlines . returning_players . count } />
83- </ div >
84- < div className = 'md:flex md:space-x-4 lg:w-1/2 lg:ml-4' >
85- < HeadlineStat title = 'New events' stat = { headlines . events . count } />
86- < HeadlineStat title = 'Unique event submitters' stat = { headlines . unique_event_submitters . count } />
87- </ div >
87+ < h2 className = 'text-2xl' > Global stats</ h2 >
88+
89+ { statsError &&
90+ < ErrorMessage error = { { message : 'Couldn\'t fetch stats' } } />
91+ }
92+
93+ { ! statsLoading &&
94+ < div className = 'grid md:grid-cols-2 lg:grid-cols-4 gap-4' >
95+ { stats . filter ( ( stat ) => stat . global ) . map ( ( stat ) => (
96+ < HeadlineStat key = { stat . id } title = { stat . name } stat = { stat . globalValue } />
97+ ) ) }
8898 </ div >
8999 }
90100
91101 { canViewPage ( user , routes . activity ) &&
92- < div className = 'mt-8 ' >
102+ < div className = '!mb-24 ' >
93103 < h2 className = 'text-2xl mt-4 mb-2 md:mt-0' > Activity</ h2 >
94104 < Link to = { routes . activity } > Go to activity log</ Link >
95105 </ div >
96106 }
97- </ div >
107+ </ Page >
98108 )
99109}
100110
0 commit comments