Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions apps/web/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { StatsCard } from "@/components/StatsCard";
import { LineChart } from "@/components/Chart";
import { Badge } from "@/components/Badge";
import { EmptyState } from "@/components/EmptyState";
import { formatCost, formatTokens, formatRelativeTime } from "@/lib/utils";

interface DashboardData {
Expand Down Expand Up @@ -265,9 +266,13 @@ export default function DashboardPage() {
height={260}
/>
) : (
<div className="flex items-center justify-center h-[260px] rounded-lg bg-dark-700/30 text-sm text-dark-400">
No message history yet.
</div>
<EmptyState
bare
icon={<MessageSquare size={22} />}
title="No message history yet"
description="Conversations will chart here as your agents start handling messages."
className="h-[260px] rounded-lg bg-dark-700/30 py-0"
/>
)}
</div>

Expand Down Expand Up @@ -295,9 +300,11 @@ export default function DashboardPage() {
))}
</div>
) : (
<div className="rounded-lg bg-dark-700/30 px-3 py-8 text-center text-sm text-dark-400">
No active channels yet.
</div>
<EmptyState
bare
title="No active channels yet"
className="rounded-lg bg-dark-700/30 py-8"
/>
)}
</div>
</div>
Expand All @@ -321,9 +328,11 @@ export default function DashboardPage() {
))}
</div>
) : (
<div className="rounded-lg bg-dark-700/30 px-3 py-8 text-center text-sm text-dark-400">
No recent activity captured yet.
</div>
<EmptyState
bare
title="No recent activity captured yet"
className="rounded-lg bg-dark-700/30 py-8"
/>
)}
</div>
</div>
Expand Down
11 changes: 8 additions & 3 deletions apps/web/components/EmptyState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ interface EmptyStateProps {
description?: string;
/** Optional call-to-action (button / link). */
action?: React.ReactNode;
/**
* Drop the card chrome (border + dark surface). Use when nesting inside an
* existing card/panel so the empty state doesn't render a card-in-a-card.
*/
bare?: boolean;
className?: string;
}

Expand All @@ -20,12 +25,12 @@ interface EmptyStateProps {
* an optional action. Keeps the existing card chrome (rounded border + dark
* surface) so it drops into the same slots without layout changes.
*/
export function EmptyState({ icon, title, description, action, className }: EmptyStateProps) {
export function EmptyState({ icon, title, description, action, bare, className }: EmptyStateProps) {
return (
<div
className={cn(
"rounded-xl border border-dark-700 bg-dark-800 px-5 py-12",
"flex flex-col items-center justify-center text-center",
"px-5 py-12 flex flex-col items-center justify-center text-center",
!bare && "rounded-xl border border-dark-700 bg-dark-800",
className,
)}
>
Expand Down
Loading