Skip to content

Components

UI Primitives

The dashboard is built on 35 Radix UI components styled with Tailwind CSS (the shadcn/ui pattern):

Interactive Elements

ComponentDescription
ButtonStandard button with variants (default, destructive, outline, ghost)
LoadingButtonButton with loading state
InputText input field
LabelForm label
CheckboxCheckbox with label
SwitchToggle switch
SliderRange slider
SelectDropdown selector

Layout

ComponentDescription
CardCard container (header, content, footer)
SidebarCollapsible sidebar
TabsTabbed navigation
AccordionExpandable sections
CollapsibleShow/hide container
SeparatorHorizontal divider
ScrollAreaScrollable area with custom scrollbar
SheetMobile drawer (slides in from the side)
TableData table

Overlays

ComponentDescription
DialogModal dialog
AlertDialogConfirmation dialog
ConfirmDialogSimplified confirmation dialog
PopoverPopup content
TooltipHover tooltip
DropdownMenuDropdown menu
ContextMenuRight-click menu

Data

ComponentDescription
AvatarUser avatar (image with fallback)
BadgeStatus badge
BreadcrumbBreadcrumb navigation
ChartRecharts wrapper with legend and tooltip
CommandCommand palette (cmdk)

Specialized

ComponentDescription
TimezonePickerSearchable timezone selector
PageSpinnerFull-page loading animation
SonnerToast notifications

Shared Components

User info in the sidebar footer, including:

  • Avatar, name, role
  • Logout action

Team branding in the sidebar header:

  • Logo (when a URL is configured)
  • Team name
  • Tagline

Navigation group in the sidebar:

  • Group title
  • List of navigation items with icons

agent-picker.tsx

Multi-select for Valorant agents:

  • Checkbox list of all agents
  • Selected agents shown as badges
  • Normalized names (KAY/O → KAYO)

pdf-preview-dialog.tsx

PDF preview inside a dialog:

  • Iframe-based viewer
  • Download button

Custom Hooks

useIsMobile()

typescript
const isMobile = useIsMobile(); // true when < 768px

useBranding(defaults?)

typescript
const { teamName, tagline, logoUrl } = useBranding({
  teamName: 'Fallback Name'
});

useSidebarNavigation(basePath)

typescript
const { activeTab, setActiveTab } = useSidebarNavigation('/admin');

useUserDiscordId()

typescript
const { user, isLoading } = useUserDiscordId();
// user = { userName: 'Player1', discordId: '123...' }

Animation Utilities

lib/animations.ts provides prebuilt animation classes:

typescript
import { stagger, microInteractions } from '@/lib/animations';

// Staggered animation
<div className={stagger(index, 'fast', 'fadeIn')}>

// Hover effect
<button className={microInteractions.hoverLift}>

// Loading state
<div className={loadingStates.shimmer}>

Error Boundary

tsx
import { withErrorBoundary } from '@/components/error-boundary';

const SafeComponent = withErrorBoundary(MyComponent);

Catches render errors and shows:

  • An error message
  • A "Try again" button
  • A "Reload page" button

MIT License