diff --git a/packages/utils/src/datetime.ts b/packages/utils/src/datetime.ts index 8cec48f5f27..31a310a79e0 100644 --- a/packages/utils/src/datetime.ts +++ b/packages/utils/src/datetime.ts @@ -335,6 +335,59 @@ export const generateDateArray = (startDate: string | Date, endDate: string | Da }; /** + * @returns {string | null} formatted date in the format of yyyy-mm-dd to be used in payload + * @description Returns date in the formatted format to be used in payload + * @param {Date | string} date + * @example renderFormattedPayloadDate("Jan 01, 20224") // "2024-01-01" + */ +export const renderFormattedPayloadDate = (date: Date | string | undefined | null): string | undefined => { + // Parse the date to check if it is valid + const parsedDate = getDate(date); + // return if undefined + if (!parsedDate) return; + // Check if the parsed date is valid before formatting + if (!isValid(parsedDate)) return; // Return null for invalid dates + // Format the date in payload format (yyyy-mm-dd) + const formattedDate = format(parsedDate, "yyyy-MM-dd"); + return formattedDate; +}; + +/** + * @returns {string} safely formatted date or fallback text + * @description Safely formats a date using renderFormattedPayloadDate and date-fns format, with fallback for invalid dates + * @param {Date | string | undefined | null} date + * @param {string} formatToken (optional) // default "MMM dd, yyyy" + * @param {string} fallback (optional) // default "Invalid date" + * @example renderSafeFormattedDate("2024-01-01") // "Jan 01, 2024" + * @example renderSafeFormattedDate(null) // "Invalid date" + * @example renderSafeFormattedDate("2024-01-01", "MM/dd/yyyy", "N/A") // "01/01/2024" + */ +export const renderSafeFormattedDate = ( + date: Date | string | undefined | null, + formatToken: string = "MMM dd, yyyy", + fallback: string = "Invalid date" +): string => { + if (!date) return fallback; + + // Use renderFormattedPayloadDate to get a properly formatted payload date + const payloadDate = renderFormattedPayloadDate(date); + + // If renderFormattedPayloadDate returns undefined/null, return fallback + if (!payloadDate) return fallback; + + try { + // Parse and format the payload date + const parsedDate = getDate(payloadDate); + if (!parsedDate || !isValid(parsedDate)) return fallback; + + return format(parsedDate, formatToken); + } catch (error) { + // Return fallback if any error occurs during formatting + return fallback; + } +}; + +/* * Formats merged date range display with smart formatting * - Single date: "Jan 24, 2025" * - Same year, same month: "Jan 24 - 28, 2025" @@ -388,4 +441,4 @@ export const formatDateRange = ( } return ""; -}; \ No newline at end of file +}; diff --git a/web/core/components/cycles/list/cycle-list-item-action.tsx b/web/core/components/cycles/list/cycle-list-item-action.tsx index bc355307871..20c6080c8fd 100644 --- a/web/core/components/cycles/list/cycle-list-item-action.tsx +++ b/web/core/components/cycles/list/cycle-list-item-action.tsx @@ -16,7 +16,6 @@ import { import { useLocalStorage } from "@plane/hooks"; import { useTranslation } from "@plane/i18n"; import { ICycle, TCycleGroups } from "@plane/types"; -// ui import { Avatar, AvatarGroup, FavoriteStar, LayersIcon, Tooltip, TransferIcon, setPromiseToast } from "@plane/ui"; // components import { CycleQuickActions, TransferIssuesModal } from "@/components/cycles"; @@ -64,7 +63,7 @@ export const CycleListItemAction: FC = observer((props) => { const searchParams = useSearchParams(); const pathname = usePathname(); // store hooks - const { addCycleToFavorites, removeCycleFromFavorites, updateCycleDetails } = useCycle(); + const { addCycleToFavorites, removeCycleFromFavorites } = useCycle(); const { captureEvent } = useEventTracker(); const { allowPermissions } = useUserPermissions(); @@ -77,7 +76,7 @@ export const CycleListItemAction: FC = observer((props) => { const { getUserDetails } = useMember(); // form - const { control, reset, getValues } = useForm({ + const { reset } = useForm({ defaultValues, });