Skip to content

Commit d40c7ff

Browse files
feat: improve mui styles as figma - sponsor services
1 parent 6939989 commit d40c7ff

9 files changed

Lines changed: 281 additions & 97 deletions

File tree

src/components/inputs/company-input-v2.js

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,20 @@
1313

1414
import React from "react";
1515
import PropTypes from "prop-types";
16+
import T from "i18n-react/dist/i18n-react";
1617
import { TextField, Autocomplete, Typography } from "@mui/material";
1718
import { queryRegistrationCompanies } from "../../utils/query-actions";
1819

1920
const CompanyInputV2 = ({ summitId, isRequired, sx, onChange, id, name, label, value, error, helperText, onBlur, placeholder, options2Show, disableShrink, ...rest }) => {
2021
const [inputValue, setInputValue] = React.useState("");
2122
const [options, setOptions] = React.useState([]);
2223

24+
const noCompanyMatchText = T.translate("request_modal.no_company_match");
25+
const createAccessRequestText = (companyName) =>
26+
T.translate("request_modal.create_company_access_request", {
27+
companyName: `"${companyName}"`
28+
});
29+
2330
React.useEffect(() => {
2431
if (inputValue === "") {
2532
setOptions(value ? [value] : []);
@@ -40,7 +47,7 @@ const CompanyInputV2 = ({ summitId, isRequired, sx, onChange, id, name, label, v
4047
setOptions(newOptions);
4148
}, options2Show);
4249
return undefined;
43-
}, [value, inputValue]);
50+
}, [value, inputValue, summitId, options2Show]);
4451

