|
import {Topic} from "../../utils/topics"; |
|
import {Layout} from "../layout"; |
|
import {Spinner} from "../spinner"; |
|
import style from "./style.module.scss"; |
|
import {Route, routes, RouteSetter} from "../../utils/route"; |
|
import {Button} from "../button"; |
|
import {Input} from "../input"; |
|
import {Link, Thermometer, Sliders} from "preact-feather"; |
|
import {Settings as SettingsType, Settings} from "../../utils/settings"; |
|
import {useMemo, useState} from "preact/hooks"; |
|
import {frenchToIso8601, iso8601ToFrench} from "../../utils/dates"; |
|
import {FormGroup} from "../form"; |
|
import {Slider} from "../slider"; |
|
import cn from "classnames"; |
|
|
|
export function Topics(props: { |
|
topics: Topic[] | null, |
|
setRoute: RouteSetter, |
|
settings: Settings, |
|
setSettings: (settings: SettingsType) => void, |
|
generateTopic: (postCount: number) => Promise<void>, |
|
pendingGeneration: boolean, |
|
latestGeneratedTopicId: string | null, |
|
}) { |
|
|
|
|
|
const sortedTopics = useMemo(() => { |
|
if (props.topics === null || props.topics.length < 1) { |
|
return props.topics; |
|
} |
|
|
|
return props.topics.sort((topicA, topicB) => { |
|
if (topicA.posts.length < 1 || topicB.posts.length < 1) { |
|
return 0; |
|
} |
|
return topicB.posts[topicB.posts.length - 1].date.localeCompare(topicA.posts[topicA.posts.length - 1].date); |
|
}); |
|
}, [props.topics]); |
|
|
|
return ( |
|
<div> |
|
{ |
|
sortedTopics === null ? |
|
<Spinner className={style.spinner}/> : |
|
<List topics={sortedTopics} setRoute={props.setRoute} |
|
latestGeneratedTopicId={props.latestGeneratedTopicId}/> |
|
} |
|
<div> |
|
<h2>Nouveau sujet</h2> |
|
<div className={style.generationSettings}> |
|
<FormGroup> |
|
<label for="postCount">Nombre de posts</label> |
|
<Slider |
|
name="postCount" |
|
value={props.settings.postCount} |
|
onChange={(v) => props.setSettings({...props.settings, postCount: v})} |
|
min={1} |
|
max={10} |
|
step={1} |
|
/> |
|
</FormGroup> |
|
</div> |
|
<Button |
|
onClick={() => props.generateTopic(props.settings.postCount)} |
|
secondary={true} |
|
loading={props.pendingGeneration} |
|
> |
|
Générer |
|
</Button> |
|
</div> |
|
<hr/> |
|
</div> |
|
) |
|
} |
|
|
|
function List(props: { |
|
topics: Topic[], |
|
setRoute: RouteSetter, |
|
latestGeneratedTopicId: string | null, |
|
}) { |
|
return ( |
|
<ul className={style.list}> |
|
<li className={style.head}> |
|
<span>Sujet</span> |
|
<span>Auteur</span> |
|
<span>NB</span> |
|
<span>Dernier msg</span> |
|
</li> |
|
{props.topics.length < 1 && <li><span>Aucun sujet</span><span></span><span></span><span></span></li>} |
|
{props.topics.map(topic => ( |
|
<li className={cn({[style.highlight]: topic.id === props.latestGeneratedTopicId})}> |
|
<span> |
|
<a href="#" onClick={(e) => { |
|
e.preventDefault(); |
|
props.setRoute(routes.topic, 0, topic.id); |
|
}}> |
|
{topic.title} |
|
</a> |
|
</span> |
|
<span>{topic.posts[0].user}</span> |
|
<span>{topic.posts.length}</span> |
|
<span>{iso8601ToFrench(topic.posts[topic.posts.length - 1].date)}</span> |
|
</li> |
|
))} |
|
</ul> |
|
) |
|
} |