Add public mode
This commit is contained in:
parent
56370ec936
commit
f16eeb6e45
@ -0,0 +1,34 @@
|
||||
import React, { PropsWithChildren } from "react";
|
||||
|
||||
const localStorageKey = "public-mode";
|
||||
|
||||
interface PublicModeContext {
|
||||
enabled: boolean;
|
||||
setEnabled: (enabled: boolean) => void;
|
||||
}
|
||||
|
||||
const PublicModeContextK = React.createContext<PublicModeContext | null>(null);
|
||||
|
||||
export function PublicModeProvider(p: PropsWithChildren): React.ReactElement {
|
||||
const [enabled, setEnabled] = React.useState(
|
||||
localStorage.getItem(localStorageKey) !== "false"
|
||||
);
|
||||
|
||||
return (
|
||||
<PublicModeContextK
|
||||
value={{
|
||||
enabled: enabled,
|
||||
setEnabled(enabled) {
|
||||
localStorage.setItem(localStorageKey, enabled ? "true" : "false");
|
||||
setEnabled(enabled);
|
||||
},
|
||||
}}
|
||||
>
|
||||
{p.children}
|
||||
</PublicModeContextK>
|
||||
);
|
||||
}
|
||||
|
||||
export function usePublicMode(): PublicModeContext {
|
||||
return React.use(PublicModeContextK)!;
|
||||
}
|
@ -15,6 +15,7 @@ import { LoadingMessageProvider } from "./hooks/context_providers/LoadingMessage
|
||||
import { SnackbarProvider } from "./hooks/context_providers/SnackbarProvider.tsx";
|
||||
import "./index.css";
|
||||
import { AsyncWidget } from "./widgets/AsyncWidget.tsx";
|
||||
import { PublicModeProvider } from "./hooks/context_providers/PublicModeProvider.tsx";
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
@ -24,12 +25,16 @@ createRoot(document.getElementById("root")!).render(
|
||||
<ConfirmDialogProvider>
|
||||
<SnackbarProvider>
|
||||
<LoadingMessageProvider>
|
||||
<PublicModeProvider>
|
||||
<AsyncWidget
|
||||
loadKey={1}
|
||||
load={async () => { await ServerApi.LoadConfig(); }}
|
||||
load={async () => {
|
||||
await ServerApi.LoadConfig();
|
||||
}}
|
||||
errMsg="Failed to load static server configuration!"
|
||||
build={() => <App />}
|
||||
/>
|
||||
</PublicModeProvider>
|
||||
</LoadingMessageProvider>
|
||||
</SnackbarProvider>
|
||||
</ConfirmDialogProvider>
|
||||
|
@ -13,8 +13,10 @@ import { fmtDateFromTime, time } from "../utils/DateUtils";
|
||||
import { AmountWidget } from "../widgets/AmountWidget";
|
||||
import { AsyncWidget } from "../widgets/AsyncWidget";
|
||||
import { MoneyMgrWebRouteContainer } from "../widgets/MoneyMgrWebRouteContainer";
|
||||
import { usePublicMode } from "../hooks/context_providers/PublicModeProvider";
|
||||
|
||||
export function HomeRoute(): React.ReactElement {
|
||||
const publicMode = usePublicMode().enabled;
|
||||
const account = useAccounts();
|
||||
|
||||
const loadKey = React.useRef(1);
|
||||
@ -62,6 +64,20 @@ export function HomeRoute(): React.ReactElement {
|
||||
</Tooltip>
|
||||
}
|
||||
>
|
||||
{publicMode ? (
|
||||
<Typography
|
||||
variant="body1"
|
||||
style={{
|
||||
textAlign: "center",
|
||||
flex: 1,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
Dasbhoard is hidden when public mode is enabled.
|
||||
</Typography>
|
||||
) : (
|
||||
<AsyncWidget
|
||||
ready={global !== undefined}
|
||||
loadKey={loadKey.current}
|
||||
@ -69,6 +85,7 @@ export function HomeRoute(): React.ReactElement {
|
||||
errMsg="Failed to load statistics!"
|
||||
build={() => <StatsDashboard global={global!} lastYear={lastYear!} />}
|
||||
/>
|
||||
)}
|
||||
</MoneyMgrWebRouteContainer>
|
||||
);
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ import Paper from "@mui/material/Paper";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { Link, Outlet } from "react-router-dom";
|
||||
import loginSplashImage from "./mufid-majnun-LVcjYwuHQlg-unsplash.jpg";
|
||||
import { PublicModeButton } from "./PublicModeButtonWidget";
|
||||
import { DarkThemeButton } from "./DarkThemeButtonWidget";
|
||||
|
||||
function Copyright(props: any): React.ReactElement {
|
||||
return (
|
||||
@ -87,6 +89,18 @@ export function BaseLoginPage() {
|
||||
<Outlet />
|
||||
|
||||
<Copyright sx={{ mt: 5 }} style={{ margin: "40px 0px" }} />
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
width: "100%",
|
||||
marginTop: "50px",
|
||||
}}
|
||||
>
|
||||
<PublicModeButton />
|
||||
<DarkThemeButton />
|
||||
</div>
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
@ -7,9 +7,11 @@ export function DarkThemeButton(): React.ReactElement {
|
||||
const darkTheme = useDarkTheme();
|
||||
|
||||
return (
|
||||
<Tooltip title="Activer / désactiver le mode sombre">
|
||||
<Tooltip title="Enable / Disable dark theme">
|
||||
<IconButton
|
||||
onClick={() => { darkTheme.setEnabled(!darkTheme.enabled); }}
|
||||
onClick={() => {
|
||||
darkTheme.setEnabled(!darkTheme.enabled);
|
||||
}}
|
||||
style={{ color: "inherit" }}
|
||||
>
|
||||
{!darkTheme.enabled ? <DarkModeIcon /> : <Brightness7Icon />}
|
@ -14,8 +14,10 @@ import { useAccounts } from "../hooks/AccountsListProvider";
|
||||
import { AccountWidget } from "./AccountWidget";
|
||||
import { RouterLink } from "./RouterLink";
|
||||
import { AmountWidget } from "./AmountWidget";
|
||||
import { usePublicMode } from "../hooks/context_providers/PublicModeProvider";
|
||||
|
||||
export function MoneyNavList(): React.ReactElement {
|
||||
const publicMode = usePublicMode();
|
||||
const accounts = useAccounts();
|
||||
return (
|
||||
<List
|
||||
@ -62,7 +64,9 @@ export function MoneyNavList(): React.ReactElement {
|
||||
<NavLink
|
||||
key={a.id}
|
||||
label={a.name}
|
||||
secondaryLabel={<AmountWidget amount={a.balance} />}
|
||||
secondaryLabel={
|
||||
publicMode.enabled ? <></> : <AmountWidget amount={a.balance} />
|
||||
}
|
||||
uri={`/account/${a.id}`}
|
||||
icon={<AccountWidget account={a} />}
|
||||
/>
|
||||
|
@ -9,8 +9,9 @@ import Toolbar from "@mui/material/Toolbar";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import * as React from "react";
|
||||
import { useAuthInfo } from "./BaseAuthenticatedPage";
|
||||
import { DarkThemeButton } from "./DarkThemeButton";
|
||||
import { DarkThemeButton } from "./DarkThemeButtonWidget";
|
||||
import { RouterLink } from "./RouterLink";
|
||||
import { PublicModeButton } from "./PublicModeButtonWidget";
|
||||
|
||||
export function MoneyWebAppBar(p: {
|
||||
onSignOut: () => void;
|
||||
@ -41,6 +42,7 @@ export function MoneyWebAppBar(p: {
|
||||
</Typography>
|
||||
|
||||
<div>
|
||||
<PublicModeButton />
|
||||
<DarkThemeButton />
|
||||
|
||||
<Button size="large" color="inherit">
|
||||
|
21
moneymgr_web/src/widgets/PublicModeButtonWidget.tsx
Normal file
21
moneymgr_web/src/widgets/PublicModeButtonWidget.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import PublicIcon from "@mui/icons-material/Public";
|
||||
import PublicOffIcon from "@mui/icons-material/PublicOff";
|
||||
import { IconButton, Tooltip } from "@mui/material";
|
||||
import { usePublicMode } from "../hooks/context_providers/PublicModeProvider";
|
||||
|
||||
export function PublicModeButton(): React.ReactElement {
|
||||
const publicMode = usePublicMode();
|
||||
|
||||
return (
|
||||
<Tooltip title={`${publicMode.enabled ? "Disable" : "Enable"} public mode`}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
publicMode.setEnabled(!publicMode.enabled);
|
||||
}}
|
||||
style={{ color: "inherit" }}
|
||||
>
|
||||
{!publicMode.enabled ? <PublicOffIcon /> : <PublicIcon />}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user