import { Badge } from "@xtablo/ui/components/badge"; import { Button } from "@xtablo/ui/components/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@xtablo/ui/components/card"; import { AlertCircle, CheckCircle2, CreditCard, Loader2Icon, Sparkles } from "lucide-react"; import { useOrganization } from "../hooks/organization"; import { normalizeBillingPlan, useCancelSubscription, useCreateCheckoutSession, useCreatePortalSession, useReactivateSubscription, useSubscription, } from "../hooks/stripe"; import { useUser } from "../providers/UserStoreProvider"; /** * Subscription management card for Settings page. */ export function SubscriptionCard() { const user = useUser(); const { data: organizationData } = useOrganization(); const { data: subscription, isLoading: subscriptionLoading } = useSubscription(); const { mutate: createCheckout, isPending: checkoutPending } = useCreateCheckoutSession(); const { mutate: openPortal, isPending: portalPending } = useCreatePortalSession(); const { mutate: cancelSubscription, isPending: cancelPending } = useCancelSubscription(); const { mutate: reactivateSubscription, isPending: reactivatePending } = useReactivateSubscription(); const fallbackPlan = normalizeBillingPlan(user.plan); const activePlan = organizationData?.active_subscription_plan ?? fallbackPlan; const isBillingOwner = organizationData?.is_billing_owner ?? false; const isPaying = activePlan === "team" || activePlan === "annual"; const isFounder = activePlan === "annual"; const requiredPlan = organizationData?.required_plan ?? "solo"; const requiredTeamQuantity = organizationData?.required_team_quantity ?? 1; const getStatusBadge = () => { if (isFounder) { return ( Founder ); } if (!subscription) { return ( Sans abonnement ); } switch (subscription.status) { case "active": return ( Actif ); case "trialing": return ( Période d'essai ); case "past_due": return ( Paiement en retard ); default: return ( {subscription.status} ); } }; return (
Abonnement
{getStatusBadge()}
{isFounder ? "Vous disposez du plan Founder (annuel) avec limites illimitées" : isPaying ? "Gérez votre abonnement et votre facturation" : "Choisissez Solo, Teams ou Founder"}
{subscriptionLoading ? (
) : ( <> {isFounder && (

Plan Founder (annuel)

Utilisateurs et tablos illimités.

)} {!isFounder && (

Plan recommandé: {requiredPlan === "team" ? "Teams" : "Solo"}

{requiredPlan === "team" ? `Votre organisation nécessite ${requiredTeamQuantity} siège${requiredTeamQuantity > 1 ? "s" : ""} Teams.` : "Votre organisation peut continuer avec Solo (1 utilisateur, 10 tablos actifs)."}

{isBillingOwner ? (
) : (

Seul le propriétaire de facturation de l'organisation peut modifier l'abonnement.

)}
)} {isPaying && subscription && !subscription.cancel_at_period_end && isBillingOwner && (

Plan {isFounder ? "Founder" : "Teams"}

Collaboration d'organisation activée

{subscription.current_period_end && (

Renouvellement le{" "} {new Date(subscription.current_period_end * 1000).toLocaleDateString( "fr-FR", { day: "numeric", month: "long", year: "numeric", } )}

)}
)} {isPaying && subscription?.cancel_at_period_end && isBillingOwner && (

Abonnement en cours d'annulation

Votre abonnement {isFounder ? "Founder" : "Teams"} sera annulé le{" "} {subscription.current_period_end && new Date(subscription.current_period_end * 1000).toLocaleDateString( "fr-FR", { day: "numeric", month: "long", year: "numeric", } )}

Vous gardez vos droits actuels jusqu'à cette date.

)} )}
); }