import React, { FC } from "react"; import Link from "next/link"; import { useRouter } from "next/router"; import { Disclosure, Transition } from "@headlessui/react"; // hooks import useToast from "hooks/use-toast"; // components import { SingleProgressStats } from "components/core"; // ui import { CustomMenu } from "components/ui"; import { AssigneesList } from "components/ui/avatar"; import { Tooltip, LinearProgressIndicator } from "@plane/ui"; // icons import { CalendarDaysIcon } from "@heroicons/react/20/solid"; import { TargetIcon, ContrastIcon, PersonRunningIcon, ArrowRightIcon, TriangleExclamationIcon, AlarmClockIcon, } from "components/icons"; import { ChevronDownIcon, LinkIcon, PencilIcon, StarIcon, TrashIcon } from "@heroicons/react/24/outline"; // helpers import { getDateRangeStatus, renderShortDateWithYearFormat, findHowManyDaysLeft } from "helpers/date-time.helper"; import { copyTextToClipboard, truncateText } from "helpers/string.helper"; // types import { ICycle } from "types"; const stateGroups = [ { key: "backlog_issues", title: "Backlog", color: "#dee2e6", }, { key: "unstarted_issues", title: "Unstarted", color: "#26b5ce", }, { key: "started_issues", title: "Started", color: "#f7ae59", }, { key: "cancelled_issues", title: "Cancelled", color: "#d687ff", }, { key: "completed_issues", title: "Completed", color: "#09a953", }, ]; export interface ICyclesBoardCard { cycle: ICycle; filter: string; } export const CyclesBoardCard: FC = (props) => { const { cycle } = props; // router const router = useRouter(); const { workspaceSlug, projectId } = router.query; // toast const { setToastAlert } = useToast(); const cycleStatus = getDateRangeStatus(cycle.start_date, cycle.end_date); const isCompleted = cycleStatus === "completed"; const endDate = new Date(cycle.end_date ?? ""); const startDate = new Date(cycle.start_date ?? ""); const handleCopyText = () => { const originURL = typeof window !== "undefined" && window.location.origin ? window.location.origin : ""; copyTextToClipboard(`${originURL}/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`).then(() => { setToastAlert({ type: "success", title: "Link Copied!", message: "Cycle link copied to clipboard.", }); }); }; const progressIndicatorData = stateGroups.map((group, index) => ({ id: index, name: group.title, value: cycle.total_issues > 0 ? ((cycle[group.key as keyof ICycle] as number) / cycle.total_issues) * 100 : 0, color: group.color, })); const groupedIssues: any = { backlog: cycle.backlog_issues, unstarted: cycle.unstarted_issues, started: cycle.started_issues, completed: cycle.completed_issues, cancelled: cycle.cancelled_issues, }; const handleRemoveFromFavorites = () => {}; const handleAddToFavorites = () => {}; const handleEditCycle = () => {}; const handleDeleteCycle = () => {}; return (

{truncateText(cycle.name, 15)}

{cycleStatus === "current" ? ( {findHowManyDaysLeft(cycle.end_date ?? new Date())} Days Left ) : cycleStatus === "upcoming" ? ( {findHowManyDaysLeft(cycle.start_date ?? new Date())} Days Left ) : cycleStatus === "completed" ? ( {cycle.total_issues - cycle.completed_issues > 0 && ( )}{" "} Completed ) : ( cycleStatus )} {cycle.is_favorite ? ( ) : ( )}
{cycleStatus !== "draft" && ( <>
{renderShortDateWithYearFormat(startDate)}
{renderShortDateWithYearFormat(endDate)}
)}
Creator:
{cycle.owned_by.avatar && cycle.owned_by.avatar !== "" ? ( {cycle.owned_by.display_name} ) : ( {cycle.owned_by.display_name.charAt(0)} )} {cycle.owned_by.display_name}
Members:
{cycle.assignees.length > 0 ? (
) : ( "No members" )}
{!isCompleted && ( )} {!isCompleted && ( Delete cycle )} { e.preventDefault(); handleCopyText(); }} > Copy cycle link
{({ open }) => (
Progress {Object.keys(groupedIssues).map((group, index) => ( {group}
} completed={groupedIssues[group]} total={cycle.total_issues} /> ))}
} position="bottom" >
{stateGroups.map((group) => (
{group.title}
{cycle[group.key as keyof ICycle] as number}{" "} -{" "} {cycle.total_issues > 0 ? `${Math.round( ((cycle[group.key as keyof ICycle] as number) / cycle.total_issues) * 100 )}%` : "0%"}
))}
)}
); };