Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion apps/web/modules/insights/insights-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
RecentFeedbackTable,
TimezoneBadge,
} from "@calcom/features/insights/components/booking";
import "@calcom/features/insights/components/tremor.css";
import { InsightsOrgTeamsProvider } from "@calcom/features/insights/context/InsightsOrgTeamsProvider";
import { Download } from "@calcom/features/insights/filters/Download";
import { OrgTeamsFilter } from "@calcom/features/insights/filters/OrgTeamsFilter";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use client";

import { ProgressBar } from "@tremor/react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState, useMemo } from "react";
Expand All @@ -16,6 +15,7 @@ import { trpc } from "@calcom/trpc/react";
import { Button } from "@calcom/ui/components/button";
import { Select } from "@calcom/ui/components/form";
import { TextField, Label, InputError } from "@calcom/ui/components/form";
import { ProgressBar } from "@calcom/ui/components/progress-bar";
import { showToast } from "@calcom/ui/toast";

import { BillingCreditsSkeleton } from "./BillingCreditsSkeleton";
Expand Down
1 change: 0 additions & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
"@stripe/stripe-js": "^1.35.0",
"@tanstack/react-query": "^5.17.15",
"@team-plain/typescript-sdk": "^5.9.0",
"@tremor/react": "^2.11.0",
"@types/turndown": "^5.0.1",
"@unkey/ratelimit": "^0.1.1",
"@upstash/redis": "^1.21.0",
Expand Down
2 changes: 2 additions & 0 deletions apps/web/public/static/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -3402,6 +3402,7 @@
"license_key_saved": "License key saved successfully",
"timezone_mismatch_tooltip": "You are viewing the report based on your profile timezone ({{userTimezone}}), while your browser is set to timezone ({{browserTimezone}})",
"failed_bookings_by_field": "Failed Bookings By Field",
"failed_bookings": "Failed bookings",
"event_type_no_hosts": "No hosts are assigned to event type",
"cache_status": "Cache Status",
"cache_last_updated": "Last updated: {{timestamp}}",
Expand Down Expand Up @@ -3429,6 +3430,7 @@
"usage_based_expiration_description": "This link can be used for {{count}} booking",
"usage_based_generic_expiration_description": "This link can be configured to expire after a set number of bookings",
"usage_based_expiration_description_plural": "This link can be used for {{count}} bookings",
"stats": "Stats",
"booking_status": "Booking status",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
}
6 changes: 1 addition & 5 deletions apps/web/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ const base = require("@calcom/config/tailwind-preset");
/** @type {import('tailwindcss').Config} */
module.exports = {
...base,
content: [
...base.content,
"../../packages/app-store/routing-forms/**/*.{js,ts,jsx,tsx}",
"../../node_modules/@tremor/**/*.{js,ts,jsx,tsx}",
],
content: [...base.content, "../../packages/app-store/routing-forms/**/*.{js,ts,jsx,tsx}"],
plugins: [...base.plugins, require("tailwindcss-animate")],
};
18 changes: 0 additions & 18 deletions packages/features/insights/components/Card.tsx

This file was deleted.

