55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import { createResource, createMemo } from "solid-js";
|
|
import { api } from "~/lib/api";
|
|
|
|
const FEATURE_TIERS: Record<string, string> = {
|
|
voiceprint: "plus",
|
|
hometitle: "plus",
|
|
removebrokers: "plus",
|
|
darkwatch_realtime: "premium",
|
|
removebrokers_unlimited: "premium",
|
|
};
|
|
|
|
const TIER_ORDER = { free: -1, basic: 0, plus: 1, premium: 2 };
|
|
|
|
export function useSubscription() {
|
|
const [subscription] = createResource(() =>
|
|
api.billing.getSubscription.query(),
|
|
);
|
|
|
|
const tier = () => subscription()?.tier ?? "free";
|
|
const effectiveTier = () => subscription()?.effectiveTier ?? "free";
|
|
const isTrialing = () => subscription()?.isTrialing ?? false;
|
|
const trials = () => subscription()?.trials ?? [];
|
|
|
|
const hasFeature = (feature: string) => {
|
|
const requiredTier = FEATURE_TIERS[feature];
|
|
if (!requiredTier) return true;
|
|
|
|
const currentLevel = TIER_ORDER[effectiveTier() as keyof typeof TIER_ORDER] ?? TIER_ORDER.free;
|
|
const requiredLevel = TIER_ORDER[requiredTier as keyof typeof TIER_ORDER] ?? 0;
|
|
|
|
if (currentLevel >= requiredLevel) return true;
|
|
|
|
const now = new Date();
|
|
return trials().some(
|
|
(t: { feature: string; status: string; expiresAt: string | Date }) =>
|
|
t.feature === feature && t.status === "active" && new Date(t.expiresAt) > now,
|
|
);
|
|
};
|
|
|
|
const requestFeatureTrial = api.billing.requestFeatureTrial.mutate;
|
|
const upgradeFromTrial = api.billing.upgradeFromTrial.mutate;
|
|
|
|
return {
|
|
subscription,
|
|
tier,
|
|
effectiveTier,
|
|
isTrialing,
|
|
trials,
|
|
isLoading: subscription.loading,
|
|
hasFeature,
|
|
requestFeatureTrial,
|
|
upgradeFromTrial,
|
|
};
|
|
}
|