Can toggle dark theme

This commit is contained in:
2023-07-08 16:54:26 +02:00
parent f93bc704a5
commit 099e517688
15 changed files with 134 additions and 63 deletions

View File

@ -1,72 +0,0 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
} from "@mui/material";
import React, { PropsWithChildren } from "react";
interface AlertContext {
alert: (message: string, title?: string) => Promise<void>;
}
const AlertContextK = React.createContext<AlertContext | null>(null);
export function AlertDialogProvider(p: PropsWithChildren): React.ReactElement {
const [open, setOpen] = React.useState(false);
const [title, setTitle] = React.useState<string | undefined>(undefined);
const [message, setMessage] = React.useState("");
const cb = React.useRef<null | (() => void)>(null);
const handleClose = () => {
setOpen(false);
if (cb.current !== null) cb.current();
cb.current = null;
};
const hook: AlertContext = {
alert: (message, title) => {
setTitle(title);
setMessage(message);
setOpen(true);
return new Promise((res) => {
cb.current = res;
});
},
};
return (
<>
<AlertContextK.Provider value={hook}>{p.children}</AlertContextK.Provider>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
{title && <DialogTitle id="alert-dialog-title">{title}</DialogTitle>}
<DialogContent>
<DialogContentText id="alert-dialog-description">
{message}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} autoFocus>
Ok
</Button>
</DialogActions>
</Dialog>
</>
);
}
export function useAlert(): AlertContext {
return React.useContext(AlertContextK)!;
}

View File

@ -14,6 +14,7 @@ import { AuthApi } from "../api/AuthApi";
import { User, UserApi } from "../api/UserApi";
import { AsyncWidget } from "./AsyncWidget";
import { RouterLink } from "./RouterLink";
import { DarkThemeButton } from "./DarkThemeButton";
interface UserContext {
user: User;
@ -90,6 +91,8 @@ export function BaseAuthenticatedPage(): React.ReactElement {
</Typography>
<div>
<DarkThemeButton />
<Button size="large" color="inherit">
{user!.name}
</Button>

View File

@ -27,9 +27,9 @@ import { Outlet, useLocation, useParams } from "react-router-dom";
import { Family, FamilyApi } from "../api/FamilyApi";
import { AsyncWidget } from "./AsyncWidget";
import { RouterLink } from "./RouterLink";
import { useSnackbar } from "./SnackbarProvider";
import { useConfirm } from "./ConfirmDialogProvider";
import { useAlert } from "./AlertDialogProvider";
import { useSnackbar } from "../context_providers/SnackbarProvider";
import { useConfirm } from "../context_providers/ConfirmDialogProvider";
import { useAlert } from "../context_providers/AlertDialogProvider";
interface FamilyContext {
family: Family;

View File

@ -8,6 +8,7 @@ import Paper from "@mui/material/Paper";
import Typography from "@mui/material/Typography";
import * as React from "react";
import { Link, Outlet } from "react-router-dom";
import { DarkThemeButton } from "./DarkThemeButton";
function Copyright(props: any) {
return (
@ -64,6 +65,10 @@ export function BaseLoginPage() {
alignItems: "center",
}}
>
<div style={{ position: "absolute", right: "10px", top: "5px" }}>
<DarkThemeButton />
</div>
<Avatar sx={{ m: 1, bgcolor: "secondary.main" }}>
<Icon path={mdiFamilyTree} size={1} />
</Avatar>

View File

@ -1,87 +0,0 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
} from "@mui/material";
import React, { PropsWithChildren } from "react";
interface ConfirmContext {
confirm: (
message: string,
title?: string,
confirmButton?: string
) => Promise<boolean>;
}
const ConfirmContextK = React.createContext<ConfirmContext | null>(null);
export function ConfirmDialogProvider(
p: PropsWithChildren
): React.ReactElement {
const [open, setOpen] = React.useState(false);
const [title, setTitle] = React.useState<string | undefined>(undefined);
const [message, setMessage] = React.useState("");
const [confirmButton, setConfirmButton] = React.useState<string | undefined>(
undefined
);
const cb = React.useRef<null | ((a: boolean) => void)>(null);
const handleClose = (confirm: boolean) => {
setOpen(false);
if (cb.current !== null) cb.current(confirm);
cb.current = null;
};
const hook: ConfirmContext = {
confirm: (message, title, confirmButton) => {
setTitle(title);
setMessage(message);
setConfirmButton(confirmButton);
setOpen(true);
return new Promise((res) => {
cb.current = res;
});
},
};
return (
<>
<ConfirmContextK.Provider value={hook}>
{p.children}
</ConfirmContextK.Provider>
<Dialog
open={open}
onClose={() => handleClose(false)}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
{title && <DialogTitle id="alert-dialog-title">{title}</DialogTitle>}
<DialogContent>
<DialogContentText id="alert-dialog-description">
{message}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={() => handleClose(false)} autoFocus>
Annuler
</Button>
<Button onClick={() => handleClose(true)} color="error">
{confirmButton ?? "Confirmer"}
</Button>
</DialogActions>
</Dialog>
</>
);
}
export function useConfirm(): ConfirmContext {
return React.useContext(ConfirmContextK)!;
}

View File

@ -0,0 +1,19 @@
import Brightness7Icon from "@mui/icons-material/Brightness7";
import DarkModeIcon from "@mui/icons-material/DarkMode";
import { IconButton, Tooltip } from "@mui/material";
import { useDarkTheme } from "../context_providers/DarkThemeProvider";
export function DarkThemeButton(): React.ReactElement {
const darkTheme = useDarkTheme();
return (
<Tooltip title="Activer / désactiver le mode sombre">
<IconButton
onClick={() => darkTheme.setEnabled(!darkTheme.enabled)}
style={{ color: "inherit" }}
>
{!darkTheme.enabled ? <DarkModeIcon /> : <Brightness7Icon />}
</IconButton>
</Tooltip>
);
}

View File

@ -1,43 +0,0 @@
import { Snackbar } from "@mui/material";
import React, { PropsWithChildren } from "react";
type SnackbarContext = (message: string, duration?: number) => void;
const SnackbarContextK = React.createContext<SnackbarContext | null>(null);
export function SnackbarProvider(p: PropsWithChildren): React.ReactElement {
const [open, setOpen] = React.useState(false);
const [message, setMessage] = React.useState("");
const [duration, setDuration] = React.useState(0);
const handleClose = () => {
setOpen(false);
};
const hook: SnackbarContext = (message, duration) => {
setMessage(message);
setDuration(duration ?? 6000);
setOpen(true);
};
return (
<>
<SnackbarContextK.Provider value={hook}>
{p.children}
</SnackbarContextK.Provider>
<Snackbar
open={open}
autoHideDuration={duration}
onClose={handleClose}
message={message}
/>
</>
);
}
export function useSnackbar(): SnackbarContext {
return React.useContext(SnackbarContextK)!;
}