Skip to content

Commit 5a3bd04

Browse files
committed
[credits] Finish the credits page
1 parent d520a58 commit 5a3bd04

3 files changed

Lines changed: 33 additions & 6 deletions

File tree

src/app/credits/credits.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
'use client';
22

3+
import { Subscribe } from '@/react-starter/components/subscribe';
4+
import { Topup } from '@/react-starter/components/topup';
35
import { formatNumber } from '@/react-starter/utils/formatter';
46

5-
export default function Credits(props: { credits?: number }) {
6-
const { credits } = props;
7+
export default function Credits(props: { credits?: number; hasSubscription: boolean }) {
8+
const { credits, hasSubscription } = props;
79

8-
return (
10+
const info = (
911
<div className="text-center">
1012
<h2 className="text-lg font-medium">You have {formatNumber(credits ?? 0)} credits</h2>
1113
<p className="mb-10 text-muted-foreground">You can purchase more credits below.</p>
1214
</div>
1315
);
16+
17+
if (hasSubscription) {
18+
return <Topup>{info}</Topup>;
19+
}
20+
21+
return <Subscribe>{info}</Subscribe>;
1422
}

src/app/credits/page.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import AppMain, { AppContent } from '@/components/app-main';
22
import { auth } from '@/lib/auth';
3-
import { getCredits } from '@/lib/user-entitlement';
3+
import { getCredits, getUserEntitlement } from '@/lib/user-entitlement';
44
import { headers } from 'next/headers';
55
import { redirect } from 'next/navigation';
66
import { ErrorBoundary } from '@/components/error';
77
import Credits from './credits';
8+
import { freemius } from '@/lib/freemius';
9+
import FSCheckoutProvider from '@/components/fs-checkout';
810

911
export default async function CreditsPage() {
1012
const session = await auth.api.getSession({
@@ -15,13 +17,21 @@ export default async function CreditsPage() {
1517
redirect('/login');
1618
}
1719

20+
const entitlement = await getUserEntitlement(session.user.id);
1821
const credits = await getCredits(session.user.id);
1922

23+
const checkout = await freemius.checkout.create({
24+
user: session?.user,
25+
isSandbox: process.env.NODE_ENV !== 'production',
26+
});
27+
2028
return (
2129
<AppMain title="Credits & Topups" isLoggedIn={true}>
2230
<AppContent>
2331
<ErrorBoundary>
24-
<Credits credits={credits} />
32+
<FSCheckoutProvider checkout={checkout.serialize()}>
33+
<Credits credits={credits} hasSubscription={!!entitlement} />
34+
</FSCheckoutProvider>
2535
</ErrorBoundary>
2636
</AppContent>
2737
</AppMain>

src/components/fs-checkout.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,26 @@ import { CheckoutSerialized } from '@freemius/sdk';
55
import { IconCircleCheck } from '@tabler/icons-react';
66
import * as React from 'react';
77
import { toast } from 'sonner';
8+
import { useRouter } from 'next/navigation';
89

910
const handlePurchase = () => {
1011
toast.success(`Purchase successful`, {
1112
icon: <IconCircleCheck className="w-6 h-6 text-grow" />,
1213
description: 'You can now use the feature you just purchased.',
1314
});
1415
};
16+
1517
export default function FSCheckoutProvider(props: { children: React.ReactNode; checkout: CheckoutSerialized }) {
18+
const router = useRouter();
19+
20+
const onAfterSync = React.useCallback(() => {
21+
handlePurchase();
22+
router.refresh();
23+
}, [router]);
24+
1625
return (
1726
<CheckoutProvider
18-
onAfterSync={handlePurchase}
27+
onAfterSync={onAfterSync}
1928
checkout={props.checkout}
2029
endpoint={process.env.NEXT_PUBLIC_APP_URL! + '/api/checkout'}
2130
>

0 commit comments

Comments
 (0)