small design changes
This commit is contained in:
@@ -61,6 +61,7 @@ Phase 1: Jellyfin media index, SSH-based remote filesystem inspection, server mo
|
|||||||
- The shared session table should keep a compact overall status summary line above the rows that reports total sessions plus playing, paused, and idle counts.
|
- The shared session table should keep a compact overall status summary line above the rows that reports total sessions plus playing, paused, and idle counts.
|
||||||
- The shared session table should keep the session identifier under the user name in a caption instead of giving it a full column, to keep the table tighter.
|
- The shared session table should keep the session identifier under the user name in a caption instead of giving it a full column, to keep the table tighter.
|
||||||
- The Users tab may open a read-only detail drawer for a selected user, but any communication actions in that drawer should remain clearly disabled/placeholders until the workflow is implemented.
|
- The Users tab may open a read-only detail drawer for a selected user, but any communication actions in that drawer should remain clearly disabled/placeholders until the workflow is implemented.
|
||||||
|
- The frontend shell should use a polished two-row header with branding on the left, user/logout controls on the right, and primary navigation in a dedicated tab row beneath.
|
||||||
- The frontend shell and primary pages should remain responsive and mobile-safe, with compact navigation, stacked controls on narrow screens, and reduced table column density where needed.
|
- The frontend shell and primary pages should remain responsive and mobile-safe, with compact navigation, stacked controls on narrow screens, and reduced table column density where needed.
|
||||||
- Backend startup should log a secret-safe configuration summary and request/activity diagnostics so configuration issues can be debugged without exposing API keys.
|
- Backend startup should log a secret-safe configuration summary and request/activity diagnostics so configuration issues can be debugged without exposing API keys.
|
||||||
|
|
||||||
@@ -175,3 +176,4 @@ Phase 1: Jellyfin media index, SSH-based remote filesystem inspection, server mo
|
|||||||
- 2026-05-03: Added OIDC/JWT auth support plus root-level Docker Compose deployment files for production and dev workflows.
|
- 2026-05-03: Added OIDC/JWT auth support plus root-level Docker Compose deployment files for production and dev workflows.
|
||||||
- 2026-05-04: Backend Docker Compose now mounts a host SSH directory into `/root/.ssh` so Paramiko can use a private key and strict host-key checking without baking secrets into the image.
|
- 2026-05-04: Backend Docker Compose now mounts a host SSH directory into `/root/.ssh` so Paramiko can use a private key and strict host-key checking without baking secrets into the image.
|
||||||
- 2026-05-04: The frontend was adjusted to be more mobile-safe by making the app shell tabs scrollable, stacking header controls on narrow screens, and hiding low-priority table columns on smaller displays.
|
- 2026-05-04: The frontend was adjusted to be more mobile-safe by making the app shell tabs scrollable, stacking header controls on narrow screens, and hiding low-priority table columns on smaller displays.
|
||||||
|
- 2026-05-04: The app header was upgraded to a two-row branded layout with a left logo mark, right-side username/logout controls, and a separate navigation row.
|
||||||
|
|||||||
+82
-36
@@ -9,7 +9,6 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|||||||
import { ThemeProvider } from "@mui/material/styles";
|
import { ThemeProvider } from "@mui/material/styles";
|
||||||
import {
|
import {
|
||||||
AppBar,
|
AppBar,
|
||||||
Toolbar,
|
|
||||||
Typography,
|
Typography,
|
||||||
Box,
|
Box,
|
||||||
Tabs,
|
Tabs,
|
||||||
@@ -54,53 +53,98 @@ function Shell({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
<AppBar position="sticky" color="inherit" elevation={0}>
|
<AppBar
|
||||||
<Toolbar
|
position="sticky"
|
||||||
|
color="inherit"
|
||||||
|
elevation={0}
|
||||||
|
sx={{
|
||||||
|
borderBottom: 1,
|
||||||
|
borderColor: "divider",
|
||||||
|
backgroundImage: "none",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: { xs: "column", md: "row" },
|
flexDirection: { xs: "column", md: "row" },
|
||||||
alignItems: { xs: "stretch", md: "center" },
|
alignItems: { xs: "stretch", md: "center" },
|
||||||
gap: 1,
|
justifyContent: "space-between",
|
||||||
py: { xs: 1, md: 0 },
|
gap: 1.5,
|
||||||
minHeight: { xs: "auto", md: 68 },
|
px: { xs: 1.5, sm: 2.5, md: 3 },
|
||||||
|
py: { xs: 1, md: 1.25 },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "space-between",
|
|
||||||
width: "100%",
|
|
||||||
gap: 1.5,
|
gap: 1.5,
|
||||||
|
minWidth: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="h6" sx={{ fontWeight: 700, lineHeight: 1 }}>
|
<Box
|
||||||
Manage
|
|
||||||
</Typography>
|
|
||||||
<Stack
|
|
||||||
direction="row"
|
|
||||||
spacing={0.75}
|
|
||||||
sx={{
|
sx={{
|
||||||
alignItems: "center",
|
width: 42,
|
||||||
flexWrap: "wrap",
|
height: 42,
|
||||||
justifyContent: "flex-end",
|
borderRadius: 2,
|
||||||
|
display: "grid",
|
||||||
|
placeItems: "center",
|
||||||
|
fontWeight: 800,
|
||||||
|
fontSize: 20,
|
||||||
|
color: "primary.contrastText",
|
||||||
|
bgcolor: "primary.main",
|
||||||
|
backgroundImage:
|
||||||
|
"linear-gradient(135deg, rgba(255,255,255,0.22), rgba(255,255,255,0))",
|
||||||
|
boxShadow: 1,
|
||||||
|
flexShrink: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{authLabel && (
|
M
|
||||||
<Chip size="small" variant="outlined" label={authLabel} />
|
</Box>
|
||||||
)}
|
<Box sx={{ minWidth: 0 }}>
|
||||||
<Chip
|
<Typography
|
||||||
size="small"
|
variant="h6"
|
||||||
variant="outlined"
|
sx={{ fontWeight: 800, lineHeight: 1.05 }}
|
||||||
label={darkMode ? "Dark" : "Light"}
|
>
|
||||||
/>
|
Manage
|
||||||
{onSignOut && (
|
</Typography>
|
||||||
<Button size="small" variant="text" onClick={onSignOut}>
|
<Typography variant="caption" color="text.secondary" noWrap>
|
||||||
Sign out
|
Media operations dashboard
|
||||||
</Button>
|
</Typography>
|
||||||
)}
|
</Box>
|
||||||
</Stack>
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
<Stack
|
||||||
|
direction="row"
|
||||||
|
spacing={1}
|
||||||
|
sx={{
|
||||||
|
alignItems: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
justifyContent: { xs: "flex-start", md: "flex-end" },
|
||||||
|
width: { xs: "100%", md: "auto" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{authLabel && (
|
||||||
|
<Chip
|
||||||
|
label={authLabel}
|
||||||
|
variant="outlined"
|
||||||
|
sx={{ maxWidth: { xs: "100%", sm: 220 } }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Chip label={darkMode ? "Dark" : "Light"} variant="outlined" />
|
||||||
|
{onSignOut && (
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
onClick={onSignOut}
|
||||||
|
sx={{ whiteSpace: "nowrap" }}
|
||||||
|
>
|
||||||
|
Logout
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box sx={{ borderTop: 1, borderColor: "divider" }}>
|
||||||
<Tabs
|
<Tabs
|
||||||
value={current}
|
value={current}
|
||||||
textColor="primary"
|
textColor="primary"
|
||||||
@@ -109,13 +153,15 @@ function Shell({
|
|||||||
scrollButtons="auto"
|
scrollButtons="auto"
|
||||||
allowScrollButtonsMobile
|
allowScrollButtonsMobile
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
px: { xs: 0.75, sm: 1.5, md: 3 },
|
||||||
minHeight: 40,
|
minHeight: 44,
|
||||||
"& .MuiTab-root": {
|
"& .MuiTab-root": {
|
||||||
minHeight: 40,
|
minHeight: 44,
|
||||||
py: 1,
|
py: 1,
|
||||||
px: 1.25,
|
px: 1.5,
|
||||||
minWidth: { xs: 96, md: 120 },
|
minWidth: { xs: 96, md: 120 },
|
||||||
|
textTransform: "none",
|
||||||
|
fontWeight: 600,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -130,7 +176,7 @@ function Shell({
|
|||||||
<Tab value="/users" label="Users" component={NavLink} to="/users" />
|
<Tab value="/users" label="Users" component={NavLink} to="/users" />
|
||||||
<Tab value="/files" label="Files" component={NavLink} to="/files" />
|
<Tab value="/files" label="Files" component={NavLink} to="/files" />
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</Toolbar>
|
</Box>
|
||||||
</AppBar>
|
</AppBar>
|
||||||
<Container
|
<Container
|
||||||
maxWidth={false}
|
maxWidth={false}
|
||||||
|
|||||||
Reference in New Issue
Block a user