Commit 6774dcff authored by Administrator's avatar Administrator

Update 3 files via Son of Anton

parent 3568bd0b
This diff is collapsed.
......@@ -7,9 +7,10 @@ import {
Edit3, Check, X, GitBranch,
} from "lucide-react";
export default function Sidebar({ activeChatId, onSelectChat, isOpen, onClose }) {
export default function Sidebar({ mobile, onClose }) {
const { state, dispatch } = useApp();
const nav = useNavigate();
const activeChatId = state.activeChatId;
const [editId, setEditId] = useState(null);
const [editTitle, setEditTitle] = useState("");
......@@ -22,11 +23,15 @@ export default function Sidebar({ activeChatId, onSelectChat, isOpen, onClose })
})();
}, [state.token, dispatch]);
function handleSelectChat(chatId) {
dispatch({ type: "SET_ACTIVE_CHAT", chatId });
if (onClose) onClose();
}
async function handleNew() {
try {
const chat = await createChat(state.token);
dispatch({ type: "ADD_CHAT", chat });
onSelectChat(chat.id);
} catch { }
}
......@@ -36,7 +41,6 @@ export default function Sidebar({ activeChatId, onSelectChat, isOpen, onClose })
try {
await deleteChat(state.token, chatId);
dispatch({ type: "REMOVE_CHAT", chatId });
if (activeChatId === chatId) onSelectChat(null);
} catch { }
}
......@@ -52,73 +56,71 @@ export default function Sidebar({ activeChatId, onSelectChat, isOpen, onClose })
const isSuperadmin = state.user?.role === "superadmin";
return (
<>
{isOpen && <div className="fixed inset-0 bg-black/50 z-40 md:hidden" onClick={onClose} />}
<div className={`fixed md:static z-50 inset-y-0 left-0 w-72 bg-anton-surface border-r border-anton-border flex flex-col transition-transform duration-200 ${isOpen ? "translate-x-0" : "-translate-x-full md:translate-x-0"}`}>
{/* Header */}
<div className="p-3 border-b border-anton-border">
<div className="flex items-center gap-2 mb-3">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-anton-accent to-red-600 flex items-center justify-center">
<Flame size={16} className="text-white" />
</div>
<div>
<h1 className="text-sm font-bold text-white">Son of Anton</h1>
<p className="text-[10px] text-anton-muted">v4.0.0 — The Architect</p>
</div>
<div className={`${mobile ? "h-full" : "h-dvh"} w-72 bg-anton-surface border-r border-anton-border flex flex-col`}>
{/* Header */}
<div className="p-3 border-b border-anton-border">
<div className="flex items-center gap-2 mb-3">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-anton-accent to-red-600 flex items-center justify-center">
<Flame size={16} className="text-white" />
</div>
<div>
<h1 className="text-sm font-bold text-white">Son of Anton</h1>
<p className="text-[10px] text-anton-muted">v4.1.0 — The Architect</p>
</div>
<button onClick={handleNew} className="w-full flex items-center justify-center gap-1.5 bg-anton-accent text-white rounded-lg py-2 text-sm hover:opacity-80 transition">
<Plus size={16} /> New Chat
</button>
</div>
<button onClick={handleNew} className="w-full flex items-center justify-center gap-1.5 bg-anton-accent text-white rounded-lg py-2 text-sm hover:opacity-80 transition">
<Plus size={16} /> New Chat
</button>
</div>
{/* Chat list */}
<div className="flex-1 overflow-y-auto p-2 space-y-0.5">
{state.chats.map((c) => (
<div key={c.id} onClick={() => { onSelectChat(c.id); onClose?.(); }}
className={`group flex items-center gap-2 px-3 py-2 rounded-lg cursor-pointer transition text-sm ${activeChatId === c.id ? "bg-anton-accent/15 text-white" : "text-anton-muted hover:bg-anton-card hover:text-white"}`}>
<MessageSquare size={14} className="shrink-0" />
{editId === c.id ? (
<div className="flex-1 flex items-center gap-1">
<input value={editTitle} onChange={(e) => setEditTitle(e.target.value)} onKeyDown={(e) => e.key === "Enter" && handleRename(c.id)}
className="flex-1 bg-anton-bg border border-anton-border rounded px-1.5 py-0.5 text-xs text-white" autoFocus />
<button onClick={() => handleRename(c.id)} className="text-green-400"><Check size={12} /></button>
<button onClick={() => setEditId(null)} className="text-red-400"><X size={12} /></button>
{/* Chat list */}
<div className="flex-1 overflow-y-auto p-2 space-y-0.5">
{state.chats.map((c) => (
<div key={c.id} onClick={() => handleSelectChat(c.id)}
className={`group flex items-center gap-2 px-3 py-2 rounded-lg cursor-pointer transition text-sm ${activeChatId === c.id ? "bg-anton-accent/15 text-white" : "text-anton-muted hover:bg-anton-card hover:text-white"}`}>
<MessageSquare size={14} className="shrink-0" />
{editId === c.id ? (
<div className="flex-1 flex items-center gap-1">
<input value={editTitle} onChange={(e) => setEditTitle(e.target.value)} onKeyDown={(e) => e.key === "Enter" && handleRename(c.id)}
className="flex-1 bg-anton-bg border border-anton-border rounded px-1.5 py-0.5 text-xs text-white" autoFocus
onClick={(e) => e.stopPropagation()} />
<button onClick={(e) => { e.stopPropagation(); handleRename(c.id); }} className="text-green-400"><Check size={12} /></button>
<button onClick={(e) => { e.stopPropagation(); setEditId(null); }} className="text-red-400"><X size={12} /></button>
</div>
) : (
<>
<span className="flex-1 truncate text-xs">{c.title}</span>
<div className="flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
{c.linked_repo_id && <GitBranch size={11} className="text-orange-400" />}
<button onClick={(e) => { e.stopPropagation(); setEditId(c.id); setEditTitle(c.title); }} className="p-0.5 hover:text-anton-accent"><Edit3 size={11} /></button>
<button onClick={(e) => handleDelete(e, c.id)} className="p-0.5 hover:text-red-400"><Trash2 size={11} /></button>
</div>
) : (
<>
<span className="flex-1 truncate text-xs">{c.title}</span>
<div className="flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
{c.linked_repo_id && <GitBranch size={11} className="text-orange-400" />}
<button onClick={(e) => { e.stopPropagation(); setEditId(c.id); setEditTitle(c.title); }} className="p-0.5 hover:text-anton-accent"><Edit3 size={11} /></button>
<button onClick={(e) => handleDelete(e, c.id)} className="p-0.5 hover:text-red-400"><Trash2 size={11} /></button>
</div>
</>
)}
</div>
))}
</div>
</>
)}
</div>
))}
</div>
{/* Footer */}
<div className="p-2 border-t border-anton-border space-y-0.5">
{isSuperadmin && (
<>
<button onClick={() => nav("/gitlab")} className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-orange-400 hover:bg-anton-card transition">
<GitBranch size={14} /> GitLab Center
</button>
<button onClick={() => nav("/admin")} className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-white transition">
<Shield size={14} /> Admin
</button>
</>
)}
<button onClick={() => nav("/knowledge")} className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-white transition">
<BookOpen size={14} /> Knowledge
</button>
<button onClick={() => dispatch({ type: "LOGOUT" })} className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-red-400 transition">
<LogOut size={14} /> Logout
</button>
<div className="px-3 py-1 text-[10px] text-anton-muted">{state.user?.username}{state.user?.role}</div>
</div>
{/* Footer */}
<div className="p-2 border-t border-anton-border space-y-0.5">
{isSuperadmin && (
<>
<button onClick={() => nav("/gitlab")} className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-orange-400 hover:bg-anton-card transition">
<GitBranch size={14} /> GitLab Center
</button>
<button onClick={() => nav("/admin")} className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-white transition">
<Shield size={14} /> Admin
</button>
</>
)}
<button onClick={() => nav("/knowledge")} className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-white transition">
<BookOpen size={14} /> Knowledge
</button>
<button onClick={() => dispatch({ type: "LOGOUT" })} className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-anton-muted hover:bg-anton-card hover:text-red-400 transition">
<LogOut size={14} /> Logout
</button>
<div className="px-3 py-1 text-[10px] text-anton-muted">{state.user?.username}{state.user?.role}</div>
</div>
</>
</div>
);
}
\ No newline at end of file
......@@ -29,7 +29,7 @@ export default function ChatPage() {
return (
<div className="h-full h-dvh flex overflow-hidden bg-anton-bg">
{/* Desktop sidebar */}
{/* Desktop sidebar — always visible */}
<div className="hidden sm:flex">
<Sidebar />
</div>
......@@ -75,7 +75,7 @@ export default function ChatPage() {
{/* Chat or empty state */}
{state.activeChatId ? (
<ChatView chatId={state.activeChatId} />
<ChatView key={state.activeChatId} chatId={state.activeChatId} />
) : (
<div className="flex-1 flex items-center justify-center p-6">
<div className="text-center max-w-sm">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment