import React, { useMemo } from "react"; import { Box, Tooltip, Typography, useTheme } from "@mui/material"; import WorkOutlineIcon from "@mui/icons-material/WorkOutline"; import ForumIcon from "@mui/icons-material/Forum"; import MarkEmailReadIcon from "@mui/icons-material/MarkEmailRead"; import EmojiEventsIcon from "@mui/icons-material/EmojiEvents"; import CloseIcon from "@mui/icons-material/Close"; import { alpha } from "@mui/material/styles"; import { JobApplication } from "../types"; function normalizeStatus(status?: string): string { if (!status) return "Applied"; if (status === "Interviewing") return "Interview"; return status; } function isTerminalRejected(status: string) { return status === "Rejected" || status === "Ghosted"; } export default function JobFlowBar({ job }: { job: JobApplication | null }) { const theme = useTheme(); const steps = useMemo( () => [ { key: "applied" as const, label: "Applied", color: theme.palette.info.main, icon: }, { key: "interview" as const, label: "Interview", color: theme.palette.primary.main, icon: }, { key: "reply" as const, label: "Reply", color: theme.palette.success.main, icon: }, { key: "offer" as const, label: "Offer", color: theme.palette.success.dark, icon: }, { key: "outcome" as const, label: "Outcome", color: theme.palette.text.secondary, icon: }, ] as const, [theme.palette.info.main, theme.palette.primary.main, theme.palette.success.main, theme.palette.success.dark, theme.palette.text.secondary], ); if (!job) return null; const status = normalizeStatus(job.status); const reply = Boolean(job.responseReceived); const rejected = isTerminalRejected(status); const activeIndex = (() => { if (rejected) return 4; if (status === "Offer") return 3; if (reply) return 2; if (status === "Interview") return 1; return 0; })(); const breakIndex = rejected ? activeIndex : null; const visibleSteps = breakIndex !== null ? steps.slice(0, breakIndex + 1) : steps; const segCount = visibleSteps.length; const segWidth = `${100 / segCount}%`; return ( Flow {visibleSteps.map((s, idx) => { const filled = idx <= activeIndex && breakIndex === null; const terminalFilled = breakIndex !== null && idx < breakIndex; const isBreak = breakIndex !== null && idx === breakIndex; const bg = filled || terminalFilled ? s.color : alpha(s.color, 0.12); const fg = filled || terminalFilled ? "#fff" : alpha(theme.palette.text.primary, 0.6); const title = (() => { if (isBreak) return `${status} (stopped here)`; if (idx === 2 && reply) return "Reply received"; return s.label; })(); return ( {isBreak ? ( ) : ( {s.icon} {s.key === "outcome" && rejected ? status : s.label} )} {isBreak ? ( {status} ) : null} ); })} ); }