import { useContext, useState } from 'preact/hooks' import { SolutionStat } from '../../shared/model' import { sortByNumericKey, sortByStringKey } from '../../shared/utils' import { prependBaseUrl } from '../api' import { Header } from '../components/Header' import { useResource, MetadataContext } from '../hooks' export const ScoresPage = () => { const metadata = useContext(MetadataContext) metadata.title = `PHC Problemi` metadata.description = 'Bacheca di problemi del PHC' const [stats] = useResource<Record<string, SolutionStat>>(`/api/stats`, {}) type Column = 'student' | 'sent' | 'correct' type Order = 'ascending' | 'descending' type SortStateSpace = [Column, Order] const [[sortStateColumn, sortStateOrder], setSortState] = useState<SortStateSpace>(['correct', 'descending']) const transitionColumn: (k: Column) => Partial<Record<Column, Record<Order, (c: Column) => SortStateSpace>>> = k => ({ [k]: { ascending: (c: Column) => (c === k ? [k, 'descending'] : [c, 'ascending']), descending: (c: Column) => (c === k ? [k, 'ascending'] : [c, 'ascending']), }, }) const transitionMap: Record<Column, Record<Order, (c: Column) => SortStateSpace>> = { ...(transitionColumn('student') as Record<'student', Record<Order, (c: Column) => SortStateSpace>>), ...(transitionColumn('sent') as Record<'sent', Record<Order, (c: Column) => SortStateSpace>>), ...(transitionColumn('correct') as Record<'correct', Record<Order, (c: Column) => SortStateSpace>>), } let orderedStats if (sortStateColumn === 'student') { orderedStats = sortByStringKey(Object.entries(stats), ([user, s]) => user, sortStateOrder === 'ascending') } else { orderedStats = sortByNumericKey( Object.entries(stats), // @ts-ignore ([user, s]) => s[sortStateColumn + 'SolutionsCount'], sortStateOrder === 'ascending' ) } return ( <> <Header /> <main class="page-scores"> <div class="subtitle">Classifica</div> <div class="scrollable"> <div class="table"> <div class="cell header"> <span>Studente</span> <span onClick={() => setSortState(transitionMap[sortStateColumn][sortStateOrder]('student'))}> <span class="material-symbols-outlined icon"> {sortStateColumn === 'student' ? sortStateOrder === 'ascending' ? 'expand_more' : 'expand_less' : 'unfold_more'} </span> </span> </div> <div class="cell header"> <span>Soluzioni Inviate</span> <span onClick={() => setSortState(transitionMap[sortStateColumn][sortStateOrder]('sent'))}> <span class="material-symbols-outlined icon"> {sortStateColumn === 'sent' ? sortStateOrder === 'ascending' ? 'expand_more' : 'expand_less' : 'unfold_more'} </span> </span> </div> <div class="cell header"> <span>Soluzioni Corrette</span> <span onClick={() => setSortState(transitionMap[sortStateColumn][sortStateOrder]('correct'))}> <span class="material-symbols-outlined icon"> {sortStateColumn === 'correct' ? sortStateOrder === 'ascending' ? 'expand_more' : 'expand_less' : 'unfold_more'} </span> </span> </div> {orderedStats.map(([user, s]) => ( <> <div class="cell"> <a href={prependBaseUrl(`/u/${user}`)}>@{user}</a> </div> <div class="cell">{s.sentSolutionsCount}</div> <div class="cell">{s.correctSolutionsCount}</div> </> ))} </div> </div> </main> </> ) }