// today.jsx — головна сторінка «На сьогодні»
function TodayPage({ tasks, onOpenTask, onToggle }) {
const today = window.TODAY.day;
const weekDays = window.WEEK_DAYS;
const objects = window.DATA.OBJECTS;
// Задачі «сьогодні» — це задачі сьогоднішнього дня + усе прострочене (тягне увагу).
const todayTasks = tasks.filter(t => t.day === today || t.status === "late");
// Задачі тижня — все інше у тижні (без сьогоднішніх і прострочених).
const weekTasks = tasks
.filter(t => t.day !== today && t.status !== "late")
.sort((a, b) => a.day.localeCompare(b.day));
// KPI
const liveCount = todayTasks.filter(t => t.status === "live").length;
const lateCount = tasks.filter(t => t.status === "late").length;
const doneCount = todayTasks.filter(t => t.status === "done").length;
const totalToday = todayTasks.length;
const weekActive = tasks.filter(t => t.status !== "done").length;
// Сортування: late → live → todo → done
const order = { late: 0, live: 1, todo: 2, done: 3 };
const sortedToday = [...todayTasks].sort((a, b) => order[a.status] - order[b.status]);
// Активні об'єкти
const activeObjects = objects.filter(o => o.progress < 100).slice(0, 4);
return (
На сьогодні
{totalToday} {plural(totalToday, "задача", "задачі", "задач")}
{lateCount > 0 && <>
{lateCount} {plural(lateCount, "прострочена", "прострочені", "прострочених")}
>}
{liveCount > 0 && <>
{liveCount} у роботі
>}
{/* KPI */}
До виконання
{totalToday - doneCount}
{doneCount} виконано · {totalToday} всього
У роботі зараз
{liveCount}
{liveCount > 0 ? "відкрити трекер" : "немає активних"}
0 ? "is-warn" : ""}`}>
Прострочено
{lateCount}
{lateCount > 0 ? "потребує уваги" : "усе вчасно"}
Цей тиждень
{weekActive}
{tasks.filter(t => t.status === "done").length} виконано
{/* СЬОГОДНІ */}
Сьогодні
{totalToday} {plural(totalToday, "задача", "задачі", "задач")}
Усі задачі →
{sortedToday.length > 0
? sortedToday.map(t => (
))
:
На сьогодні задач немає.
}
{/* НА ЦЬОМУ ТИЖНІ — плоский перелік з датою справа */}
Найближчі дні
{weekTasks.length} {plural(weekTasks.length, "задача", "задачі", "задач")} · до 29 травня
Розклад →
{weekTasks.length > 0
? weekTasks.map(t => (
))
:
На цьому тижні задач немає.
}
{/* ОБ'ЄКТИ */}
{activeObjects.map(o => (
{o.code}
{o.name}
{o.client} · {o.address}
{o.stageShort} · {o.grade}
Дедлайн {o.deadline}
{o.revision}
{o.progress}%
))}
);
}
// dateLabel: повертає короткий ярлик дати для рядка задачі
// - hideForToday: коли true, для today повертає null (бо й так в секції «Сьогодні»)
function dateLabel(day, today, hideForToday) {
if (day === today) return hideForToday ? null : "Сьогодні";
const d = parseInt(day, 10);
const t = parseInt(today, 10);
const delta = d - t;
const dayMap = { "25": "пн", "26": "вт", "27": "ср", "28": "чт", "29": "пт" };
const short = dayMap[day] || "";
if (delta === -1) return `Вчора · ${day} трв`;
if (delta === 1) return `Завтра · ${day} трв`;
if (delta < 0) return `${day} трв · ${Math.abs(delta)} д. тому`;
return `${short ? short + " · " : ""}${day} трв`;
}
function plural(n, one, few, many) {
const m10 = n % 10;
const m100 = n % 100;
if (m10 === 1 && m100 !== 11) return one;
if (m10 >= 2 && m10 <= 4 && (m100 < 12 || m100 > 14)) return few;
return many;
}
window.TodayPage = TodayPage;
window.plural = plural;
window.dateLabel = dateLabel;