mirror of
https://github.com/narrrl/holy-flavor-rater.git
synced 2026-11-04 00:47:02 +01:00
ui redesign
This commit is contained in:
1 parent
d0a027a2a1
commit
67da3061a6
49 files changed
+1496
-458
No files matched your search
@@ -45,7 +45,15 @@ export const BrandMark = ({ onNavigate, compact = false }: BrandMarkProps) => {
|
||||
>
|
||||
<Typography
|
||||
component="span"
|
||||
sx={{ fontWeight: 900, fontSize: '1.15rem', lineHeight: 1, color: '#fff' }}
|
||||
// The tile is the primary gradient, so the monogram must use the
|
||||
// contrast colour the palette computes for it — a literal white
|
||||
// disappears on the light-accent themes (latte, t0p_sai, mint).
|
||||
sx={{
|
||||
fontWeight: 900,
|
||||
fontSize: '1.15rem',
|
||||
lineHeight: 1,
|
||||
color: 'primary.contrastText',
|
||||
}}
|
||||
>
|
||||
H
|
||||
</Typography>
|
||||
|
||||
@@ -12,10 +12,13 @@ export interface CategoryBarProps {
|
||||
}
|
||||
|
||||
/**
|
||||
* Horizontal nav pinned just under the top bar on every breakpoint. Categories
|
||||
* are the dominant browse axis — laid out as a scrollable row of tabs — with
|
||||
* Home / Community / Dashboard as primary links on the left. Replaces the old
|
||||
* left rail on desktop and mirrors the same sticky chrome on mobile.
|
||||
* The browse row. Categories are the dominant browse axis, so they get a
|
||||
* scrollable row of their own with Home / Community / Dashboard leading it.
|
||||
*
|
||||
* This renders as the *second row inside* the nav pane (see `GlassAppBar`) —
|
||||
* it deliberately carries no sticky positioning or glass of its own, so the
|
||||
* two rows share one pane, one rim and one blur pass instead of stacking two
|
||||
* translucent bars on top of each other.
|
||||
*/
|
||||
export const CategoryBar = ({ categories }: CategoryBarProps) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -27,12 +30,16 @@ export const CategoryBar = ({ categories }: CategoryBarProps) => {
|
||||
|
||||
const tabSx = (active: boolean) => ({
|
||||
flexShrink: 0,
|
||||
borderRadius: 2,
|
||||
borderRadius: (theme: Theme) => `${theme.tokens.radius.pill}px`,
|
||||
px: 1.75,
|
||||
py: 0.75,
|
||||
fontWeight: active ? 700 : 500,
|
||||
color: active ? 'primary.main' : 'text.secondary',
|
||||
bgcolor: active ? (theme: Theme) => alpha(theme.palette.primary.main, 0.12) : 'transparent',
|
||||
bgcolor: active ? (theme: Theme) => alpha(theme.palette.primary.main, 0.14) : 'transparent',
|
||||
border: '1px solid',
|
||||
borderColor: active ? (theme: Theme) => alpha(theme.palette.primary.main, 0.35) : 'transparent',
|
||||
transition: (theme: Theme) =>
|
||||
`background-color ${theme.tokens.motion.fast} ${theme.tokens.motion.ease}, border-color ${theme.tokens.motion.fast} ${theme.tokens.motion.ease}`,
|
||||
'&:hover': {
|
||||
color: 'text.primary',
|
||||
bgcolor: 'action.hover',
|
||||
@@ -43,80 +50,66 @@ export const CategoryBar = ({ categories }: CategoryBarProps) => {
|
||||
<Box
|
||||
component="nav"
|
||||
sx={{
|
||||
position: 'sticky',
|
||||
top: { xs: 56, sm: 64 },
|
||||
zIndex: (theme) => theme.zIndex.appBar - 1,
|
||||
borderBottom: '1px solid',
|
||||
borderColor: (theme) => theme.tokens.glass.border,
|
||||
backgroundColor: (theme) =>
|
||||
alpha(theme.palette.background.default, theme.palette.mode === 'light' ? 0.8 : 0.6),
|
||||
backdropFilter: (theme) => theme.tokens.glass.blurStrong,
|
||||
WebkitBackdropFilter: (theme) => theme.tokens.glass.blurStrong,
|
||||
maxWidth: 1400,
|
||||
mx: 'auto',
|
||||
px: { xs: 1, sm: 4, md: 6 },
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: { xs: 0.5, md: 1 },
|
||||
minHeight: { xs: 46, md: 52 },
|
||||
overflowX: 'auto',
|
||||
'&::-webkit-scrollbar': { display: 'none' },
|
||||
scrollbarWidth: 'none',
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
component={Link}
|
||||
to="/"
|
||||
disableRipple
|
||||
sx={{ ...tabSx(isActive('/')), ml: { xs: -0.5, md: -1.75 } }}
|
||||
>
|
||||
<HomeOutlinedIcon sx={{ fontSize: '1.1rem', mr: 0.75 }} />
|
||||
{t('nav.home')}
|
||||
</Button>
|
||||
|
||||
{user && (
|
||||
<Button component={Link} to="/community" disableRipple sx={tabSx(isActive('/community'))}>
|
||||
<GroupsOutlinedIcon sx={{ fontSize: '1.1rem', mr: 0.75 }} />
|
||||
{t('nav.community')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{user && (
|
||||
<Button component={Link} to="/dashboard" disableRipple sx={tabSx(isActive('/dashboard'))}>
|
||||
<CollectionsBookmarkOutlinedIcon sx={{ fontSize: '1.1rem', mr: 0.75 }} />
|
||||
{t('nav.dashboard')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
maxWidth: 1400,
|
||||
mx: 'auto',
|
||||
px: { xs: 1, sm: 4, md: 6 },
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: { xs: 0.5, md: 1 },
|
||||
minHeight: { xs: 46, md: 52 },
|
||||
overflowX: 'auto',
|
||||
'&::-webkit-scrollbar': { display: 'none' },
|
||||
scrollbarWidth: 'none',
|
||||
alignSelf: 'stretch',
|
||||
my: 1.25,
|
||||
mx: 0.5,
|
||||
borderLeft: '1px solid',
|
||||
borderColor: 'divider',
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
component={Link}
|
||||
to="/"
|
||||
disableRipple
|
||||
sx={{ ...tabSx(isActive('/')), ml: { xs: -0.5, md: -1.75 } }}
|
||||
>
|
||||
<HomeOutlinedIcon sx={{ fontSize: '1.1rem', mr: 0.75 }} />
|
||||
{t('nav.home')}
|
||||
</Button>
|
||||
/>
|
||||
|
||||
{user && (
|
||||
<Button component={Link} to="/community" disableRipple sx={tabSx(isActive('/community'))}>
|
||||
<GroupsOutlinedIcon sx={{ fontSize: '1.1rem', mr: 0.75 }} />
|
||||
{t('nav.community')}
|
||||
{categories.map((cat) => {
|
||||
const path = `/category/${cat.slug}`;
|
||||
return (
|
||||
<Button
|
||||
key={cat.slug}
|
||||
component={Link}
|
||||
to={path}
|
||||
disableRipple
|
||||
sx={tabSx(location.pathname === path)}
|
||||
>
|
||||
{t(`categories.${cat.slug}`, { defaultValue: cat.name })}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{user && (
|
||||
<Button component={Link} to="/dashboard" disableRipple sx={tabSx(isActive('/dashboard'))}>
|
||||
<CollectionsBookmarkOutlinedIcon sx={{ fontSize: '1.1rem', mr: 0.75 }} />
|
||||
{t('nav.dashboard')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
alignSelf: 'stretch',
|
||||
my: 1.25,
|
||||
mx: 0.5,
|
||||
borderLeft: '1px solid',
|
||||
borderColor: 'divider',
|
||||
}}
|
||||
/>
|
||||
|
||||
{categories.map((cat) => {
|
||||
const path = `/category/${cat.slug}`;
|
||||
return (
|
||||
<Button
|
||||
key={cat.slug}
|
||||
component={Link}
|
||||
to={path}
|
||||
disableRipple
|
||||
sx={tabSx(location.pathname === path)}
|
||||
>
|
||||
{t(`categories.${cat.slug}`, { defaultValue: cat.name })}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -22,20 +22,25 @@ import AdminPanelSettingsOutlinedIcon from '@mui/icons-material/AdminPanelSettin
|
||||
import LogoutOutlinedIcon from '@mui/icons-material/LogoutOutlined';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { GlassAppBar } from '../ui';
|
||||
import { CategoryBar } from './CategoryBar';
|
||||
import { GlobalSearch } from '../../app/GlobalSearch';
|
||||
import { useAuth } from '../../hooks/useAuth';
|
||||
import { BrandMark } from './BrandMark';
|
||||
import { NotificationMenu } from './NotificationMenu';
|
||||
|
||||
export interface TopBarProps {
|
||||
categories: { name: string; slug: string }[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Top bar for every breakpoint. Promotes global search to the primary, centered
|
||||
* slot; notifications + an account menu sit on the right. Everything that used to
|
||||
* be a flat sidebar row (profile, dashboard, settings, support, admin, following,
|
||||
* logout) lives behind the avatar menu — so there's no mobile drawer anymore, the
|
||||
* same dropdown serves all sizes. Browse links (home/community/categories) live
|
||||
* in the CategoryBar below.
|
||||
* in the CategoryBar, which now rides as the second row of this same glass pane.
|
||||
*/
|
||||
export const TopBar = () => {
|
||||
export const TopBar = ({ categories }: TopBarProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { user, following, logout } = useAuth();
|
||||
|
||||
@@ -49,6 +54,7 @@ export const TopBar = () => {
|
||||
return (
|
||||
<GlassAppBar
|
||||
toolbarSx={{ maxWidth: 1400, width: '100%', mx: 'auto', px: { xs: 1, sm: 4, md: 6 } }}
|
||||
secondary={<CategoryBar categories={categories} />}
|
||||
>
|
||||
<BrandMark />
|
||||
|
||||
|
||||
Reference in new issue
Block a user