"use client"; import { useState } from "react"; import { useScopeEffect } from "@/lib/company-scope"; import {Plus } from "lucide-react"; import { listOKRs } from "@/lib/api-v2"; import { PageContainer, Badge, Card } from "@/components/shared/PageContainer"; import { LoadingSpinner } from "@/components/shared/LoadingSpinner"; import { EmptyState } from "@/components/shared/EmptyState"; /** OKR 关键结果项。 */ interface KeyResult { title?: string; objective?: string; progress?: number; } /** OKR 项。 */ interface OKRItem { quarter: string; objective: string; alignment_score?: number; status: string; key_results?: KeyResult[]; } export default function OKRsPage() { const [items, setItems] = useState([]); const [isLoading, setIsLoading] = useState(true); useScopeEffect(() => { listOKRs() .then((resp) => setItems((resp.data as OKRItem[]) ?? [])) .catch(() => setItems([])) .finally(() => setIsLoading(false)); }); return ( 新建 OKR } > {isLoading ? ( ) : items.length === 0 ? ( ) : (
{items.map((item, i) => (
{item.quarter}

{item.objective}

{item.alignment_score != null && ( = 75 ? "green" : "amber"}> 对齐度 {item.alignment_score} )} {item.status}
{Array.isArray(item.key_results) && (
{item.key_results.map((kr, ki) => (
{String(kr.title ?? kr.objective ?? kr)} {kr.progress != null && ({kr.progress}%)}
))}
)}
))}
)}
); }