實作應用管理的清單

This commit is contained in:
2025-08-05 16:26:03 +08:00
parent 5b407ff29c
commit 3fa02fc1d1
7 changed files with 381 additions and 30 deletions

View File

@@ -78,9 +78,33 @@ const mockSearchData: SearchResult[] = []
export function AdminLayout({ children, currentPage, onPageChange }: AdminLayoutProps) {
const { user, logout, isLoading } = useAuth()
// Move ALL hooks to the top, before any conditional logic
const [sidebarOpen, setSidebarOpen] = useState(true)
const [searchQuery, setSearchQuery] = useState("")
const [searchResults, setSearchResults] = useState<SearchResult[]>([])
const [showSearchResults, setShowSearchResults] = useState(false)
const [notifications, setNotifications] = useState<Notification[]>(mockNotifications)
const [showNotifications, setShowNotifications] = useState(false)
const [showLogoutDialog, setShowLogoutDialog] = useState(false)
// 認證檢查
// Handle search
useEffect(() => {
if (searchQuery.trim()) {
const filtered = mockSearchData.filter(
(item) =>
item.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
item.subtitle.toLowerCase().includes(searchQuery.toLowerCase()),
)
setSearchResults(filtered.slice(0, 8)) // Limit to 8 results
setShowSearchResults(true)
} else {
setSearchResults([])
setShowSearchResults(false)
}
}, [searchQuery])
// 認證檢查 - moved after all hooks
if (isLoading) {
return (
<div className="min-h-screen flex items-center justify-center">
@@ -120,34 +144,6 @@ export function AdminLayout({ children, currentPage, onPageChange }: AdminLayout
)
}
// Search state
const [searchQuery, setSearchQuery] = useState("")
const [searchResults, setSearchResults] = useState<SearchResult[]>([])
const [showSearchResults, setShowSearchResults] = useState(false)
// Notification state
const [notifications, setNotifications] = useState<Notification[]>(mockNotifications)
const [showNotifications, setShowNotifications] = useState(false)
// Logout confirmation state
const [showLogoutDialog, setShowLogoutDialog] = useState(false)
// Handle search
useEffect(() => {
if (searchQuery.trim()) {
const filtered = mockSearchData.filter(
(item) =>
item.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
item.subtitle.toLowerCase().includes(searchQuery.toLowerCase()),
)
setSearchResults(filtered.slice(0, 8)) // Limit to 8 results
setShowSearchResults(true)
} else {
setSearchResults([])
setShowSearchResults(false)
}
}, [searchQuery])
// Get unread notification count
const unreadCount = notifications.filter((n) => !n.read).length