Kairo-Jinkendo/frontend/src/widgets/WorkspaceTodayWidget.jsx

100 lines
3.2 KiB
React
Raw Normal View History

import { useCallback, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { listWorkspaceTodayActions } from '../api/workspace.js'
import { StatusBadge } from '../components/StatusBadge.jsx'
import { PriorityBadge } from '../components/PriorityBadge.jsx'
import { EmptyState } from '../components/EmptyState.jsx'
import { ErrorState } from '../components/ErrorState.jsx'
import { LoadingState } from '../components/LoadingState.jsx'
import { WidgetCard } from '../components/WidgetCard.jsx'
import { actionPath, scopedPath } from '../utils/routes.js'
function formatDue(iso) {
if (!iso) return null
try {
return new Date(iso).toLocaleString('de-DE', {
day: '2-digit',
month: '2-digit',
hour: '2-digit',
minute: '2-digit',
})
} catch {
return iso
}
}
export function WorkspaceTodayWidget() {
const [actions, setActions] = useState([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const load = useCallback(async () => {
setLoading(true)
setError(null)
try {
const data = await listWorkspaceTodayActions(10)
setActions(Array.isArray(data) ? data : [])
} catch (err) {
setError(err.message)
} finally {
setLoading(false)
}
}, [])
useEffect(() => {
load()
}, [load])
return (
<WidgetCard
title="Heute"
subtitle="Deine Maßnahmen — überfällig und dringend zuerst"
actions={
<button type="button" className="btn btn-ghost" onClick={load} disabled={loading}>
Aktualisieren
</button>
}
footer={
actions.length > 0 ? (
<Link to="/work/mine" className="link-inline">
Alle meine Maßnahmen →
</Link>
) : null
}
>
{loading && <LoadingState />}
{!loading && error && <ErrorState message={error} onRetry={load} />}
{!loading && !error && actions.length === 0 && (
<EmptyState message="Keine Maßnahmen für heute — prüfe „Nächste sinnvolle Schritte“ oben." />
)}
{!loading && !error && actions.length > 0 && (
<ul className="item-list">
{actions.map((action) => (
<li key={action.id} className="list-item card-list-item">
<div className="list-item-main">
{action.is_overdue && (
<span className="badge status-badge status-blocked">Überfällig</span>
)}
<strong>{action.title}</strong>
{action.initiative_title && (
<span className="muted list-item-sub">{action.initiative_title}</span>
)}
{action.due_at && (
<span className="muted list-item-sub">Fällig: {formatDue(action.due_at)}</span>
)}
</div>
<div className="list-item-meta">
<StatusBadge status={action.status} />
<PriorityBadge priority={action.priority} />
<Link to={actionPath(action.id)} className="btn btn-secondary btn-sm">
Öffnen
</Link>
</div>
</li>
))}
</ul>
)}
</WidgetCard>
)
}