import { useEffect, useState } from 'preact/hooks' import { Funnel } from '@phosphor-icons/react' import { marked } from 'marked' // @ts-ignore import extendedLatex from 'marked-extended-latex' marked.use( extendedLatex({ lazy: false, render: (formula: string, display: boolean) => { return display ? '$$' + formula + '$$' : '$' + formula + '$' }, }), ) import type { Database } from '@/data/domande-esami.yaml' const useRemoteValue = <T,>(url: string): T | null => { const [value, setValue] = useState<T | null>(null) useEffect(() => { fetch(url) .then(response => response.json()) .then(value => setValue(value)) .catch(error => console.error(error)) }, [url]) return value } type Props = { course: string } export const DomandeEsamiCourse = ({ course }: Props) => { const database = useRemoteValue<Database>(`/domande-esami/api/${course}.json`) if (!database) { return <>Loading...</> } if ('requestIdleCallback' in window) { // @ts-ignore requestIdleCallback(() => window.renderMath()) } else { // @ts-ignore setTimeout(() => window.renderMath(), 100) } const courseTags = [ ...new Set( database.questions.filter(question => question.course === course).flatMap(question => question.tags), ), ] const [selectedTag, setSelectedTag] = useState<string | null>(null) const filteredQuestions = database.questions .filter(question => question.course === course) .filter(question => (selectedTag ? question.tags.includes(selectedTag) : true)) return ( <> <div class="grid-center"> <h3> <a href="/domande-esami">Domande Esami</a> </h3> <h1>{database.names[course]}</h1> </div> {courseTags.length > 1 && ( <div class="card filter"> <div class="grid-h"> <Funnel /> <strong>Filtra Tag</strong> </div> <div class="flex-row-wrap"> {!selectedTag ? courseTags.map(tag => ( <div class="chip clickable" onClick={() => setSelectedTag(tag)}> {tag} </div> )) : courseTags.map(tag => ( <div class={tag === selectedTag ? 'chip clickable' : 'chip clickable disabled'} onClick={() => setSelectedTag(tag === selectedTag ? null : tag)} > {tag} </div> ))} </div> </div> )} <div class="wide-card-list" id="questions"> {filteredQuestions.length === 0 ? ( <div class="grid-center"> <em>No questions found</em> </div> ) : ( filteredQuestions.map(question => ( <div class="card"> <div class="text" dangerouslySetInnerHTML={{ __html: marked(question.content, { async: false }), }} /> <div class="metadata"> {question.tags.map(tag => ( <div class="chip small">{tag}</div> ))} </div> </div> )) )} </div> </> ) }