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
+26 -18
View File
@@ -1,23 +1,31 @@
import { StateUpdater } from 'preact/hooks'
import { JSX } from 'preact/jsx-runtime'
type Props = {
options: Record<string, string>
value: string
setValue?: StateUpdater<string>
type Props<K extends string, T extends K> = {
options: Record<K, string | JSX.Element>
value: T
setValue?: StateUpdater<K>
}
export const Select = ({ options, value, setValue }: Props) => (
<div class="input-select">
<select
onInput={e => setValue?.(e.target instanceof HTMLSelectElement ? e.target.value : '')}
>
{Object.entries(options).map(([k, v]) => (
<option value={k} selected={value === k}>
{v}
</option>
))}
</select>
<span class="material-symbols-outlined">expand_more</span>
</div>
)
export const Select = <K extends string, T extends K>({ options, value, setValue }: Props<K, T>) => {
const optionValues = new Set(Object.keys(options))
return (
<div class="input-select">
<select
onInput={e => {
if (e.target instanceof HTMLSelectElement && optionValues.has(e.target.value)) {
setValue?.(e.target.value as K)
}
}}
>
{Object.entries<string | JSX.Element>(options).map(([k, v]) => (
<option value={k} selected={value === k}>
{v}
</option>
))}
</select>
<span class="material-symbols-outlined">expand_more</span>
</div>
)
}
+41 -18
View File
@@ -1,3 +1,4 @@
import { useState } from 'preact/hooks'
import { JSX } from 'preact/jsx-runtime'
import {
MetadataProps,
@@ -19,6 +20,7 @@ const STATUS_SELECT_OPTIONS: Record<SolutionStatus, JSX.Element> = {
type Props = {
id: SolutionId
createdAt: string
sentBy?: UserId
forProblem: ProblemId
content: string
@@ -31,6 +33,7 @@ type Props = {
export const Solution = ({
id,
createdAt,
sentBy,
forProblem,
content,
@@ -70,6 +73,14 @@ export const Solution = ({
refreshSolution?.()
}
const [viewRaw, setViewRaw] = useState<boolean>(false)
const toggleViewRaw = () => {
setViewRaw(prev => !prev)
}
const d = new Date(createdAt)
return (
<div class={['solution', status].join(' ')}>
<div class="solution-header">
@@ -87,35 +98,38 @@ export const Solution = ({
per il <a href={`/problem/${forProblem}`}>Problema {forProblem}</a>
</>
)}
{!isNaN(d as any) && (
<>
{' del '}
<span title={!isNaN(d as any) ? d.toISOString() : undefined} class="dotted">
{d.getFullYear()}/{d.getMonth().toString().padStart(2, '0')}/
{d.getDate().toString().padStart(2, '0')}{' '}
{d.getHours().toString().padStart(2, '0')}:
{d.getMinutes().toString().padStart(2, '0')}
</span>
</>
)}
</div>
</div>
<div class="solution-content">
<Markdown source={content} />
{viewRaw ? (
<pre>
<code>{content}</code>
</pre>
) : (
<Markdown source={content} />
)}
</div>
{status && (
<div class="solution-footer">
{/* <div class="row">
<div class="label">Stato</div>
<Select value={status} options={STATUS_SELECT_OPTIONS} />
</div> */}
<div class="row">
<div class="status-label">{STATUS_SELECT_OPTIONS[status]}</div>
{adminControls && (
<>
<button
disabled={status === 'correct'}
class="icon"
onClick={markAsCorrect}
>
<span class="material-symbols-outlined correct">
check_circle
</span>
<button disabled={status === 'correct'} class="icon" onClick={markAsCorrect}>
<span class="material-symbols-outlined correct">check_circle</span>
</button>
<button
disabled={status === 'wrong'}
class="icon"
onClick={markAsWrong}
>
<button disabled={status === 'wrong'} class="icon" onClick={markAsWrong}>
<span class="material-symbols-outlined wrong">cancel</span>
</button>
{status !== 'pending' && (
@@ -127,6 +141,15 @@ export const Solution = ({
)}
</>
)}
<button
class="icon"
onClick={toggleViewRaw}
title={!viewRaw ? 'Mostra markdown grezzo' : 'Mostra testo matematicoso'}
>
<span class="material-symbols-outlined">
{!viewRaw ? 'data_object' : 'functions'}
</span>
</button>
</div>
</div>
)}