2026-02-16 10:16:33 -08:00
|
|
|
'use client';
|
|
|
|
|
|
|
|
|
|
import { X, Send } from 'lucide-react';
|
|
|
|
|
import { ThreadView, type ThreadItem } from './thread-view';
|
|
|
|
|
import { useState } from 'react';
|
|
|
|
|
|
|
|
|
|
interface ThreadDrawerProps {
|
|
|
|
|
isOpen: boolean;
|
|
|
|
|
onClose: () => void;
|
|
|
|
|
title: string;
|
|
|
|
|
id: string;
|
|
|
|
|
items?: ThreadItem[];
|
2026-02-16 23:50:20 -08:00
|
|
|
embedded?: boolean; // New prop for embedded mode
|
2026-02-16 10:16:33 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sample data for demo
|
|
|
|
|
const SAMPLE_ITEMS: ThreadItem[] = [
|
|
|
|
|
{
|
|
|
|
|
id: '1',
|
|
|
|
|
type: 'status_change',
|
|
|
|
|
from: 'backlog',
|
|
|
|
|
to: 'in_progress',
|
|
|
|
|
timestamp: new Date(Date.now() - 2 * 60 * 60 * 1000),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: '2',
|
|
|
|
|
type: 'comment',
|
|
|
|
|
author: 'zenchantlive',
|
|
|
|
|
content: 'Started working on this task.',
|
|
|
|
|
timestamp: new Date(Date.now() - 1 * 60 * 60 * 1000),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: '3',
|
|
|
|
|
type: 'protocol_event',
|
|
|
|
|
event: 'HANDOFF',
|
|
|
|
|
content: 'Handed off to agent',
|
|
|
|
|
timestamp: new Date(Date.now() - 30 * 60 * 1000),
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
2026-02-16 23:50:20 -08:00
|
|
|
export function ThreadDrawer({ isOpen, onClose, title, id, items = SAMPLE_ITEMS, embedded = false }: ThreadDrawerProps) {
|
2026-02-16 10:16:33 -08:00
|
|
|
const [comment, setComment] = useState('');
|
|
|
|
|
|
|
|
|
|
if (!isOpen) return null;
|
|
|
|
|
|
|
|
|
|
return (
|
2026-02-16 21:45:27 -08:00
|
|
|
<div
|
2026-02-17 00:01:45 -08:00
|
|
|
className="h-full flex flex-col bg-[#1a1a1a]/95 backdrop-blur-2xl"
|
2026-02-16 21:45:27 -08:00
|
|
|
style={{
|
2026-02-17 00:01:45 -08:00
|
|
|
width: embedded ? '100%' : '26rem',
|
2026-02-16 23:50:20 -08:00
|
|
|
borderLeft: embedded ? 'none' : '1px solid rgba(255, 255, 255, 0.1)',
|
2026-02-17 00:01:45 -08:00
|
|
|
boxShadow: embedded ? 'none' : '-10px 0 40px rgba(0, 0, 0, 0.5)',
|
2026-02-16 21:45:27 -08:00
|
|
|
}}
|
|
|
|
|
>
|
2026-02-17 00:01:45 -08:00
|
|
|
{/* Header: Mission Control Style */}
|
2026-02-16 10:16:33 -08:00
|
|
|
<div
|
2026-02-17 00:01:45 -08:00
|
|
|
className="flex items-center justify-between p-5 border-b border-white/5 bg-white/[0.02]"
|
2026-02-16 10:16:33 -08:00
|
|
|
>
|
2026-02-17 00:01:45 -08:00
|
|
|
<div className="flex-1 min-w-0 pr-4">
|
|
|
|
|
<div className="flex items-center gap-2 mb-1">
|
|
|
|
|
<div className="w-1 h-1 rounded-full bg-teal-500 animate-ping" />
|
|
|
|
|
<span className="text-[10px] font-bold font-mono text-teal-500/70 tracking-[0.2em]">MISSION_{id}</span>
|
|
|
|
|
</div>
|
2026-02-16 21:45:27 -08:00
|
|
|
<h2
|
2026-02-17 00:01:45 -08:00
|
|
|
className="text-base font-bold text-white truncate leading-tight tracking-tight"
|
2026-02-16 21:45:27 -08:00
|
|
|
title={title}
|
2026-02-16 10:16:33 -08:00
|
|
|
>
|
2026-02-16 21:45:27 -08:00
|
|
|
{title}
|
|
|
|
|
</h2>
|
2026-02-16 10:16:33 -08:00
|
|
|
</div>
|
2026-02-16 21:45:27 -08:00
|
|
|
<button
|
|
|
|
|
onClick={onClose}
|
2026-02-17 00:01:45 -08:00
|
|
|
className="p-2 rounded-xl bg-white/5 hover:bg-white/10 border border-white/5 transition-all text-text-muted hover:text-white"
|
2026-02-16 21:45:27 -08:00
|
|
|
aria-label="Close"
|
|
|
|
|
>
|
2026-02-17 00:01:45 -08:00
|
|
|
<X size={18} />
|
2026-02-16 21:45:27 -08:00
|
|
|
</button>
|
|
|
|
|
</div>
|
2026-02-16 10:16:33 -08:00
|
|
|
|
2026-02-16 21:45:27 -08:00
|
|
|
{/* Thread Content */}
|
2026-02-17 00:01:45 -08:00
|
|
|
<div className="flex-1 overflow-y-auto p-5 custom-scrollbar space-y-6">
|
|
|
|
|
<div className="flex flex-col gap-6">
|
|
|
|
|
<ThreadView items={items} />
|
|
|
|
|
</div>
|
2026-02-16 21:45:27 -08:00
|
|
|
</div>
|
2026-02-16 10:16:33 -08:00
|
|
|
|
2026-02-17 00:01:45 -08:00
|
|
|
{/* Compose: Technical Input Field */}
|
2026-02-16 21:45:27 -08:00
|
|
|
<div
|
2026-02-17 00:01:45 -08:00
|
|
|
className="p-5 border-t border-white/5 bg-black/20"
|
2026-02-16 21:45:27 -08:00
|
|
|
>
|
2026-02-17 00:01:45 -08:00
|
|
|
<div className="flex items-center gap-3 p-1.5 rounded-2xl bg-[#252525] border border-white/5 shadow-inner group focus-within:border-teal-500/30 transition-all">
|
2026-02-16 21:45:27 -08:00
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={comment}
|
|
|
|
|
onChange={(e) => setComment(e.target.value)}
|
2026-02-17 00:01:45 -08:00
|
|
|
placeholder="Transmit message..."
|
|
|
|
|
className="flex-1 bg-transparent px-3 py-2 text-sm text-white placeholder:text-text-muted/30 outline-none"
|
2026-02-16 21:45:27 -08:00
|
|
|
onKeyDown={(e) => {
|
|
|
|
|
if (e.key === 'Enter' && comment.trim()) {
|
|
|
|
|
setComment('');
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<button
|
2026-02-17 00:01:45 -08:00
|
|
|
className="p-2.5 rounded-xl bg-emerald-500 text-white shadow-[0_0_15px_rgba(16,185,129,0.3)] hover:shadow-[0_0_20px_rgba(16,185,129,0.5)] transition-all active:scale-95 flex-shrink-0"
|
2026-02-16 21:45:27 -08:00
|
|
|
aria-label="Send comment"
|
|
|
|
|
>
|
2026-02-17 00:01:45 -08:00
|
|
|
<Send size={16} fill="currentColor" />
|
2026-02-16 21:45:27 -08:00
|
|
|
</button>
|
2026-02-16 10:16:33 -08:00
|
|
|
</div>
|
2026-02-17 00:01:45 -08:00
|
|
|
<div className="mt-3 flex items-center justify-between px-1">
|
|
|
|
|
<span className="text-[8px] font-mono text-text-muted/30 uppercase tracking-[0.2em]">Encrypted Channel_Active</span>
|
|
|
|
|
<div className="flex gap-2">
|
|
|
|
|
<div className="w-1 h-1 rounded-full bg-white/10" />
|
|
|
|
|
<div className="w-1 h-1 rounded-full bg-white/10" />
|
|
|
|
|
<div className="w-1 h-1 rounded-full bg-white/10" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-02-16 10:16:33 -08:00
|
|
|
</div>
|
2026-02-16 21:45:27 -08:00
|
|
|
</div>
|
2026-02-16 10:16:33 -08:00
|
|
|
);
|
2026-02-16 23:50:20 -08:00
|
|
|
}
|