+6
-36
app/(home)/premium/page.tsx
+6
-36
app/(home)/premium/page.tsx
···
1
1
import Comment from "@/components/comment";
2
2
-
import ImageGrid from "@/components/image-grid";
3
2
import { OverviewLink } from "@/components/overview-link";
4
3
import { UserAvatar } from "@/components/ui/avatar";
5
4
import { Badge } from "@/components/ui/badge";
6
5
import { InputBaseAdornment, InputBaseAdornmentButton } from "@/components/ui/input-base";
7
6
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
8
8
-
import { defaultFetchOptions } from "@/lib/api";
9
7
import type User from "@/lib/discord/user";
10
8
import { getUser } from "@/lib/discord/user";
11
9
import BotStylePic from "@/public/docs-assets/bot-style.webp";
12
10
import NotificationsStylePic from "@/public/docs-assets/notifications-style.webp";
13
13
-
import type { ApiV1TopguildsGetResponse } from "@/typings";
14
11
import { cn } from "@/utils/cn";
15
12
import { getBaseUrl, getCanonicalUrl } from "@/utils/urls";
16
13
import type { Metadata } from "next";
···
28
25
const bots = ["1125449347451068437", "985213199248924722", "1097907896987160666"].map((userId) => getUser(userId));
29
26
30
27
const items = [
31
31
-
{ title: "Price", free: "€0 /forever", premium: "€4 /month" },
28
28
+
{ title: "Price", free: 0, premium: 4, unit: "€/month" },
32
29
33
30
{ title: "Your Benefits", icon: <HiUser /> },
34
31
{ title: "Text to Speech", free: Infinity, premium: Infinity, unit: "chars /month" },
···
81
78
};
82
79
};
83
80
84
84
-
export default async function Home() {
85
85
-
const topGuilds = await fetch(`${process.env.NEXT_PUBLIC_API}/top-guilds`, defaultFetchOptions).then((res) => res.json()) as ApiV1TopguildsGetResponse[];
86
86
-
81
81
+
export default function Home() {
87
82
return (
88
83
<div className="w-full">
89
84
···
97
92
</span>
98
93
</div>
99
94
100
100
-
{topGuilds && (
101
101
-
<ImageGrid
102
102
-
images={
103
103
-
topGuilds
104
104
-
.sort((a, b) => b.memberCount - a.memberCount)
105
105
-
.map((guild) => ({
106
106
-
id: guild.id,
107
107
-
url: (guild.icon || "/discord.webp").replace("gif", "webp"),
108
108
-
link: getCanonicalUrl("leaderboard", guild.id)
109
109
-
}))
110
110
-
}
111
111
-
/>
112
112
-
) }
113
113
-
114
114
-
<div className="dark:bg-wamellow bg-wamellow-100 dark:text-neutral-300 text-neutral-700 mt-10 w-full rounded-xl overflow-hidden">
95
95
+
<div className="dark:bg-wamellow bg-wamellow-100 dark:text-neutral-300 text-neutral-700 mt-2 w-full rounded-xl overflow-hidden">
115
96
116
97
<div className="flex items-center pb-4 text-2xl p-4 font-semibold bg-wamellow">
117
98
<span className="dark:text-neutral-100 text-neutral-900 w-2/4 block md:hidden">Features</span>
···
209
190
/>
210
191
211
192
<div className="p-2 fixed z-10 bottom-0 left-0 w-full md:hidden">
212
212
-
<div className="dark:bg-wamellow bg-wamellow-100 backdrop-blur-lg backdrop-brightness-50 rounded-lg shadow-md w-full flex flex-col gap-2 items-center justify-center p-3">
213
213
-
214
214
-
<div className="flex gap-2 items-center">
215
215
-
<span className="dark:text-neutral-200 text-neutral-800 font-medium text-sm">Upgrade your experience further!</span>
216
216
-
<Badge
217
217
-
variant="flat"
218
218
-
radius="rounded"
219
219
-
>
220
220
-
€4 /month
221
221
-
</Badge>
222
222
-
</div>
223
223
-
224
224
-
<Subscribe />
193
193
+
<div className="dark:bg-wamellow bg-wamellow-100 backdrop-blur-lg backdrop-brightness-50 rounded-lg shadow-md w-full p-3 ">
194
194
+
<Subscribe header />
225
195
</div>
226
196
</div>
227
197
···
238
208
239
209
if (typeof is === "number") {
240
210
return (<>
241
241
-
{is === Infinity ? <IoMdInfinite className="w-7 h-7" title="Infinite" /> : is.toLocaleString()}
211
211
+
{is === Infinity ? <IoMdInfinite className="size-7" title="Infinite" /> : is.toLocaleString()}
242
212
<span className="text-sm text-muted-foreground ml-1">{unit}</span>
243
213
</>);
244
214
}
+18
-7
app/(home)/premium/subscribe.component.tsx
+18
-7
app/(home)/premium/subscribe.component.tsx
···
1
1
"use client";
2
2
import { userStore } from "@/common/user";
3
3
+
import { Badge } from "@/components/ui/badge";
3
4
import { Button } from "@/components/ui/button";
4
5
import { InputBase, InputBaseAdornment, InputBaseAdornmentButton, InputBaseControl, InputBaseInput } from "@/components/ui/input-base";
5
5
-
import { Separator } from "@/components/ui/separator";
6
6
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
7
7
import { cn } from "@/utils/cn";
8
8
import Link from "next/link";
9
9
import { type HTMLProps, useState } from "react";
10
10
import { HiArrowDown, HiArrowUp, HiLightningBolt, HiOutlineInformationCircle } from "react-icons/hi";
11
11
12
12
-
export function Subscribe() {
12
12
+
export function Subscribe({ header }: { header?: boolean; }) {
13
13
const premium = userStore((u) => u?.premium || false);
14
14
const [donation, setDonation] = useState(0);
15
15
···
32
32
33
33
return (
34
34
<div className="w-full">
35
35
+
{header && (
36
36
+
<div className="flex gap-2 justify-center mb-2">
37
37
+
<span className="dark:text-neutral-200 text-neutral-800 font-medium text-sm">Upgrade your experience further!</span>
38
38
+
<Badge
39
39
+
variant="flat"
40
40
+
radius="rounded"
41
41
+
>
42
42
+
€{donation + 4} /month
43
43
+
</Badge>
44
44
+
</div>
45
45
+
)}
46
46
+
35
47
<div className="w-full relative overflow-hidden rounded-lg border border-border group p-px h-fit">
36
48
<span className="absolute inset-[-1000%] animate-[spin_5s_linear_infinite_reverse] bg-[conic-gradient(from_90deg_at_0%_50%,#8b5cf6_50%,hsl(var(--input)/30)_7%)]" />
37
49
<Button
38
50
asChild
39
39
-
className='w-full px-2 backdrop-blur-xs backdrop-brightness-50 md:backdrop-brightness-25 bg-none rounded-[6px] hover:bg-[#8b5cf6]/50'
51
51
+
className='w-full px-2 backdrop-blur-xs backdrop-brightness-50 md:backdrop-brightness-25 bg-none rounded-md hover:bg-[#8b5cf6]/50'
40
52
>
41
53
<Link
42
54
prefetch={false}
···
48
60
</Button>
49
61
</div>
50
62
51
51
-
<div className="relative w-full gap-2 h-3">
52
52
-
<Separator className="w-full mt-4" />
53
53
-
<span className="absolute bg-[#0d0d0d] px-2 -top-1.5 left-1/2 -translate-x-1/2 text-muted-foreground font-medium text-xs uppercase">choose what to pay</span>
63
63
+
<div className="w-full flex justify-center my-2">
64
64
+
<span className="text-muted-foreground font-medium text-xs uppercase">choose what to pay</span>
54
65
</div>
55
66
56
56
-
<div className="flex gap-1 w-full mt-2">
67
67
+
<div className="flex gap-1 w-full">
57
68
{[4, 8, 12, 18, 25].map((amount) => (
58
69
<Button
59
70
key={amount}