Move top-up UI to `/store/credits`

This commit is contained in:
Krzysztof Czerwinski 2025-01-01 14:19:35 +01:00
parent 7063751bb0
commit 27019e47f7
6 changed files with 72 additions and 32 deletions

View File

@ -275,8 +275,8 @@ class UserCredit(UserCreditBase):
} }
], ],
mode="payment", mode="payment",
success_url=settings.config.platform_base_url + "/profile?topup=success", success_url=settings.config.platform_base_url + "/store/credits?topup=success",
cancel_url=settings.config.platform_base_url + "/profile?topup=cancel", cancel_url=settings.config.platform_base_url + "/store/credits?topup=cancel",
) )
# Create pending transaction # Create pending transaction

View File

@ -29,16 +29,12 @@ import {
} from "@/components/ui/alert-dialog"; } from "@/components/ui/alert-dialog";
import useSupabase from "@/hooks/useSupabase"; import useSupabase from "@/hooks/useSupabase";
import Spinner from "@/components/Spinner"; import Spinner from "@/components/Spinner";
import useCredits from "@/hooks/useCredits";
import { Input } from "@/components/ui/input";
export default function PrivatePage() { export default function PrivatePage() {
const { supabase, user, isUserLoading } = useSupabase(); const { supabase, user, isUserLoading } = useSupabase();
const router = useRouter(); const router = useRouter();
const providers = useContext(CredentialsProvidersContext); const providers = useContext(CredentialsProvidersContext);
const { toast } = useToast(); const { toast } = useToast();
const { credits, requestTopUp } = useCredits();
const [amount, setAmount] = useState(5);
const [confirmationDialogState, setConfirmationDialogState] = useState< const [confirmationDialogState, setConfirmationDialogState] = useState<
| { | {
@ -151,31 +147,6 @@ export default function PrivatePage() {
</Button> </Button>
</div> </div>
<Separator className="my-6" /> <Separator className="my-6" />
<h2 className="mb-4 text-lg">Top-Up Credits</h2>
<div className="w-full max-w-md space-y-4">
<div className="text-md">
Current credits: <b>{credits}</b> <br />1 USD = 100 credits, 5 USD is
a minimum top-up
</div>
<div className="flex gap-2">
<Input
type="number"
placeholder="Top up amount $"
value={amount}
onChange={(e) => setAmount(parseInt(e.target.value))}
className="flex-1"
min="5"
step="1"
/>
<Button
onClick={() => requestTopUp(amount)}
className="whitespace-nowrap"
>
Top-Up
</Button>
</div>
</div>
<Separator className="my-6" />
<h2 className="mb-4 text-lg">Connections & Credentials</h2> <h2 className="mb-4 text-lg">Connections & Credentials</h2>
<Table> <Table>
<TableHeader> <TableHeader>

View File

@ -0,0 +1,49 @@
"use client";
import { Button } from "@/components/agptui/Button";
import useCredits from "@/hooks/useCredits";
import { useState } from "react";
export default function CreditsPage() {
const { credits, requestTopUp } = useCredits();
const [amount, setAmount] = useState(5);
return (
<div className="w-full min-w-[800px] px-4 sm:px-8">
<h1 className="font-circular mb-6 text-[28px] font-normal text-neutral-900 dark:text-neutral-100 sm:mb-8 sm:text-[35px]">
Credits
</h1>
<p className="font-circular mb-6 text-base font-normal leading-tight text-neutral-600 dark:text-neutral-400">
Current credits: <b>{credits}</b> <br />
</p>
<h2 className="font-circular mb-4 text-lg font-normal leading-7 text-neutral-700 dark:text-neutral-300">
Top-up Credits
</h2>
<div className="w-full">
<label className="font-circular mb-1.5 block text-base font-normal leading-tight text-neutral-700 dark:text-neutral-300">
1 USD = 100 credits, 5 USD is a minimum top-up
</label>
<div className="rounded-[55px] border border-slate-200 px-4 py-2.5 dark:border-slate-700 dark:bg-slate-800">
<input
type="number"
name="displayName"
value={amount}
placeholder="Top-up amount in USD"
min="5"
step="1"
className="font-circular w-full border-none bg-transparent text-base font-normal text-neutral-900 placeholder:text-neutral-400 focus:outline-none dark:text-white dark:placeholder:text-neutral-500"
onChange={(e) => setAmount(parseInt(e.target.value))}
/>
</div>
</div>
<Button
type="submit"
variant="default"
className="mt-4 font-circular h-[50px] rounded-[35px] bg-neutral-800 px-6 py-3 text-base font-medium text-white transition-colors hover:bg-neutral-900 dark:bg-neutral-200 dark:text-neutral-900 dark:hover:bg-neutral-100"
onClick={() => requestTopUp(amount)}
>
{"Top-up"}
</Button>
</div>
)
}

View File

@ -7,6 +7,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
links: [ links: [
{ text: "Creator Dashboard", href: "/store/dashboard" }, { text: "Creator Dashboard", href: "/store/dashboard" },
{ text: "Agent dashboard", href: "/store/agent-dashboard" }, { text: "Agent dashboard", href: "/store/agent-dashboard" },
{ text: "Credits", href: "/store/credits" },
{ text: "Integrations", href: "/store/integrations" }, { text: "Integrations", href: "/store/integrations" },
{ text: "Profile", href: "/store/profile" }, { text: "Profile", href: "/store/profile" },
{ text: "Settings", href: "/store/settings" }, { text: "Settings", href: "/store/settings" },

View File

@ -8,6 +8,7 @@ import {
IconIntegrations, IconIntegrations,
IconProfile, IconProfile,
IconSliders, IconSliders,
IconCoin,
} from "../ui/icons"; } from "../ui/icons";
interface SidebarLinkGroup { interface SidebarLinkGroup {
@ -49,6 +50,15 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
Creator dashboard Creator dashboard
</div> </div>
</Link> </Link>
<Link
href="/store/credits"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconCoin className="h-6 w-6" />
<div className="p-ui-medium text-base font-medium leading-normal">
Credits
</div>
</Link>
<Link <Link
href="/integrations" href="/integrations"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white" className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
@ -93,6 +103,15 @@ export const Sidebar: React.FC<SidebarProps> = ({ linkGroups }) => {
Agent dashboard Agent dashboard
</div> </div>
</Link> </Link>
<Link
href="/store/credits"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"
>
<IconCoin className="h-6 w-6" />
<div className="p-ui-medium text-base font-medium leading-normal">
Credits
</div>
</Link>
<Link <Link
href="/integrations" href="/integrations"
className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white" className="inline-flex w-full items-center gap-2.5 rounded-xl px-3 py-3 text-neutral-800 hover:bg-neutral-800 hover:text-white dark:text-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-white"

View File

@ -323,7 +323,7 @@ export const IconCoin = createIcon((props) => (
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
strokeWidth="2" strokeWidth="1.25"
strokeLinecap="round" strokeLinecap="round"
strokeLinejoin="round" strokeLinejoin="round"
aria-label="Coin Icon" aria-label="Coin Icon"