// 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.length} Усі об'єкти →
{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;