import React from "react";
import { Box, Text } from "ink";
import type { Project } from "../types/index.ts";
interface ProjectItemProps {
project: Project;
isSelected: boolean;
isCursor: boolean;
}
/**
* Get status icon for a project
*/
function getStatusIcon(project: Project): { icon: string; color: string } {
if (project.type === "non-git") {
return { icon: "-", color: "gray" };
}
if (project.type === "git-submodule") {
return { icon: "○", color: "magenta" };
}
if (!project.status) {
return { icon: "?", color: "gray" };
}
if (project.status.isDirty) {
return { icon: "●", color: "yellow" };
}
return { icon: "✓", color: "green" };
}
/**
* Format sync status badges
*/
function getSyncBadges(project: Project): React.ReactNode[] {
const badges: React.ReactNode[] = [];
if (!project.status) return badges;
if (project.status.isAhead && project.status.unpushedCommits > 0) {
badges.push(
↑{project.status.unpushedCommits}
);
}
if (project.status.isBehind && project.status.unpulledCommits > 0) {
badges.push(
↓{project.status.unpulledCommits}
);
}
if (!project.status.hasRemote && project.type === "git") {
badges.push(
no-remote
);
}
return badges;
}
/**
* Format the last activity date
*/
function formatLastActivity(date: Date | null | undefined): string {
if (!date) return "";
const now = new Date();
const diff = now.getTime() - date.getTime();
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
if (days === 0) return "today";
if (days === 1) return "yesterday";
if (days < 7) return `${days}d ago`;
if (days < 30) return `${Math.floor(days / 7)}w ago`;
if (days < 365) return `${Math.floor(days / 30)}mo ago`;
return `${Math.floor(days / 365)}y ago`;
}
export function ProjectItem({ project, isSelected, isCursor }: ProjectItemProps) {
const { icon, color } = getStatusIcon(project);
const syncBadges = getSyncBadges(project);
const lastActivity = formatLastActivity(project.status?.lastLocalCommit);
const bgColor = isCursor ? "blue" : undefined;
const textColor = isCursor ? "white" : undefined;
return (
{/* Cursor indicator */}
{isCursor ? ">" : " "}
{/* Selection checkbox */}
{isSelected ? "[x]" : "[ ]"}
{/* Status icon */}
{icon}
{/* Project name */}
{project.name}
{project.status?.currentBranch && (
⎇ {project.status.currentBranch}
)}
{project.type === "git-submodule" && (
(sub)
)}
{project.projectMarker && project.type === "non-git" && (
[{project.projectMarker}]
)}
{/* Sync badges */}
{syncBadges.map((badge, i) => (
{badge}
))}
{/* Last activity */}
{lastActivity}
);
}