diff --git a/packages/utils/src/datetime.ts b/packages/utils/src/datetime.ts index 0a12a22708..01dd5de01f 100644 --- a/packages/utils/src/datetime.ts +++ b/packages/utils/src/datetime.ts @@ -333,3 +333,56 @@ export const generateDateArray = (startDate: string | Date, endDate: string | Da } return dateArray; }; + +/** + * @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; + } +}; 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 eeebc9a006..9e348026c7 100644 --- a/web/core/components/cycles/list/cycle-list-item-action.tsx +++ b/web/core/components/cycles/list/cycle-list-item-action.tsx @@ -1,7 +1,6 @@ "use client"; import React, { FC, MouseEvent, useEffect, useMemo, useState } from "react"; -import { format, parseISO } from "date-fns"; import { observer } from "mobx-react"; import { useParams, usePathname, useSearchParams } from "next/navigation"; import { useForm } from "react-hook-form"; @@ -17,13 +16,13 @@ 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"; +import { renderSafeFormattedDate } from "@plane/utils"; // components import { CycleQuickActions, TransferIssuesModal } from "@/components/cycles"; import { DateRangeDropdown } from "@/components/dropdowns"; import { ButtonAvatars } from "@/components/dropdowns/member/avatar"; -import { getDate, renderSafeFormattedDate } from "@/helpers/date-time.helper"; +import { getDate } from "@/helpers/date-time.helper"; import { getFileURL } from "@/helpers/file.helper"; // hooks import { generateQueryParams } from "@/helpers/router.helper"; @@ -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, }); diff --git a/web/helpers/date-time.helper.ts b/web/helpers/date-time.helper.ts index 73ed48bff4..cff0da2c2d 100644 --- a/web/helpers/date-time.helper.ts +++ b/web/helpers/date-time.helper.ts @@ -475,38 +475,3 @@ export const checkDateCriteria = (dateToCheck: Date | null, filterDate: Date, ty return type === "after" ? normalizedCheck >= normalizedFilter : normalizedCheck <= normalizedFilter; }; - -/** - * @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; - } -};