From f7bcca7a8e1b60c07e57a2bf668507e6286eea81 Mon Sep 17 00:00:00 2001 From: zenchantlive Date: Tue, 17 Feb 2026 00:01:45 -0800 Subject: [PATCH] feat(ui3): high-fidelity command center redesign with stage-library layout and unified sidebar --- .beads/bd.sock.startlock | 1 + src/components/activity/activity-panel.tsx | 192 +++++++++++---------- src/components/shared/thread-drawer.tsx | 66 ++++--- src/components/social/social-page.tsx | 105 +++++++---- src/hooks/use-url-state.ts | 2 +- 5 files changed, 208 insertions(+), 158 deletions(-) create mode 100644 .beads/bd.sock.startlock diff --git a/.beads/bd.sock.startlock b/.beads/bd.sock.startlock new file mode 100644 index 0000000..7cbf78a --- /dev/null +++ b/.beads/bd.sock.startlock @@ -0,0 +1 @@ +95088 diff --git a/src/components/activity/activity-panel.tsx b/src/components/activity/activity-panel.tsx index 337a76b..f15a74b 100644 --- a/src/components/activity/activity-panel.tsx +++ b/src/components/activity/activity-panel.tsx @@ -174,35 +174,37 @@ export function ActivityPanel({ issues, collapsed = false }: ActivityPanelProps) if (collapsed) { return ( -
- {/* Collapsed Agent Icons */} -
- {agentRoster.slice(0, 5).map(agent => ( +
+ {/* Collapsed Agent Icons with ZFC Rings */} +
+ {agentRoster.slice(0, 6).map(agent => (
- - +
+ + {getInitials(agent.name)} -
))}
- {/* Divider */} -
+
- {/* Mini Activity Dots (Just visual pulse) */} -
- {/* Just show a few recent activity dots as a visual "heartbeat" */} - {activities.slice(0, 5).map((act) => ( + {/* Activity Pulses */} +
+ {activities.slice(0, 8).map((act) => (
))}
@@ -211,44 +213,52 @@ export function ActivityPanel({ issues, collapsed = false }: ActivityPanelProps) } return ( -
+
{/* AGENT ROSTER SECTION */} -
-
-

Agents

-
- {activeAgents > 0 && ( - - {activeAgents} active - - )} - {staleAgents > 0 && ( - - {staleAgents} stale - - )} +
+
+
+
+

Live Agents

+
+
+ {activeAgents} ONLINE
{agentRoster.length === 0 ? ( -

No active agents

+

No agents broadcasting

) : ( -
+
{agentRoster.map(agent => (
- - - {getInitials(agent.name)} - - -
- {agent.name} - - {agent.status} - +
+
+ + + {getInitials(agent.name)} + + +
+
+ {agent.name} +
+ + {agent.status} + + + {agent.lastSeen ? formatRelativeTime(agent.lastSeen) : 'N/A'} + +
))} @@ -257,62 +267,62 @@ export function ActivityPanel({ issues, collapsed = false }: ActivityPanelProps)
{/* ACTIVITY FEED SECTION */} -
-
-

Recent Activity

+
+
+ +

Telemetry Stream

- + {isLoading ? ( -
- Loading... +
+
+ SYNCING...
) : activities.length === 0 ? ( -
- No recent activity +
+

VOID_STREAM_NULL

) : ( -
- {activities.map((activity, index) => { +
+ {activities.map((activity) => { const eventInfo = getEventKindInfo(activity.kind); return ( -
-
-
-
+
+
+ +
+
+
+ + {eventInfo.label} + + + {formatRelativeTime(activity.timestamp)} +
-
-
- - {eventInfo.label} - - - {activity.beadId} - -
-

- {activity.beadTitle} -

-
- {activity.actor && ( - - {activity.actor} - - )} - - {formatRelativeTime(activity.timestamp)} - -
+ +

+ {activity.beadTitle} +

+ +
+ + {activity.beadId} + + {activity.actor && ( +
+
+ {activity.actor[0].toUpperCase()} +
+ {activity.actor} +
+ )}
- {index < activities.length - 1 && ( - - )}
); })} diff --git a/src/components/shared/thread-drawer.tsx b/src/components/shared/thread-drawer.tsx index f475455..a5be5ec 100644 --- a/src/components/shared/thread-drawer.tsx +++ b/src/components/shared/thread-drawer.tsx @@ -45,26 +45,24 @@ export function ThreadDrawer({ isOpen, onClose, title, id, items = SAMPLE_ITEMS, return (
- {/* Header */} + {/* Header: Mission Control Style */}
-
- - {id} - +
+
+
+ MISSION_{id} +

{title} @@ -72,35 +70,31 @@ export function ThreadDrawer({ isOpen, onClose, title, id, items = SAMPLE_ITEMS,

{/* Thread Content */} -
- +
+
+ +
- {/* Compose */} + {/* Compose: Technical Input Field */}
-
+
setComment(e.target.value)} - placeholder="Add a comment..." - className="flex-1 px-3 py-2 rounded-md text-sm outline-none focus:ring-1 focus:ring-teal-500/50 transition-all" - style={{ - backgroundColor: 'var(--color-bg-input)', - color: 'var(--color-text-primary)', - border: '1px solid rgba(255, 255, 255, 0.1)', - }} + placeholder="Transmit message..." + className="flex-1 bg-transparent px-3 py-2 text-sm text-white placeholder:text-text-muted/30 outline-none" onKeyDown={(e) => { if (e.key === 'Enter' && comment.trim()) { setComment(''); @@ -108,16 +102,20 @@ export function ThreadDrawer({ isOpen, onClose, title, id, items = SAMPLE_ITEMS, }} />
+
+ Encrypted Channel_Active +
+
+
+
+
+
); diff --git a/src/components/social/social-page.tsx b/src/components/social/social-page.tsx index 463fb28..8de8755 100644 --- a/src/components/social/social-page.tsx +++ b/src/components/social/social-page.tsx @@ -4,6 +4,7 @@ import { useMemo } from 'react'; import type { BeadIssue } from '../../lib/types'; import { buildSocialCards } from '../../lib/social-cards'; import { SocialCard } from './social-card'; +import { cn } from '@/lib/utils'; interface SocialPageProps { issues: BeadIssue[]; @@ -13,44 +14,84 @@ interface SocialPageProps { export function SocialPage({ issues, selectedId, onSelect }: SocialPageProps) { const cards = useMemo(() => buildSocialCards(issues), [issues]); + + const selectedTask = useMemo(() => + cards.find(c => c.id === selectedId) || null, + [cards, selectedId]); + + const otherCards = useMemo(() => + cards.filter(c => c.id !== selectedId), + [cards, selectedId]); return ( -
- {/* Top: Card Stream (Restricted Height) */} -
-
-
- {cards.map((card) => ( - onSelect(card.id)} - /> - ))} - {cards.length === 0 && ( -
-
📭
-

No active tasks found in stream.

+
+ {/* Background Atmosphere */} +
+ +
+
+ + {/* STAGE: Featured / Selected Task (Media Player "Now Playing") */} +
+ {selectedTask ? ( +
+
+
+
+ Module Active +
+
+
+
+
+
+ +
+
+ ) : ( +
+ {/* Holographic Ring Effect */} +
+
+ +
+
+ + + +
+

Initialize Focus

+

STANDBY_MODE // AWAITING_INPUT

+
)} -
-
-
+
- {/* Bottom: Conversation Deck (Fills remaining space) */} -
- {/* Placeholder for Chat Interface */} -
-
- - - -
-

Conversation Deck

-

Select a task above to open its secure communication channel and activity log.

+ {/* LIBRARY: The Feed (Masonry Grid) */} +
+
+

Module Library

+
{otherCards.length} Units Available
+
+ +
+ {otherCards.map((card) => ( + onSelect(card.id)} + className="hover:scale-[1.02] active:scale-[0.98]" + /> + ))} +
+
); -} +} \ No newline at end of file diff --git a/src/hooks/use-url-state.ts b/src/hooks/use-url-state.ts index 3e9a74c..6e4736e 100644 --- a/src/hooks/use-url-state.ts +++ b/src/hooks/use-url-state.ts @@ -27,7 +27,7 @@ export interface UrlState { } const DEFAULT_VIEW: ViewType = 'social'; -const DEFAULT_PANEL: PanelState = 'closed'; +const DEFAULT_PANEL: PanelState = 'open'; const DEFAULT_DRAWER: DrawerState = 'closed'; const DEFAULT_GRAPH_TAB: GraphTabType = 'flow';