"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 (
);
}