12 changes: 8 additions & 4 deletions packages/features/insights/components/ChartCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function ChartCard({
legendSize,
children,
}: {
title: string;
title: string | React.ReactNode;
subtitle?: string;
cta?: { label: string; onClick: () => void };
legend?: Array<LegendItem>;
Expand All @@ -31,7 +31,11 @@ export function ChartCard({
return (
<div className="bg-muted group relative flex w-full flex-col items-center rounded-2xl px-1 pb-1">
<div className="flex h-11 w-full shrink-0 items-center justify-between gap-2 px-4">
<h2 className="text-emphasis mr-4 shrink-0 text-sm font-semibold">{title}</h2>
{typeof title === "string" ? (
<h2 className="text-emphasis mr-4 shrink-0 text-sm font-semibold">{title}</h2>
) : (
title
)}
<div className="no-scrollbar flex items-center gap-2 overflow-x-auto">
{legend && legend.length > 0 && <Legend items={legend} size={legendSize} />}
{cta && (
Expand Down Expand Up @@ -80,13 +84,13 @@ function Legend({ items, size = "default" }: { items: LegendItem[]; size?: Legen
{items.map((item, index) => (
<Fragment key={item.label}>
<div
className="relative flex items-center gap-2 rounded-md px-1.5 py-1"
className="relative flex items-center gap-2 rounded-md px-1.5 py-0.5"
style={{ backgroundColor: `${item.color}33` }}>
<div className="h-2 w-2 rounded-full" style={{ backgroundColor: item.color }} />
<Tooltip content={item.label}>
<p
className={classNames(
"text-default truncate text-sm font-medium leading-none",
"text-default truncate py-0.5 text-sm font-medium leading-none",
size === "sm" ? "w-16" : ""
)}>
{item.label}
Expand Down
71 changes: 51 additions & 20 deletions packages/features/insights/components/KPICard.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,73 @@
"use client";

import { Flex, Text, Metric, BadgeDelta } from "@tremor/react";

import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Badge } from "@calcom/ui/components/badge";
import { Icon } from "@calcom/ui/components/icon";
import { Tooltip } from "@calcom/ui/components/tooltip";

import { calculateDeltaType, colors, valueFormatter } from "../lib";
import { calculateDeltaType, valueFormatter } from "../lib";

export const KPICard = ({
title,
previousMetricData,
previousDateRange,
}: {
title: string;
value: number;
previousMetricData: {
count: number;
deltaPrevious: number;
};
previousDateRange: { startDate: string; endDate: string };
}) => {
const { t } = useLocale();

const deltaType = calculateDeltaType(previousMetricData.deltaPrevious - previousMetricData.count);
const deltaValue = Number(previousMetricData.deltaPrevious).toFixed(0);

const getBadgeVariant = (type: string) => {
switch (type) {
case "increase":
case "moderateIncrease":
return "success" as const;
case "decrease":
case "moderateDecrease":
return "error" as const;
case "unchanged":
default:
return "gray" as const;
}
};

// Get appropriate icon for delta
const getDeltaIcon = (type: string) => {
switch (type) {
case "increase":
case "moderateIncrease":
return "arrow-up" as const;
case "decrease":
case "moderateDecrease":
return "arrow-down" as const;
case "unchanged":
default:
return null;
}
};

const badgeVariant = getBadgeVariant(deltaType);
const deltaIcon = getDeltaIcon(deltaType);

return (
<div>
<Text className="text-default">{title}</Text>
<Flex className="items-baseline justify-start space-x-3 truncate">
<Metric className="text-emphasis">{valueFormatter(previousMetricData.count)}</Metric>
</Flex>
<Flex className="mt-4 justify-start space-x-2">
<BadgeDelta
deltaType={calculateDeltaType(previousMetricData.deltaPrevious - previousMetricData.count)}
/>
<Flex className="justify-start space-x-1 truncate">
<Text
color={colors[calculateDeltaType(previousMetricData.deltaPrevious - previousMetricData.count)]}>
{Number(previousMetricData.deltaPrevious).toFixed(0)}%
</Text>

<div className="text-default text-sm">{title}</div>
<div className="flex items-baseline justify-start space-x-3 truncate">
<div className="text-emphasis text-2xl font-semibold">{valueFormatter(previousMetricData.count)}</div>
</div>
<div className="mt-4 flex items-center justify-start space-x-2">
<Badge variant={badgeVariant} className="flex items-center gap-1">
{deltaIcon && <Icon name={deltaIcon} className="h-3 w-3" />}
{deltaValue}%
</Badge>
<div className="flex justify-start space-x-1 truncate">
<Tooltip
content={t("from_to_date_period", {
startDate: previousDateRange.startDate,
Expand All @@ -46,8 +77,8 @@ export const KPICard = ({
{t("from_last_period")}
</small>
</Tooltip>
</Flex>
</Flex>
</div>
</div>
</div>
);
};
8 changes: 0 additions & 8 deletions packages/features/insights/components/LineChart.tsx

This file was deleted.

25 changes: 12 additions & 13 deletions packages/features/insights/components/LoadingInsights.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
import classNames from "@calcom/ui/classNames";
import { SkeletonText } from "@calcom/ui/components/skeleton";

import { CardInsights } from "./Card";
import { ChartCard } from "./ChartCard";

export const LoadingInsight = () => {
return (
<CardInsights>
<SkeletonText className="w-32" />
<ChartCard title={<SkeletonText className="w-32" />}>
<div className="m-auto flex h-80 flex-col items-center justify-center">
<svg
className={classNames("mx-4 h-8 w-8 animate-spin", "text-black dark:text-white")}
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className="animate-spin">
<path d="M21 12a9 9 0 1 1-6.219-8.56" />
</svg>
</div>
</CardInsights>
</ChartCard>
);
};
31 changes: 15 additions & 16 deletions packages/features/insights/components/UserStatsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,24 @@

import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { User } from "@calcom/prisma/client";
import { Avatar } from "@calcom/ui/components/avatar";

import { ChartCardItem } from "./ChartCard";

export const UserStatsTable = ({
data,
}: {
data:
| {
userId: number | null;
user: Pick<User, "avatarUrl" | "name">;
emailMd5?: string;
count?: number;
averageRating?: number | null;
username?: string;
}[]
| undefined;
}) => {
type UserStatsData = {
userId: number;
user: {
id: number;
username: string | null;
name: string | null;
email: string;
avatarUrl: string;
};
emailMd5: string;
count: number;
}[];

export const UserStatsTable = ({ data }: { data: UserStatsData }) => {
const { t } = useLocale();

// Filter out items without user data
Expand All @@ -32,7 +31,7 @@ export const UserStatsTable = ({
filteredData.map((item) => (
<ChartCardItem
key={item.userId || `user-${Math.random()}`}
count={item.averageRating ? item.averageRating.toFixed(1) : item.count}
count={Number.isInteger(item.count) ? item.count : item.count.toFixed(1)}
className="py-3">
<div className="flex items-center">
<Avatar
Expand Down
Loading
Loading