"use client"; import { useEffect, useState } from "react"; import { Separator } from "@kandev/ui/separator"; import { formatRelativeTime } from "@/lib/utils"; import { getTreeCostSummary, type TreeCostSummary } from "@/lib/api/domains/tree-api"; import type { Task } from "@/app/office/tasks/[id]/types"; import { PropertyRow } from "./components/property-row"; import { StatusPicker } from "./components/status-picker"; import { PriorityPicker } from "./components/priority-picker"; import { LabelsPicker } from "./components/labels-picker"; import { AssigneePicker } from "./components/assignee-picker"; import { ProjectPicker } from "./components/project-picker"; import { ParentPicker } from "./components/parent-picker"; import { BlockersPicker } from "./components/blockers-picker"; import { SubIssuesRow } from "./components/sub-issues-row"; import { ReviewersPicker } from "./components/reviewers-picker"; import { ApproversPicker } from "./components/approvers-picker"; import { PendingApprovalBadge } from "./components/pending-approval-badge"; type TaskPropertiesProps = { task: Task; }; function formatDate(dateStr: string): string { return new Date(dateStr).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric", }); } // formatCurrency converts subcents (hundredths of a cent — the office // cost storage unit per docs/specs/office-costs/spec.md) to a USD string. function formatCurrency(subcents: number): string { return new Intl.NumberFormat(undefined, { style: "currency", currency: "USD", }).format(subcents / 10000); } function formatNumber(value: number): string { return new Intl.NumberFormat().format(value); } const NONE_LABEL = None; function IdentitySection({ task }: { task: Task }) { return ( <> ); } function DependenciesSection({ task }: { task: Task }) { return ( <> {task.blocking.length > 0 ? task.blocking.join(", ") : NONE_LABEL} ); } function ReviewSection({ task }: { task: Task }) { return ( <> ); } function TimelineSection({ task }: { task: Task }) { const dateOrDash = (d?: string | null) => d ? formatDate(d) : --; return ( <> {task.createdBy} {dateOrDash(task.startedAt)} {dateOrDash(task.completedAt)} {formatDate(task.createdAt)} {formatRelativeTime(task.updatedAt)} ); } function TreeCostSection({ task }: { task: Task }) { const [summary, setSummary] = useState(null); useEffect(() => { let cancelled = false; if (task.children.length === 0) { return; } getTreeCostSummary(task.id) .then((res) => { if (!cancelled) setSummary(res); }) .catch(() => { if (!cancelled) setSummary(null); }); return () => { cancelled = true; }; }, [task.id, task.children.length]); if (task.children.length === 0 || !summary) return null; return ( <> {formatCurrency(summary.cost_subcents)} {summary.task_count} {formatNumber(summary.tokens_in)} {formatNumber(summary.tokens_cached_in)} {formatNumber(summary.tokens_out)} ); } export function TaskProperties({ task }: TaskPropertiesProps) { return (
); }