"use client"; import { FC, MouseEvent, useRef } from "react"; import { observer } from "mobx-react"; import { usePathname, useRouter, useSearchParams } from "next/navigation"; // icons import { Check, Info } from "lucide-react"; // types import type { TCycleGroups } from "@plane/types"; // ui import { CircularProgressIndicator } from "@plane/ui"; // components import { ListItem } from "@/components/core/list"; import { CycleListItemAction } from "@/components/cycles/list"; // helpers import { generateQueryParams } from "@/helpers/router.helper"; // hooks import { useCycle } from "@/hooks/store"; import { usePlatformOS } from "@/hooks/use-platform-os"; type TCyclesListItem = { cycleId: string; handleEditCycle?: () => void; handleDeleteCycle?: () => void; handleAddToFavorites?: () => void; handleRemoveFromFavorites?: () => void; workspaceSlug: string; projectId: string; className?: string; }; export const CyclesListItem: FC = observer((props) => { const { cycleId, workspaceSlug, projectId, className = "" } = props; // refs const parentRef = useRef(null); // router const router = useRouter(); const searchParams = useSearchParams(); const pathname = usePathname(); // hooks const { isMobile } = usePlatformOS(); // store hooks const { getCycleById } = useCycle(); // derived values const cycleDetails = getCycleById(cycleId); if (!cycleDetails) return null; // computed // TODO: change this logic once backend fix the response const cycleStatus = cycleDetails.status ? (cycleDetails.status.toLocaleLowerCase() as TCycleGroups) : "draft"; const isCompleted = cycleStatus === "completed"; const cycleTotalIssues = cycleDetails.backlog_issues + cycleDetails.unstarted_issues + cycleDetails.started_issues + cycleDetails.completed_issues + cycleDetails.cancelled_issues; const completionPercentage = (cycleDetails.completed_issues / cycleTotalIssues) * 100; const progress = isNaN(completionPercentage) ? 0 : Math.floor(completionPercentage); // handlers const openCycleOverview = (e: MouseEvent) => { e.preventDefault(); e.stopPropagation(); const query = generateQueryParams(searchParams, ["peekCycle"]); if (searchParams.has("peekCycle")) { router.push(`${pathname}?${query}`); } else { router.push(`${pathname}?${query}&peekCycle=${cycleId}`); } }; // handlers const handleArchivedCycleClick = (e: MouseEvent) => { openCycleOverview(e); }; const handleItemClick = cycleDetails.archived_at ? handleArchivedCycleClick : undefined; return ( {isCompleted ? ( progress === 100 ? ( ) : ( {`!`} ) ) : progress === 100 ? ( ) : ( {`${progress}%`} )} } appendTitleElement={ } actionableItems={ } isMobile={isMobile} parentRef={parentRef} /> ); });