Display in a chip the number of unmatched inbox entries

This commit is contained in:
2025-05-12 18:46:40 +02:00
parent 0b586039c3
commit 1e8064946a
5 changed files with 138 additions and 41 deletions

View File

@ -1,13 +1,14 @@
import { Box, Button } from "@mui/material";
import * as React from "react";
import { Outlet, useNavigate } from "react-router-dom";
import { useAuth } from "../App";
import { AuthApi, AuthInfo } from "../api/AuthApi";
import { useAuth } from "../App";
import { AccountsListProvider } from "../hooks/AccountsListProvider";
import { ChooseAccountDialogProvider } from "../hooks/context_providers/ChooseAccountDialogProvider";
import { UnmatchedInboxEntriesCountProvider } from "../hooks/UnmatchedInboxEntriesCountProvider";
import { AsyncWidget } from "./AsyncWidget";
import { MoneyNavList } from "./MoneyNavList";
import { MoneyWebAppBar } from "./MoneyWebAppBar";
import { ChooseAccountDialogProvider } from "../hooks/context_providers/ChooseAccountDialogProvider";
interface AuthInfoContext {
info: AuthInfo;
@ -48,48 +49,50 @@ export function BaseAuthenticatedPage(): React.ReactElement {
reloadAuthInfo: load,
}}
>
<AccountsListProvider>
<ChooseAccountDialogProvider>
<Box
component="div"
sx={{
minHeight: "100vh",
display: "flex",
flexDirection: "column",
backgroundColor: (theme) =>
theme.palette.mode === "light"
? theme.palette.grey[100]
: theme.palette.grey[900],
color: (theme) =>
theme.palette.mode === "light"
? theme.palette.grey[900]
: theme.palette.grey[100],
}}
>
<MoneyWebAppBar onSignOut={signOut} />
<UnmatchedInboxEntriesCountProvider>
<AccountsListProvider>
<ChooseAccountDialogProvider>
<Box
component="div"
sx={{
minHeight: "100vh",
display: "flex",
flex: "2",
flexDirection: "column",
backgroundColor: (theme) =>
theme.palette.mode === "light"
? theme.palette.grey[100]
: theme.palette.grey[900],
color: (theme) =>
theme.palette.mode === "light"
? theme.palette.grey[900]
: theme.palette.grey[100],
}}
>
<MoneyNavList />
<div
style={{
flexGrow: 1,
flexShrink: 0,
flexBasis: 0,
minWidth: 0,
<MoneyWebAppBar onSignOut={signOut} />
<Box
sx={{
display: "flex",
flex: "2",
}}
>
<Outlet />
</div>
<MoneyNavList />
<div
style={{
flexGrow: 1,
flexShrink: 0,
flexBasis: 0,
minWidth: 0,
display: "flex",
}}
>
<Outlet />
</div>
</Box>
</Box>
</Box>
</ChooseAccountDialogProvider>
</AccountsListProvider>
</ChooseAccountDialogProvider>
</AccountsListProvider>
</UnmatchedInboxEntriesCountProvider>
</AuthInfoContextK>
)}
/>

View File

@ -1,8 +1,10 @@
import { mdiCashMultiple, mdiHome, mdiInbox } from "@mdi/js";
import Icon from "@mdi/react";
import {
Chip,
Divider,
List,
ListItem,
ListItemButton,
ListItemIcon,
ListItemText,
@ -15,10 +17,12 @@ import { usePublicMode } from "../hooks/context_providers/PublicModeProvider";
import { AccountWidget } from "./AccountWidget";
import { AmountWidget } from "./AmountWidget";
import { RouterLink } from "./RouterLink";
import { useUnmatchedInboxEntriesCount } from "../hooks/UnmatchedInboxEntriesCountProvider";
export function MoneyNavList(): React.ReactElement {
const publicMode = usePublicMode();
const accounts = useAccounts();
const unmatched = useUnmatchedInboxEntriesCount();
return (
<List
dense
@ -35,11 +39,17 @@ export function MoneyNavList(): React.ReactElement {
uri="/accounts"
icon={<Icon path={mdiCashMultiple} size={1} />}
/>
{/* TODO : show number of unmatched */}
<NavLink
label="Inbox"
uri="/inbox"
icon={<Icon path={mdiInbox} size={1} />}
secondary={
unmatched.count > 0 ? (
<Chip label={unmatched.count} size="small" />
) : (
<></>
)
}
/>
<Divider />
{accounts.list.isEmpty && (
@ -76,14 +86,17 @@ function NavLink(p: {
uri: string;
label: string | React.ReactElement;
secondaryLabel?: string | React.ReactElement;
secondary?: React.ReactElement;
}): React.ReactElement {
const location = useLocation();
return (
<RouterLink to={p.uri}>
<ListItemButton selected={p.uri === location.pathname}>
<ListItemIcon>{p.icon}</ListItemIcon>
<ListItemText primary={p.label} secondary={p.secondaryLabel} />
</ListItemButton>
<ListItem secondaryAction={p.secondary} disablePadding>
<ListItemButton selected={p.uri === location.pathname}>
<ListItemIcon>{p.icon}</ListItemIcon>
<ListItemText primary={p.label} secondary={p.secondaryLabel} />
</ListItemButton>
</ListItem>
</RouterLink>
);
}