all: Aggiunte varie feature e riscritte svariate cose
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
import { route } from 'preact-router'
|
||||
import { useContext, useEffect, useState } from 'preact/hooks'
|
||||
import { isAdministrator, Problem as ProblemModel, Solution as SolutionModel } from '../../shared/model'
|
||||
import { prependBaseUrl, server } from '../api'
|
||||
import { Header } from '../components/Header'
|
||||
import { MarkdownEditor } from '../components/MarkdownEditor'
|
||||
import { Problem } from '../components/Problem'
|
||||
import { Solution } from '../components/Solution'
|
||||
import { MetadataContext, useListResource, useResource } from '../hooks'
|
||||
import { useCurrentUser } from '../hooks/useCurrentUser'
|
||||
|
||||
type RouteProps = {
|
||||
id: string
|
||||
}
|
||||
|
||||
export const ProblemPage = ({ id }: RouteProps) => {
|
||||
const metadata = useContext(MetadataContext)
|
||||
metadata.title = `Problem ${id}`
|
||||
metadata.description = 'Bacheca di problemi del PHC'
|
||||
|
||||
const [user] = useCurrentUser()
|
||||
|
||||
const [source, setSource] = useState('')
|
||||
|
||||
const [problem, refreshProblem] = useResource<ProblemModel | null>(`/api/problem/${id}`, null, problem => {
|
||||
if (problem === null) {
|
||||
route(prependBaseUrl('/'))
|
||||
}
|
||||
})
|
||||
|
||||
const [solutions, refreshSolutions, setSolutionHeuristic] = useListResource<SolutionModel>(`/api/solutions?problem=${id}`)
|
||||
const userSolutions: [number, SolutionModel][] = solutions.flatMap((s, index) => (user && s.sentBy === user.id ? [[index, s]] : []))
|
||||
const otherSolutions: [number, SolutionModel][] = solutions.flatMap((s, index) => (user && s.sentBy !== user.id ? [[index, s]] : []))
|
||||
|
||||
const notLoggedSolutions: [number, SolutionModel][] = user ? [] : solutions.map((s, index) => [index, s])
|
||||
|
||||
const sendSolution = async () => {
|
||||
if (source.trim().length === 0) {
|
||||
alert('La soluzione che hai inserito è vuota!')
|
||||
return
|
||||
}
|
||||
|
||||
await server.post('/api/solution', {
|
||||
forProblem: id,
|
||||
content: source,
|
||||
})
|
||||
|
||||
setSource('')
|
||||
|
||||
refreshSolutions()
|
||||
}
|
||||
|
||||
const [editing, setEditing] = useState<boolean>(false)
|
||||
const [modifiedProblemSource, setModifiedProblemSource] = useState<string>('')
|
||||
|
||||
useEffect(() => {
|
||||
if (problem) {
|
||||
setModifiedProblemSource(problem.content)
|
||||
}
|
||||
}, [problem?.content])
|
||||
|
||||
const updateProblem = async () => {
|
||||
await server.patch(`/api/problem/${id}`, {
|
||||
content: modifiedProblemSource,
|
||||
})
|
||||
refreshProblem()
|
||||
setEditing(false)
|
||||
}
|
||||
|
||||
const deleteProblem = async () => {
|
||||
if (confirm('Sei veramente sicuro di voler eliminare questo problema?')) {
|
||||
await server.delete(`/api/problem/${id}`)
|
||||
route(prependBaseUrl('/'))
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main class="page-problem">
|
||||
<div class="subtitle">Testo del problema</div>
|
||||
{!editing ? (
|
||||
<>
|
||||
{problem && <Problem {...problem} />}
|
||||
{user && isAdministrator(user.role) && (
|
||||
<>
|
||||
<button onClick={() => setEditing(true)}>Modifica problema</button>
|
||||
<button onClick={() => deleteProblem()}>Elimina problema</button>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<MarkdownEditor
|
||||
placeholder="Modifica testo del problema..."
|
||||
source={modifiedProblemSource}
|
||||
setSource={setModifiedProblemSource}
|
||||
/>
|
||||
<div class="col">
|
||||
<button onClick={() => updateProblem()}>Aggiorna problema</button>
|
||||
<button onClick={() => setEditing(false)}>Annulla</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{userSolutions.length > 0 && (
|
||||
<details open>
|
||||
<summary>Le tue soluzioni</summary>
|
||||
<div class="solution-list">
|
||||
{userSolutions.map(([index, s]) => (
|
||||
<Solution
|
||||
{...s}
|
||||
adminControls={user !== null && isAdministrator(user.role)}
|
||||
refreshSolution={refreshSolutions}
|
||||
setSolution={solFn => setSolutionHeuristic(index, solFn)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</details>
|
||||
)}
|
||||
{otherSolutions.length > 0 && (
|
||||
<details>
|
||||
<summary>Altre soluzioni</summary>
|
||||
<div class="solution-list">
|
||||
{otherSolutions.map(([index, s]) => (
|
||||
<Solution
|
||||
{...s}
|
||||
adminControls={user !== null && isAdministrator(user.role)}
|
||||
refreshSolution={refreshSolutions}
|
||||
setSolution={solFn => setSolutionHeuristic(index, solFn)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</details>
|
||||
)}
|
||||
{notLoggedSolutions.length > 0 && (
|
||||
<details>
|
||||
<summary>Soluzioni</summary>
|
||||
<div class="solution-list">
|
||||
{notLoggedSolutions.map(([index, s]) => (
|
||||
<Solution
|
||||
{...s}
|
||||
adminControls={user !== null && isAdministrator(user.role)}
|
||||
refreshSolution={refreshSolutions}
|
||||
setSolution={solFn => setSolutionHeuristic(index, solFn)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</details>
|
||||
)}
|
||||
{user && (
|
||||
<>
|
||||
<hr />
|
||||
<div class="subtitle">Invia una soluzione al problema</div>
|
||||
<MarkdownEditor placeholder="Scrivi una soluzione al problema..." {...{ source, setSource }} />
|
||||
<button onClick={sendSolution}>Invia Soluzione</button>
|
||||
<p class="icon-text">
|
||||
<span class="material-symbols-outlined">warning</span>
|
||||
Attenzione, una soluzione inviata non può essere modificata!
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user