- Gallery
- Dashboard & Analytics
- ActivityFeed
New
ActivityFeed
Timeline of events with avatars, timestamps, action badges, and connecting line
Dashboard & Analyticsactivityfeedtimelineevents
Dependencies
shadcn/ui components needed:
npx shadcn@latest add cardnpx shadcn@latest add avatarnpx shadcn@latest add badgenpx shadcn@latest add scroll-areaHow 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 * as React from "react"4import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"5import { Avatar, AvatarFallback } from "@/components/ui/avatar"6import { Badge } from "@/components/ui/badge"7import { ScrollArea } from "@/components/ui/scroll-area"8import { cn } from "@/lib/utils"910interface ActivityItem {11 user: string12 action: string13 type: "created" | "updated" | "deleted" | "commented"14 time: string15}1617interface ActivityFeedProps {18 items?: ActivityItem[]19 className?: string20}2122const typeColors = {23 created: "bg-emerald-500/10 text-emerald-600 border-emerald-200",24 updated: "bg-blue-500/10 text-blue-600 border-blue-200",25 deleted: "bg-red-500/10 text-red-600 border-red-200",26 commented: "bg-purple-500/10 text-purple-600 border-purple-200",27}2829export function ActivityFeed({ items = [30 { user: "Sarah Chen", action: "created new project", type: "created", time: "2m ago" },31 { user: "Alex Rivera", action: "updated dashboard", type: "updated", time: "15m ago" },32 { user: "Jordan Lee", action: "deleted old report", type: "deleted", time: "1h ago" },33 { user: "Morgan Smith", action: "commented on thread", type: "commented", time: "2h ago" },34 { user: "Taylor Kim", action: "created new user", type: "created", time: "3h ago" },35], className }: ActivityFeedProps) {36 return (37 <Card className={cn("w-full", className)}>38 <CardHeader>39 <CardTitle>Activity Feed</CardTitle>40 </CardHeader>41 <CardContent>42 <ScrollArea className="h-[400px] pr-4">43 <div className="relative">44 <div className="absolute left-4 top-0 bottom-0 w-px bg-border" />45 {items.map((item, i) => (46 <div key={i} className="relative pl-10 pb-6 group hover:bg-muted/50 rounded-lg p-2 -mx-2 transition-colors">47 <div className="absolute left-2 w-5 h-5 rounded-full bg-background border-2 border-primary flex items-center justify-center">48 <div className="w-2 h-2 rounded-full bg-primary" />49 </div>50 <div className="flex items-start gap-3">51 <Avatar className="w-8 h-8">52 <AvatarFallback className="text-xs bg-primary/10 text-primary">{item.user.split(" ").map(n => n[0]).join("")}</AvatarFallback>53 </Avatar>54 <div className="flex-1 min-w-0">55 <p className="text-sm">56 <span className="font-semibold">{item.user}</span>57 {" "}{item.action}58 </p>59 <div className="flex items-center gap-2 mt-1">60 <Badge variant="outline" className={cn("text-xs", typeColors[item.type])}>61 {item.type}62 </Badge>63 <span className="text-xs text-muted-foreground">{item.time}</span>64 </div>65 </div>66 </div>67 </div>68 ))}69 </div>70 </ScrollArea>71 </CardContent>72 </Card>73 )74}