4552
return (
4653
<Autocomplete
@@ -69,18 +76,18 @@ const CompanyInputV2 = ({ summitId, isRequired, sx, onChange, id, name, label, v
6976
onChange={(_, newValue) => {
7077
let tmpValue = newValue?.inputValue || newValue;
7178
// if new option is selected ...
72-
if (newValue && typeof newValue === 'object' && newValue.inputValue) {
79+
if (newValue && typeof newValue === "object" && newValue.inputValue) {
7380
tmpValue = {
7481
id: 0,
7582
name: newValue.inputValue
7683
};
77-
}
84+
}
7885
setOptions(tmpValue ? [tmpValue, ...options] : options);
7986
let ev = {
8087
target: {
8188
id: name,
8289
value: tmpValue,
83-
type: 'companyinput'
90+
type: "companyinput"
8491
}
8592
};
8693
onChange(ev);
@@ -90,15 +97,24 @@ const CompanyInputV2 = ({ summitId, isRequired, sx, onChange, id, name, label, v
9097
}}
9198
filterOptions={(options, params) => {
9299
const { inputValue } = params;
100+
const trimmedInput = inputValue.trim();
93101
const filtered = [...options];
102+
94103
// Suggest the creation of a new value
95104
const isExisting = options.some(
96-
(option) => inputValue === option.title
105+
(option) => {
106+
if (typeof option === "string") {
107+
return option.toLowerCase() === trimmedInput.toLowerCase();
108+
}
109+
110+
return option.name?.toLowerCase() === trimmedInput.toLowerCase();
111+
}
97112
);
98-
if (inputValue !== "" && !isExisting) {
113+
114+
if (trimmedInput !== "" && !isExisting) {
99115
filtered.push({
100-
inputValue,
101-
name: `Select "${inputValue}"`
116+
inputValue: trimmedInput,
117+
name: noCompanyMatchText
102118
});
103119
}
104120

@@ -115,20 +131,48 @@ const CompanyInputV2 = ({ summitId, isRequired, sx, onChange, id, name, label, v
115131
helperText={helperText}
116132
error={error}
117133
margin="normal"
118-
InputLabelProps={{ shrink: disableShrink }}
134+
InputLabelProps={disableShrink ? { shrink: false } : undefined}
119135
/>
120136
)}
121137
renderOption={(props, option) => {
122138
const { key, ...optionProps } = props;
139+
const isCreateOption = Boolean(option.inputValue);
140+
123141
return (
124142
// eslint-disable-next-line react/jsx-props-no-spreading
125-
<li key={key} {...optionProps}>
126-
<Typography
127-
variant="body2"
128-
sx={{ fontSize: "1em", color: "text.secondary" }}
129-
>
130-
{option.name}
131-
</Typography>
143+
<li
144+
key={key}
145+
{...optionProps}
146+
style={{
147+
...(isCreateOption
148+
? {
149+
borderTop: "1px solid rgba(0,0,0,0.12)",
150+
display: "block",
151+
padding: "10px 15px"
152+
}
153+
: {})
154+
}}
155+
>
156+
{isCreateOption ? (
157+
<>
158+
<Typography variant="body2" sx={{ color: "text.secondary" }}>
159+
{noCompanyMatchText}
160+
</Typography>
161+
<Typography
162+
variant="body2"
163+
sx={{ color: "primary.main", fontWeight: 500 }}
164+
>
165+
{createAccessRequestText(option.inputValue)}
166+
</Typography>
167+
</>
168+
) : (
169+
<Typography
170+
variant="body2"
171+
sx={{ color: "text.secondary", padding: "5px 0" }}
172+
>
173+
{option.name}
174+
</Typography>
175+
)}
132176
</li>
133177
);
134178
}}

src/components/mui/AuthButton/index.js

Lines changed: 169 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,56 +11,188 @@
1111
* limitations under the License.
1212
* */
1313

14-
import React, { useState } from "react";
15-
import T from "i18n-react";
16-
import {Button, Box} from '@mui/material';
17-
import styles from "./styles.module.scss"
14+
import React, {useRef, useState} from "react";
15+
import T from "i18n-react/dist/i18n-react";
16+
import {useTheme} from "@mui/material/styles";
17+
import Box from "@mui/material/Box";
18+
import Button from "@mui/material/Button";
19+
import Divider from "@mui/material/Divider";
20+
import IconButton from "@mui/material/IconButton";
21+
import ListItemIcon from "@mui/material/ListItemIcon";
22+
import ListItemText from "@mui/material/ListItemText";
23+
import Menu from "@mui/material/Menu";
24+
import MenuItem from "@mui/material/MenuItem";
25+
import Typography from "@mui/material/Typography";
26+
import AccountCircleIcon from "@mui/icons-material/AccountCircle";
27+
import LogoutIcon from "@mui/icons-material/Logout";
28+
import PersonIcon from "@mui/icons-material/Person";
29+
import SettingsIcon from "@mui/icons-material/Settings";
30+
import styles from "./styles.module.scss";
1831

19-
const AuthButton = ({ isLoggedUser, doLogin, initLogOut, picture }) => {
20-
const [showLogOut, setShowLogOut] = useState(false);
32+
const AuthButton = ({
33+
isLoggedUser,
34+
doLogin,
35+
initLogOut,
36+
profileEmail,
37+
profileName
38+
}) => {
39+
const theme = useTheme();
40+
const anchorRef = useRef(null);
41+
const [menuOpen, setMenuOpen] = useState(false);
2142

22-
const toggleLogOut = () => {
23-
setShowLogOut(!showLogOut);
43+
const menuFontSize = theme?.custom?.menu?.fontSize || "1.4rem";
44+
const menuLineHeight = theme?.custom?.menu?.lineHeight || "2rem";
45+
const menuIconColor = theme?.custom?.menu?.icon || theme.palette.text.secondary;
46+
47+
const openMenu = () => {
48+
setMenuOpen(true);
49+
};
50+
51+
const closeMenu = () => {
52+
setMenuOpen(false);
2453
};
2554

2655
if (isLoggedUser) {
2756
return (
28-
<div className={styles.userMenu} onClick={toggleLogOut}>
29-
<div
30-
className={styles.profilePic}
31-
style={{ backgroundImage: `url(${picture})` }}
32-
/>
33-
{showLogOut && (
34-
<Button
35-
className={styles.logout}
36-
variant="contained"
37-
size="small"
38-
color="secondary"
57+
<Box className={styles.userMenu}>
58+
<IconButton
59+
aria-controls={menuOpen ? "user-menu" : undefined}
60+
aria-expanded={menuOpen ? "true" : undefined}
61+
aria-haspopup="true"
62+
onClick={openMenu}
63+
size="medium"
64+
data-testid="user-menu-button"
65+
sx={{
66+
color: theme.palette.text.primary,
67+
p: 0,
68+
width: 28,
69+
height: 28
70+
}}
71+
ref={anchorRef}
72+
>
73+
<AccountCircleIcon sx={{fontSize: 28}}/>
74+
</IconButton>
75+
<Menu
76+
id="user-menu"
77+
anchorEl={anchorRef.current}
78+
open={menuOpen}
79+
onClose={closeMenu}
80+
anchorOrigin={{
81+
vertical: "bottom",
82+
horizontal: "right"
83+
}}
84+
transformOrigin={{
85+
vertical: "top",
86+
horizontal: "right"
87+
}}
88+
slotProps={{
89+
paper: {
90+
sx: {
91+
mt: 1.5,
92+
minWidth: 260,
93+
borderRadius: 2,
94+
overflow: "hidden",
95+
boxShadow: "0 16px 40px rgba(0, 0, 0, 0.18)"
96+
}
97+
},
98+
list: {
99+
disablePadding: true,
100+
sx: {py: 0}
101+
}
102+
}}
103+
>
104+
<Box sx={{px: 3, py: 2.5}}>
105+
<Typography
106+
variant="body1"
107+
sx={{
108+
fontSize: menuFontSize,
109+
lineHeight: menuLineHeight,
110+
color: theme.palette.text.primary,
111+
mb: 0.5
112+
}}
113+
>
114+
{profileName || "User"}
115+
</Typography>
116+
<Typography
117+
variant="body2"
118+
sx={{
119+
fontSize: menuFontSize,
120+
lineHeight: menuLineHeight,
121+
color: theme.palette.text.secondary
122+
}}
123+
>
124+
{profileEmail || ""}
125+
</Typography>
126+
</Box>
127+
<Divider/>
128+
<MenuItem onClick={closeMenu} sx={{py: 1.5, px: 3, gap: 1.5}}>
129+
<ListItemIcon sx={{minWidth: 32, color: menuIconColor}}>
130+
<SettingsIcon sx={{fontSize: 24}}/>
131+
</ListItemIcon>
132+
<ListItemText
133+
primary={T.translate("general.settings")}
134+
primaryTypographyProps={{
135+
sx: {
136+
fontSize: menuFontSize,
137+
color: theme.palette.text.primary
138+
}
139+
}}
140+
/>
141+
</MenuItem>
142+
<MenuItem onClick={closeMenu} sx={{py: 1.5, px: 3, gap: 1.5}}>
143+
<ListItemIcon sx={{minWidth: 32, color: menuIconColor}}>
144+
<PersonIcon sx={{fontSize: 24}}/>
145+
</ListItemIcon>
146+
<ListItemText
147+
primary={T.translate("general.profile")}
148+
primaryTypographyProps={{
149+
sx: {
150+
fontSize: menuFontSize,
151+
color: theme.palette.text.primary
152+
}
153+
}}
154+
/>
155+
</MenuItem>
156+
<Divider/>
157+
<MenuItem
39158
onClick={() => {
159+
closeMenu();
40160
initLogOut();
41161
}}
162+
sx={{py: 1.5, px: 3, gap: 1.5}}
42163
>
43-
{T.translate("buttons.sign_out")}
44-
</Button>
45-
)}
46-
</div>
47-
);
48-
}
49-
return (
50-
<Box className={styles.login}>
51-
<Button
52-
variant="contained"
53-
size="small"
54-
color="secondary"
55-
onClick={() => {
56-
doLogin();
57-
}}
58-
>
59-
{T.translate("buttons.log_in")}
60-
</Button>
164+
<ListItemIcon sx={{minWidth: 32, color: menuIconColor}}>
165+
<LogoutIcon sx={{fontSize: 24}}/>
166+
</ListItemIcon>
167+
<ListItemText
168+
primary={T.translate("buttons.sign_out")}
169+
primaryTypographyProps={{
170+
sx: {
171+
fontSize: menuFontSize,
172+
color: theme.palette.text.primary
173+
}
174+
}}
175+
/>
176+
</MenuItem>
177+
</Menu>
61178
</Box>
62179
);
180+
}
63181

182+
return (
183+
<Box className={styles.login}>
184+
<Button
185+
variant="contained"
186+
size="small"
187+
color="secondary"
188+
onClick={() => {
189+
doLogin();
190+
}}
191+
>
192+
{T.translate("buttons.log_in")}
193+
</Button>
194+
</Box>
195+
);
64196
};
65197

66198
export default AuthButton;
Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,13 @@
11
.userMenu {
22
position: absolute;
3-
top: 12px;
4-
right: 34px;
5-
height: 40px;
6-
width: 140px;
7-
cursor: pointer;
3+
top: 50%;
4+
right: 24px;
5+
display: flex;
6+
justify-content: flex-end;
7+
transform: translateY(-50%);
88
}
99

1010
.login {
1111
width: 100%;
1212
text-align: right;
13-
}
14-
15-
.logout {
16-
top: 4px;
17-
right: 4px;
18-
}
19-
20-
.profilePic {
21-
height: 40px;
22-
width: 40px;
23-
border: 1px solid #afafaf;
24-
border-radius: 20px;
25-
overflow: hidden;
26-
float: right;
27-
background-size: cover;
2813
}

0 commit comments

Comments
 (0)