Can toggle dark theme
This commit is contained in:
@ -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)!;
|
||||
}
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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)!;
|
||||
}
|
19
geneit_app/src/widgets/DarkThemeButton.tsx
Normal file
19
geneit_app/src/widgets/DarkThemeButton.tsx
Normal 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>
|
||||
);
|
||||
}
|
@ -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)!;
|
||||
}
|
Reference in New Issue
Block a user