Workspace activity card built on ActivityFeedCard: a large event count, a timeline of deploys, merges and comments with one highlighted event, a 48-hour summary row and a full-width View all link.
import { cn } from "cn"
import {
ActivityFeedCard,
type ActivityFeedEvent,
} from "@/components/activity/activity-feed-card"
import { buttonVariants } from "@/components/ui/button"
// The copy: change text here, not in the markup.
const COPY = {
title: "Activity",
body: "What changed across the workspace.",
count: "events",
window: "Last 48 hours",
latest: "Latest",
cta: "View all activity",
} as const
const EVENTS: ActivityFeedEvent[] = [
{
id: 1,
actor: "Lena Orvik",
action: "deployed",
target: "api-gateway",
time: "2h",
featured: true,
},
{
id: 2,
actor: "Tomas Vey",
action: "commented on",
target: "#482",
time: "3h",
comment:
"Looks right to me. One small note on the error handling, then merge.",
},
{
id: 3,
actor: "Ines Halloran",
action: "merged",
target: "rate-limiter",
time: "5h",
},
{
id: 4,
actor: "Kofi Brandt",
action: "tagged",
target: "v2.4.0",
time: "1d",
},
{
id: 5,
actor: "Mira Sato",
action: "closed",
target: "#311",
time: "1d",
comment: "Fixed by the latest deploy. It no longer happens on staging.",
},
{
id: 6,
actor: "Elias Quill",
action: "joined the workspace",
time: "2d",
},
]
export default function ActivityFeed() {
return (
<ActivityFeedCard
className="mx-auto w-full max-w-sm"
title={COPY.title}
description={COPY.body}
events={EVENTS}
countLabel={COPY.count}
summary={{
period: COPY.window,
latest: (
<>
{COPY.latest} {EVENTS[0].time}
</>
),
}}
actions={
<a
href="#"
data-slot="button"
className={cn(
buttonVariants({ variant: "secondary", size: "lg" }),
"w-full"
)}
>
{COPY.cta}
</a>
}
/>
)
}
pnpm dlx shadcn add @01orbital/activity-feednpx shadcn add @01orbital/activity-feedyarn shadcn add @01orbital/activity-feedbunx --bun shadcn add @01orbital/activity-feedFree under the MIT license. Add the @01orbital registry to components.json once (install guide), then run the command.
It lands at components/blocks/feed/activity-feed/index.tsx, as source you own and edit.
import ActivityFeed from "@/components/blocks/feed/activity-feed"
export default function Example() {
return <ActivityFeed />
}npm: cn. The CLI installs them for you.
Registry pieces it installs with it:
activity-feed-cardbuttonCompare
Every Feed block side by side: whether it follows the theme or stays dark, the stock parts it is built on, and whether it is free. Open one for its preview, props and install.
Audit Log
Dense security audit log in a card: one timeline row per event with the actor in bold, a right-aligned time and a muted Geist Mono line of IP, key or device detail, plus an Export button.