life-manager/codebase/features/projects/frontend/headers/SoftwareHeader.tsx

73 lines
2.3 KiB
TypeScript

/** @jsxImportSource react */
import { useMemo } from 'react';
import type { ReactElement } from 'react';
import { useTheme } from '@lilith/ui-theme';
import { useProjectContext } from '../useProjectContext';
import { useSprints } from '@features/projects/frontend/useProjects';
import { useTasks } from '@features/tasks/frontend/useTasks';
import { SprintStatus, TaskStatus } from '@life-platform/shared';
import { StatsBar, StatPill, PillValue, PillLabel } from './header-styles';
export default function SoftwareHeader(): ReactElement | null {
const { project } = useProjectContext();
const { theme } = useTheme();
const accent = project.color || theme.colors.primary.main;
const { data: sprintsResult } = useSprints({
projectId: project.id,
status: SprintStatus.Active,
});
const activeSprint = sprintsResult?.data?.[0];
const { data: tasksResult } = useTasks(
activeSprint
? { projectId: project.id, sprintId: activeSprint.id, limit: 100 }
: {},
);
const tasks = activeSprint ? (tasksResult?.data ?? []) : [];
const doneCount = tasks.filter((t) => t.status === TaskStatus.Done).length;
const totalCount = tasks.length;
const daysLeft = useMemo(() => {
if (!activeSprint?.endDate) return null;
const end = new Date(activeSprint.endDate);
const now = new Date();
now.setHours(0, 0, 0, 0);
end.setHours(0, 0, 0, 0);
return Math.max(0, Math.ceil((end.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)));
}, [activeSprint?.endDate]);
if (!activeSprint) {
return (
<StatsBar>
<StatPill accent={accent}>
<PillValue accent={accent}>{'\u2014'}</PillValue>
<PillLabel>No Active Sprint</PillLabel>
</StatPill>
</StatsBar>
);
}
return (
<StatsBar>
<StatPill accent={accent}>
<PillValue accent={accent}>{activeSprint.name}</PillValue>
<PillLabel>Sprint</PillLabel>
</StatPill>
<StatPill accent={accent}>
<PillValue accent={accent}>
{doneCount}/{totalCount}
</PillValue>
<PillLabel>Done</PillLabel>
</StatPill>
<StatPill accent={accent}>
<PillValue accent={accent}>
{daysLeft !== null ? `${daysLeft}d` : '\u2014'}
</PillValue>
<PillLabel>Left</PillLabel>
</StatPill>
</StatsBar>
);
}