feature: Problem sorting, solution view raw toggle button

This commit is contained in:
2022-11-23 19:08:29 +01:00
parent dcaa052f30
commit 28a1a85531
9 changed files with 222 additions and 70 deletions
+48 -14
View File
@@ -1,9 +1,11 @@
import { route } from 'preact-router'
import { useState } from 'preact/hooks'
import { isAdministrator, isStudent, Solution as SolutionModel } from '../../shared/model'
import { isAdministrator, isStudent, Solution as SolutionModel, SolutionId } from '../../shared/model'
import { sortByStringKey } from '../../shared/utils'
import { server } from '../api'
import { Header } from '../components/Header'
import { MarkdownEditor } from '../components/MarkdownEditor'
import { Select } from '../components/Select'
import { Solution } from '../components/Solution'
import { useCurrentUser, useListResource, useResource } from '../hooks'
@@ -25,6 +27,8 @@ const CreateProblem = ({}) => {
)
}
type SortOrder = 'latest' | 'oldest'
export const AdminPage = ({}) => {
const [user] = useCurrentUser(user => {
if (!user) {
@@ -37,26 +41,56 @@ export const AdminPage = ({}) => {
const [solutions, refreshSolutions, setSolutionHeuristic] =
useListResource<SolutionModel>(`/api/solutions`)
const [sortOrder, setSortOrder] = useState<SortOrder>('oldest')
const sortedSolutions = sortByStringKey(solutions, s => s.createdAt, sortOrder === 'oldest')
const [trackInteracted, setTrackedInteracted] = useState<Set<SolutionId>>(new Set())
const hasUntrackedPending =
sortedSolutions.filter(s => s.status === 'pending' || trackInteracted.has(s.id)).length > 0
return (
user && (
<main class="page-admin">
<Header {...{ user }} />
<div class="subtitle">Nuovo problema</div>
<CreateProblem />
<div class="subtitle">Soluzioni ancora da approvare/rifiutare</div>
<div class="solution-list">
{solutions.map(
(s, index) =>
s.status === 'pending' && (
<Solution
adminControls
{...s}
setSolution={solFn => setSolutionHeuristic(index, solFn)}
refreshSolution={refreshSolutions}
<div class="subtitle">Soluzioni da correggere</div>
{hasUntrackedPending ? (
<div class="solution-list">
<div class="controls">
<div class="sort-order">
<Select
value={sortOrder}
setValue={setSortOrder}
options={{
latest: 'Prima più recenti',
oldest: 'Prima più antichi',
}}
/>
)
)}
</div>
</div>
</div>
{sortedSolutions.map(
(s, index) =>
(s.status === 'pending' || trackInteracted.has(s.id)) && (
<Solution
adminControls
{...s}
setSolution={solFn => {
setTrackedInteracted(prev => new Set([...prev, s.id]))
setSolutionHeuristic(index, solFn)
}}
refreshSolution={refreshSolutions}
/>
)
)}
</div>
) : (
<>
<em>Nessuna soluzione ancora da correggere</em>
</>
)}
</main>
)
)
+28 -4
View File
@@ -1,17 +1,40 @@
import { route } from 'preact-router'
import { useEffect, useState } from 'preact/hooks'
import { Problem as ProblemModel } from '../../shared/model'
import { sortByNumericKey, sortByStringKey } from '../../shared/utils'
import { Header } from '../components/Header'
import { Problem } from '../components/Problem'
import { Select } from '../components/Select'
import { useResource, useCurrentUser } from '../hooks'
function byTime(p: ProblemModel): string {
return p.createdAt
}
function bySolvedProblems(p: ProblemModel & { solutionsCount: number }): number {
return p.solutionsCount
}
type SortOrder = 'latest' | 'oldest' | 'top-solved' | 'least-solved'
const SORT_ORDER: Record<SortOrder, boolean> = {
'latest': false,
'oldest': true,
'top-solved': false,
'least-solved': true,
}
export const HomePage = () => {
const [user] = useCurrentUser()
const [problems] = useResource<ProblemModel[]>('/api/problems', [])
const [problems] = useResource<(ProblemModel & { solutionsCount: number })[]>('/api/problems', [])
console.log(problems)
const [sortOrder, setSortOrder] = useState<SortOrder>('oldest')
const sortedProblems =
sortOrder === 'latest' || sortOrder === 'oldest'
? sortByStringKey(problems, byTime, SORT_ORDER[sortOrder])
: sortByNumericKey(problems, bySolvedProblems, SORT_ORDER[sortOrder])
return (
<main class="page-home">
@@ -20,7 +43,8 @@ export const HomePage = () => {
<div class="fill-row board-controls">
<div class="sort-order">
<Select
value="oldest"
value={sortOrder}
setValue={setSortOrder}
options={{
'latest': 'Prima più recenti',
'oldest': 'Prima più antichi',
@@ -31,7 +55,7 @@ export const HomePage = () => {
</div>
</div>
{problems.map(p => (
{sortedProblems.map(p => (
<Problem {...p} />
))}
</div>
+3 -5
View File
@@ -1,9 +1,5 @@
import { useContext, useState } from 'preact/hooks'
import {
isAdministrator,
Problem as ProblemModel,
Solution as SolutionModel,
} from '../../shared/model'
import { isAdministrator, Problem as ProblemModel, Solution as SolutionModel } from '../../shared/model'
import { server } from '../api'
import { Header } from '../components/Header'
import { MarkdownEditor } from '../components/MarkdownEditor'
@@ -37,6 +33,8 @@ export const ProblemPage = ({ id }: RouteProps) => {
content: source,
})
setSource('')
refreshSolutions()
}