feat: enhance UI and functionality in various components
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
EmptyTitle,
|
||||
} from '@/components/ui/empty'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
interface MobileCardListProps<TData> {
|
||||
table: Table<TData>
|
||||
@@ -21,6 +22,7 @@ interface MobileCardListProps<TData> {
|
||||
emptyTitle?: string
|
||||
emptyDescription?: string
|
||||
getRowKey?: (row: Row<TData>) => string | number
|
||||
getRowClassName?: (row: Row<TData>) => string | undefined
|
||||
}
|
||||
|
||||
interface MobileColumnMeta {
|
||||
@@ -238,6 +240,7 @@ export function MobileCardList<TData>(props: MobileCardListProps<TData>) {
|
||||
emptyTitle,
|
||||
emptyDescription,
|
||||
getRowKey,
|
||||
getRowClassName,
|
||||
} = props
|
||||
const { t } = useTranslation()
|
||||
|
||||
@@ -278,7 +281,10 @@ export function MobileCardList<TData>(props: MobileCardListProps<TData>) {
|
||||
{rows.map((row) => {
|
||||
const key = getRowKey ? getRowKey(row) : row.id
|
||||
return (
|
||||
<div key={key} className='bg-card px-3 py-2.5'>
|
||||
<div
|
||||
key={key}
|
||||
className={cn('bg-card px-3 py-2.5', getRowClassName?.(row))}
|
||||
>
|
||||
<RowComponent row={row} />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -120,70 +120,87 @@ export function WorkspaceSwitcher({
|
||||
return null
|
||||
}
|
||||
|
||||
const canSwitchWorkspace = availableWorkspaces.length > 1
|
||||
const workspaceButtonContent = (
|
||||
<>
|
||||
{activeWorkspace.id === WORKSPACE_IDS.SYSTEM_SETTINGS ? (
|
||||
<div className='bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg'>
|
||||
<activeWorkspace.logo className='size-4' />
|
||||
</div>
|
||||
) : (
|
||||
<div className='flex aspect-square size-8 items-center justify-center overflow-hidden rounded-lg'>
|
||||
<img
|
||||
src={logo}
|
||||
alt={t('Logo')}
|
||||
className='size-full rounded-lg object-cover'
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className='grid flex-1 text-start text-sm leading-tight group-data-[collapsible=icon]:hidden'>
|
||||
<span className='truncate font-semibold'>{activeWorkspace.name}</span>
|
||||
<span className='truncate text-xs'>{activeWorkspace.plan}</span>
|
||||
</div>
|
||||
{canSwitchWorkspace && (
|
||||
<ChevronsUpDown className='ms-auto group-data-[collapsible=icon]:hidden' />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
|
||||
return (
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<SidebarMenuButton
|
||||
size='lg'
|
||||
className='data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground'
|
||||
>
|
||||
{activeWorkspace.id === WORKSPACE_IDS.SYSTEM_SETTINGS ? (
|
||||
<div className='bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg'>
|
||||
<activeWorkspace.logo className='size-4' />
|
||||
</div>
|
||||
) : (
|
||||
<div className='flex aspect-square size-8 items-center justify-center overflow-hidden rounded-lg'>
|
||||
<img
|
||||
src={logo}
|
||||
alt={t('Logo')}
|
||||
className='size-full rounded-lg object-cover'
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className='grid flex-1 text-start text-sm leading-tight group-data-[collapsible=icon]:hidden'>
|
||||
<span className='truncate font-semibold'>
|
||||
{activeWorkspace.name}
|
||||
</span>
|
||||
<span className='truncate text-xs'>{activeWorkspace.plan}</span>
|
||||
</div>
|
||||
<ChevronsUpDown className='ms-auto group-data-[collapsible=icon]:hidden' />
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
className='w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg'
|
||||
align='start'
|
||||
side={isMobile ? 'bottom' : 'right'}
|
||||
sideOffset={4}
|
||||
>
|
||||
<DropdownMenuLabel className='text-muted-foreground text-xs'>
|
||||
{t('Workspaces')}
|
||||
</DropdownMenuLabel>
|
||||
{availableWorkspaces.map((workspace, index) => (
|
||||
<DropdownMenuItem
|
||||
key={workspace.id}
|
||||
onClick={() => handleWorkspaceChange(workspace)}
|
||||
className='gap-2 p-2'
|
||||
{canSwitchWorkspace ? (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<SidebarMenuButton
|
||||
size='lg'
|
||||
className='data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground'
|
||||
>
|
||||
{index === 0 ? (
|
||||
<div className='flex size-6 items-center justify-center overflow-hidden rounded-sm border'>
|
||||
<img
|
||||
src={logo}
|
||||
alt='Logo'
|
||||
className='size-full object-cover'
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className='flex size-6 items-center justify-center rounded-sm border'>
|
||||
<workspace.logo className='size-4 shrink-0' />
|
||||
</div>
|
||||
)}
|
||||
{workspace.name}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
{workspaceButtonContent}
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
className='w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg'
|
||||
align='start'
|
||||
side={isMobile ? 'bottom' : 'right'}
|
||||
sideOffset={4}
|
||||
>
|
||||
<DropdownMenuLabel className='text-muted-foreground text-xs'>
|
||||
{t('Workspaces')}
|
||||
</DropdownMenuLabel>
|
||||
{availableWorkspaces.map((workspace, index) => (
|
||||
<DropdownMenuItem
|
||||
key={workspace.id}
|
||||
onClick={() => handleWorkspaceChange(workspace)}
|
||||
className='gap-2 p-2'
|
||||
>
|
||||
{index === 0 ? (
|
||||
<div className='flex size-6 items-center justify-center overflow-hidden rounded-sm border'>
|
||||
<img
|
||||
src={logo}
|
||||
alt='Logo'
|
||||
className='size-full object-cover'
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className='flex size-6 items-center justify-center rounded-sm border'>
|
||||
<workspace.logo className='size-4 shrink-0' />
|
||||
</div>
|
||||
)}
|
||||
{workspace.name}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
) : (
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
size='lg'
|
||||
className='cursor-default hover:bg-transparent hover:text-sidebar-foreground active:bg-transparent active:text-sidebar-foreground'
|
||||
>
|
||||
<div>{workspaceButtonContent}</div>
|
||||
</SidebarMenuButton>
|
||||
)}
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user