Skip to content

Commit

Permalink
feat(saas): get subscription count from lemon
Browse files Browse the repository at this point in the history
  • Loading branch information
alifarooq9 committed May 2, 2024
1 parent f6c27cf commit 0151175
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 33 deletions.
6 changes: 4 additions & 2 deletions starterkits/saas/src/app/(app)/admin/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import { adminDashConfig } from "@/app/(app)/admin/dashboard/_constants/page-con
import { buttonVariants } from "@/components/ui/button";
import { siteUrls } from "@/config/urls";
import { cn } from "@/lib/utils";
import { getSubscriptionsCount } from "@/server/actions/plans/query";
import { getUsersCount } from "@/server/actions/user/queries";
import { DollarSignIcon, Users2Icon } from "lucide-react";
import Link from "next/link";

export default async function AdminDashPage() {
const usersCountData = await getUsersCount();

const usersChartData = usersCountData.usersCountByMonth;

const subscriptionsCountData = await getSubscriptionsCount({});

return (
<AppPageShell
title={adminDashConfig.title}
Expand Down Expand Up @@ -54,7 +56,7 @@ export default async function AdminDashPage() {

<StatsCard
title="Subscriptions"
value="100"
value={String(subscriptionsCountData.totalCount)}
Icon={DollarSignIcon}
subText="Total subscriptions made"
/>
Expand Down
4 changes: 2 additions & 2 deletions starterkits/saas/src/config/pricing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export const pricingPlans: PrincingPlan[] = [
monthly: 99,
yearly: 999,
},
variantId: { monthly: 335144, yearly: 335149 },
variantId: { monthly: 362869, yearly: 362870 },
currency: {
code: "USD",
symbol: "$",
Expand All @@ -159,7 +159,7 @@ export const pricingPlans: PrincingPlan[] = [
monthly: 199,
yearly: 1999,
},
variantId: { monthly: 335161, yearly: 335167 },
variantId: { monthly: 362872, yearly: 362874 },
currency: {
code: "USD",
symbol: "$",
Expand Down
File renamed without changes.
113 changes: 84 additions & 29 deletions starterkits/saas/src/server/actions/plans/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@ import { db } from "@/server/db";
import { subscriptions } from "@/server/db/schema";
import { configureLemonSqueezy } from "@/server/lemonsqueezy";
import { protectedProcedure } from "@/server/procedures";
import { createCheckout, getSubscription } from "@lemonsqueezy/lemonsqueezy.js";
import {
createCheckout,
getSubscription,
listSubscriptions,
type Subscription,
} from "@lemonsqueezy/lemonsqueezy.js";
import { eq } from "drizzle-orm";
import { redirect } from "next/navigation";
import { eachMonthOfInterval, format, startOfMonth, subMonths } from "date-fns";

export async function getCheckoutURL(variantId?: number, embed = false) {
await protectedProcedure();
Expand Down Expand Up @@ -62,42 +68,91 @@ export async function getCheckoutURL(variantId?: number, embed = false) {
}

export async function getOrgSubscription() {
configureLemonSqueezy();
await protectedProcedure();
try {
await protectedProcedure();
configureLemonSqueezy();

const { currentOrg } = await getOrganizations();

const orgSubscription = await db.query.subscriptions.findFirst({
where: eq(subscriptions.orgId, currentOrg.id),
});

if (!orgSubscription) {
return null;
}

const lemonSubscription = await getSubscription(
orgSubscription?.lemonSqueezyId,
);

if (!lemonSubscription.data?.data) {
return null;
}

const customerPortalUrl =
lemonSubscription.data.data.attributes.urls.customer_portal;

// add plan details to the subscription
const plan = pricingPlans.find(
(p) =>
p.variantId?.monthly === orgSubscription?.variantId ||
p.variantId?.yearly === orgSubscription?.variantId,
);

return {
...lemonSubscription.data.data.attributes,
lemonSqueezyId: lemonSubscription.data.data.id,
customerPortalUrl,
id: orgSubscription.id,
plan,
};
} catch (error) {
return null;
}
}

const { currentOrg } = await getOrganizations();
type SubscriptionCountByMonth = {
status?: Subscription["data"]["attributes"]["status"];
};

const orgSubscription = await db.query.subscriptions.findFirst({
where: eq(subscriptions.orgId, currentOrg.id),
});
export async function getSubscriptionsCount({
status,
}: SubscriptionCountByMonth) {
await protectedProcedure();
configureLemonSqueezy();

if (!orgSubscription) {
return null;
}
const dateBeforeMonths = subMonths(new Date(), 6);

const lemonSubscription = await getSubscription(
orgSubscription?.lemonSqueezyId,
);
const startDateOfTheMonth = startOfMonth(dateBeforeMonths);

if (!lemonSubscription.data?.data) {
return null;
}
const subscriptions = await listSubscriptions({
filter: {
storeId: env.LEMONSQUEEZY_STORE_ID,
status,
},
});

const customerPortalUrl =
lemonSubscription.data.data.attributes.urls.customer_portal;
const months = eachMonthOfInterval({
start: startDateOfTheMonth,
end: new Date(),
});

// add plan details to the subscription
const plan = pricingPlans.find(
(p) =>
p.variantId?.monthly === orgSubscription?.variantId ||
p.variantId?.yearly === orgSubscription?.variantId,
);
const subscriptionsCountByMonth = months.map((month) => {
const monthStr = format(month, "MMM-yyy");
const count =
subscriptions.data?.data.filter(
(subscription) =>
format(
new Date(subscription.attributes.created_at),
"MMM-yyy",
) === monthStr,
)?.length ?? 0;
return { Date: monthStr, Count: count };
});

return {
...lemonSubscription.data.data.attributes,
lemonSqueezyId: lemonSubscription.data.data.id,
customerPortalUrl,
id: orgSubscription.id,
plan,
totalCount: subscriptions.data?.data.length ?? 0,
subscriptionsCountByMonth,
};
}

0 comments on commit 0151175

Please sign in to comment.