/
DKoko
/
task-manager-light
Обзор
Документация
Войти
/
DKoko
/
task-manager-light
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/lib/tasks-shared.ts
86 строк
3 KB
NMitin
feat(tasks): сортировка и сохранение фильтра между визитами
6 часов назад
6 часов назад
490c3b0
Код
Авторство
О чём код?
// Клиент-безопасная часть модели задач (без server-only зависимостей вроде better-sqlite3). // Импортируется и в серверных route handlers, и в клиентских компонентах. export const STATUSES = ['new', 'in_progress', 'done', 'cancelled'] as const export type Status = (typeof STATUSES)[number] export const STATUS_LABELS: Record<Status, string> = { new: 'Новая', in_progress: 'В работе', done: 'Выполнена', cancelled: 'Отменена', } export interface Task { id: string title: string description: string status: Status statusSetAt: number dueDate: number | null assignee: string createdAt: number updatedAt: number } export function isStatus(v: unknown): v is Status { return typeof v === 'string' && (STATUSES as readonly string[]).includes(v) } export const SORTS = ['due', 'status'] as const export type Sort = (typeof SORTS)[number] export const DEFAULT_SORT: Sort = 'due' export const SORT_LABELS: Record<Sort, string> = { due: 'По сроку', status: 'По статусу', } export function isSort(v: unknown): v is Sort { return typeof v === 'string' && (SORTS as readonly string[]).includes(v) } // --- Дата срока (только дата, без времени) --- /** 'YYYY-MM-DD' → unix ms полуночи (локальный часовой пояс). null/'' → null. */ export function dateToMs(dateStr: string | null | undefined): number | null { if (!dateStr) return null const parts = dateStr.split('-').map(Number) if (parts.length !== 3 || parts.some((n) => Number.isNaN(n))) return null const [y, m, d] = parts return new Date(y, m - 1, d).getTime() } /** unix ms → 'YYYY-MM-DD'. null → null. */ export function msToDate(ms: number | null | undefined): string | null { if (ms == null) return null const dt = new Date(ms) const y = dt.getFullYear() const m = String(dt.getMonth() + 1).padStart(2, '0') const d = String(dt.getDate()).padStart(2, '0') return `${y}-${m}-${d}` } export function isOverdue(task: Pick<Task, 'dueDate' | 'status'>): boolean { if (task.dueDate == null) return false if (task.status === 'done' || task.status === 'cancelled') return false const today = new Date() today.setHours(0, 0, 0, 0) return task.dueDate < today.getTime() } /** unix ms → 'DD.MM.YYYY'. */ export function formatDate(ms: number): string { const d = new Date(ms) const dd = String(d.getDate()).padStart(2, '0') const mm = String(d.getMonth() + 1).padStart(2, '0') return `${dd}.${mm}.${d.getFullYear()}` } /** unix ms → 'DD.MM.YYYY HH:MM'. */ export function formatDateTime(ms: number): string { const d = new Date(ms) const hh = String(d.getHours()).padStart(2, '0') const min = String(d.getMinutes()).padStart(2, '0') return `${formatDate(ms)} ${hh}:${min}` }