mirror of
https://github.com/narrrl/holy-flavor-rater.git
synced 2026-11-03 16:41:27 +01:00
removed stats
This commit is contained in:
1 parent
30a0ccda1b
commit
d0aff29a71
6 files changed
+34
-109
No files matched your search
@@ -1,9 +1,6 @@
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Box, Typography } from '@mui/material';
|
import { Box, Typography } from '@mui/material';
|
||||||
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
|
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
|
||||||
import EmojiEventsOutlinedIcon from '@mui/icons-material/EmojiEventsOutlined';
|
|
||||||
import FiberNewOutlinedIcon from '@mui/icons-material/FiberNewOutlined';
|
|
||||||
import CategoryOutlinedIcon from '@mui/icons-material/CategoryOutlined';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { GlassCard, SectionHeader } from '../ui';
|
import { GlassCard, SectionHeader } from '../ui';
|
||||||
|
|
||||||
@@ -81,88 +78,3 @@ export const CategoryBrowseGrid = ({ categories }: CategoryBrowseGridProps) => {
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface QuickStatsStripProps {
|
|
||||||
topName?: string;
|
|
||||||
topScore?: number;
|
|
||||||
newestName?: string;
|
|
||||||
categoryCount: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Desktop-only featured strip — fills the wider canvas with at-a-glance picks. */
|
|
||||||
export const QuickStatsStrip = ({
|
|
||||||
topName,
|
|
||||||
topScore,
|
|
||||||
newestName,
|
|
||||||
categoryCount,
|
|
||||||
}: QuickStatsStripProps) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const items = [
|
|
||||||
{
|
|
||||||
icon: <EmojiEventsOutlinedIcon />,
|
|
||||||
label: t('home.statTopRated', { defaultValue: 'Top Rated' }),
|
|
||||||
value: topName,
|
|
||||||
sub: topScore != null ? `${topScore.toFixed(1)} / 10` : undefined,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <FiberNewOutlinedIcon />,
|
|
||||||
label: t('home.statNewest', { defaultValue: 'Newest Arrival' }),
|
|
||||||
value: newestName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <CategoryOutlinedIcon />,
|
|
||||||
label: t('home.statCategories', { defaultValue: 'Categories' }),
|
|
||||||
value: String(categoryCount),
|
|
||||||
},
|
|
||||||
].filter((i) => i.value);
|
|
||||||
|
|
||||||
if (items.length === 0) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: 'grid',
|
|
||||||
gridTemplateColumns: `repeat(${items.length}, 1fr)`,
|
|
||||||
gap: 2,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{items.map((item) => (
|
|
||||||
<GlassCard
|
|
||||||
key={item.label}
|
|
||||||
intensity="subtle"
|
|
||||||
sx={{ p: 2.5, display: 'flex', alignItems: 'center', gap: 2 }}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: 44,
|
|
||||||
height: 44,
|
|
||||||
flexShrink: 0,
|
|
||||||
borderRadius: 2,
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
color: 'primary.main',
|
|
||||||
bgcolor: 'action.hover',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{item.icon}
|
|
||||||
</Box>
|
|
||||||
<Box sx={{ minWidth: 0 }}>
|
|
||||||
<Typography variant="caption" color="text.secondary" sx={{ fontWeight: 600 }}>
|
|
||||||
{item.label}
|
|
||||||
</Typography>
|
|
||||||
<Typography variant="subtitle1" sx={{ fontWeight: 700, lineHeight: 1.2 }} noWrap>
|
|
||||||
{item.value}
|
|
||||||
</Typography>
|
|
||||||
{item.sub && (
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
|
||||||
{item.sub}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
</GlassCard>
|
|
||||||
))}
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -3,6 +3,7 @@ import { Box, Button, alpha } from '@mui/material';
|
|||||||
import type { Theme } from '@mui/material';
|
import type { Theme } from '@mui/material';
|
||||||
import HomeOutlinedIcon from '@mui/icons-material/HomeOutlined';
|
import HomeOutlinedIcon from '@mui/icons-material/HomeOutlined';
|
||||||
import GroupsOutlinedIcon from '@mui/icons-material/GroupsOutlined';
|
import GroupsOutlinedIcon from '@mui/icons-material/GroupsOutlined';
|
||||||
|
import CollectionsBookmarkOutlinedIcon from '@mui/icons-material/CollectionsBookmarkOutlined';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useAuth } from '../../hooks/useAuth';
|
import { useAuth } from '../../hooks/useAuth';
|
||||||
|
|
||||||
@@ -66,7 +67,12 @@ export const DesktopCategoryBar = ({ categories }: DesktopCategoryBarProps) => {
|
|||||||
scrollbarWidth: 'none',
|
scrollbarWidth: 'none',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button component={Link} to="/" disableRipple sx={tabSx(isActive('/'))}>
|
<Button
|
||||||
|
component={Link}
|
||||||
|
to="/"
|
||||||
|
disableRipple
|
||||||
|
sx={{ ...tabSx(isActive('/')), ml: -1.75 }}
|
||||||
|
>
|
||||||
<HomeOutlinedIcon sx={{ fontSize: '1.1rem', mr: 0.75 }} />
|
<HomeOutlinedIcon sx={{ fontSize: '1.1rem', mr: 0.75 }} />
|
||||||
{t('nav.home')}
|
{t('nav.home')}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -78,6 +84,18 @@ export const DesktopCategoryBar = ({ categories }: DesktopCategoryBarProps) => {
|
|||||||
</Button>
|
</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
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
alignSelf: 'stretch',
|
alignSelf: 'stretch',
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export const DesktopTopBar = () => {
|
|||||||
const unreadCount = user?.unread_notifications_count || 0;
|
const unreadCount = user?.unread_notifications_count || 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GlassAppBar>
|
<GlassAppBar toolbarSx={{ maxWidth: 1400, width: '100%', mx: 'auto', px: { md: 6 } }}>
|
||||||
<BrandMark />
|
<BrandMark />
|
||||||
|
|
||||||
<GlobalSearch />
|
<GlobalSearch />
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useEffect, useState, type ReactNode } from 'react';
|
import { useEffect, useState, type ReactNode } from 'react';
|
||||||
import { styled, alpha } from '@mui/material/styles';
|
import { styled, alpha } from '@mui/material/styles';
|
||||||
|
import type { SxProps, Theme } from '@mui/material/styles';
|
||||||
import AppBar from '@mui/material/AppBar';
|
import AppBar from '@mui/material/AppBar';
|
||||||
import Toolbar from '@mui/material/Toolbar';
|
import Toolbar from '@mui/material/Toolbar';
|
||||||
|
|
||||||
@@ -24,9 +25,12 @@ const StyledAppBar = styled(AppBar, {
|
|||||||
export interface GlassAppBarProps {
|
export interface GlassAppBarProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
threshold?: number;
|
threshold?: number;
|
||||||
|
/** Extra styles merged onto the inner Toolbar — e.g. to constrain its content
|
||||||
|
* to the page-content column so the bar aligns with the main content edges. */
|
||||||
|
toolbarSx?: SxProps<Theme>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GlassAppBar = ({ children, threshold = 12 }: GlassAppBarProps) => {
|
export const GlassAppBar = ({ children, threshold = 12, toolbarSx }: GlassAppBarProps) => {
|
||||||
const [scrolled, setScrolled] = useState(false);
|
const [scrolled, setScrolled] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -38,7 +42,14 @@ export const GlassAppBar = ({ children, threshold = 12 }: GlassAppBarProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledAppBar position="sticky" elevation={0} scrolled={scrolled}>
|
<StyledAppBar position="sticky" elevation={0} scrolled={scrolled}>
|
||||||
<Toolbar sx={{ minHeight: { xs: 56, sm: 64 }, px: { xs: 1, sm: 4, md: 6 } }}>
|
<Toolbar
|
||||||
|
sx={
|
||||||
|
[
|
||||||
|
{ minHeight: { xs: 56, sm: 64 }, px: { xs: 1, sm: 4, md: 6 } },
|
||||||
|
toolbarSx || {},
|
||||||
|
] as SxProps<Theme>
|
||||||
|
}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
</StyledAppBar>
|
</StyledAppBar>
|
||||||
|
|||||||
@@ -116,9 +116,6 @@ const resources = {
|
|||||||
hallOfFameSubtitle: 'Highest-rated flavors in the archive',
|
hallOfFameSubtitle: 'Highest-rated flavors in the archive',
|
||||||
browseCategories: 'Browse Categories',
|
browseCategories: 'Browse Categories',
|
||||||
browseCategoriesSubtitle: 'Jump straight into a flavor line',
|
browseCategoriesSubtitle: 'Jump straight into a flavor line',
|
||||||
statTopRated: 'Top Rated',
|
|
||||||
statNewest: 'Newest Arrival',
|
|
||||||
statCategories: 'Categories',
|
|
||||||
recForYou: 'Recommended for You',
|
recForYou: 'Recommended for You',
|
||||||
recForYouSubtitle: 'Picked by tasters who share your palate',
|
recForYouSubtitle: 'Picked by tasters who share your palate',
|
||||||
popularPicks: 'Popular Picks',
|
popularPicks: 'Popular Picks',
|
||||||
@@ -652,9 +649,6 @@ const resources = {
|
|||||||
hallOfFameSubtitle: 'Die bestbewerteten Sorten im Archiv',
|
hallOfFameSubtitle: 'Die bestbewerteten Sorten im Archiv',
|
||||||
browseCategories: 'Kategorien durchstöbern',
|
browseCategories: 'Kategorien durchstöbern',
|
||||||
browseCategoriesSubtitle: 'Direkt zu einer Sorten-Linie springen',
|
browseCategoriesSubtitle: 'Direkt zu einer Sorten-Linie springen',
|
||||||
statTopRated: 'Bestbewertet',
|
|
||||||
statNewest: 'Neuheit',
|
|
||||||
statCategories: 'Kategorien',
|
|
||||||
recForYou: 'Für dich empfohlen',
|
recForYou: 'Für dich empfohlen',
|
||||||
recForYouSubtitle: 'Ausgewählt von Testern mit ähnlichem Geschmack',
|
recForYouSubtitle: 'Ausgewählt von Testern mit ähnlichem Geschmack',
|
||||||
popularPicks: 'Beliebte Sorten',
|
popularPicks: 'Beliebte Sorten',
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import {
|
|||||||
EmptyState,
|
EmptyState,
|
||||||
} from '../components/ui';
|
} from '../components/ui';
|
||||||
import MainPageRecommendations from './MainPageRecommendations';
|
import MainPageRecommendations from './MainPageRecommendations';
|
||||||
import { CategoryBrowseGrid, QuickStatsStrip } from '../components/home/DesktopHomeSections';
|
import { CategoryBrowseGrid } from '../components/home/DesktopHomeSections';
|
||||||
import { useCategories } from '../api/queries/useCategories';
|
import { useCategories } from '../api/queries/useCategories';
|
||||||
|
|
||||||
const TOP_LIMIT = 5;
|
const TOP_LIMIT = 5;
|
||||||
@@ -274,16 +274,6 @@ const MainPage: React.FC = () => {
|
|||||||
</GlassCard>
|
</GlassCard>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Desktop-only featured strip — fills the wider canvas */}
|
|
||||||
{isDesktop && (
|
|
||||||
<QuickStatsStrip
|
|
||||||
topName={currentTop?.name}
|
|
||||||
topScore={currentTop?.average_rating ?? undefined}
|
|
||||||
newestName={newestFlavors[0]?.name}
|
|
||||||
categoryCount={categories.length}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Hall of Fame */}
|
{/* Hall of Fame */}
|
||||||
<Box>
|
<Box>
|
||||||
<SectionHeader
|
<SectionHeader
|
||||||
|
|||||||
Reference in new issue
Block a user