Files
calendar/apps/web/modules/settings/billing/components/ActiveUserBreakdownSkeleton.tsx
T
sean-brydonGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
d52e2d9fad feat: active user billing (#27867)
* factory and statergie

* chore: use correct method of DI

* feat: add onchagne

* add logic to HWM stat

* add webhook resolver methods to each statergy

* move seat tracking + webhooks over to own statergy

* Move to factory base approach

* move logic to correct class

* rename create -> createByTeamId

* fix: remove debug `true ||` overrides from IS_STRIPE_ENABLED and IS_TEAM_BILLING_ENABLED

Remove accidentally committed debug overrides that short-circuited
IS_STRIPE_ENABLED and IS_TEAM_BILLING_ENABLED to always be true,
bypassing Stripe credential checks. This would break self-hosted
instances without Stripe configured.

Identified by cubic (https://cubic.dev)

Co-Authored-By: unknown <>

* feat: active user billing

* add tests

* UI side for users on active billing

* use correct period of stripe sub

* feat: claude feedback

* fix: skip Stripe sync for canceled/expired subscriptions to prevent repeated API calls

Co-Authored-By: unknown <>

* feat: feedback

* feat: only render when active users mode is set

* fix type error

* fix: constants + feature flags

* fix: default to null in tests

* chore: use seats in test

* fix: use node:crypto protocol for Node.js builtin imports

Co-Authored-By: sean@cal.com <Sean@brydon.io>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-12 13:57:32 +00:00

30 lines
961 B
TypeScript

"use client";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { PanelCard } from "@calcom/ui/components/card";
import { SkeletonText } from "@calcom/ui/components/skeleton";
export function ActiveUserBreakdownSkeleton() {
const { t } = useLocale();
return (
<PanelCard title={t("active_users_billing")} className="mt-5">
<div className="p-4">
<SkeletonText className="mb-4 h-4 w-64" />
<div className="mb-3 flex gap-4 border-b pb-3">
<SkeletonText className="h-4 w-32" />
<SkeletonText className="h-4 w-40" />
<SkeletonText className="h-4 w-20" />
</div>
{Array.from({ length: 5 }).map((_, i) => (
<div key={i} className="flex gap-4 py-3">
<SkeletonText className="h-4 w-32" />
<SkeletonText className="h-4 w-40" />
<SkeletonText className="h-4 w-20" />
</div>
))}
</div>
</PanelCard>
);
}