mirror of
https://github.com/hanzoai/calendar.git
synced 2026-10-30 14:46:43 +00:00
1368ffe55d
* refactor: move data-table hooks/contexts/provider from features to web modules Co-Authored-By: [email protected] <[email protected]> * fix: update broken useColumnResizing import path in DataTable.tsx Co-Authored-By: [email protected] <[email protected]> * fix: update remaining broken import paths for moved hooks Co-Authored-By: [email protected] <[email protected]> * docs: update GUIDE.md import paths and file references for moved modules Co-Authored-By: [email protected] <[email protected]> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
161 lines
5.6 KiB
TypeScript
161 lines
5.6 KiB
TypeScript
"use client";
|
|
|
|
import { usePathname } from "next/navigation";
|
|
import { useState, useCallback } from "react";
|
|
|
|
import { ColumnFilterType, type FilterableColumn } from "@calcom/features/data-table";
|
|
import { DataTableProvider } from "~/data-table/DataTableProvider";
|
|
import { DataTableFilters, DateRangeFilter } from "~/data-table/components";
|
|
import type { FilterType } from "@calcom/types/data-table";
|
|
import { useDataTable } from "~/data-table/hooks/useDataTable";
|
|
import { useSegments } from "~/data-table/hooks/useSegments";
|
|
import {
|
|
AverageEventDurationChart,
|
|
BookingKPICards,
|
|
BookingsByHourChart,
|
|
CSATOverTimeChart,
|
|
EventTrendsChart,
|
|
HighestNoShowHostTable,
|
|
HighestRatedMembersTable,
|
|
LeastBookedTeamMembersTable,
|
|
LowestRatedMembersTable,
|
|
MostBookedTeamMembersTable,
|
|
MostCancelledBookingsTables,
|
|
MostCompletedTeamMembersTable,
|
|
LeastCompletedTeamMembersTable,
|
|
NoShowHostsOverTimeChart,
|
|
PopularEventsTable,
|
|
RecentNoShowGuestsChart,
|
|
RecentFeedbackTable,
|
|
TimezoneBadge,
|
|
} from "@calcom/web/modules/insights/components/booking";
|
|
import { InsightsOrgTeamsProvider } from "../components/context/InsightsOrgTeamsProvider";
|
|
import { DateTargetSelector, type DateTarget } from "../components/filters/DateTargetSelector";
|
|
import { Download } from "../components/filters/Download/Download";
|
|
import { OrgTeamsFilter } from "../components/filters/OrgTeamsFilter";
|
|
import { useInsightsBookings } from "@calcom/web/modules/insights/hooks/useInsightsBookings";
|
|
import { useInsightsOrgTeams } from "@calcom/web/modules/insights/hooks/useInsightsOrgTeams";
|
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
|
import { ButtonGroup } from "@calcom/ui/components/buttonGroup";
|
|
|
|
export default function InsightsPage({ timeZone }: { timeZone: string }) {
|
|
const pathname = usePathname();
|
|
if (!pathname) return null;
|
|
return (
|
|
<DataTableProvider tableIdentifier={pathname} useSegments={useSegments} timeZone={timeZone}>
|
|
<InsightsOrgTeamsProvider>
|
|
<InsightsPageContent />
|
|
</InsightsOrgTeamsProvider>
|
|
</DataTableProvider>
|
|
);
|
|
}
|
|
|
|
const createdAtColumn: Extract<FilterableColumn, { type: Extract<FilterType, "dr"> }> = {
|
|
id: "createdAt",
|
|
title: "createdAt",
|
|
type: ColumnFilterType.DATE_RANGE,
|
|
};
|
|
|
|
const startTimeColumn: Extract<FilterableColumn, { type: Extract<FilterType, "dr"> }> = {
|
|
id: "startTime",
|
|
title: "startTime",
|
|
type: ColumnFilterType.DATE_RANGE,
|
|
};
|
|
|
|
function InsightsPageContent() {
|
|
const { t } = useLocale();
|
|
const { table } = useInsightsBookings();
|
|
const { isAll, teamId, userId } = useInsightsOrgTeams();
|
|
const { removeFilter } = useDataTable();
|
|
const [dateTarget, _setDateTarget] = useState<"startTime" | "createdAt">("startTime");
|
|
|
|
const setDateTarget = useCallback(
|
|
(target: "startTime" | "createdAt") => {
|
|
_setDateTarget(target);
|
|
removeFilter(target === "startTime" ? "createdAt" : "startTime");
|
|
},
|
|
[_setDateTarget, removeFilter]
|
|
);
|
|
|
|
return (
|
|
<>
|
|
<div
|
|
className="flex flex-wrap items-center gap-2"
|
|
data-testid={`insights-filters-${isAll}-${teamId}-${userId}`}>
|
|
<OrgTeamsFilter />
|
|
<DataTableFilters.FilterBar table={table} />
|
|
<DataTableFilters.ClearFiltersButton exclude={["startTime", "createdAt"]} />
|
|
<div className="grow" />
|
|
<Download />
|
|
<ButtonGroup combined>
|
|
<DateRangeFilter
|
|
column={dateTarget === "startTime" ? startTimeColumn : createdAtColumn}
|
|
options={{ convertToTimeZone: true }}
|
|
/>
|
|
<DateTargetSelector value={dateTarget as DateTarget} onChange={setDateTarget} />
|
|
</ButtonGroup>
|
|
<TimezoneBadge />
|
|
</div>
|
|
|
|
<div className="my-4 stack-y-4">
|
|
<BookingKPICards />
|
|
|
|
<EventTrendsChart />
|
|
|
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
|
<NoShowHostsOverTimeChart />
|
|
<CSATOverTimeChart />
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-4">
|
|
<div className="sm:col-span-2">
|
|
<BookingsByHourChart />
|
|
</div>
|
|
<div className="sm:col-span-2">
|
|
<AverageEventDurationChart />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-4">
|
|
<MostBookedTeamMembersTable />
|
|
<LeastBookedTeamMembersTable />
|
|
<MostCompletedTeamMembersTable />
|
|
<LeastCompletedTeamMembersTable />
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-4">
|
|
<MostCancelledBookingsTables />
|
|
<HighestNoShowHostTable />
|
|
<div className="sm:col-span-2">
|
|
<RecentNoShowGuestsChart />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-4">
|
|
<HighestRatedMembersTable />
|
|
<LowestRatedMembersTable />
|
|
<div className="sm:col-span-2">
|
|
<RecentFeedbackTable />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-4">
|
|
<div className="sm:col-span-2">
|
|
<PopularEventsTable />
|
|
</div>
|
|
</div>
|
|
|
|
<small className="text-default block text-center">
|
|
{t("looking_for_more_insights")}{" "}
|
|
<a
|
|
className="text-blue-500 hover:underline"
|
|
href="mailto:[email protected]?subject=Feature%20Request%3A%20More%20Analytics&body=Hey%20Cal.com%20Team%2C%20I%20love%20the%20analytics%20page%20but%20I%20am%20looking%20for%20...">
|
|
{" "}
|
|
{t("contact_support")}
|
|
</a>
|
|
</small>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|