From 8f336377f6a188b3b4738895f6a9de1dca934c6f Mon Sep 17 00:00:00 2001 From: sagitchu Date: Sun, 15 Mar 2026 22:28:44 +0800 Subject: [PATCH] Revert user page search bar to inline implementation for consistency --- vite-frontend/src/pages/user.tsx | 424 ++++++++++++++++++++----------- 1 file changed, 270 insertions(+), 154 deletions(-) diff --git a/vite-frontend/src/pages/user.tsx b/vite-frontend/src/pages/user.tsx index f4ed6b2..2a3a557 100644 --- a/vite-frontend/src/pages/user.tsx +++ b/vite-frontend/src/pages/user.tsx @@ -1,4 +1,3 @@ -import { SearchBar } from "@/components/search-bar"; import { useState, useEffect, useMemo, useCallback, useRef } from "react"; import toast from "react-hot-toast"; import { parseDate } from "@internationalized/date"; @@ -60,12 +59,7 @@ import { getUserGroupList, getUserGroups, } from "@/api"; -import { - SearchIcon, - EditIcon, - DeleteIcon, - SettingsIcon, -} from "@/components/icons"; +import { EditIcon, DeleteIcon, SettingsIcon, SearchIcon } from "@/components/icons"; import { PageLoadingState } from "@/components/page-state"; import { useLocalStorageState } from "@/hooks/use-local-storage-state"; import { removeItemsById, replaceItemById } from "@/utils/list-state"; @@ -784,6 +778,7 @@ export default function UserPage() { const handleQuotaReset = async (scope: "daily" | "monthly" | "all") => { const userId = userForm.id; + if (!userId) { return; } @@ -888,34 +883,67 @@ export default function UserPage() { {/* 页面头部 */}
-
- { - setIsSearchVisible(false); - setSearchKeyword(""); - }} - onOpen={() => { - setIsSearchVisible(true); - setTimeout(() => { - const searchInput = document.querySelector('input[placeholder*="搜索"]'); - if (searchInput) (searchInput as HTMLElement).focus(); - }, 150); - }} - /> +
+ {!isSearchVisible ? ( + + ) : ( +
+ setSearchKeyword(e.target.value)} + onKeyDown={(e) => e.key === "Enter" && handleSearch()} + /> + +
+ )}
- + +
{/* 用户列表 */} @@ -1126,8 +1154,11 @@ export default function UserPage() { )} {/* 用户表单模态框 */} -
每月用量
- {formatFlow(Number(editingUser.monthlyUsedBytes ?? 0))} /{" "} - {formatQuotaLimit(editingUser.monthlyQuotaGB)} + {formatFlow(Number(editingUser.monthlyUsedBytes ?? 0))}{" "} + / {formatQuotaLimit(editingUser.monthlyQuotaGB)}
@@ -1386,37 +1417,61 @@ export default function UserPage() {

分配新权限

-

隧道列表

- +

+ 隧道列表 +

+ {/* 顶部触发框 */} -
setIsTunnelListExpanded(!isTunnelListExpanded)} + onClick={() => + setIsTunnelListExpanded(!isTunnelListExpanded) + } > - 0 ? "text-primary-500 font-bold" : "text-default-400"}`}> - {batchTunnelSelections.size > 0 - ? `已选 ${batchTunnelSelections.size} 项:` + Array.from(batchTunnelSelections.keys()).map(id => tunnels.find(t => t.id === id)?.name).join('、') + 0 ? "text-primary-500 font-bold" : "text-default-400"}`} + > + {batchTunnelSelections.size > 0 + ? `已选 ${batchTunnelSelections.size} 项:` + + Array.from(batchTunnelSelections.keys()) + .map( + (id) => tunnels.find((t) => t.id === id)?.name, + ) + .join("、") : "请选择隧道(勾选后配置限速)"} - + + +
{/* 列表悬浮层 */} {isTunnelListExpanded && ( -
e.stopPropagation()} + onClick={(e) => e.stopPropagation()} >
{tunnels.map((tunnel) => { const isAssigned = isTunnelAssigned(tunnel.id); - const isSelected = batchTunnelSelections.has(tunnel.id); - const tunnelSpeedLimits = getSpeedLimitsForTunnel(tunnel.id); - const currentSpeedId = batchTunnelSelections.get(tunnel.id); + const isSelected = batchTunnelSelections.has( + tunnel.id, + ); + const tunnelSpeedLimits = getSpeedLimitsForTunnel( + tunnel.id, + ); + const currentSpeedId = batchTunnelSelections.get( + tunnel.id, + ); return ( -
{ @@ -1426,47 +1481,80 @@ export default function UserPage() { }} >
- - {tunnel.name} + + {tunnel.name} +
{/* 右侧限速选择:复刻 image_24879b */} {isSelected && !isAssigned && ( -
e.stopPropagation()}> +
e.stopPropagation()} + >
)} - {isAssigned && 已分配} + {isAssigned && ( + + 已分配 + + )}
); })}
- +
)}
-
+
+ + +
+ + + )} + +
- - - + + + {/* 编辑隧道权限模态框 */} - {/* 删除确认对话框 */} - {/* 删除隧道权限确认对话框 */} - {/* 重置流量确认对话框 */} - {/* 重置隧道流量确认对话框 */} -