Update homepage to use filters.
This commit is contained in:
parent
6e85edbf05
commit
90d18311fb
8 changed files with 552 additions and 21 deletions
|
|
@ -25,6 +25,8 @@ import {
|
|||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogActions,
|
||||
TableSortLabel,
|
||||
Tooltip,
|
||||
} from '@mui/material'
|
||||
import { Delete as DeleteIcon } from '@mui/icons-material'
|
||||
import { useTasks } from '~/hooks/useTasks'
|
||||
|
|
@ -122,6 +124,19 @@ export function TaskList({ className, initialTasks }: TaskListProps) {
|
|||
return `${Math.floor(diffInDays / 365)}y ago`
|
||||
}
|
||||
|
||||
const formatFullTimestamp = (dateString: string) => {
|
||||
const date = new Date(dateString)
|
||||
return date.toLocaleString(undefined, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
timeZoneName: 'short',
|
||||
})
|
||||
}
|
||||
|
||||
const handleSelectAll = (checked: boolean) => {
|
||||
if (checked) {
|
||||
setSelectedTaskIds(new Set(filteredAndSortedTasks.map(task => task.id)))
|
||||
|
|
@ -165,6 +180,43 @@ export function TaskList({ className, initialTasks }: TaskListProps) {
|
|||
}
|
||||
}
|
||||
|
||||
const handleSort = (field: string) => {
|
||||
let newSortBy: SortOption
|
||||
|
||||
switch (field) {
|
||||
case 'title':
|
||||
newSortBy = sortBy === 'title_asc' ? 'title_desc' : 'title_asc'
|
||||
break
|
||||
case 'status':
|
||||
newSortBy = 'status'
|
||||
break
|
||||
case 'created':
|
||||
newSortBy = sortBy === 'created_asc' ? 'created_desc' : 'created_asc'
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
setSortBy(newSortBy)
|
||||
}
|
||||
|
||||
const getSortDirection = (field: string): 'asc' | 'desc' | false => {
|
||||
switch (field) {
|
||||
case 'title':
|
||||
if (sortBy === 'title_asc') return 'asc'
|
||||
if (sortBy === 'title_desc') return 'desc'
|
||||
return false
|
||||
case 'status':
|
||||
return sortBy === 'status' ? 'asc' : false
|
||||
case 'created':
|
||||
if (sortBy === 'created_asc') return 'asc'
|
||||
if (sortBy === 'created_desc') return 'desc'
|
||||
return false
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const isAllSelected =
|
||||
filteredAndSortedTasks.length > 0 &&
|
||||
filteredAndSortedTasks.every(task => selectedTaskIds.has(task.id))
|
||||
|
|
@ -287,15 +339,35 @@ export function TaskList({ className, initialTasks }: TaskListProps) {
|
|||
}}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell sx={{ fontWeight: 'bold' }}>Title</TableCell>
|
||||
<TableCell sx={{ fontWeight: 'bold' }}>
|
||||
<TableSortLabel
|
||||
active={getSortDirection('title') !== false}
|
||||
direction={getSortDirection('title') || 'asc'}
|
||||
onClick={() => handleSort('title')}
|
||||
>
|
||||
Title
|
||||
</TableSortLabel>
|
||||
</TableCell>
|
||||
{!isMobile && (
|
||||
<TableCell sx={{ fontWeight: 'bold' }}>Description</TableCell>
|
||||
)}
|
||||
<TableCell sx={{ fontWeight: 'bold', width: 100 }}>
|
||||
Status
|
||||
<TableSortLabel
|
||||
active={getSortDirection('status') !== false}
|
||||
direction={getSortDirection('status') || 'asc'}
|
||||
onClick={() => handleSort('status')}
|
||||
>
|
||||
Status
|
||||
</TableSortLabel>
|
||||
</TableCell>
|
||||
<TableCell sx={{ fontWeight: 'bold', width: 120 }}>
|
||||
Created
|
||||
<TableSortLabel
|
||||
active={getSortDirection('created') !== false}
|
||||
direction={getSortDirection('created') || 'asc'}
|
||||
onClick={() => handleSort('created')}
|
||||
>
|
||||
Created
|
||||
</TableSortLabel>
|
||||
</TableCell>
|
||||
{!isMobile && (
|
||||
<TableCell sx={{ fontWeight: 'bold', width: 120 }}>
|
||||
|
|
@ -383,17 +455,41 @@ export function TaskList({ className, initialTasks }: TaskListProps) {
|
|||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{formatCompactDate(task.created_at)}
|
||||
</Typography>
|
||||
<Tooltip
|
||||
title={formatFullTimestamp(task.created_at)}
|
||||
arrow
|
||||
placement="top"
|
||||
>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color="text.secondary"
|
||||
sx={{ cursor: 'help' }}
|
||||
>
|
||||
{formatCompactDate(task.created_at)}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
{!isMobile && (
|
||||
<TableCell>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{task.completed_at
|
||||
? formatCompactDate(task.completed_at)
|
||||
: '—'}
|
||||
</Typography>
|
||||
{task.completed_at ? (
|
||||
<Tooltip
|
||||
title={formatFullTimestamp(task.completed_at)}
|
||||
arrow
|
||||
placement="top"
|
||||
>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color="text.secondary"
|
||||
sx={{ cursor: 'help' }}
|
||||
>
|
||||
{formatCompactDate(task.completed_at)}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
—
|
||||
</Typography>
|
||||
)}
|
||||
</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue