import { Virtuoso } from "react-virtuoso"; import { Badge, Button, Spin } from "antd"; import { useTranslation } from "react-i18next"; import { forwardRef, useMemo, useRef } from "react"; import day from "../../utils/day.js"; import "./task-center.styles.scss"; import { ArrowRightOutlined, CalendarOutlined, ClockCircleOutlined, PlusCircleOutlined, QuestionCircleOutlined } from "@ant-design/icons"; const TaskCenterComponent = forwardRef( ({ visible, tasks, loading, error, onTaskClick, onLoadMore, hasMore, createNewTask, incompleteTaskCount }, ref) => { const { t } = useTranslation(); const virtuosoRef = useRef(null); const sectionIcons = { [t("tasks.labels.overdue")]: , [t("tasks.labels.due_today")]: , [t("tasks.labels.upcoming")]: , [t("tasks.labels.no_due_date")]: }; const groups = useMemo(() => { const now = day(); const today = now.startOf("day"); const overdue = tasks.filter((t) => t.due_date && day(t.due_date).isBefore(today)); const dueToday = tasks.filter((t) => t.due_date && day(t.due_date).isSame(today, "day")); const upcoming = tasks.filter( (t) => t.due_date && day(t.due_date).isAfter(today) && !day(t.due_date).isSame(today, "day") ); const noDueDate = tasks.filter((t) => !t.due_date); return [ { label: t("tasks.labels.overdue"), tasks: overdue }, { label: t("tasks.labels.due_today"), tasks: dueToday }, { label: t("tasks.labels.upcoming"), tasks: upcoming }, { label: t("tasks.labels.no_due_date"), tasks: noDueDate } ].filter((group) => group.tasks.length > 0); }, [tasks, t]); const groupCounts = useMemo(() => groups.map((group) => group.tasks.length), [groups]); const flatTasks = useMemo(() => groups.flatMap((group) => group.tasks), [groups]); const priorityColors = { 1: "red", 2: "orange", 3: "green" }; const getPriorityColor = (priority) => priorityColors[priority] || null; const groupContent = (groupIndex) => { const { label, tasks } = groups[groupIndex]; let displayCount = tasks.length; if (label === t("tasks.labels.no_due_date")) { displayCount = incompleteTaskCount - groups.reduce((sum, group, idx) => (idx !== groupIndex ? sum + group.tasks.length : sum), 0); } return (
{sectionIcons[label]} {label} ({displayCount})
); }; const itemContent = (index) => { const task = flatTasks[index]; const priorityColor = getPriorityColor(task.priority); return (
onTaskClick(task.id)} role="button" tabIndex={0} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { onTaskClick(task.id); } }} >
{task.title}
{t("tasks.labels.ro-number", { ro_number: task.job?.ro_number || t("general.labels.na") })}
{task.due_date && {day(task.due_date).fromNow()}} {!!priorityColor && }
); }; if (error) { return (

{t("tasks.labels.my_tasks_center")}

{t("tasks.errors.load_failed")}
); } return (

{t("tasks.labels.my_tasks_center")}

{tasks.length === 0 && !loading ? (
{t("tasks.labels.no_tasks")}
) : ( loading ? (
) : null }} /> )}
); } ); TaskCenterComponent.displayName = "TaskCenterComponent"; export default TaskCenterComponent;