Component Protection

Implementing Component rotection Based on Subscription Plans

To protect Components based on a user's subscription plan, you can add the following hook to your codebase. This will be available in future releases > V1.1.0.

Add this hook in the hooks path: (hooks/use-subscribed.ts)

import { getClientPlan } from "@/actions/client/payment/stripe/subscriptions";
import { SubscriptionPlan } from "@prisma/client";
import { useQuery } from "@tanstack/react-query";
import { useSession } from "next-auth/react";

export function useSubscribed() {
    const { data: session } = useSession();
    const { data: clientPlan } = useQuery({
        queryKey: ["clientPlan"],
        queryFn: async () => await getClientPlan(),
        enabled: !!session,
    });

    const checkSubscription = (plan: SubscriptionPlan, type?: string) => {
        if (!clientPlan) return false;
        const matchesPlan = clientPlan.subscriptionPlan === plan;
        return type
            ? matchesPlan && clientPlan.subscriptionType === type
            : matchesPlan;
    };

    // Allow admins to access all features since enterprise plans have access to all features
    const isAdmin = session?.user.roles.includes("ADMIN");

    return {
        starterPlan: checkSubscription(SubscriptionPlan.STARTER),
        premiumPlan: checkSubscription(SubscriptionPlan.PREMIUM, "RECURRING"),
        plusPlan: checkSubscription(SubscriptionPlan.PLUS, "RECURRING"),
        enterprisePlan:
            checkSubscription(SubscriptionPlan.ENTREPRISE, "ONETIME") ||
            isAdmin,
    };
}

How to use it

Suppose you have a client component that only users subscribed to the Plus plan can access:

"use client";
import { useSubscribed } from "@/hooks/use-subscribed";

export default function Component() {
    const { data: session, status } = useSession();
    const isSubscribed = useSubscribed();

    if (status === "loading") {
        return <Icons.spinner className="mx-auto h-12 w-12 animate-spin" />;
    }

    if (!isSubscribed || !isSubscribed.plusPlan) {
        return (
            <div className="text-center mt-10">
                You need to subscribe to the Plus plan to access this component.
            </div>
        );
    }

    return (
        <Card className="">
            Content
        </Card>
    );
}

Last updated