Skip to content

Commit d1405ad

Browse files
authored
Merge branch 'main' into sync-prod-2
2 parents 7d60b7d + 401c850 commit d1405ad

File tree

12 files changed

+716
-456
lines changed

12 files changed

+716
-456
lines changed

.vscode/settings.json

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
{
2-
"css.customData": [
3-
".vscode/tailwind.json"
4-
],
5-
"editor.defaultFormatter": "esbenp.prettier-vscode",
6-
"[typescriptreact]": {
7-
"editor.defaultFormatter": "vscode.typescript-language-features"
8-
}
2+
"css.customData": [".vscode/tailwind.json"],
3+
"editor.defaultFormatter": "esbenp.prettier-vscode",
4+
"[typescriptreact]": {
5+
"editor.defaultFormatter": "vscode.typescript-language-features"
6+
}
97
}

app/api/servers/route.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { NextResponse } from 'next/server'
2+
import { getServer } from '@/lib/redis'
3+
4+
export async function GET() {
5+
try {
6+
const servers = await getServer()
7+
8+
if (!servers) {
9+
return NextResponse.json(
10+
{ error: 'No servers found or user not authenticated' },
11+
{
12+
status: 404,
13+
headers: {
14+
'Cache-Control': 's-maxage=60, stale-while-revalidate=300'
15+
}
16+
}
17+
)
18+
}
19+
20+
return NextResponse.json(servers, {
21+
status: 200,
22+
headers: {
23+
'Cache-Control': 's-maxage=60, stale-while-revalidate=300'
24+
}
25+
})
26+
} catch (error) {
27+
console.error('Error fetching servers:', error)
28+
return NextResponse.json(
29+
{ error: 'Failed to fetch servers' },
30+
{
31+
status: 500,
32+
headers: {
33+
'Cache-Control': 'no-cache'
34+
}
35+
}
36+
)
37+
}
38+
}

app/globals.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898

9999
@layer base {
100100
* {
101-
@apply brand-focus rounded border-border ring-offset-background;
101+
@apply brand-focus border-border ring-offset-background;
102102
}
103103

104104
body {

app/premium/_components/checkoutButton.tsx

+28-44
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
11
'use client'
22

3-
import { Button } from '@/components/ui/button'
3+
import { Button, type ButtonProps } from '@/components/ui/button'
4+
import { Fragment, useEffect, useState } from 'react'
45
import { loadStripe } from '@stripe/stripe-js'
5-
import { useState } from 'react'
6+
import { LoaderCircle } from 'lucide-react'
67
import { toast } from 'sonner'
78
import axios from 'axios'
89

9-
interface CheckoutButtonProps {
10+
interface CheckoutButtonProps extends ButtonProps {
1011
monthly: string
1112
serverId: string | undefined
1213
priceId: string
14+
loading?: boolean
1315
}
1416

1517
// sub button
1618
export default function CheckoutButton({
1719
monthly,
1820
serverId,
19-
priceId
21+
priceId,
22+
loading
2023
}: CheckoutButtonProps) {
21-
const [loading, setLoading] = useState(false)
24+
const [isLoading, setIsLoading] = useState(loading)
25+
26+
const handleClick = async () => {
27+
setIsLoading(true)
28+
await handleCheckout()
29+
}
2230

2331
const handleCheckout = async () => {
24-
setLoading(true)
25-
const stripePromise = loadStripe(
26-
process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!
27-
)
32+
const stripeKey = process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
33+
if (!stripeKey) throw new Error('Stripe key not found')
34+
35+
const stripePromise = loadStripe(stripeKey)
2836
const stripe = await stripePromise
2937

3038
toast.promise(
@@ -56,48 +64,24 @@ export default function CheckoutButton({
5664
)
5765
}
5866
)
59-
60-
setLoading(false)
6167
}
6268

69+
useEffect(() => {
70+
setIsLoading(loading)
71+
}, [loading])
72+
6373
return (
6474
<button
65-
disabled={!serverId || loading}
66-
onClick={handleCheckout}
75+
type="button"
6776
className="ml-auto mt-4 flex w-fit items-center justify-center rounded-lg bg-brand-blue-100 px-5 py-1 text-sm font-bold leading-loose text-white disabled:cursor-not-allowed disabled:bg-background-darker disabled:text-foreground/40"
77+
onClick={handleClick}
78+
disabled={isLoading ? isLoading : !serverId}
6879
>
69-
{loading ?
70-
<>
71-
<svg
72-
width="100"
73-
height="101"
74-
className="mr-2 inline h-4 w-4 animate-spin text-foreground"
75-
viewBox="0 0 100 101"
76-
fill="none"
77-
xmlns="http://www.w3.org/2000/svg"
78-
>
79-
<g clip-path="url(#clip0_353_3030)">
80-
<path
81-
d="M100 50.5907C100 78.205 77.6142 100.591 50 100.591C22.3858 100.591 0 78.205 0 50.5907C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5907ZM9.08144 50.5907C9.08144 73.1894 27.4013 91.5092 50 91.5092C72.5987 91.5092 90.9186 73.1894 90.9186 50.5907C90.9186 27.9921 72.5987 9.67224 50 9.67224C27.4013 9.67224 9.08144 27.9921 9.08144 50.5907Z"
82-
fill="#171717"
83-
/>
84-
<path
85-
d="M93.9683 39.0409C96.3937 38.4038 97.8631 35.9116 97.0086 33.5539C95.2939 28.8227 92.8717 24.3692 89.8174 20.348C85.8459 15.1192 80.8833 10.7238 75.2131 7.41289C69.5429 4.10194 63.2761 1.94025 56.7705 1.05124C51.7673 0.367542 46.6983 0.446844 41.7352 1.27873C39.262 1.69328 37.8137 4.19778 38.4508 6.62326C39.088 9.04874 41.5701 10.4717 44.0512 10.1071C47.8518 9.54855 51.7198 9.52689 55.5409 10.0491C60.8649 10.7766 65.9935 12.5457 70.6338 15.2552C75.2742 17.9648 79.3354 21.5619 82.5856 25.841C84.9182 28.9121 86.8004 32.2913 88.1818 35.8758C89.0837 38.2158 91.5428 39.6781 93.9683 39.0409Z"
86-
fill="#0598F4"
87-
/>
88-
</g>
89-
<defs>
90-
<clipPath id="clip0_353_3030">
91-
<rect
92-
width="100"
93-
height="101"
94-
fill="white"
95-
/>
96-
</clipPath>
97-
</defs>
98-
</svg>
80+
{isLoading ?
81+
<Fragment>
82+
<LoaderCircle className="animate-spin size-4 mr-2" />
9983
Loading...
100-
</>
84+
</Fragment>
10185
: 'Checkout'}
10286
</button>
10387
)

0 commit comments

Comments
 (0)