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

112 lines
4.0 KiB
TypeScript
Raw Normal View History

2023-09-01 06:11:13 +02:00
import React, { FunctionComponent, MouseEvent, useCallback, useEffect, useState } from "react";
2020-04-22 22:07:52 +02:00
import style from "./style.module.css";
2020-07-09 13:00:42 +02:00
import { useHistory } from 'react-router';
2020-04-20 11:14:46 +02:00
import { base58UUID } from '../../util/uuid';
2020-04-20 14:07:26 +02:00
import { useStoredProjectList } from "../../hooks/use-stored-project-list";
import { formatDate } from "../../util/date";
import { Direction, useSort } from "../../hooks/useSort";
2023-09-01 06:11:13 +02:00
import { useTitle } from "../../hooks/use-title";
2020-04-20 11:14:46 +02:00
2020-07-09 13:00:42 +02:00
const Home: FunctionComponent = () => {
2023-09-01 06:11:13 +02:00
useTitle('Accueil')
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>
2020-04-20 11:14:46 +02:00
</div>
</div>
2020-04-20 11:14:46 +02:00
</div>
</div>
</div>
);
2020-04-20 11:14:46 +02:00
};
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>
)
}
2020-04-20 11:14:46 +02:00
export default Home;