From 4e68344f23b60cd191dbf154290faa25d0875143 Mon Sep 17 00:00:00 2001 From: JSC Date: Tue, 12 Aug 2025 22:53:08 +0200 Subject: [PATCH] feat: add CreditsNav component to display user credits in AppSidebar --- src/components/AppSidebar.tsx | 3 ++ src/components/nav/CreditsNav.tsx | 56 +++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/components/nav/CreditsNav.tsx diff --git a/src/components/AppSidebar.tsx b/src/components/AppSidebar.tsx index 0b07b66..e14617e 100644 --- a/src/components/AppSidebar.tsx +++ b/src/components/AppSidebar.tsx @@ -16,6 +16,7 @@ import { import { NavGroup } from './nav/NavGroup' import { NavItem } from './nav/NavItem' import { UserNav } from './nav/UserNav' +import { CreditsNav } from './nav/CreditsNav' import { CompactPlayer } from './player/CompactPlayer' import { Separator } from '@/components/ui/separator' import { useAuth } from '@/contexts/AuthContext' @@ -64,6 +65,8 @@ export function AppSidebar({ showCompactPlayer = false }: AppSidebarProps) { )} + + diff --git a/src/components/nav/CreditsNav.tsx b/src/components/nav/CreditsNav.tsx new file mode 100644 index 0000000..b3b1ee1 --- /dev/null +++ b/src/components/nav/CreditsNav.tsx @@ -0,0 +1,56 @@ +import { useEffect, useState } from 'react' +import { CircleDollarSign } from 'lucide-react' +import NumberFlow from '@number-flow/react' +import { SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '../ui/sidebar' +import { userEvents, USER_EVENTS } from '@/lib/events' +import type { User } from '@/types/auth' + +interface CreditsNavProps { + user: User +} + +export function CreditsNav({ user }: CreditsNavProps) { + const [credits, setCredits] = useState(user.credits) + + useEffect(() => { + const handleCreditsChanged = (data: { credits_after: number }) => { + setCredits(data.credits_after) + } + + userEvents.on(USER_EVENTS.USER_CREDITS_CHANGED, handleCreditsChanged) + + return () => { + userEvents.off(USER_EVENTS.USER_CREDITS_CHANGED, handleCreditsChanged) + } + }, []) + + // Update credits when user prop changes (initial load or refresh) + useEffect(() => { + setCredits(user.credits) + }, [user.credits]) + + const tooltipText = `Credits: ${credits} / ${user.plan.max_credits}` + + // Determine icon color based on credit levels + const getIconColor = () => { + if (credits === 0) return 'text-red-500' + if (credits <= user.plan.max_credits * 0.2) return 'text-yellow-500' + return 'text-green-500' + } + + return ( + + + + +
+ Credits: + + / + +
+
+
+
+ ) +} \ No newline at end of file