Full refactor to Typescript

This commit is contained in:
2022-11-17 19:19:33 +01:00
parent de3f10b3ee
commit ffd3c99292
19 changed files with 180 additions and 95 deletions
@@ -1,12 +1,18 @@
import { Link } from 'preact-router/match'
import { isAdministrator, USER_ROLE_ADMIN, USER_ROLE_MODERATOR } from '../../shared/constants.js'
import { isAdministrator, User, UserRole } from '../../shared/model'
const ROLE_LABEL = {
[USER_ROLE_ADMIN]: 'Admin',
[USER_ROLE_MODERATOR]: 'Moderatore',
const ROLE_LABEL: Record<UserRole, string> = {
['admin']: 'Admin',
['moderator']: 'Moderatore',
['student']: 'Studente',
}
export const Header = ({ user, noLogin }) => (
type Props = {
user?: User | null
noLogin?: boolean
}
export const Header = ({ user, noLogin }: Props) => (
<header>
<div class="logo">
<a href="/">PHC / Problemi</a>
@@ -7,7 +7,7 @@ import remarkRehype from 'remark-rehype'
import rehypeKatex from 'rehype-katex'
import rehypeStringify from 'rehype-stringify'
async function renderMarkdownAsync(source) {
async function renderMarkdownAsync(source: string) {
return await unified()
.use(remarkParse)
.use(remarkMath)
@@ -29,13 +29,15 @@ async function renderMarkdownAsync(source) {
// .processSync(source)
// }
export const Markdown = ({ source }) => {
const elementRef = useRef()
export const Markdown = ({ source }: { source: string }) => {
const elementRef = useRef<HTMLDivElement>(null)
useEffect(async () => {
if (elementRef.current) {
elementRef.current.innerHTML = await renderMarkdownAsync(source)
}
useEffect(() => {
renderMarkdownAsync(source).then(data => {
if (elementRef.current) {
elementRef.current.innerHTML = data.toString()
}
})
}, [source])
return <div class="markdown" ref={elementRef}></div>
@@ -1,8 +1,14 @@
import { useEffect, useRef } from 'preact/hooks'
import { Markdown } from './Markdown.jsx'
import { Component, JSX } from 'preact'
import { StateUpdater, useEffect, useRef } from 'preact/hooks'
import { Markdown } from './Markdown'
export const MarkdownEditor = ({ source, setSource }) => {
const editorRef = useRef()
type Props = {
source: string
setSource: StateUpdater<string>
}
export const MarkdownEditor = ({ source, setSource }: Props) => {
const editorRef = useRef<HTMLTextAreaElement>(null)
useEffect(() => {
if (editorRef.current) {
@@ -22,9 +28,11 @@ export const MarkdownEditor = ({ source, setSource }) => {
<div class="editor">
<h1>Editor</h1>
<textarea
onInput={e => setSource(e.target.value)}
onInput={e =>
setSource(e.target instanceof HTMLTextAreaElement ? e.target.value : '')
}
value={source}
cols="60"
cols={60}
ref={editorRef}
placeholder="Scrivi una nuova soluzione..."
></textarea>
@@ -1,6 +1,12 @@
import { Markdown } from './Markdown.jsx'
import { Markdown } from './Markdown'
export const Problem = ({ id, content, solutionsCount }) => {
type Props = {
id: string
content: string
solutionsCount?: number
}
export const Problem = ({ id, content, solutionsCount }: Props) => {
return (
<div class="problem">
<div class="problem-header">
@@ -11,7 +17,7 @@ export const Problem = ({ id, content, solutionsCount }) => {
<div class="problem-content">
<Markdown source={content} />
</div>
{solutionsCount > 0 && (
{solutionsCount && solutionsCount > 0 && (
<div class="problem-footer">
{solutionsCount} soluzion{solutionsCount === 1 ? 'e' : 'i'}
</div>
-12
View File
@@ -1,12 +0,0 @@
export const Select = ({ options, value, setValue }) => (
<div class="input-select">
<select onInput={e => setValue?.(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>
)
+23
View File
@@ -0,0 +1,23 @@
import { StateUpdater } from 'preact/hooks'
import { JSX } from 'preact/jsx-runtime'
type Props = {
options: Record<string, string>
value: string
setValue?: StateUpdater<string>
}
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>
)
@@ -1,25 +1,29 @@
import { refToUserId } from '../../shared/db-refs.js'
import { Markdown } from './Markdown.jsx'
import { ProblemId, SolutionStatus, UserId } from '../../shared/model'
import { Markdown } from './Markdown'
export const Solution = ({ sentBy, forProblem, content }) => {
const userId = refToUserId(sentBy)
const problemId = refToUserId(forProblem)
type Props = {
sentBy?: UserId
forProblem: ProblemId
content: string
status?: SolutionStatus
}
export const Solution = ({ sentBy, forProblem, content }: Props) => {
return (
<div class="solution">
<div class="solution-header">
<div>
Soluzione
{userId && (
{sentBy && (
<>
{' '}
di <a href={`/user/${userId}`}>@{userId}</a>
di <a href={`/user/${sentBy}`}>@{sentBy}</a>
</>
)}
{problemId && (
{forProblem && (
<>
{' '}
per il <a href={`/problem/${problemId}`}>Problema {problemId}</a>
per il <a href={`/problem/${forProblem}`}>Problema {forProblem}</a>
</>
)}
</div>