add badge

This commit is contained in:
2026-01-02 15:32:04 -03:00
parent 1abfd0e93e
commit 57b23d7cd2
9 changed files with 146 additions and 69 deletions

View File

@@ -1,9 +1,15 @@
'use client'
import { formatCNPJ } from '@brazilian-utils/brazilian-utils'
import { CheckIcon, ChevronsUpDownIcon, PlusIcon } from 'lucide-react'
import { createContext, useContext, useState } from 'react'
import { useLocation, useParams } from 'react-router'
import {
BadgeCheckIcon,
BadgeIcon,
CheckIcon,
ChevronsUpDownIcon,
PlusIcon
} from 'lucide-react'
import { createContext, use } from 'react'
import { useLocation } from 'react-router'
import {
DropdownMenu,
@@ -23,22 +29,22 @@ import {
import { initials } from '@repo/ui/lib/utils'
import { Link } from 'react-router'
export type Workspace = {
id: string
name: string
cnpj: string
import type { Workspace, WorkspaceContextProps } from '@/middleware/workspace'
type Subscription = {
billing_day: number
payment_method: 'PIX' | 'BANK_SLIP' | 'MANUAL'
}
type WorkspaceContextProps = {
workspaces: Workspace[]
activeWorkspace: Workspace
setActiveWorkspace: React.Dispatch<React.SetStateAction<Workspace | null>>
}
const WorkspaceContext = createContext<WorkspaceContextProps | null>(null)
const WorkspaceContext = createContext<
| (WorkspaceContextProps & {
subscription: Subscription | null
})
| null
>(null)
export function useWorksapce() {
const ctx = useContext(WorkspaceContext)
const ctx = use(WorkspaceContext)
if (!ctx) {
throw new Error('WorkspaceContext is null')
@@ -48,20 +54,26 @@ export function useWorksapce() {
}
export function WorkspaceProvider({
activeWorkspace,
workspaces,
subscription,
children
}: {
activeWorkspace: Workspace
workspaces: Workspace[]
subscription?: Subscription
children: React.ReactNode
}) {
const { orgid } = useParams()
const [activeWorkspace, setActiveWorkspace] = useState<Workspace | any>(
() => workspaces.find(({ id }) => id === orgid) || {}
)
return (
<WorkspaceContext
value={{ workspaces, activeWorkspace, setActiveWorkspace }}
value={{
activeWorkspace,
workspaces,
subscription:
subscription && Object.keys(subscription).length > 0
? subscription
: null
}}
>
{children}
</WorkspaceContext>
@@ -71,11 +83,10 @@ export function WorkspaceProvider({
export function WorkspaceSwitcher() {
const location = useLocation()
const { isMobile, state } = useSidebar()
const { activeWorkspace, setActiveWorkspace, workspaces } = useWorksapce()
const { activeWorkspace, workspaces, subscription } = useWorksapce()
const [, fragment, _] = location.pathname.slice(1).split('/')
const onSelect = (workspace: Workspace) => {
setActiveWorkspace(workspace)
window.location.assign(`/${workspace.id}/${fragment}`)
}
@@ -89,17 +100,20 @@ export function WorkspaceSwitcher() {
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground bg-secondary hover:bg-secondary/80 border cursor-pointer"
>
<div
className="aria-expanded:border flex aspect-square size-8 items-center justify-center rounded-lg"
className="aria-expanded:border flex aspect-square size-8 items-center justify-center rounded-lg relative"
aria-expanded={state === 'expanded'}
>
{initials(activeWorkspace?.name)}
{subscription && (
<BadgeCheckIcon className="fill-blue-500 absolute size-3 -top-1 -right-1" />
)}
{initials(activeWorkspace.name)}
</div>
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-medium">
{activeWorkspace?.name}
{activeWorkspace.name}
</span>
<span className="truncate text-xs text-muted-foreground">
{formatCNPJ(activeWorkspace?.cnpj)}
{formatCNPJ(activeWorkspace.cnpj)}
</span>
</div>
<ChevronsUpDownIcon className="ml-auto" />