import type { ReactNode } from "react"; import type { Issue } from "@paperclipai/shared"; import { Link } from "@/lib/router"; import { Eye, X } from "lucide-react"; import { createIssueDetailPath, rememberIssueDetailLocationState, withIssueDetailHeaderSeed, } from "../lib/issueDetailBreadcrumb"; import { cn } from "../lib/utils"; import { StatusIcon } from "./StatusIcon"; import { productivityReviewTriggerLabel } from "./ProductivityReviewBadge"; type UnreadState = "hidden" | "visible" | "fading"; interface IssueRowProps { issue: Issue; issueLinkState?: unknown; selected?: boolean; mobileLeading?: ReactNode; desktopMetaLeading?: ReactNode; desktopLeadingSpacer?: boolean; mobileMeta?: ReactNode; desktopTrailing?: ReactNode; trailingMeta?: ReactNode; titleSuffix?: ReactNode; titleClassName?: string; checklistStepNumber?: number | string | null; checklistCurrentStep?: boolean; checklistDependencyChips?: ReactNode; checklistRowId?: string; unreadState?: UnreadState | null; onMarkRead?: () => void; onArchive?: () => void; archiveDisabled?: boolean; className?: string; } export function IssueRow({ issue, issueLinkState, selected = false, mobileLeading, desktopMetaLeading, desktopLeadingSpacer = false, mobileMeta, desktopTrailing, trailingMeta, titleSuffix, titleClassName, checklistStepNumber = null, checklistCurrentStep = false, checklistDependencyChips, checklistRowId, unreadState = null, onMarkRead, onArchive, archiveDisabled, className, }: IssueRowProps) { const issuePathId = issue.identifier ?? issue.id; const identifier = issue.identifier ?? issue.id.slice(0, 8); const showUnreadSlot = unreadState !== null; const showUnreadDot = unreadState === "visible" || unreadState === "fading"; const selectedStatusClass = selected ? "!text-muted-foreground !border-muted-foreground" : undefined; const detailState = withIssueDetailHeaderSeed(issueLinkState, issue); const productivityReview = issue.productivityReview ?? null; const productivityReviewIndicator = productivityReview ? ( ) : null; const hasChecklistStep = checklistStepNumber !== null; const checklistStep = hasChecklistStep ? ( ) : null; return ( rememberIssueDetailLocationState(issuePathId, detailState)} className={cn( "group flex items-start gap-2 border-b border-border py-2.5 pl-2 pr-3 text-sm no-underline text-inherit transition-colors last:border-b-0 sm:items-center sm:py-2 sm:pl-1", selected ? "hover:bg-transparent" : "hover:bg-accent/50", checklistCurrentStep ? "border-l-2 border-l-primary bg-primary/5 pl-[calc(theme(spacing.2)-2px)] sm:pl-[calc(theme(spacing.1)-2px)]" : null, className, )} > {mobileLeading ?? } {productivityReviewIndicator} {issue.title}{titleSuffix} {checklistDependencyChips ? ( {checklistDependencyChips} ) : null} {desktopLeadingSpacer ? ( ) : null} {desktopMetaLeading ?? ( <> {productivityReviewIndicator} {checklistStep} {identifier} )} {mobileMeta ? ( <> {mobileMeta} ) : null} {(desktopTrailing || trailingMeta) ? ( {desktopTrailing} {trailingMeta ? ( {trailingMeta} ) : null} ) : null} {showUnreadSlot ? ( {showUnreadDot ? ( ) : onArchive ? ( ) : ( ) : null} ); }