guesstimate/client/src/routes/home/index.tsx

110 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { FunctionComponent, MouseEvent, useCallback, useState } from "react";
import style from "./style.module.css";
import { useHistory } from 'react-router';
import { base58UUID } from '../../util/uuid';
import { useStoredProjectList } from "../../hooks/use-stored-project-list";
import { formatDate } from "../../util/date";
import { Direction, useSort } from "../../hooks/useSort";
const Home: FunctionComponent = () => {
const [projects] = useStoredProjectList()
const [sortingKey, setSortingKey] = useState('updatedAt')
const [sortingDirection, setSortingDirection] = useState<Direction>(Direction.DESC)
const sortedProjects = useSort(projects, sortingKey, sortingDirection)
const history = useHistory()
const openNewProject = () => {
const uuid = base58UUID()
history.push(`/p/${uuid}`)
};
const openProject = useCallback((evt: MouseEvent<HTMLTableRowElement>) => {
const projectId = evt.currentTarget.dataset.projectId;
history.push(`/p/${projectId}`)
}, [])
const sortBy = useCallback((evt: MouseEvent<HTMLTableCellElement>) => {
const key = evt.currentTarget.dataset.sortKey
if (!key) return
if (sortingKey !== key) {
setSortingKey(key)
return
}
setSortingDirection(sortingDirection => -sortingDirection)
}, [sortingKey, sortingDirection])
return (
<div className={`container ${style.home}`}>
<div className="columns">
<div className="column">
<div className="buttons is-right">
<button className="button is-primary is-medium"
onClick={openNewProject}>
<strong>+</strong>&nbsp;&nbsp;Nouveau projet
</button>
</div>
<div className="box">
<div className="table-container">
<table className="table is-fullwidth is-hoverable">
<thead>
<tr className="is-size-5">
<TableHeader onClick={sortBy} label="Projet" isCurrentSortingKey={sortingKey === 'label'} sortingDirection={sortingDirection} sortingKey="label" />
<TableHeader onClick={sortBy} label="Mis à jour le" isCurrentSortingKey={sortingKey === 'updatedAt'} sortingDirection={sortingDirection} sortingKey="updatedAt" />
</tr>
</thead>
<tbody>
{
sortedProjects.map(p => (
<tr
key={`project-${p.id}`}
data-project-id={p.id}
onClick={openProject}
className="is-clickable">
<td>
<span className="mr-3">🗒</span>
{p.label ? p.label : "Projet sans nom"}
</td>
<td>
{p.updatedAt ? formatDate(p.updatedAt) : "--"}
</td>
</tr>
))
}
{
projects.length === 0 ?
<tr className={style.noProjects}>
<td colSpan={2}>
Aucun project pour l'instant.
</td>
</tr> :
null
}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
);
};
interface TableHeaderProps {
onClick?: React.MouseEventHandler<HTMLTableCellElement>
sortingKey: string
isCurrentSortingKey: boolean
sortingDirection: Direction
label: string
}
const TableHeader: FunctionComponent<TableHeaderProps> = ({ onClick, isCurrentSortingKey, sortingKey, label, sortingDirection }) => {
return (
<th className="is-clickable" onClick={onClick} data-sort-key={sortingKey}>{label}<span className={`ml-1 ${!isCurrentSortingKey ? 'is-hidden' : ''}`}>{sortingDirection === Direction.ASC ? '' : ''}</span></th>
)
}
export default Home;