Bluewoo HRMS
Design SystemComponents

Data Display

Table, badge, and avatar patterns

Data Display Components

Components for displaying data in HRMS.

Table

Tables are used for employee lists, time-off records, etc.

<ContentCard>
  <Table>
    <TableHeader>
      <TableRow>
        <TableHead>Employee</TableHead>
        <TableHead>Department</TableHead>
        <TableHead>Status</TableHead>
        <TableHead className="text-right">Actions</TableHead>
      </TableRow>
    </TableHeader>
    <TableBody>
      <TableRow>
        <TableCell>
          <div className="flex items-center gap-3">
            <Avatar className="h-8 w-8">
              <AvatarImage src="/avatar.jpg" />
              <AvatarFallback>JD</AvatarFallback>
            </Avatar>
            <div>
              <p className="font-medium">John Doe</p>
              <p className="text-sm text-muted-foreground">john@company.com</p>
            </div>
          </div>
        </TableCell>
        <TableCell>Engineering</TableCell>
        <TableCell>
          <Badge variant="success">Active</Badge>
        </TableCell>
        <TableCell className="text-right">
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="ghost" size="icon">
                <MoreHorizontal className="h-4 w-4" />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuItem>View</DropdownMenuItem>
              <DropdownMenuItem>Edit</DropdownMenuItem>
              <DropdownMenuSeparator />
              <DropdownMenuItem className="text-destructive">Delete</DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        </TableCell>
      </TableRow>
    </TableBody>
  </Table>
</ContentCard>

Table Styling

Tables are wrapped in ContentCard (not given their own border):

// ✅ CORRECT: Table inside ContentCard
<ContentCard>
  <Table>...</Table>
</ContentCard>

// ❌ WRONG: Table with its own border
<div className="border rounded-lg">
  <Table>...</Table>
</div>

Badge

Badges indicate status or category.

Badge Variants

// Default
<Badge>Default</Badge>

// Secondary
<Badge variant="secondary">Secondary</Badge>

// Destructive
<Badge variant="destructive">Destructive</Badge>

// Outline
<Badge variant="outline">Outline</Badge>

Status Badges

// Success (Active, Approved)
<Badge className="bg-success text-white">Active</Badge>

// Warning (Pending, On Leave)
<Badge className="bg-warning text-white">Pending</Badge>

// Error (Rejected, Terminated)
<Badge className="bg-error text-white">Rejected</Badge>

Badge Component

const badgeVariants = cva(
  "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground",
        secondary: "bg-secondary text-secondary-foreground",
        destructive: "bg-destructive text-destructive-foreground",
        outline: "border border-input text-foreground",
        success: "bg-success text-white",
        warning: "bg-warning text-white",
        error: "bg-error text-white",
      },
    },
    defaultVariants: {
      variant: "default",
    },
  }
);

Avatar

User profile images with fallback.

<Avatar className="h-10 w-10">
  <AvatarImage src="/avatar.jpg" alt="John Doe" />
  <AvatarFallback>JD</AvatarFallback>
</Avatar>

Avatar Sizes

SizeClassUsage
Smallh-8 w-8Table rows
Defaulth-10 w-10List items
Largeh-12 w-12Headers
XLh-20 w-20Profile pages

Avatar with Status

<div className="relative">
  <Avatar className="h-10 w-10">
    <AvatarImage src="/avatar.jpg" />
    <AvatarFallback>JD</AvatarFallback>
  </Avatar>
  <span className="absolute bottom-0 right-0 h-3 w-3 rounded-full bg-success border-2 border-card" />
</div>

Avatar Group

<div className="flex -space-x-2">
  <Avatar className="h-8 w-8 border-2 border-card">
    <AvatarImage src="/avatar1.jpg" />
    <AvatarFallback>U1</AvatarFallback>
  </Avatar>
  <Avatar className="h-8 w-8 border-2 border-card">
    <AvatarImage src="/avatar2.jpg" />
    <AvatarFallback>U2</AvatarFallback>
  </Avatar>
  <Avatar className="h-8 w-8 border-2 border-card">
    <AvatarImage src="/avatar3.jpg" />
    <AvatarFallback>U3</AvatarFallback>
  </Avatar>
  <div className="h-8 w-8 rounded-full bg-muted flex items-center justify-center text-xs font-medium border-2 border-card">
    +5
  </div>
</div>

Empty State

When there's no data to display:

<ContentCard>
  <div className="flex flex-col items-center justify-center py-12 text-center">
    <div className="w-12 h-12 rounded-full bg-muted flex items-center justify-center mb-4">
      <Users className="w-6 h-6 text-muted-foreground" />
    </div>
    <h3 className="text-lg font-semibold mb-1">No employees yet</h3>
    <p className="text-sm text-muted-foreground mb-4">
      Get started by adding your first employee.
    </p>
    <Button>
      <Plus className="w-4 h-4 mr-2" />
      Add Employee
    </Button>
  </div>
</ContentCard>

Skeleton Loading

<ContentCard>
  <div className="space-y-4">
    <div className="flex items-center gap-3">
      <Skeleton className="h-10 w-10 rounded-full" />
      <div className="space-y-2">
        <Skeleton className="h-4 w-32" />
        <Skeleton className="h-3 w-24" />
      </div>
    </div>
    <Skeleton className="h-4 w-full" />
    <Skeleton className="h-4 w-3/4" />
  </div>
</ContentCard>

Pagination

<div className="flex items-center justify-between px-2">
  <p className="text-sm text-muted-foreground">
    Showing 1-10 of 156 employees
  </p>
  <div className="flex items-center gap-2">
    <Button variant="outline" size="sm" disabled>
      Previous
    </Button>
    <Button variant="outline" size="sm">
      Next
    </Button>
  </div>
</div>