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";
2
3import { 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";
10
11interface User {
12 name: string;
13 avatar: string;
14 role: string;
15 status: "online" | "away" | "offline";
16}
17
18const 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];
29
30const statusColors = {
31 online: "bg-green-500",
32 away: "bg-yellow-500",
33 offline: "bg-gray-400",
34};
35
36const 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};
41
42export 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 <div
67 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}

Related Social & Communication Components

Command Palette

Search for a command to run...