first commit
This commit is contained in:
104
src/components/Header.tsx
Normal file
104
src/components/Header.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
import React, { useState } from 'react'
|
||||
import { AppBar, Toolbar, IconButton, Typography, Button, Menu, MenuItem, Box, Chip, TextField } from '@mui/material'
|
||||
import MenuIcon from '@mui/icons-material/Menu'
|
||||
import SettingsIcon from '@mui/icons-material/Settings'
|
||||
import StorageIcon from '@mui/icons-material/Storage'
|
||||
import { useServers } from '../context/ServersContext'
|
||||
|
||||
type HeaderProps = {
|
||||
onOpenSettings?: () => void
|
||||
onToggleSidebar?: () => void
|
||||
searchQuery?: string
|
||||
onSearchQueryChange?: (value: string) => void
|
||||
searchDisabled?: boolean
|
||||
}
|
||||
|
||||
export default function Header({ onOpenSettings, onToggleSidebar, searchQuery = '', onSearchQueryChange, searchDisabled = false }: HeaderProps) {
|
||||
const { servers, activeServerId, setActiveServerId } = useServers()
|
||||
const [anchor, setAnchor] = useState<HTMLElement | null>(null)
|
||||
|
||||
const active = servers.find((s) => s.id === activeServerId)
|
||||
const activeServerLabel = active ? active.name || active.host : 'No server configured'
|
||||
|
||||
const handleOpen = (e: React.MouseEvent<HTMLElement>) => setAnchor(e.currentTarget)
|
||||
const handleClose = () => setAnchor(null)
|
||||
|
||||
return (
|
||||
<AppBar position="static" color="transparent" elevation={0} sx={{ mb: 0, borderBottom: '1px solid rgba(255,255,255,0.04)' }}>
|
||||
<Toolbar variant="dense" sx={{ minHeight: { xs: 'auto', sm: 48 }, py: { xs: 1, sm: 0.25 }, gap: 1, flexWrap: { xs: 'wrap', sm: 'nowrap' } }}>
|
||||
<IconButton onClick={() => onToggleSidebar && onToggleSidebar()} aria-label="menu" size="medium" sx={{ flexShrink: 0 }}>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
|
||||
<TextField
|
||||
value={searchQuery}
|
||||
onChange={(event) => onSearchQueryChange && onSearchQueryChange(event.target.value)}
|
||||
disabled={searchDisabled}
|
||||
size="small"
|
||||
placeholder="Search library"
|
||||
sx={{
|
||||
flex: { xs: '1 1 calc(100% - 104px)', sm: 1 },
|
||||
minWidth: 0,
|
||||
maxWidth: { sm: 520 },
|
||||
order: { xs: 1, sm: 0 },
|
||||
'& .MuiInputBase-input': { fontSize: { xs: 14, sm: 13 }, py: 0.9 },
|
||||
}}
|
||||
/>
|
||||
|
||||
<IconButton onClick={() => onOpenSettings && onOpenSettings()} aria-label="settings" size="medium" sx={{ width: 40, height: 40, flexShrink: 0, order: { xs: 2, sm: 0 } }}>
|
||||
<SettingsIcon sx={{ fontSize: 20 }} />
|
||||
</IconButton>
|
||||
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, width: { xs: '100%', sm: 'auto' }, minWidth: 0, order: { xs: 3, sm: 0 } }}>
|
||||
<Button
|
||||
variant="text"
|
||||
onClick={handleOpen}
|
||||
startIcon={<StorageIcon sx={{ fontSize: 18 }} />}
|
||||
sx={{
|
||||
px: 0.75,
|
||||
py: 0.25,
|
||||
fontSize: { xs: 13, sm: 13 },
|
||||
justifyContent: 'flex-start',
|
||||
minWidth: 0,
|
||||
flex: { xs: 1, sm: '0 1 auto' },
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
>
|
||||
{activeServerLabel}
|
||||
</Button>
|
||||
{active?.lastTest && active.lastTest.ok === false && (
|
||||
<Chip label={active.lastTest.message} color="error" size="small" sx={{ maxWidth: { xs: 132, sm: 200 } }} />
|
||||
)}
|
||||
<Menu anchorEl={anchor} open={Boolean(anchor)} onClose={handleClose}>
|
||||
{servers.length === 0 ? (
|
||||
<MenuItem disabled>No servers configured</MenuItem>
|
||||
) : (
|
||||
servers.map((s) => (
|
||||
<MenuItem
|
||||
key={s.id}
|
||||
selected={s.id === activeServerId}
|
||||
onClick={() => {
|
||||
setActiveServerId(s.id)
|
||||
handleClose()
|
||||
}}
|
||||
>
|
||||
{s.name || s.host}
|
||||
</MenuItem>
|
||||
))
|
||||
)}
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
handleClose()
|
||||
onOpenSettings && onOpenSettings()
|
||||
}}
|
||||
>
|
||||
Manage servers...
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Box>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user