/insights (#6511)
* init page * init insights frontend * nit * nit * nit * merge * fixed icons * i18n, needs features * Init insights trpc * Using trpc on client * Added events timeline * Seed analytics script * connect ui with trpc * Added and fixed event time lines * WIP popular days and avg time duration event type * added new metric graphs * improved upgrade tip * always show upgrade screen * upgrade tremor.so and select inputs for page * Remove log * Move everything to components and add context * Fix select types using calcom ui one * Adding translations * Add missing translations * Add more translations * min fix * Fixes for date select * Prefer early return and mobile design fixes * Fix style for mobile * Fix data with userId filter from popular events * add user id to average time duration * Removed submodules * Delete website * Update yarn.lock * Code organization and type fixes * trpc fixes * Builds are now passing * Relocates server code * Cleanup * Medium size screen fixes * Added TODO --------- Co-authored-by: Alan <alannnc@gmail.com> Co-authored-by: zomars <zomars@me.com>
This commit is contained in:
43 files changed
+2536
-72
No files matched your search
@@ -99,6 +99,11 @@ const nextConfig = {
|
||||
skipDefaultConversion: true,
|
||||
preventFullImport: true,
|
||||
},
|
||||
"@calcom/features/insights/components": {
|
||||
transform: "@calcom/features/insights/components/{{member}}",
|
||||
skipDefaultConversion: true,
|
||||
preventFullImport: true,
|
||||
},
|
||||
lodash: {
|
||||
transform: "lodash/{{member}}",
|
||||
},
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
"@stripe/react-stripe-js": "^1.10.0",
|
||||
"@stripe/stripe-js": "^1.35.0",
|
||||
"@tanstack/react-query": "^4.3.9",
|
||||
"@tremor/react": "^2.0.0",
|
||||
"@types/turndown": "^5.0.1",
|
||||
"@vercel/edge-config": "^0.1.1",
|
||||
"@vercel/edge-functions-ui": "^0.2.1",
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
import {
|
||||
AverageEventDurationChart,
|
||||
BookingKPICards,
|
||||
BookingStatusLineChart,
|
||||
LeastBookedTeamMembersTable,
|
||||
MostBookedTeamMembersTable,
|
||||
PopularEventsTable,
|
||||
} from "@calcom/features/insights/components";
|
||||
import { FiltersProvider } from "@calcom/features/insights/context/FiltersProvider";
|
||||
import { useFilterContext } from "@calcom/features/insights/context/provider";
|
||||
import { Filters } from "@calcom/features/insights/filters";
|
||||
import Shell from "@calcom/features/shell/Shell";
|
||||
import { UpgradeTip } from "@calcom/features/tips";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc";
|
||||
import { Button, ButtonGroup } from "@calcom/ui";
|
||||
import { FiRefreshCcw, FiUserPlus, FiUsers } from "@calcom/ui/components/icon";
|
||||
|
||||
const Heading = () => {
|
||||
const { t } = useLocale();
|
||||
const {
|
||||
filter: { selectedTeamName },
|
||||
} = useFilterContext();
|
||||
return (
|
||||
<div className="min-w-52">
|
||||
<p className="text-lg font-semibold">
|
||||
{t("analytics_for_organisation", {
|
||||
organisationName: selectedTeamName,
|
||||
})}
|
||||
</p>
|
||||
<p>{t("subtitle_analytics")}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default function InsightsPage() {
|
||||
const { t } = useLocale();
|
||||
const { data: user } = trpc.viewer.me.useQuery();
|
||||
const features = [
|
||||
{
|
||||
icon: <FiUsers className="h-5 w-5 text-red-500" />,
|
||||
title: t("view_bookings_across"),
|
||||
description: t("view_bookings_across_description"),
|
||||
},
|
||||
{
|
||||
icon: <FiRefreshCcw className="h-5 w-5 text-blue-500" />,
|
||||
title: t("identify_booking_trends"),
|
||||
description: t("identify_booking_trends_description"),
|
||||
},
|
||||
{
|
||||
icon: <FiUserPlus className="h-5 w-5 text-green-500" />,
|
||||
title: t("spot_popular_event_types"),
|
||||
description: t("spot_popular_event_types_description"),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Shell>
|
||||
<UpgradeTip
|
||||
title={t("make_informed_decisions")}
|
||||
description={t("make_informed_decisions_description")}
|
||||
features={features}
|
||||
background="/banners/insights.jpg"
|
||||
buttons={
|
||||
<div className="space-y-2 rtl:space-x-reverse sm:space-x-2">
|
||||
<ButtonGroup>
|
||||
<Button color="primary" href={`${WEBAPP_URL}/settings/teams/new`}>
|
||||
{t("create_team")}
|
||||
</Button>
|
||||
<Button color="secondary" href="https://go.cal.com/insights" target="_blank">
|
||||
{t("learn_more")}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
}>
|
||||
{!user ? (
|
||||
<></>
|
||||
) : (
|
||||
<FiltersProvider>
|
||||
<div className="mb-4 ml-auto flex w-full flex-wrap justify-between">
|
||||
<Heading />
|
||||
<Filters />
|
||||
</div>
|
||||
<div className="mb-4 space-y-6">
|
||||
<BookingKPICards />
|
||||
|
||||
<BookingStatusLineChart />
|
||||
|
||||
<div className="grid grid-cols-1 gap-5 md:grid-cols-2">
|
||||
<PopularEventsTable />
|
||||
|
||||
<AverageEventDurationChart />
|
||||
</div>
|
||||
<div className="grid grid-cols-1 gap-5 md:grid-cols-2">
|
||||
<MostBookedTeamMembersTable />
|
||||
<LeastBookedTeamMembersTable />
|
||||
</div>
|
||||
<small className="block text-center text-gray-600">
|
||||
{t("looking_for_more_analytics")}
|
||||
<a
|
||||
className="text-blue-500 hover:underline"
|
||||
href="mailto:updates@cal.com?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>
|
||||
</FiltersProvider>
|
||||
)}
|
||||
</UpgradeTip>
|
||||
</Shell>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 155 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 204 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 173 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 56 KiB |
@@ -111,7 +111,7 @@
|
||||
"hidden_team_owner_message": "You need a pro account to use teams, you are hidden until you upgrade.",
|
||||
"link_expires": "p.s. It expires in {{expiresIn}} hours.",
|
||||
"upgrade_to_per_seat": "Upgrade to Per-Seat",
|
||||
"seat_options_doesnt_support_confirmation":"Seats option doesn't support confirmation requirement",
|
||||
"seat_options_doesnt_support_confirmation": "Seats option doesn't support confirmation requirement",
|
||||
"team_upgrade_seats_details": "Of the {{memberCount}} members in your team, {{unpaidCount}} seat(s) are unpaid. At ${{seatPrice}}/month per seat the estimated total cost of your membership is ${{totalCost}}/month.",
|
||||
"team_upgrade_banner_description": "Thank you for trialing our new team plan. We noticed your team \"{{teamName}}\" needs to be upgraded.",
|
||||
"team_upgrade_banner_action": "Upgrade here",
|
||||
@@ -433,7 +433,7 @@
|
||||
"password_hint_min": "Minimum 7 characters long",
|
||||
"password_hint_admin_min": "Minimum 15 characters long",
|
||||
"password_hint_num": "Contain at least 1 number",
|
||||
"max_limit_allowed_hint":"Must be {{limit}} or fewer characters long",
|
||||
"max_limit_allowed_hint": "Must be {{limit}} or fewer characters long",
|
||||
"invalid_password_hint": "The password must be a minimum of {{passwordLength}} characters long containing at least one number and have a mixture of uppercase and lowercase letters",
|
||||
"incorrect_password": "Password is incorrect.",
|
||||
"incorrect_username_password": "Username or password is incorrect.",
|
||||
@@ -863,7 +863,7 @@
|
||||
"add_new_calendar": "Add a new calendar",
|
||||
"set_calendar": "Set where to add new events to when you're booked.",
|
||||
"delete_schedule": "Delete schedule",
|
||||
"delete_schedule_description":"Deleting a schedule will remove it from all event types. This action cannot be undone.",
|
||||
"delete_schedule_description": "Deleting a schedule will remove it from all event types. This action cannot be undone.",
|
||||
"schedule_created_successfully": "{{scheduleName}} schedule created successfully",
|
||||
"availability_updated_successfully": "{{scheduleName}} schedule updated successfully",
|
||||
"schedule_deleted_successfully": "Schedule deleted successfully",
|
||||
@@ -1631,22 +1631,30 @@
|
||||
"a_routing_form": "A Routing Form",
|
||||
"form_description_placeholder": "Form Description",
|
||||
"keep_me_connected_with_form": "Keep me connected with the form",
|
||||
"fields_in_form_duplicated":"Any changes in Router and Fields of the form being duplicated, would reflect in the duplicate.",
|
||||
"fields_in_form_duplicated": "Any changes in Router and Fields of the form being duplicated, would reflect in the duplicate.",
|
||||
"form_deleted": "Form deleted",
|
||||
"delete_form": "Are you sure you want to delete this form?",
|
||||
"delete_form_action": "Yes, delete Form",
|
||||
"delete_form_confirmation":"Anyone who you've shared the link with will no longer be able to access it.",
|
||||
"delete_form_confirmation_2":"All associated responses will be deleted.",
|
||||
"delete_form_confirmation": "Anyone who you've shared the link with will no longer be able to access it.",
|
||||
"delete_form_confirmation_2": "All associated responses will be deleted.",
|
||||
"typeform_redirect_url_copied": "Typeform Redirect URL copied! You can go and set the URL in Typeform form.",
|
||||
"modifications_in_fields_warning": "Modifications in fields and routes of following forms will be reflected in this form.",
|
||||
"connected_forms": "Connected Forms",
|
||||
"form_modifications_warning": "Following forms would be affected when you modify fields or routes here.",
|
||||
"responses_collection_waiting_description": "Wait for some time for responses to be collected. You can go and submit the form yourself as well.",
|
||||
"this_is_what_your_users_would_see":"This is what your users would see",
|
||||
"this_is_what_your_users_would_see": "This is what your users would see",
|
||||
"identifies_name_field": "Identifies field by this name.",
|
||||
"add_1_option_per_line": "Add 1 option per line",
|
||||
"select_a_router": "Select a router",
|
||||
"add_a_new_route": "Add a new Route",
|
||||
"make_informed_decisions": "Make informed decisions with Insights",
|
||||
"make_informed_decisions_description": "Our Insights dashboard surfaces all activity across your team and shows you trends that enable better team scheduling and decision making.",
|
||||
"view_bookings_across": "View bookings across all members",
|
||||
"view_bookings_across_description": "See who’s receiving the most bookings and ensure the best distribution across your team",
|
||||
"identify_booking_trends": "Identify booking trends",
|
||||
"identify_booking_trends_description": "See what times of the week and what times during the day are popular for your bookers",
|
||||
"spot_popular_event_types": "Spot popular event types",
|
||||
"spot_popular_event_types_description": "See which of your event types are receiving the most clicks and bookings",
|
||||
"no_responses_yet": "No responses yet",
|
||||
"this_will_be_the_placeholder": "This will be the placeholder",
|
||||
"this_meeting_has_not_started_yet": "This meeting has not started yet",
|
||||
@@ -1657,8 +1665,27 @@
|
||||
"verification_code": "Verification code",
|
||||
"can_you_try_again": "Can you try again with a different time?",
|
||||
"verify": "Verify",
|
||||
"invalid_event_name_variables":"There is an invalid variable in your event name",
|
||||
"invalid_event_name_variables": "There is an invalid variable in your event name",
|
||||
"select_all": "Select All",
|
||||
"default_conferencing_bulk_title": "Bulk update existing event types",
|
||||
"default_conferencing_bulk_description": "Update the locations for the selected event types"
|
||||
"default_conferencing_bulk_description": "Update the locations for the selected event types",
|
||||
"looking_for_more_analytics": "Looking for more analytics?",
|
||||
"add_filter": "Add filter",
|
||||
"select_user": "Select User",
|
||||
"select_event_type": "Select Event Type",
|
||||
"select_date_range": "Select Date Range",
|
||||
"popular_events": "Popular Events",
|
||||
"no_event_types_found": "No event types found",
|
||||
"average_event_duration": "Average Event Duration",
|
||||
"most_booked_members": "Most Booked Members",
|
||||
"least_booked_members": "Least Booked Members",
|
||||
"events_created": "Events Created",
|
||||
"events_completed": "Events Completed",
|
||||
"events_cancelled": "Events Cancelled",
|
||||
"events_rescheduled": "Events Rescheduled",
|
||||
"from_last_period": "from last period",
|
||||
"from_to_date_period": "From: {{startDate}} To: {{endDate}}",
|
||||
"analytics_for_organisation": "Analytics for {{organisationName}}",
|
||||
"subtitle_analytics": "This is a organisation analytics",
|
||||
"event_trends": "Event Trends"
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB |
@@ -2,5 +2,5 @@ const base = require("@calcom/config/tailwind-preset");
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
...base,
|
||||
content: [...base.content],
|
||||
content: [...base.content, "../../node_modules/@tremor/**/*.{js,ts,jsx,tsx}"],
|
||||
};
|
||||
Reference in new issue
Block a user