bdc3cb9d6e
* feat: allow to choose dateTarget for /insights (startTime by default) * feat: add timestamp selector for insights date filtering - Add TimestampFilter component with Start Time/Created At options - Extend useInsightsBookingParameters hook with timestamp selection - Update all insight components to use dateTarget parameter - Add i18n translations for new UI strings - Position selector next to DateRangeFilter as requested Addresses user request to add select box next to date range filter allowing users to choose between startTime (default) and createdAt for displaying booking metrics on the Insights page. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: rename TimestampFilter to DateTargetSelector with nuqs URL state - Rename TimestampFilter component to DateTargetSelector - Implement nuqs hook in InsightsPageContent for URL state management - Update useInsightsBookingParameters to return dateTarget from URL state - Add dateTarget field to insightsRoutingServiceInputSchema and related types - Simplify individual insight components to use insightsBookingParams directly - Remove manual timestampTarget destructuring from all components - Update all tRPC routing service calls to include dateTarget parameter - All TypeScript checks now pass successfully Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * update styles * fix inconsistency * feat: replace Select with Command component and rename filter ID - Replace Select with Command + Popover for compact width and wider dropdown - Add descriptive option labels with translations - Change filter ID from 'createdAt' to 'timestamp' across all components - Maintain URL state management with nuqs - Fix ESLint warning for missing dependency in useEffect Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: revert routing components to use createdAt filter ID - Keep timestamp filter ID change scoped only to main insights page - Routing components should continue using createdAt as filter ID - Only insights-view.tsx and related booking hooks use timestamp Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * update styles * fix trpc router * refactor timestamp column for insights booking service * fix * update text * rename and clean up * fix endDate in DateRangeFilter * fix type errors * fix startTime filter and type errors * provide default date range * add completed to getMembersStatsWithCount * add unit tests * fix type error * address feedback --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
38 lines
1.5 KiB
TypeScript
38 lines
1.5 KiB
TypeScript
import dayjs from "@calcom/dayjs";
|
|
|
|
/**
|
|
* Converts a timestamp to maintain the same local time in a different timezone.
|
|
*
|
|
* For example, if it's midnight (00:00) in Paris time:
|
|
* - Input : "2025-05-22T22:00:00.000Z" (Midnight/00:00 in Paris)
|
|
* - Output: "2025-05-22T15:00:00.000Z" (Midnight/00:00 in Seoul)
|
|
*
|
|
* This ensures that times like midnight (00:00) or end of day (23:59)
|
|
* remain at those exact local times when converting between timezones.
|
|
* The output timestamp is based on the timezone in the user's profile settings.
|
|
*
|
|
* For example, the profile timezone is Asia/Seoul,
|
|
* but the current user is in Europe/Paris.
|
|
* `Date` pickers will normally emit timestamps in the user's local timezone. (00:00:00 ~ 23:59:59 in Paris time)
|
|
* but what we really want is to fetch the data based on the user's profile timezone. (00:00:00 ~ 23:59:59 in Seoul time)
|
|
* That's why we need to convert the timestamp to the user's profile timezone.
|
|
*/
|
|
export const preserveLocalTime = (isoString: string, originalTimeZone: string, targetTimeZone: string) => {
|
|
// Parse the input time
|
|
const time = dayjs(isoString).tz(originalTimeZone);
|
|
// Get the wall clock time components
|
|
const hours = time.hour();
|
|
const minutes = time.minute();
|
|
const seconds = time.second();
|
|
const milliseconds = time.millisecond();
|
|
|
|
// Create a new date in target timezone with same wall clock time
|
|
return dayjs
|
|
.tz(time.format("YYYY-MM-DD"), targetTimeZone)
|
|
.hour(hours)
|
|
.minute(minutes)
|
|
.second(seconds)
|
|
.millisecond(milliseconds)
|
|
.toISOString();
|
|
};
|