* refactor: update PopuplarEvents chart to use InsightsBookingService * use buildHashMapForUsers * refactor least booked * refactor charts * combine methods * refactor booking kpi cards * remove unused code * fix booking kpi cards * restore code that was removed accidentally * Revert "restore code that was removed accidentally" This reverts commit 0c0b444b02498b94fb29ef470da065bad3ad7ece. * Revert "fix booking kpi cards" This reverts commit b1e8e9afbd3632a5239495566551ae12bd926b66. * refactor booking kpi cards * revert method and remove unused code * fix previous period * fix metrics * clean up trpc call params * clean up Download.tsx * split utils * restructure folders for components * clean up imports * rename TotalUserFeedbackTable to UserStatsTable * add guide * use client * add curly braces to case * fix tests
215 lines
5.4 KiB
TypeScript
215 lines
5.4 KiB
TypeScript
import dayjs from "@calcom/dayjs";
|
|
|
|
type TimeViewType = "week" | "month" | "year" | "day";
|
|
|
|
export interface DateRange {
|
|
startDate: string;
|
|
endDate: string;
|
|
formattedDate: string;
|
|
formattedDateFull: string;
|
|
}
|
|
|
|
export interface GetDateRangesParams {
|
|
startDate: string;
|
|
endDate: string;
|
|
timeZone: string;
|
|
timeView: "day" | "week" | "month" | "year";
|
|
weekStart: "Sunday" | "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday" | string;
|
|
}
|
|
|
|
export const getTimeView = (startDate: string, endDate: string) => {
|
|
const diff = dayjs(endDate).diff(dayjs(startDate), "day");
|
|
if (diff > 365) {
|
|
return "year";
|
|
} else if (diff > 90) {
|
|
return "month";
|
|
} else if (diff > 30) {
|
|
return "week";
|
|
} else {
|
|
return "day";
|
|
}
|
|
};
|
|
|
|
export const getDateRanges = ({
|
|
startDate: _startDate,
|
|
endDate: _endDate,
|
|
timeZone,
|
|
timeView,
|
|
weekStart,
|
|
}: GetDateRangesParams): DateRange[] => {
|
|
if (!["day", "week", "month", "year"].includes(timeView)) {
|
|
return [];
|
|
}
|
|
|
|
const startDate = dayjs(_startDate).tz(timeZone);
|
|
const endDate = dayjs(_endDate).tz(timeZone);
|
|
const ranges: DateRange[] = [];
|
|
let currentStartDate = startDate;
|
|
|
|
while (currentStartDate.isBefore(endDate)) {
|
|
let currentEndDate = currentStartDate.endOf(timeView).tz(timeZone);
|
|
|
|
// Adjust week boundaries based on weekStart parameter
|
|
if (timeView === "week") {
|
|
const weekStartNum =
|
|
{
|
|
Sunday: 0,
|
|
Monday: 1,
|
|
Tuesday: 2,
|
|
Wednesday: 3,
|
|
Thursday: 4,
|
|
Friday: 5,
|
|
Saturday: 6,
|
|
}[weekStart] ?? 0;
|
|
|
|
currentEndDate = currentEndDate.add(weekStartNum, "day");
|
|
if (currentEndDate.subtract(7, "day").isAfter(currentStartDate)) {
|
|
currentEndDate = currentEndDate.subtract(7, "day");
|
|
}
|
|
}
|
|
|
|
if (currentEndDate.isAfter(endDate)) {
|
|
currentEndDate = endDate;
|
|
ranges.push({
|
|
startDate: currentStartDate.toISOString(),
|
|
endDate: currentEndDate.toISOString(),
|
|
formattedDate: formatPeriod({
|
|
start: currentStartDate,
|
|
end: currentEndDate,
|
|
timeView,
|
|
wholeStart: startDate,
|
|
wholeEnd: endDate,
|
|
}),
|
|
formattedDateFull: formatPeriodFull({
|
|
start: currentStartDate,
|
|
end: currentEndDate,
|
|
timeView,
|
|
wholeStart: startDate,
|
|
wholeEnd: endDate,
|
|
}),
|
|
});
|
|
break;
|
|
}
|
|
|
|
ranges.push({
|
|
startDate: currentStartDate.toISOString(),
|
|
endDate: currentEndDate.toISOString(),
|
|
formattedDate: formatPeriod({
|
|
start: currentStartDate,
|
|
end: currentEndDate,
|
|
timeView,
|
|
wholeStart: startDate,
|
|
wholeEnd: endDate,
|
|
}),
|
|
formattedDateFull: formatPeriodFull({
|
|
start: currentStartDate,
|
|
end: currentEndDate,
|
|
timeView,
|
|
wholeStart: startDate,
|
|
wholeEnd: endDate,
|
|
}),
|
|
});
|
|
|
|
currentStartDate = currentEndDate.add(1, "day").startOf("day").tz(timeZone);
|
|
}
|
|
|
|
return ranges;
|
|
};
|
|
|
|
export const formatPeriod = ({
|
|
start,
|
|
end,
|
|
timeView,
|
|
wholeStart,
|
|
wholeEnd,
|
|
}: {
|
|
start: dayjs.Dayjs;
|
|
end: dayjs.Dayjs;
|
|
timeView: TimeViewType;
|
|
wholeStart: dayjs.Dayjs;
|
|
wholeEnd: dayjs.Dayjs;
|
|
}): string => {
|
|
const omitYear = wholeStart.year() === wholeEnd.year();
|
|
|
|
switch (timeView) {
|
|
case "day": {
|
|
const shouldShowMonth = wholeStart.isSame(start, "day") || start.date() === 1;
|
|
|
|
if (shouldShowMonth) {
|
|
return omitYear ? start.format("MMM D") : start.format("MMM D, YYYY");
|
|
} else {
|
|
return omitYear ? start.format("D") : start.format("D, YYYY");
|
|
}
|
|
}
|
|
case "week": {
|
|
const startFormat = "MMM D";
|
|
let endFormat = "MMM D";
|
|
if (start.format("MMM") === end.format("MMM")) {
|
|
endFormat = "D";
|
|
}
|
|
|
|
if (start.format("YYYY") !== end.format("YYYY")) {
|
|
return `${start.format(`${startFormat} , YYYY`)} - ${end.format(`${endFormat}, YYYY`)}`;
|
|
}
|
|
|
|
if (omitYear) {
|
|
return `${start.format(startFormat)} - ${end.format(endFormat)}`;
|
|
} else {
|
|
return `${start.format(startFormat)} - ${end.format(endFormat)}, ${end.format("YYYY")}`;
|
|
}
|
|
}
|
|
case "month": {
|
|
return omitYear ? start.format("MMM") : start.format("MMM YYYY");
|
|
}
|
|
case "year": {
|
|
return start.format("YYYY");
|
|
}
|
|
default:
|
|
return "";
|
|
}
|
|
};
|
|
|
|
export const formatPeriodFull = ({
|
|
start,
|
|
end,
|
|
timeView,
|
|
wholeStart,
|
|
wholeEnd,
|
|
}: {
|
|
start: dayjs.Dayjs;
|
|
end: dayjs.Dayjs;
|
|
timeView: TimeViewType;
|
|
wholeStart: dayjs.Dayjs;
|
|
wholeEnd: dayjs.Dayjs;
|
|
}): string => {
|
|
const omitYear = wholeStart.year() === wholeEnd.year();
|
|
|
|
switch (timeView) {
|
|
case "day": {
|
|
return omitYear ? start.format("MMM D") : start.format("MMM D, YYYY");
|
|
}
|
|
case "week": {
|
|
const startFormat = "MMM D";
|
|
const endFormat = "MMM D";
|
|
|
|
if (start.format("YYYY") !== end.format("YYYY")) {
|
|
return `${start.format(`${startFormat}, YYYY`)} - ${end.format(`${endFormat}, YYYY`)}`;
|
|
}
|
|
|
|
if (omitYear) {
|
|
return `${start.format(startFormat)} - ${end.format(endFormat)}`;
|
|
} else {
|
|
return `${start.format(startFormat)} - ${end.format(endFormat)}, ${end.format("YYYY")}`;
|
|
}
|
|
}
|
|
case "month": {
|
|
return omitYear ? start.format("MMM") : start.format("MMM YYYY");
|
|
}
|
|
case "year": {
|
|
return start.format("YYYY");
|
|
}
|
|
default:
|
|
return "";
|
|
}
|
|
};
|