forked from kriasoft/graphql-starter-kit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
UserMenu.tsx
113 lines (102 loc) · 3.17 KB
/
UserMenu.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* SPDX-FileCopyrightText: 2014-present Kriasoft */
/* SPDX-License-Identifier: MIT */
import { Brightness4, Logout, Settings } from "@mui/icons-material";
import {
Link,
ListItemIcon,
ListItemText,
Menu,
MenuItem,
MenuProps,
Switch,
} from "@mui/material";
import * as React from "react";
import { Link as NavLink, useNavigate } from "react-router-dom";
import { useSignOut } from "../core/auth.js";
import { useTheme, useToggleTheme } from "../theme/index.js";
export function UserMenu(props: UserMenuProps): JSX.Element {
const { PaperProps, MenuListProps, ...other } = props;
const close = useClose(props.onClose);
const signOut = useHandleSignOut(props.onClose);
const toggleTheme = useToggleTheme();
const theme = useTheme();
return (
<Menu
id="user-menu"
role="menu"
open={Boolean(props.anchorEl)}
anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
transformOrigin={{ vertical: "top", horizontal: "right" }}
PaperProps={{ ...PaperProps, sx: { ...PaperProps?.sx, width: 320 } }}
MenuListProps={{ ...MenuListProps, dense: true }}
{...other}
>
<MenuItem component={NavLink} to="/account" onClick={close}>
<ListItemIcon sx={{ minWidth: 40 }} children={<Settings />} />
<ListItemText primary="Account Details" />
</MenuItem>
<MenuItem>
<ListItemIcon sx={{ minWidth: 40 }} children={<Brightness4 />} />
<ListItemText primary="Dark Mode" />
<Switch
name="theme"
checked={theme?.palette?.mode === "dark"}
onChange={toggleTheme}
/>
</MenuItem>
<MenuItem onClick={signOut}>
<ListItemIcon sx={{ minWidth: 40 }} children={<Logout />} />
<ListItemText primary="Log Out" />
</MenuItem>
{/* Copyright and links to legal documents */}
<MenuItem
sx={{
"&:hover": { background: "none" },
color: (x) => x.palette.grey[500],
paddingTop: (x) => x.spacing(0.5),
paddingBottom: (x) => x.spacing(0.5),
fontSize: "0.75rem",
}}
>
<span>© 2021 Company Name</span>
<span style={{ padding: "0 4px" }}>•</span>
<Link
sx={{ color: "inherit" }}
to="/privacy"
component={NavLink}
onClick={close}
children="Privacy"
/>
<span style={{ padding: "0 4px" }}>•</span>
<Link
sx={{ color: "inherit" }}
to="/terms"
component={NavLink}
onClick={close}
children="Terms"
/>
</MenuItem>
</Menu>
);
}
function useClose(onClose?: MenuProps["onClose"]) {
return React.useCallback(
(event: React.MouseEvent) => {
onClose?.(event, "backdropClick");
},
[onClose],
);
}
function useHandleSignOut(onClose?: MenuProps["onClose"]) {
const navigate = useNavigate();
const signOut = useSignOut();
return React.useCallback(
(event: React.MouseEvent) => {
event.preventDefault();
onClose?.(event, "backdropClick");
signOut().then(() => navigate("/"));
},
[onClose, signOut, navigate],
);
}
export type UserMenuProps = Omit<MenuProps, "open">;