Skip to content

Commit

Permalink
feat: add credits page
Browse files Browse the repository at this point in the history
  • Loading branch information
altaywtf committed Dec 16, 2023
1 parent b3434d0 commit a8f4302
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
73 changes: 73 additions & 0 deletions app/credits/components/credit-list-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
'use client';

import { createCheckoutSession } from '@/lib/services/stripe/checkout';
import { Badge, Button, Flex, Text } from '@radix-ui/themes';
import { atom, useAtom } from 'jotai';

type Props = {
amount: number;
id: string;
popular?: boolean;
quantity: number;
};

const checkoutStatusAtom = atom<
{ id: string; type: 'loading' } | { type: 'idle' }
>({
type: 'idle',
});

export function CreditListItem({ amount, id, popular, quantity }: Props) {
const [checkoutStatus, setCheckoutStatus] = useAtom(checkoutStatusAtom);

const handleClick = async () => {
try {
setCheckoutStatus({ id, type: 'loading' });

const checkoutSession = await createCheckoutSession({
baseUrl: `${window.location.origin}/credits`,
priceId: id,
});

if (!checkoutSession.url) {
setCheckoutStatus({ type: 'idle' });
return;
}

window.location.href = checkoutSession.url;
} catch (error) {
setCheckoutStatus({ type: 'idle' });
}
};

return (
<Flex align="center" direction="row" justify="between">
<Flex direction="column" gap="1">
<Flex align="center" gap="1">
<Text size="3" weight="medium">
{quantity} credits
</Text>

{popular ? <Badge color="mint">Most popular</Badge> : null}
</Flex>

<Text color="gray" size="2">
${(amount / quantity).toFixed(2)} per episode summarization.
</Text>
</Flex>

<Button
data-disabled={checkoutStatus.type === 'loading' ? 'true' : undefined}
highContrast
onClick={handleClick}
size="2"
style={{ minWidth: 64 }}
variant="soft"
>
{checkoutStatus.type === 'loading' && checkoutStatus.id === id
? 'Loading...'
: `$${amount}`}
</Button>
</Flex>
);
}
1 change: 1 addition & 0 deletions app/credits/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AppLayout as default } from '@/components/layout/app-layout';
45 changes: 45 additions & 0 deletions app/credits/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { fetchAccountAICredits } from '@/lib/services/account';
import { getPrices } from '@/lib/services/stripe/prices';
import { Box, Card, Flex, Heading, Separator, Text } from '@radix-ui/themes';
import { Provider } from 'jotai';

import { CreditListItem } from './components/credit-list-item';

export default async function Page() {
const credits = await fetchAccountAICredits();
const prices = await getPrices();

return (
<Box mx="auto" style={{ maxWidth: 'var(--container-1)' }}>
<Card size="3">
<Flex direction="column" gap="4">
<Flex direction="column" gap="2">
<Heading as="h3" size="4" trim="both">
Buy AI credits
</Heading>

<Text color="gray" size="2">
You currently have <Text weight="medium">{credits}</Text> credits.
</Text>
</Flex>

<Separator orientation="horizontal" size="4" />

<Provider>
<Flex direction="column" gap="4">
{prices.map((price, index) => (
<CreditListItem
amount={price.unit_amount! / 100}
id={price.id}
key={price.id}
popular={index === 1}
quantity={price.transform_quantity!.divide_by}
/>
))}
</Flex>
</Provider>
</Flex>
</Card>
</Box>
);
}

0 comments on commit a8f4302

Please sign in to comment.