- Gallery
- Social & Communication
- OnlineUsers
OnlineUsers
Online users sidebar with avatar, name, status dot, grouped by status.
Social & Communicationonlineuserspresencesidebarstatus
Dependencies
Other dependencies:
@/components/ui/avatar@/components/ui/card@/components/ui/separator@/components/ui/scroll-area
How to use this component
Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.
Code
1"use client";23import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";4import { Card } from "@/components/ui/card";5import { Separator } from "@/components/ui/separator";6import { ScrollArea } from "@/components/ui/scroll-area";7import { Input } from "@/components/ui/input";8import { Search } from "lucide-react";9import { Badge } from "@/components/ui/badge";1011interface User {12 name: string;13 avatar: string;14 role: string;15 status: "online" | "away" | "offline";16}1718const users: User[] = [19 { name: "Alice Johnson", avatar: "https://i.pravatar.cc/150?img=1", role: "Designer", status: "online" },20 { name: "Bob Smith", avatar: "https://i.pravatar.cc/150?img=3", role: "Developer", status: "online" },21 { name: "Carol White", avatar: "https://i.pravatar.cc/150?img=5", role: "Manager", status: "online" },22 { name: "David Brown", avatar: "https://i.pravatar.cc/150?img=8", role: "Developer", status: "online" },23 { name: "Eve Davis", avatar: "https://i.pravatar.cc/150?img=9", role: "Designer", status: "away" },24 { name: "Frank Miller", avatar: "https://i.pravatar.cc/150?img=11", role: "Developer", status: "away" },25 { name: "Grace Lee", avatar: "https://i.pravatar.cc/150?img=16", role: "Manager", status: "offline" },26 { name: "Henry Wilson", avatar: "https://i.pravatar.cc/150?img=18", role: "Designer", status: "offline" },27 { name: "Ivy Chen", avatar: "https://i.pravatar.cc/150?img=20", role: "Developer", status: "offline" },28];2930const statusColors = {31 online: "bg-green-500",32 away: "bg-yellow-500",33 offline: "bg-gray-400",34};3536const groupedUsers = {37 online: users.filter((u) => u.status === "online"),38 away: users.filter((u) => u.status === "away"),39 offline: users.filter((u) => u.status === "offline"),40};4142export default function OnlineUsers() {43 return (44 <Card className="w-72">45 <div className="p-4 border-b">46 <div className="flex items-center justify-between mb-3">47 <h3 className="font-semibold">Team Members</h3>48 <Badge variant="secondary" className="text-xs">{users.length}</Badge>49 </div>50 <div className="relative">51 <Search className="absolute left-2 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />52 <Input placeholder="Search..." className="pl-8 h-8 text-sm" />53 </div>54 </div>55 <ScrollArea className="h-80">56 <div className="p-2">57 {Object.entries(groupedUsers).map(([status, statusUsers]) => (58 <div key={status}>59 <div className="flex items-center gap-2 px-2 py-2">60 <div className={`w-2 h-2 rounded-full ${statusColors[status as keyof typeof statusColors]}`} />61 <span className="text-xs font-medium capitalize text-muted-foreground">62 {status} — {statusUsers.length}63 </span>64 </div>65 {statusUsers.map((user) => (66 <div67 key={user.name}68 className="flex items-center gap-3 p-2 rounded-lg hover:bg-muted cursor-pointer transition-colors"69 >70 <div className="relative">71 <Avatar className="w-8 h-8">72 <AvatarImage src={user.avatar} />73 <AvatarFallback>{user.name[0]}</AvatarFallback>74 </Avatar>75 <div className={`absolute bottom-0 right-0 w-2.5 h-2.5 rounded-full border-2 border-background ${statusColors[user.status]}`} />76 </div>77 <div className="flex-1 min-w-0">78 <p className="text-sm font-medium truncate">{user.name}</p>79 <p className="text-xs text-muted-foreground truncate">{user.role}</p>80 </div>81 </div>82 ))}83 {status !== "offline" && <Separator className="my-2" />}84 </div>85 ))}86 </div>87 </ScrollArea>88 </Card>89 );90}