add stripe (#121)

* add some stripe stuff

* more stripe stuff

* more stripe things

* more stripr stuff

* more stripe stuff

* more stripe stuff

* add more stuff

* add more stripe stuff

* more stuff

* fix types
This commit is contained in:
KM Koushik
2025-03-23 07:06:56 +11:00
committed by GitHub
parent 6cfe41cd86
commit 403ad8b93e
34 changed files with 1352 additions and 238 deletions

View File

@@ -0,0 +1,45 @@
import { Plan } from "@prisma/client";
import { PLAN_PERKS } from "~/lib/constants/payments";
import { CheckCircle2 } from "lucide-react";
import { api } from "~/trpc/react";
import Spinner from "@unsend/ui/src/spinner";
import { useTeam } from "~/providers/team-context";
import { Badge } from "@unsend/ui/src/badge";
import { format } from "date-fns";
export const PlanDetails = () => {
const subscriptionQuery = api.billing.getSubscriptionDetails.useQuery();
const { currentTeam } = useTeam();
if (subscriptionQuery.isLoading || !currentTeam) {
return null;
}
const planKey = currentTeam.plan as keyof typeof PLAN_PERKS;
const perks = PLAN_PERKS[planKey] || [];
return (
<div>
<div className="capitalize text-lg">
{subscriptionQuery.data?.status === "active"
? planKey.toLowerCase()
: "free"}
</div>
<div className="flex items-center gap-2">
<div className="text-muted-foreground text-sm">Current plan</div>
{subscriptionQuery.data?.cancelAtPeriodEnd && (
<Badge variant="secondary">
Cancels {format(subscriptionQuery.data.cancelAtPeriodEnd, "MMM dd")}
</Badge>
)}
</div>
<ul className="mt-4 space-y-3">
{perks.map((perk, index) => (
<li key={index} className="flex items-center gap-2">
<CheckCircle2 className="h-4 w-4 text-green-500 flex-shrink-0" />
<span className="text-sm">{perk}</span>
</li>
))}
</ul>
</div>
);
};

View File

@@ -0,0 +1,24 @@
import { Button } from "@unsend/ui/src/button";
import Spinner from "@unsend/ui/src/spinner";
import { api } from "~/trpc/react";
export const UpgradeButton = () => {
const checkoutMutation = api.billing.createCheckoutSession.useMutation();
const onClick = async () => {
const url = await checkoutMutation.mutateAsync();
if (url) {
window.location.href = url;
}
};
return (
<Button
onClick={onClick}
className="mt-4 w-[120px]"
disabled={checkoutMutation.isPending}
>
{checkoutMutation.isPending ? <Spinner className="w-4 h-4" /> : "Upgrade"}
</Button>
);
};