refactor(dashboard): reorganize menu actions across sidebar/header/profile

Move shutdown into header popup + profile, move remote into sidebar above
settings, add flag-only language switcher in header, and add language card
plus shutdown/logout actions to the profile page.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
decolua
2026-06-06 16:05:44 +07:00
co-authored by Cursor
parent 293cf40455
commit f161b295a5
6 changed files with 235 additions and 107 deletions
+18 -39
View File
@@ -10,6 +10,7 @@ import { MEDIA_PROVIDER_KINDS } from "@/shared/constants/providers";
import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard";
import Button from "./Button";
import { ConfirmModal } from "./Modal";
import NineRemotePromoModal from "./NineRemotePromoModal";
// const VISIBLE_MEDIA_KINDS = ["embedding", "image", "imageToText", "tts", "stt", "webSearch", "webFetch", "video", "music"];
const VISIBLE_MEDIA_KINDS = ["embedding", "image", "tts", "stt"];
@@ -40,8 +41,7 @@ const systemItems = [
export default function Sidebar({ onClose }) {
const pathname = usePathname();
const [mediaOpen, setMediaOpen] = useState(false);
const [showShutdownModal, setShowShutdownModal] = useState(false);
const [isShuttingDown, setIsShuttingDown] = useState(false);
const [showRemoteModal, setShowRemoteModal] = useState(false);
const [isDisconnected, setIsDisconnected] = useState(false);
const [updateInfo, setUpdateInfo] = useState(null);
const [showUpdateModal, setShowUpdateModal] = useState(false);
@@ -106,18 +106,6 @@ export default function Sidebar({ onClose }) {
// user runs the command manually in another terminal.
const handleShutdown = async () => {
setIsShuttingDown(true);
try {
await fetch("/api/version/shutdown", { method: "POST" });
} catch (e) {
// Expected to fail as server shuts down; ignore error
}
setIsShuttingDown(false);
setShowShutdownModal(false);
setIsDisconnected(true);
};
return (
<>
<aside className="flex w-72 flex-col border-r border-border-subtle bg-vibrancy backdrop-blur-xl transition-colors duration-300 min-h-full">
@@ -302,6 +290,20 @@ export default function Sidebar({ onClose }) {
) : null;
})}
{/* Remote */}
<button
onClick={() => setShowRemoteModal(true)}
className={cn(
"flex items-center gap-3 px-3 py-1 rounded-lg transition-all group w-full",
"text-text-muted hover:bg-surface-2 hover:text-text-main"
)}
>
<span className="material-symbols-outlined text-[18px] group-hover:text-primary transition-colors">
computer
</span>
<span className="text-[13px] font-medium">Remote</span>
</button>
{/* Settings */}
<Link
href="/dashboard/profile"
@@ -326,33 +328,10 @@ export default function Sidebar({ onClose }) {
</div>
</nav>
{/* Footer section */}
<div className="p-3 border-t border-border-subtle">
{/* Shutdown button */}
<Button
variant="outline"
fullWidth
icon="power_settings_new"
onClick={() => setShowShutdownModal(true)}
className="text-red-500 border-red-200 hover:bg-red-50 hover:border-red-300"
>
Shutdown
</Button>
</div>
</aside>
{/* Shutdown Confirmation Modal */}
<ConfirmModal
isOpen={showShutdownModal}
onClose={() => setShowShutdownModal(false)}
onConfirm={handleShutdown}
title="Close Proxy"
message="Are you sure you want to close the proxy server?"
confirmText="Close"
cancelText="Cancel"
variant="danger"
loading={isShuttingDown}
/>
{/* Remote Promo Modal */}
<NineRemotePromoModal isOpen={showRemoteModal} onClose={() => setShowRemoteModal(false)} />
{/* Update Confirmation Modal */}
<ConfirmModal