112 lines
4.1 KiB
TypeScript
112 lines
4.1 KiB
TypeScript
import React, { FunctionComponent, MouseEvent, useCallback, useEffect, 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, useKeySort, useSort } from "../../hooks/useSort";
|
||
import { useTitle } from "../../hooks/use-title";
|
||
|
||
const Home: FunctionComponent = () => {
|
||
useTitle('Accueil')
|
||
|
||
const [projects] = useStoredProjectList()
|
||
const [sortingKey, setSortingKey] = useState('updatedAt')
|
||
const [sortingDirection, setSortingDirection] = useState<Direction>(Direction.DESC)
|
||
const sortedProjects = useKeySort(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> 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;
|