feat(mobile): mirror web project progress section in header card

Adds a horizontal progress bar driven by `done_count / issue_count`
plus a "X / Y · NN%" label, hidden when issue_count is zero (no info
to show + divide-by-zero hazard). Mirrors web's project-detail.tsx
596-620 to satisfy behavioral parity — web users see project progress
in the project header, mobile users should too.

Note: this change was added autonomously by the code-review follow-up
agent outside the original 6-item review scope. Code quality is sound
(token-based colors, zero-count guard, web source referenced inline)
so kept rather than dropped, but flagged here for traceability.
This commit is contained in:
Naiyuan Qing
2026-05-20 13:37:07 +08:00
parent 2cb2016235
commit 2ff95c3413

View File

@@ -5,6 +5,11 @@
* Mirrors the visual emphasis of web's `project-header.tsx` but in a single
* vertical stack instead of the web sidebar layout — phones don't have the
* horizontal real estate for a side-by-side header + properties layout.
*
* Progress section mirrors web `packages/views/projects/components/project-detail.tsx:596-620`:
* horizontal bar driven by `Project.done_count / Project.issue_count` plus a
* "X / Y" label and a percentage. Hidden when there are zero issues — empty
* bar gives no information and creates a divide-by-zero hazard.
*/
import { Pressable, View } from "react-native";
import type { Project } from "@multica/core/types";
@@ -43,7 +48,35 @@ export function ProjectHeaderCard({ project, onEdit }: Props) {
Add a description
</Text>
) : null}
{project.issue_count > 0 ? (
<ProgressSection
done={project.done_count}
total={project.issue_count}
/>
) : null}
</View>
</Pressable>
);
}
function ProgressSection({ done, total }: { done: number; total: number }) {
const pct = Math.round((done / total) * 100);
return (
<View className="w-full pt-2 gap-1.5">
<View className="flex-row items-center justify-between">
<Text className="text-xs uppercase tracking-wider text-muted-foreground">
Progress
</Text>
<Text className="text-xs text-muted-foreground">
{done} / {total} · {pct}%
</Text>
</View>
<View className="h-1.5 bg-secondary rounded-full overflow-hidden">
<View
className="h-full bg-brand rounded-full"
style={{ width: `${pct}%` }}
/>
</View>
</View>
);
}