Show number of credits left
This commit is contained in:
parent
a46ff8692c
commit
5256d428e0
@ -11,20 +11,60 @@ import {
|
||||
import { useStore } from "../../store/store";
|
||||
import { capitalize } from "./utils";
|
||||
import StripeCustomerPortalLink from "./StripeCustomerPortalLink";
|
||||
import { Progress } from "../ui/progress";
|
||||
import { useAuthenticatedFetch } from "./useAuthenticatedFetch";
|
||||
import { SAAS_BACKEND_URL } from "../../config";
|
||||
import { CreditsUsage } from "./types";
|
||||
import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
|
||||
export default function AvatarDropdown() {
|
||||
const { user, isLoaded, isSignedIn } = useUser();
|
||||
const { signOut } = useClerk();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [isLoadingUsage, setIsLoadingUsage] = useState(false);
|
||||
const [usedCredits, setUsedCredits] = useState(0);
|
||||
const [totalCredits, setTotalCredits] = useState(0);
|
||||
|
||||
const subscriberTier = useStore((state) => state.subscriberTier);
|
||||
const setPricingDialogOpen = useStore((state) => state.setPricingDialogOpen);
|
||||
const isFreeUser = subscriberTier === "free";
|
||||
|
||||
const { user, isLoaded, isSignedIn } = useUser();
|
||||
const { signOut } = useClerk();
|
||||
const authenticatedFetch = useAuthenticatedFetch();
|
||||
|
||||
async function open(isOpen: boolean) {
|
||||
setIsOpen(isOpen);
|
||||
|
||||
// Do not fetch usage if the user is a free user
|
||||
// or that information hasn't loaded yet
|
||||
// or the dropdown is closed
|
||||
if (isFreeUser || !subscriberTier || !isOpen) return;
|
||||
|
||||
setIsLoadingUsage(true);
|
||||
|
||||
try {
|
||||
const res: CreditsUsage = await authenticatedFetch(
|
||||
SAAS_BACKEND_URL + "/credits/usage",
|
||||
"POST"
|
||||
);
|
||||
|
||||
setUsedCredits(res.used_monthly_credits);
|
||||
setTotalCredits(res.total_monthly_credits);
|
||||
} catch (e) {
|
||||
toast.error(
|
||||
"Failed to fetch credit usage. Please contact support to get this issue fixed."
|
||||
);
|
||||
} finally {
|
||||
setIsLoadingUsage(false);
|
||||
}
|
||||
}
|
||||
|
||||
// If Clerk is still loading or user is logged out, don't show anything
|
||||
if (!isLoaded || !isSignedIn) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<DropdownMenu>
|
||||
<DropdownMenu open={isOpen} onOpenChange={open}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Avatar className="w-8 h-8 cursor-pointer">
|
||||
<AvatarImage src={user?.imageUrl} alt="Profile image" />
|
||||
@ -44,6 +84,28 @@ export default function AvatarDropdown() {
|
||||
<DropdownMenuLabel>
|
||||
{capitalize(subscriberTier) + " Subscriber"}
|
||||
</DropdownMenuLabel>
|
||||
|
||||
{/* Loading credit usage */}
|
||||
{isLoadingUsage && (
|
||||
<DropdownMenuItem className="text-xs text-gray-700">
|
||||
Loading credit usage...
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
|
||||
{/* Credits usage */}
|
||||
{!isLoadingUsage && (
|
||||
<>
|
||||
<DropdownMenuItem>
|
||||
<Progress value={(usedCredits / totalCredits) * 100} />
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="text-xs text-gray-700">
|
||||
{usedCredits} out of {totalCredits} credits used.
|
||||
{subscriberTier !== "pro" && (
|
||||
<> Upgrade to Pro to get more credits.</>
|
||||
)}
|
||||
</DropdownMenuItem>
|
||||
</>
|
||||
)}
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem asChild={true}>
|
||||
<a href="mailto:support@picoapps.xyz" target="_blank">
|
||||
|
||||
@ -10,3 +10,8 @@ export interface UserResponse {
|
||||
export interface PortalSessionResponse {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface CreditsUsage {
|
||||
total_monthly_credits: number;
|
||||
used_monthly_credits: number;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user