@material-ui/core#InputAdornment JavaScript Examples
The following examples show how to use
@material-ui/core#InputAdornment.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: eyeToggle.js From horondi_client_fe with MIT License | 6 votes |
export function endAdornment(isVisible, setShowPass) {
return {
endAdornment: (
<InputAdornment position='end'>
<IconButton
aria-label='toggle password visibility'
onClick={(e) => toggleInputType(e, setShowPass)}
>
{isVisible ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
)
};
}
Example #2
Source File: SettingsPage.js From Doto with MIT License | 6 votes |
InputNameField = props => {
return (
<FormControl id="input-field">
<Input
startAdornment={
<InputAdornment position="start">
<AccountCircle />
</InputAdornment>
}
value={props.name}
disabled={true}
/>
</FormControl>
);
}
Example #3
Source File: SearchBar.js From git-brunching with GNU General Public License v3.0 | 6 votes |
SearchBar = (props) => {
const {
getAll, getSearched, classes, searchText,
} = props;
const onSearchClicked = (text) => {
if (text === "") {
getAll();
} else {
getSearched(text);
}
};
const onTextChange = (e) => {
onSearchClicked(e.target.value);
};
return (
<TextField
id="standard-search"
variant="outlined"
className={classes.root}
placeholder="Search"
value={searchText}
onChange={onTextChange}
InputProps={{
startAdornment: (
<InputAdornment position="start" style={{ marginRight: 0 }}>
<IconButton disabled>
<Search />
</IconButton>
</InputAdornment>
),
className: classes.input,
}}
type="search"
/>
);
}
Example #4
Source File: PasswordInput.js From medha-STPC with GNU Affero General Public License v3.0 | 6 votes |
input = props => (
<TextField
autoFocus={props.autoFocus ? props.autoFocus : false}
className={props.className}
id={props.id}
label={props.label}
name={props.name}
onChange={props.onChange}
value={props.value}
variant={props.variant ? props.variant : "standard"}
error={props.error ? props.error : false}
placeholder={props.placeholder}
type={props.type}
helperText={props.helperText}
inputProps={{
endAdornment: (
<InputAdornment position="end">
<RemoveRedEye />
</InputAdornment>
)
}}
/>
)
Example #5
Source File: ItemSearch.js From warsinhk with MIT License | 6 votes |
ItemSearch = props => {
const { onChange, placeholder } = props
return (
<StyledTextField
placeholder={placeholder}
onChange={onChange}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
size="small"
/>
)
}
Example #6
Source File: InputAdornmentPassword.js From AED-Map with MIT License | 6 votes |
InputAdornmentPassword = ({ showPassword, handleClickShowPassword, handleMouseDownPassword }) => (
<InputAdornment position="end">
<IconButton
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
>
{showPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
)
Example #7
Source File: NumberField.jsx From archeage-tools with The Unlicense | 6 votes |
render() {
const { inputStyle, min, max, step, endAdornment, InputProps, ...otherProps } = this.props;
const { value } = this.state;
return (
<TextField
margin="dense"
{...otherProps}
value={value}
onChange={this.handleChange}
onFocus={this.handleFocus(true)}
onBlur={this.handleFocus(false)}
type="number"
inputProps={{
style: { textAlign: 'right', ...inputStyle },
min,
max,
step,
}}
InputProps={{
endAdornment: endAdornment ? <InputAdornment position="end">{endAdornment}</InputAdornment> : null,
...InputProps,
}}
/>
);
}
Example #8
Source File: BlogPostsSearch.js From course-manager with MIT License | 6 votes |
export default function BlogPostsSearch({ posts }) {
return (
<RootStyle>
<Autocomplete
size="small"
disablePortal
popupIcon={null}
options={posts}
getOptionLabel={(post) => post.title}
renderInput={(params) => (
<TextField
{...params}
placeholder="Search post..."
InputProps={{
...params.InputProps,
startAdornment: (
<>
<InputAdornment position="start">
<Box
component={Icon}
icon={searchFill}
sx={{
ml: 1,
width: 20,
height: 20,
color: 'text.disabled'
}}
/>
</InputAdornment>
{params.InputProps.startAdornment}
</>
)
}}
/>
)}
/>
</RootStyle>
);
}
Example #9
Source File: CreateNewBudget.js From Simplify-Testing-with-React-Testing-Library with MIT License | 5 votes |
render() {
const { classes } = this.props;
const { open, category, amount } = this.state;
return (
<Fragment>
<Button
variant='contained'
className={classes.newBudgetBtn}
color='primary'
onClick={this.handleOpen}
>
Create New Budget
</Button>
<Modal
aria-labelledby='Create New Budget'
aria-describedby="Create's a new budget"
open={open}
onClose={this.handleClose}
>
<div className={classes.paper}>
<Typography variant='body1' id='modal-title'>
Select a category and enter a budget amount.
</Typography>
<FormControl
style={{
width: '181px',
marginTop: '10px',
marginBottom: '20px',
}}
>
<InputLabel htmlFor='category-native-simple'>Category</InputLabel>
<Select
native
value={category}
onChange={this.handleChange}
inputProps={{
name: 'category',
id: 'category-native-simple',
}}
>
<option value='' />
{this.renderBudgetOptions()}
</Select>
</FormControl>
<FormControl style={{ display: 'block', marginBottom: '20px' }}>
<InputLabel htmlFor='adornment-amount'>Amount</InputLabel>
<Input
type='number'
inputProps={{
name: 'amount',
id: 'amount-native-simple',
}}
placeholder='Enter a number'
onChange={this.handleChange}
startAdornment={
<InputAdornment position='start'>$</InputAdornment>
}
/>
<Typography color='error' variant='body1'>
* Budgets must be in increments of 5. {<br />}* Amounts less
than 5 will default to $5.
</Typography>
</FormControl>
<Button
disabled={amount && category ? false : true}
fullWidth
variant='contained'
color='secondary'
onClick={this.handleAddNewBudget}
>
Add Budget
</Button>
</div>
</Modal>
</Fragment>
);
}
Example #10
Source File: Searchbar.js From course-manager with MIT License | 5 votes |
// ----------------------------------------------------------------------
export default function Searchbar() {
const [isOpen, setOpen] = useState(false);
const handleOpen = () => {
setOpen((prev) => !prev);
};
const handleClose = () => {
setOpen(false);
};
return (
<ClickAwayListener onClickAway={handleClose}>
<div>
{!isOpen && (
<IconButton onClick={handleOpen}>
<Icon icon={searchFill} width={20} height={20} />
</IconButton>
)}
<Slide direction="down" in={isOpen} mountOnEnter unmountOnExit>
<SearchbarStyle>
<Input
autoFocus
fullWidth
disableUnderline
placeholder="Search…"
startAdornment={
<InputAdornment position="start">
<Box
component={Icon}
icon={searchFill}
sx={{ color: 'text.disabled', width: 20, height: 20 }}
/>
</InputAdornment>
}
sx={{ mr: 1, fontWeight: 'fontWeightBold' }}
/>
<Button variant="contained" onClick={handleClose}>
Search
</Button>
</SearchbarStyle>
</Slide>
</div>
</ClickAwayListener>
);
}
Example #11
Source File: SetIncome.js From Simplify-Testing-with-React-Testing-Library with MIT License | 5 votes |
render() {
const { classes } = this.props;
const { open, income } = this.state;
return (
<Fragment>
<Button
variant='contained'
className={classes.newIncomeBtn}
color='secondary'
onClick={this.handleOpen}
>
Set Income
</Button>
<Modal
aria-labelledby='Set Income Amount '
aria-describedby="Set's the income amount"
open={open}
onClose={this.handleClose}
>
<div className={classes.paper}>
<Typography variant='body1' id='modal-title'>
Enter you total income.
</Typography>
<FormControl
style={{
display: 'block',
marginTop: '10px',
marginBottom: '20px',
}}
>
<InputLabel htmlFor='adornment-amount'>Amount</InputLabel>
<Input
type='number'
placeholder='Enter a number'
onChange={this.handleChange}
startAdornment={
<InputAdornment position='start'>$</InputAdornment>
}
/>
</FormControl>
<Button
disabled={income <= 0 ? true : false}
fullWidth
variant='contained'
color='secondary'
onClick={this.handleSetIncome}
>
Submit
</Button>
</div>
</Modal>
</Fragment>
);
}
Example #12
Source File: SearchBar.js From reddish with MIT License | 5 votes |
SearchBar = ({ isMobile, setSearchOpen }) => {
const [searchInput, setSearchInput] = useState('');
const history = useHistory();
const classes = useNavStyles();
const handleSearch = (e) => {
e.preventDefault();
if (searchInput === '') return;
history.push(`/search/${searchInput}`);
};
const clearSearch = () => {
if (isMobile) {
setSearchOpen(false);
}
setSearchInput('');
};
return (
<div className={classes.search}>
<form onSubmit={handleSearch}>
<TextField
type="search"
placeholder="Search for posts…"
value={searchInput}
onChange={(e) => setSearchInput(e.target.value)}
className={classes.inputField}
variant="outlined"
margin="dense"
fullWidth
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon color="primary" />
</InputAdornment>
),
endAdornment: (searchInput || isMobile) && (
<InputAdornment position="end">
<IconButton color="primary" size="small" onClick={clearSearch}>
<HighlightOffIcon />
</IconButton>
</InputAdornment>
),
}}
/>
</form>
</div>
);
}
Example #13
Source File: MainSettings.js From Interceptor with MIT License | 5 votes |
render() {
//console.log("Rendering MainSettings");
return (
<Dialog
open={this.props.show}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">Main settings</DialogTitle>
<DialogContent>
<Grid container spacing={2} direction="column" alignItems="flex-start">
<Grid item>
<FormControl>
<InputLabel htmlFor="ws_url">WebSocket URL</InputLabel>
<Input
id="ws_url"
value={this.state.ws_url}
onChange={event => this.setState({ ws_url: event.target.value })}
aria-describedby="ws_url-helper-text"
inputProps={{
'aria-label': 'WebSocket URL',
}}
/>
<FormHelperText id="ws_url-helper-text">Tethered WiFi ws://192.168.43.1:8989</FormHelperText>
</FormControl>
</Grid>
<Grid item>
<FormControl>
<InputLabel htmlFor="rateHz">Render rate</InputLabel>
<Input
id="rateHz"
value={this.state.rateHz}
onChange={event => this.setState({ rateHz: Math.min(Math.max(parseInt(event.target.value), 0.5), 20) })}
endAdornment={<InputAdornment position="end">Hz</InputAdornment>}
aria-describedby="rateHz-helper-text"
inputProps={{
'aria-label': 'Render rate',
}}
/>
<FormHelperText id="rateHz-helper-text">Min: 0.5, Max: 20</FormHelperText>
</FormControl>
</Grid>
<Grid item>
<FormControlLabel
control={<Switch checked={this.state.dark_theme} onChange={() => this.setState({ dark_theme: !this.state.dark_theme })} name="dark_theme" />}
label="Dark theme"
/>
</Grid>
</Grid>
</DialogContent>
<DialogActions>
<Button onClick={() => this.props.setSettings(this.state.ws_url, this.state.rateHz, this.state.dark_theme)} color="default">
Save
</Button>
</DialogActions>
</Dialog>
);
}
Example #14
Source File: IconsLibrary.jsx From doc2pen with Creative Commons Zero v1.0 Universal | 5 votes |
function IconsLibrary() {
const [searchString, setSearchString] = useState("");
const classes = useStyles();
return (
<div className={style.root}>
<div className={style.panel}>
<TextField
id="outlined-search"
label="Search Icons"
type="search"
variant="outlined"
value={searchString}
className={classes.search}
autoComplete="off"
autoFocus={true}
onChangeCapture={e => setSearchString(e.target.value)}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton>
<Search />
</IconButton>
</InputAdornment>
),
}}
/>
</div>
<Divider />
<div className={style.iconLib}>
<IconPreview
iconPackSVGs={iconPack1SVGs}
categoryTitle="Tech Stack Icons"
searchString={searchString}
/>
{/* https://drwn.io/ */}
<IconPreview
iconPackSVGs={iconPack21SVGs}
categoryTitle="Stick Figure Icons - Light"
searchString={searchString}
/>
<IconPreview
iconPackSVGs={iconPack22SVGs}
categoryTitle="Stick Figure Icons - Bold"
searchString={searchString}
/>
{/* https://svgsilh.com/tag/stickman-1.html */}
<IconPreview
iconPackSVGs={iconPack3SVGs}
categoryTitle="Speech Bubble Icons"
searchString={searchString}
/>
{/* https://drwn.io/ */}
{/* https://freesvg.org/search/ */}
{/* https://www.flaticon.com/free-icons/hand-drawn-speech-bubble */}
{/* https://www.flaticon.com/packs/speech-bubbles-2 */}
{/* https://www.svgrepo.com/svg/82688/thought-bubble */}
<IconPreview
iconPackSVGs={iconPack41SVGs}
categoryTitle="Devices & Hardware Icons - Bold"
searchString={searchString}
/>
<IconPreview
iconPackSVGs={iconPack42SVGs}
categoryTitle="Devices & Hardware Icons - Light"
searchString={searchString}
/>
{/* https://www.svgrepo.com/vectors/device/ */}
{/* https://www.flaticon.com/packs/smart-devices?k=1615927940770 */}
{/* https://freeicons.io/material-icons-file-3/devices-icon-17364 */}
</div>
</div>
);
}
Example #15
Source File: SearchBar.js From stack-underflow with MIT License | 5 votes |
SearchBar = ({ isMobile, setSearchOpen }) => {
const [searchInput, setSearchInput] = useState('');
const history = useHistory();
const classes = useNavStyles();
const handleSearch = (e) => {
e.preventDefault();
if (searchInput === '') return;
history.push(`/search/${searchInput}`);
};
const clearSearch = () => {
if (isMobile) {
setSearchOpen(false);
}
setSearchInput('');
};
return (
<div className={classes.searchBar}>
<form onSubmit={handleSearch}>
<TextField
type="search"
size="small"
placeholder="Search for questions…"
value={searchInput}
onChange={(e) => setSearchInput(e.target.value)}
variant="outlined"
fullWidth
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon color="primary" />
</InputAdornment>
),
endAdornment: (searchInput || isMobile) && (
<InputAdornment position="end">
<IconButton color="primary" size="small" onClick={clearSearch}>
<ArrowBackIcon />
</IconButton>
</InputAdornment>
),
}}
/>
</form>
</div>
);
}
Example #16
Source File: Search.js From to-view-list with MIT License | 5 votes |
Search = () => {
const query = useRef();
const classes = useSearchStyles();
const [, dispatch] = useEntryContext();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('xs'));
const handleSearchChange = () => {
if (query.current.value !== '') {
dispatch(setSearchInput(query.current.value));
} else {
dispatch(clearSearch());
}
};
const handleClear = () => {
query.current.value = '';
dispatch(clearSearch());
};
const clearButton = () => {
if (isMobile) {
return (
<IconButton color="secondary" onClick={handleClear} size="small">
<HighlightOffIcon />
</IconButton>
);
}
return (
<Button
color="primary"
onClick={handleClear}
startIcon={<HighlightOffIcon />}
>
Clear
</Button>
);
};
return (
<div className={classes.root}>
<TextField
className={classes.field}
fullWidth
label="Search"
variant="outlined"
placeholder="By title, tag or description"
inputRef={query}
onChange={handleSearchChange}
color="secondary"
size={isMobile ? 'small' : 'medium'}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon color="secondary" />
</InputAdornment>
),
endAdornment: (
<InputAdornment position="end">
{query?.current?.value !== '' && clearButton()}
</InputAdornment>
),
}}
/>
</div>
);
}
Example #17
Source File: GraphSettings.js From Interceptor with MIT License | 5 votes |
render() {
//console.log("Rendering GraphSettings");
return (
<Dialog
open={this.props.show}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">Graphs settings</DialogTitle>
<DialogContent>
<Grid container spacing={2} direction="column" alignItems="flex-start">
<Grid item>
<FormControl>
<InputLabel htmlFor="cols">Graph columns</InputLabel>
<Input
id="cols"
value={this.state.cols}
onChange={event => this.setState({ cols: Math.min(Math.max(parseInt(event.target.value), 1), 12) })}
aria-describedby="cols-helper-text"
inputProps={{
'aria-label': 'Graph columns',
}}
/>
<FormHelperText id="cols-helper-text">Max: 12</FormHelperText>
</FormControl>
</Grid>
<Grid item>
<FormControl>
<InputLabel htmlFor="rateHz">Render rate</InputLabel>
<Input
id="rateHz"
value={this.state.rateHz}
onChange={event => this.setState({ rateHz: Math.min(Math.max(parseInt(event.target.value), 0.5), 20) })}
endAdornment={<InputAdornment position="end">Hz</InputAdornment>}
aria-describedby="rateHz-helper-text"
inputProps={{
'aria-label': 'Render rate',
}}
/>
<FormHelperText id="rateHz-helper-text">Min: 0.5, Max: 20</FormHelperText>
</FormControl>
</Grid>
<Grid item>
<FormControl>
<InputLabel htmlFor="max_datapoints">Max data points</InputLabel>
<Input
id="max_datapoints"
value={this.state.max_datapoints}
onChange={event => this.setState({ max_datapoints: Math.min(Math.max(parseInt(event.target.value), 20), 10000) })}
aria-describedby="max_datapoints-helper-text"
inputProps={{
'aria-label': 'Max data points',
}}
/>
<FormHelperText id="max_datapoints-helper-text">Max: 10000</FormHelperText>
</FormControl>
</Grid>
<Grid item>
<FormControlLabel
control={<Switch checked={this.state.webgl} onChange={() => this.setState({ webgl: !this.state.webgl })} name="webGL" />}
label="WebGL support"
/>
</Grid>
</Grid>
</DialogContent>
<DialogActions>
<Button onClick={() => this.props.setSettings(this.state.cols, this.state.rateHz, this.state.max_datapoints, this.state.webgl)} color="default">
Save
</Button>
</DialogActions>
</Dialog>
);
}
Example #18
Source File: SetIncome.js From Simplify-Testing-with-React-Testing-Library with MIT License | 5 votes |
render() {
const { classes } = this.props;
const { open, income } = this.state;
return (
<Fragment>
<MuiThemeProvider theme={addIncomeBtnTheme}>
<Button
variant='contained'
className={classes.newIncomeBtn}
color='secondary'
onClick={this.handleOpen}
>
Set Income
</Button>
</MuiThemeProvider>
<Modal
aria-labelledby='Set Income Amount '
aria-describedby="Set's the income amount"
open={open}
onClose={this.handleClose}
>
<div className={classes.paper}>
<Typography variant='body1' id='modal-title'>
Enter you total income.
</Typography>
<FormControl
style={{
display: 'block',
marginTop: '10px',
marginBottom: '20px',
}}
>
<InputLabel htmlFor='adornment-amount'>Amount</InputLabel>
<Input
type='number'
placeholder='Enter a number'
onChange={this.handleChange}
startAdornment={
<InputAdornment position='start'>$</InputAdornment>
}
/>
</FormControl>
<MuiThemeProvider theme={addIncomeBtnTheme}>
<Button
disabled={income <= 0 ? true : false}
fullWidth
variant='contained'
color='secondary'
onClick={this.handleSetIncome}
>
Submit
</Button>
</MuiThemeProvider>
</div>
</Modal>
</Fragment>
);
}
Example #19
Source File: UserListToolbar.js From course-manager with MIT License | 5 votes |
export default function UserListToolbar({ numSelected, filterName, onFilterName }) {
return (
<RootStyle
sx={{
...(numSelected > 0 && {
color: 'primary.main',
bgcolor: 'primary.lighter'
})
}}
>
{numSelected > 0 ? (
<Typography component="div" variant="subtitle1">
{numSelected} selected
</Typography>
) : (
<SearchStyle
value={filterName}
onChange={onFilterName}
placeholder="Search user..."
startAdornment={
<InputAdornment position="start">
<Box component={Icon} icon={searchFill} sx={{ color: 'text.disabled' }} />
</InputAdornment>
}
/>
)}
{numSelected > 0 ? (
<Tooltip title="Delete">
<IconButton>
<Icon icon={trash2Fill} />
</IconButton>
</Tooltip>
) : (
<Tooltip title="Filter list">
<IconButton>
<Icon icon={roundFilterList} />
</IconButton>
</Tooltip>
)}
</RootStyle>
);
}
Example #20
Source File: AddComment.js From yasn with MIT License | 5 votes |
export default function InputWithIcon(props) {
const classes = useStyles();
const cookies = new Cookies();
const email = cookies.get('userCookie').Email;
const googleToken = cookies.get('userCookie').Token;
return (
<div>
<div className={classes.margin}>
<Formik
initialValues={{
comment: '',
}}
validate={() => {}}
onSubmit={async (values) => {
if (values.comment && props.userId) {
axios
.post(
`${ConnectServerUrl}/addcomment?` +
queryString.stringify(
{ googleToken, email },
{ withCredentials: true }
),
{
comment: values.comment,
postId: props.postId,
username: props.username,
userId: props.userId,
name: props.name,
}
)
.then(function (res) {
if (res.data === 'success') {
console.log('comment added!');
window.location.reload();
}
})
.catch(function (error) {
console.log(error);
});
}
}}
>
{({ values, handleChange, handleBlur, handleSubmit }) => (
<form onSubmit={handleSubmit} className={classes.root}>
<FormControl fullWidth className={classes.margin}>
{/* <InputLabel htmlFor="standard-adornment-amount">
Add a comment
</InputLabel> */}
<Input
id="standard-adornment-amount"
name="comment"
value={values.comment}
onChange={handleChange}
onBlur={handleBlur}
placeholder="Add a comment"
endAdornment={
<InputAdornment position="end">
<IconButton aria-label="send" size="medium" type="submit">
<SendIcon />
</IconButton>
</InputAdornment>
}
/>
</FormControl>
</form>
)}
</Formik>
</div>
</div>
);
}
Example #21
Source File: CopyDialog.jsx From archeage-tools with The Unlicense | 5 votes |
render() {
const { open, handleClose, title, label, value } = this.props;
const { copied } = this.state;
return (
<Dialog
open={open}
onClose={handleClose}
maxWidth="lg"
>
<AppBar position="static">
<Toolbar variant="dense">
<Typography variant="subtitle1" className="title-text">{title}</Typography>
<IconButton color="inherit" aria-label="Close" onClick={handleClose}>
<Close />
</IconButton>
</Toolbar>
</AppBar>
<DialogContent>
<TextField
label={label}
value={value}
InputProps={{
readOnly: true,
ref: (node) => this.copyTextfield = node,
endAdornment: (
<InputAdornment position="end">
<Tooltip title="Copy">
<FileCopy style={{ cursor: 'pointer' }} onClick={this.handleCopy} />
</Tooltip>
</InputAdornment>
),
}}
fullWidth
multiline
helperText={copied ? <Typography color="primary" variant="body2" component="span">Copied!</Typography> : ''}
style={{ width: 300 }}
/>
</DialogContent>
</Dialog>
);
}
Example #22
Source File: header.js From ark-funds-monitor with GNU Affero General Public License v3.0 | 5 votes |
render() {
return (
<div className="header-section">
<Grid container spacing={3} justify="center" alignItems="center">
<Grid item xs={6} md={10} className='title-container'>
{/* <span className="logo">
<a href="http://karlzhu-se.github.io/ark-funds-monitor/">
<img height="90" width="120" src="https://ark-funds.com/wp-content/uploads/2020/07/ark-logo-1-1.svg" alt="ark-funds.com" title="" />
</a>
</span> */}
<a className='title' href="http://karlzhu-se.github.io/ark-funds-monitor/">
<span>ARK Funds Monitor</span>
</a>
{/* <div className="github-section">
<span>View it on</span>
<a className="github-icon" href="https://github.com/KarlZhu-SE/ark-funds-monitor" target="_blank" rel="noopener noreferrer" aria-label="Github">
<svg height="24" viewBox="0 0 16 16" version="1.1" width="24" aria-hidden="true"><path fillRule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg>
</a>
</div> */}
</Grid>
<Grid item xs={6} md={2} className="ticker-input-section">
<form onSubmit={this.handleSubmit}>
<FormControl>
<div>
<Input
id="ticker-textfield"
value={this.state.inputTicker}
onCompositionStart={this.handlingComposition}
onCompositionUpdate={this.handlingComposition}
onCompositionEnd={this.handleComposition}
onChange={this.handleChange}
onBlur={this.handleBlur}
placeholder='Ticker'
endAdornment={
<InputAdornment position="start">
<IconButton
aria-label="Search"
onClick={this.handleSubmit}
edge="end"
>
<SearchIcon color="primary" />
</IconButton>
</InputAdornment>
}
/>
</div>
</FormControl>
</form>
</Grid>
</Grid>
</div>
);
}
Example #23
Source File: Subscribe.jsx From dineforward with MIT License | 5 votes |
Subscribe = () => {
const classes = useStyles();
return (
<Grid container>
<Grid item xs={12} sm={6} md={6} className={classNames(classes.mlAuto, classes.mrAuto)}>
<div className={classes.textCenter}>
<h3 className={classes.title}>Subscribe to our Newsletter</h3>
<p className={classes.description}>
Join our newsletter and get news in your inbox every week! We hate spam too, so no
worries about this.
</p>
</div>
<Card raised className={classes.card}>
<CardContent className={classes.cardBody}>
<form>
<Grid container>
<Grid item xs={12} sm={6} md={6} lg={8}>
<TextField
id="emailPreFooter"
className={classes.cardForm}
fullWidth
inputProps={{
startAdornment: (
<InputAdornment position="start">
<Mail />
</InputAdornment>
),
placeholder: 'Your Email...',
}}
/>
</Grid>
<Grid xs={12} sm={6} md={6} lg={4}>
<Button color="primary" className={classes.subscribeButton}>
subscribe
</Button>
</Grid>
</Grid>
</form>
</CardContent>
</Card>
</Grid>
</Grid>
);
}
Example #24
Source File: PageWrapper.jsx From zubhub with GNU Affero General Public License v3.0 | 4 votes |
/**
* @function PageWrapper View
* @author Raymond Ndibe <[email protected]>
*
* @todo - describe function's signature
*/
function PageWrapper(props) {
const backToTopEl = React.useRef(null);
const classes = useStyles();
const common_classes = useCommonStyles();
const trigger = useScrollTrigger();
const [searchType, setSearchType] = useState(
getQueryParams(window.location.href).get('type') || SearchType.PROJECTS,
);
const formRef = useRef();
const token = useSelector(state => state.auth.token);
const [state, setState] = React.useState({
username: null,
anchor_el: null,
loading: false,
open_search_form: false,
});
const [options, setOptions] = useState([]);
const [query, setQuery] = useState('');
const [queryInput, setQueryInput] = useState('');
const throttledFetchOptions = useMemo(
() =>
throttle(async (query, searchType) => {
if (query.length === 0) {
setOptions([]);
return;
}
const api = new API();
let completions = [];
if (searchType === SearchType.TAGS) {
completions = await api.autocompleteTags({ query, token });
completions = completions.map(({ name }) => ({
title: name,
}));
} else if (searchType === SearchType.PROJECTS) {
completions = await api.autocompleteProjects({ query, token });
completions = completions.map(({ id, title, creator, images }) => ({
title,
shortInfo: creator.username,
image: images.length > 0 ? images[0].image_url : null,
link: `/projects/${id}`,
}));
} else {
completions = await api.autocompleteCreators({ query, token });
completions = completions.map(({ username, avatar }) => ({
title: username,
image: avatar,
link: `/creators/${username}`,
}));
}
setOptions(completions);
}, 2),
[],
);
useEffect(() => {
throttledFetchOptions(
query ||
(props.location.search &&
getQueryParams(window.location.href).get('q')),
searchType,
);
}, [query, searchType]);
useEffect(() => {
throttledFetchOptions.cancel();
}, []);
useEffect(() => {
handleSetState({ loading: true });
fetchHero(props)
.then(() => {
if (props.auth.token) {
return props.getAuthUser(props);
}
})
.finally(() => {
handleSetState({ loading: false });
});
}, [props.auth.token]);
React.useEffect(() => {
handleSetState(handleProfileMenuClose());
}, [trigger]);
const handleSetState = obj => {
if (obj) {
Promise.resolve(obj).then(obj => {
setState(state => ({ ...state, ...obj }));
});
}
};
const onSearchOptionClick = async (_, option) => {
if (!option || !option.title) return;
await new Promise(resolve => setTimeout(resolve, 100));
if (option.link) {
window.history.pushState({}, '', option.link);
window.location.reload();
return;
}
const queryParams = new URLSearchParams({
type: searchType,
q: option.title,
});
window.history.pushState({}, '', `/search?${queryParams}`);
window.location.reload();
};
const handleSubmit = e => {
e.preventDefault();
const queryParams = new URLSearchParams({
type: searchType,
q: query,
});
window.history.pushState({}, '', `/search?${queryParams}`);
window.location.reload();
};
const { anchor_el, loading, open_search_form } = state;
const { t } = props;
const { zubhub, hero } = props.projects;
const profileMenuOpen = Boolean(anchor_el);
return (
<>
<ToastContainer />
<CssBaseline />
<AppBar className={classes.navBarStyle}>
<Container className={classes.mainContainerStyle}>
<Toolbar className={classes.toolBarStyle}>
<Box className={classes.logoStyle}>
<Link to="/">
<img
src={zubhub?.header_logo_url ? zubhub.header_logo_url : logo}
alt="logo"
/>
</Link>
<Box
className={clsx(
classes.languageSelectBoxStyle,
common_classes.displayInlineFlex,
common_classes.alignCenter,
common_classes.addOnSmallScreen,
)}
>
<TranslateIcon />
<Select
className={classes.languageSelectStyle}
value=""
onChange={e => handleChangeLanguage({ e, props })}
>
{Object.keys(languageMap).map((ln, index) => (
<MenuItem key={index} value={ln}>
{languageMap[ln]}
</MenuItem>
))}
</Select>
</Box>
<Box
className={clsx(
classes.languageSelectBoxStyle,
common_classes.displayInlineFlex,
common_classes.alignCenter,
common_classes.removeOnSmallScreen,
)}
>
<TranslateIcon />
<Select
className={classes.languageSelectStyle}
value={props.i18n.language}
onChange={e => handleChangeLanguage({ e, props })}
>
{Object.keys(languageMap).map((ln, index) => (
<MenuItem key={index} value={ln}>
{languageMap[ln]}
</MenuItem>
))}
</Select>
</Box>
<form
action="/search"
className={clsx(classes.searchFormStyle, classes.removeOn894)}
role="search"
onSubmit={handleSubmit}
ref={formRef}
>
<FormControl variant="outlined">
<InputLabel
htmlFor="q"
className={classes.searchFormLabelStyle}
>
{t('pageWrapper.inputs.search.label')}
</InputLabel>
<FormGroup row>
<FormControl variant="outlined">
<InputSelect
searchType={searchType}
onSearchTypeChange={setSearchType}
name="type"
>
<MenuItem value={SearchType.PROJECTS}>
Projects
</MenuItem>
<MenuItem value={SearchType.CREATORS}>
Creators
</MenuItem>
<MenuItem value={SearchType.TAGS}>Tags</MenuItem>
</InputSelect>
</FormControl>
<Autocomplete
options={options}
defaultValue={{
title:
props.location.search &&
getQueryParams(window.location.href).get('q'),
}}
renderOption={(option, { inputValue }) => (
<Option
option={option}
inputValue={inputValue}
onOptionClick={onSearchOptionClick}
/>
)}
onChange={onSearchOptionClick}
>
{params => (
<TextField
name="q"
id="q"
type="search"
variant="outlined"
{...params}
InputProps={{
...params.InputProps,
className: clsx(
classes.searchFormInputStyle,
'search-form-input',
),
endAdornment: (
<InputAdornment position="end">
<IconButton
type="submit"
className={classes.searchFormSubmitStyle}
aria-label={t(
'pageWrapper.inputs.search.label',
)}
>
<SearchIcon />
</IconButton>
</InputAdornment>
),
pattern: '(.|s)*S(.|s)*',
defaultValue: {
title:
props.location.search &&
getQueryParams(window.location.href).get('q'),
},
}}
onChange={e => setQuery(e.target.value)}
placeholder={`${t(
'pageWrapper.inputs.search.label',
)}...`}
/>
)}
</Autocomplete>
</FormGroup>
</FormControl>
</form>
</Box>
<div className={classes.navActionStyle}>
{!props.auth.token ? (
<>
<IconButton
className={clsx(
classes.toggleSearchFormStyle,
classes.addOn894,
)}
id="toggle-search"
aria-label="toggle search form"
onClick={() =>
handleSetState(handleToggleSearchForm(state))
}
>
<SearchIcon />
</IconButton>
<Link
className={clsx(
classes.textDecorationNone,
common_classes.removeOnSmallScreen,
)}
to="/login"
>
<CustomButton
variant="outlined"
size="large"
secondaryButtonStyle
customButtonStyle
>
{t('pageWrapper.navbar.login')}
</CustomButton>
</Link>
<Link
className={clsx(
classes.textDecorationNone,
common_classes.removeOnSmallScreen,
)}
to="/signup"
>
<CustomButton
variant="contained"
size="large"
primaryButtonStyle
customButtonStyle
className={common_classes.marginLeft1em}
>
{t('pageWrapper.navbar.signup')}
</CustomButton>
</Link>
<MenuRoundedIcon
className={common_classes.addOnSmallScreen}
aria-label={t('pageWrapper.navbar.menu')}
aria-controls="menu"
aria-haspopup="true"
onClick={e => handleSetState(handleProfileMenuOpen(e))}
/>
<Menu
className={common_classes.addOnSmallScreen}
disableScrollLock={true}
id="menu"
anchorEl={anchor_el}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={profileMenuOpen}
onClose={e => handleSetState(handleProfileMenuClose(e))}
>
<MenuItem>
<Link className={classes.textDecorationNone} to="/login">
<Typography
variant="subtitle2"
color="textPrimary"
component="span"
>
{t('pageWrapper.navbar.login')}
</Typography>
</Link>
</MenuItem>
<MenuItem>
<Link className={classes.textDecorationNone} to="/signup">
<Typography
variant="subtitle2"
color="textPrimary"
component="span"
>
{t('pageWrapper.navbar.signup')}
</Typography>
</Link>
</MenuItem>
</Menu>
</>
) : (
<>
<Link
className={clsx(
classes.textDecorationNone,
common_classes.marginRight1em,
common_classes.removeOnSmallScreen,
)}
to="/projects/create"
>
<CustomButton
variant="contained"
primaryButtonStyle
customButtonStyle
size="small"
>
{t('pageWrapper.navbar.createProject')}
</CustomButton>
</Link>
<IconButton
className={clsx(
classes.toggleSearchFormStyle,
classes.addOn894,
)}
id="toggle-search"
aria-label="toggle search form"
onClick={() =>
handleSetState(handleToggleSearchForm(state))
}
>
<SearchIcon />
</IconButton>
<NotificationButton
className={clsx(
common_classes.marginRight1em,
common_classes.removeOnSmallScreen,
)}
/>
<Avatar
className={clsx(
classes.avatarStyle,
common_classes.removeOnSmallScreen,
)}
aria-label={`${props.auth.username}' Avatar`}
aria-controls="profile_menu"
aria-haspopup="true"
onClick={e => handleSetState(handleProfileMenuOpen(e))}
src={props.auth.avatar}
alt={props.auth.username}
/>
<Menu
className={classes.profileMenuStyle}
disableScrollLock={true}
id="profile_menu"
anchorEl={anchor_el}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={profileMenuOpen}
onClose={e => handleSetState(handleProfileMenuClose(e))}
>
<MenuItem>
<Tooltip title={props.auth.username} placement="top">
<Typography
variant="subtitle2"
color="textPrimary"
component="span"
className={classes.profileStyle}
>
{props.auth.username }
</Typography>
</Tooltip>
</MenuItem>
<MenuItem>
<a className={classes.textDecorationNone} href="/profile">
<Typography
variant="subtitle2"
color="textPrimary"
component="span"
>
{t('pageWrapper.navbar.profile')}
</Typography>
</a>
</MenuItem>
<MenuItem className={common_classes.addOnSmallScreen}>
<Link
className={classes.textDecorationNone}
to="/projects/create"
>
<Typography
variant="subtitle2"
color="textPrimary"
component="span"
>
{t('pageWrapper.navbar.createProject')}
</Typography>
</Link>
</MenuItem>
<MenuItem>
<Link
className={classes.textDecorationNone}
to={`/creators/${props.auth.username}/projects`}
>
<Typography
variant="subtitle2"
color="textPrimary"
component="span"
>
{t('pageWrapper.navbar.projects')}
</Typography>
</Link>
</MenuItem>
<MenuItem>
<Link
className={classes.textDecorationNone}
to={`/creators/${props.auth.username}/followers`}
>
<Typography
variant="subtitle2"
color="textPrimary"
component="span"
>
{t('pageWrapper.navbar.followers')}
</Typography>
</Link>
</MenuItem>
<MenuItem>
<Link
className={classes.textDecorationNone}
to={`/creators/${props.auth.username}/following`}
>
<Typography
variant="subtitle2"
color="textPrimary"
component="span"
>
{t('pageWrapper.navbar.following')}
</Typography>
</Link>
</MenuItem>
<MenuItem>
<Link
className={classes.textDecorationNone}
to="/projects/saved"
>
<Typography
variant="subtitle2"
color="textPrimary"
component="span"
>
{t('pageWrapper.navbar.savedProjects')}
</Typography>
</Link>
</MenuItem>
<MenuItem className={classes.logOutStyle}>
<Typography
className={common_classes.colorRed}
variant="subtitle2"
component="span"
onClick={e => logout(e, props)}
>
{t('pageWrapper.navbar.logout')}
</Typography>
</MenuItem>
</Menu>
</>
)}
</div>
</Toolbar>
{open_search_form ? (
<ClickAwayListener
onClickAway={e => handleSetState(closeSearchFormOrIgnore(e))}
>
<form
action="/search"
className={clsx(classes.smallSearchFormStyle, classes.addOn894)}
role="search"
ref={formRef}
>
<FormControl variant="outlined" style={{ minWidth: 'unset' }}>
<InputSelect
searchType={searchType}
onSearchTypeChange={setSearchType}
name="type"
>
<MenuItem value={SearchType.PROJECTS}>Projects</MenuItem>
<MenuItem value={SearchType.CREATORS}>Creators</MenuItem>
<MenuItem value={SearchType.TAGS}>Tags</MenuItem>
</InputSelect>
</FormControl>
<FormControl
variant="outlined"
style={{ flex: '1 1 auto', maxWidth: '350px' }}
>
<InputLabel
htmlFor="q"
className={classes.searchFormLabelStyle}
>
{t('pageWrapper.inputs.search.label')}
</InputLabel>
<Autocomplete
options={options}
defaultValue={
props.location.search &&
getQueryParams(window.location.href).get('q')
}
renderOption={(option, { inputValue }) => (
<Option
option={option}
inputValue={inputValue}
onOptionClick={onSearchOptionClick}
/>
)}
onChange={onSearchOptionClick}
>
{params => (
<TextField
name="q"
id="q"
type="search"
variant="outlined"
{...params}
InputProps={{
...params.InputProps,
className: clsx(
classes.smallSearchFormInputStyle,
'search-form-input',
),
endAdornment: (
<InputAdornment position="end">
<IconButton
type="submit"
className={classes.searchFormSubmitStyle}
aria-label={t(
'pageWrapper.inputs.search.label',
)}
>
<SearchIcon />
</IconButton>
</InputAdornment>
),
pattern: '(.|s)*S(.|s)*',
}}
placeholder={`${t(
'pageWrapper.inputs.search.label',
)}...`}
onChange={e => setQuery(e.target.value)}
/>
)}
</Autocomplete>
</FormControl>
</form>
</ClickAwayListener>
) : null}
</Container>
</AppBar>
<Toolbar ref={backToTopEl} />
{loading ? <LoadingPage /> : props.children}
<footer className={clsx('footer-distributed', classes.footerStyle)}>
<Box>
<a href="https://unstructured.studio">
<img
src={
zubhub?.footer_logo_url
? zubhub.footer_logo_url
: unstructuredLogo
}
className={classes.footerLogoStyle}
alt="unstructured-studio-logo"
/>
</a>
<div>
<Box
className={clsx(
classes.languageSelectBoxStyle,
common_classes.displayInlineFlex,
common_classes.alignCenter,
common_classes.addOnSmallScreen,
)}
>
<TranslateIcon />
<Select
className={classes.languageSelectStyle}
value=""
onChange={e => handleChangeLanguage({ e, props })}
>
{Object.keys(languageMap).map((ln, index) => (
<MenuItem key={index} value={ln}>
{languageMap[ln]}
</MenuItem>
))}
</Select>
</Box>
<Box
className={clsx(
classes.languageSelectBoxStyle,
common_classes.displayInlineFlex,
common_classes.alignCenter,
common_classes.removeOnSmallScreen,
)}
>
<TranslateIcon />
<Select
className={classes.languageSelectStyle}
value={props.i18n.language}
onChange={e => handleChangeLanguage({ e, props })}
>
{Object.keys(languageMap).map((ln, index) => (
<MenuItem key={index} value={ln}>
{languageMap[ln]}
</MenuItem>
))}
</Select>
</Box>
</div>
</Box>
<section className={classes.footerSectionStyle}>
<Box className={classes.footerBoxStyle}>
<Typography
variant="subtitle2"
color="textPrimary"
className={classes.footerTitleStyle}
>
{t('pageWrapper.footer.privacy')}
</Typography>
<Link
to={`/privacy_policy`}
className={common_classes.textDecorationNone}
>
<Typography
variant="subtitle2"
color="textPrimary"
className={classes.footerLinkStyle}
>
{t('pageWrapper.footer.guidelines')}
</Typography>
</Link>
<Link
to={`/terms_of_use`}
className={common_classes.textDecorationNone}
>
<Typography
variant="subtitle2"
color="textPrimary"
className={classes.footerLinkStyle}
>
{t('pageWrapper.footer.termsOfUse')}
</Typography>
</Link>
</Box>
<Box className={classes.footerBoxStyle}>
<Typography
variant="subtitle2"
color="textPrimary"
className={classes.footerTitleStyle}
>
{t('pageWrapper.footer.about')}
</Typography>
<Link to="/about" className={common_classes.textDecorationNone}>
<Typography
variant="subtitle2"
color="textPrimary"
className={classes.footerLinkStyle}
>
{t('pageWrapper.footer.zubhub')}
</Typography>
</Link>
</Box>
<Box className={classes.footerBoxStyle}>
<Typography
variant="subtitle2"
color="textPrimary"
className={classes.footerTitleStyle}
>
{t('pageWrapper.footer.help')}
</Typography>
<a
target="__blank"
rel="noreferrer"
href={
hero.tinkering_resource_url
? hero.tinkering_resource_url
: 'https://kriti.unstructured.studio/'
}
className={common_classes.textDecorationNone}
>
<Typography
variant="subtitle2"
color="textPrimary"
className={classes.footerLinkStyle}
>
{t('pageWrapper.footer.resources')}
</Typography>
</a>
<Link
to={`/faqs`}
className={clsx(
common_classes.textDecorationNone,
common_classes.displayNone,
)}
>
<Typography
variant="subtitle2"
color="textPrimary"
className={classes.footerLinkStyle}
>
{t('pageWrapper.footer.faqs')}
</Typography>
</Link>
<a
href="mailto:[email protected]"
className={common_classes.textDecorationNone}
>
<Typography
variant="subtitle2"
color="textPrimary"
className={classes.footerLinkStyle}
>
{t('pageWrapper.footer.contactUs')}
</Typography>
</a>
</Box>
</section>
<Zoom in={useScrollTrigger}>
<div
onClick={e => handleScrollTopClick(e, backToTopEl)}
role="presentation"
className={classes.scrollTopButtonStyle}
>
<Fab color="secondary" size="small" aria-label="scroll back to top">
<KeyboardArrowUpIcon />
</Fab>
</div>
</Zoom>
</footer>
</>
);
}
Example #25
Source File: profile-page.js From horondi_client_fe with MIT License | 4 votes |
ProfilePage = () => {
const [userImageUrl, setUserImageUrl] = useState(null);
const [upload, setUpload] = useState(null);
const [deleteAvatar, setDeleteAvatar] = useState(false);
const [shouldValidate, setShouldValidate] = useState(false);
const { t, i18n } = useTranslation();
const language = i18n.language === 'ua' ? 0 : 1;
const classes = useStyles();
const appStyles = useAppStyles();
const dispatch = useDispatch();
const {
userData,
userLoading,
confirmationEmailSent,
userRecovered,
confirmationLoading,
recoveryLoading
} = useSelector(({ User }) => ({
userData: User.userData,
userLoading: User.userLoading,
confirmationEmailSent: User.confirmationEmailSent,
userRecovered: User.userRecovered,
confirmationLoading: User.confirmationLoading,
recoveryLoading: User.recoveryLoading
}));
const handleSaveUser = ({ firstName, lastName, email, phoneNumber, ...address }) => {
if (phoneNumber === null) {
phoneNumber = '';
}
const user = { firstName, lastName, email, phoneNumber, address };
Object.keys(address).forEach((key) => {
if (address[key] === null) {
address[key] = '';
}
});
dispatch(updateUser({ user, id: userData._id, upload, deleteAvatar }));
setShouldValidate(false);
};
const { errors, values, touched, handleBlur, resetForm, handleSubmit, handleChange } = useFormik({
initialValues,
onSubmit: handleSaveUser,
validationSchema,
validateOnChange: shouldValidate,
validateOnBlur: shouldValidate
});
const handleConfirmation = () => {
dispatch(sendConfirmationEmail({ email: userData.email, language }));
};
const handlePasswordChange = () => {
dispatch(recoverUser({ email: userData.email, language }));
};
useEffect(() => {
if (userData) {
const { firstName, lastName, email, phoneNumber, address } = userData;
resetForm({
values: {
firstName,
lastName,
email,
phoneNumber,
...address
}
});
}
if (userData.images && userData.images.thumbnail) {
setUserImageUrl(IMG_URL + userData.images.thumbnail);
}
}, [userData, resetForm]);
const getTextFields = (textFields) =>
Object.keys(textFields).map((name) => (
<TextField
key={name}
type='text'
name={name}
variant={TEXT_FIELD_VARIANT.OUTLINED}
value={values[name]?.startsWith('+380') ? values[name].slice(4) : values[name]}
InputProps={
name === 'phoneNumber'
? {
maxLength: 9,
startAdornment: <InputAdornment position='start'>+380</InputAdornment>
}
: {}
}
label={t(`profilePage.labels.${name}`)}
fullWidth
color={MATERIAL_UI_COLOR.PRIMARY}
onChange={handleChange}
error={touched[name] && !!errors[name]}
helperText={t(errors[name])}
className={handleClassName(classes.dataInput, classes.nameInputs, name)}
/>
));
const emailSent = (titleText) => (
<div className={classes.emailSent} data-testid='emailSent'>
<OpenedLetterIcon className={classes.openedLetterIcon} />
<h3 className={classes.formTitle}>{titleText}</h3>
<p>{t('profilePage.checkEmailText')}</p>
</div>
);
const passwordChange = () =>
userRecovered ? (
emailSent(t('profilePage.passwordChange.heading'))
) : (
<>
<h3 className={classes.formTitle}>{t('profilePage.passwordChange.heading')}</h3>
<span className={classes.userActionsText}>{t('profilePage.passwordChange.text')}</span>
<Button
className={`${classes.button} ${classes.userActionsButton}`}
onClick={handlePasswordChange}
data-testid='passwordChangeBtn'
>
{t('profilePage.passwordChange.btnTitle')}
</Button>
</>
);
const confirmEmail = () =>
confirmationEmailSent ? (
emailSent(t('profilePage.emailConfirm.heading'))
) : (
<>
<h3 className={classes.formTitle}>{t('profilePage.emailConfirm.heading')}</h3>
<TextField
data-cy='confirmEmail'
id='confirmEmail'
label={t('profilePage.labels.confirmEmail')}
className={classes.userActionsInput}
fullWidth
variant={TEXT_FIELD_VARIANT.OUTLINED}
color={MATERIAL_UI_COLOR.PRIMARY}
value={values.email}
name='confirmEmail'
onChange={handleChange}
onBlur={handleBlur}
error={Boolean(touched.confirmEmail && t(errors.confirmEmail))}
helperText={touched.confirmEmail && t(errors.confirmEmail)}
/>
<span className={classes.userActionsText}>
{!confirmationEmailSent && t('profilePage.emailConfirm.text')}
</span>
<Button
className={`${classes.button} ${classes.userActionsButton}`}
onClick={handleConfirmation}
data-testid='emailConfirmBtn'
>
{t('profilePage.emailConfirm.btnTitle')}
</Button>
</>
);
return (
<div className={appStyles.rootApp}>
<div className={appStyles.containerApp}>
<div className={classes.profileTitleInfo}>
<h2 className={classes.profileTitle}>{t('profilePage.titles.mainTitle')}</h2>
<div className={classes.titleLine} />
</div>
<div className={classes.profile}>
<div>
{userLoading ? (
<div className={classes.userForm}>
<Loader gridColumn='span 3' />
</div>
) : (
<div className={classes.userFormControl}>
<form onSubmit={handleSubmit} className={classes.userForm} data-testid='userForm'>
<Avatar
userImageUrl={userImageUrl}
setUserImageUrl={setUserImageUrl}
setUpload={setUpload}
setDeleteAvatar={setDeleteAvatar}
t={t}
/>
<h3 className={classes.formTitle}>{t('profilePage.titles.contactTitle')}</h3>
{getTextFields(PROFILE_USER_CONTACT_DATA)}
<h3 className={classes.formTitle}>{t('profilePage.titles.addressTitle')}</h3>
{getTextFields(PROFILE_USER_ADDRESS_DATA)}
<Button
fullWidth
className={`${classes.button} ${classes.saveBtn}`}
type='submit'
onClick={() => setShouldValidate(true)}
data-testid='submitBtn'
>
{t('profilePage.labels.saveBtnTitle')}
</Button>
</form>
</div>
)}
</div>
<div className={classes.userActions}>
<div className={classes.newPassword}>
{recoveryLoading ? <Loader /> : passwordChange()}
</div>
{!userData.confirmed && (
<div className={classes.confirmUser}>
{confirmationLoading ? <Loader /> : confirmEmail()}
</div>
)}
</div>
</div>
</div>
</div>
);
}
Example #26
Source File: signUp.js From eSim-Cloud with GNU General Public License v3.0 | 4 votes |
export default function SignUp () {
const classes = useStyles()
const auth = useSelector(state => state.authReducer)
const dispatch = useDispatch()
var homeURL = `${window.location.protocol}\\\\${window.location.host}/`
useEffect(() => {
dispatch(authDefault())
document.title = 'Sign Up - eSim '
}, [dispatch])
const history = useHistory()
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [email, setEmail] = useState('')
const [accept, setAccept] = useState(true)
const [showPassword, setShowPassword] = useState(false)
const handleClickShowPassword = () => setShowPassword(!showPassword)
const handleMouseDownPassword = () => setShowPassword(!showPassword)
// Function call for google oAuth sign up.
const handleGoogleSignup = () => {
var host = window.location.protocol + '//' + window.location.host
dispatch(googleLogin(host))
}
const handleSignup = (event) => {
event.preventDefault()
dispatch(signUp(email, username, password, history))
}
return (
<Container component="main" maxWidth="xs">
<Card className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Register | Sign Up
</Typography>
{/* Display's error messages while signing in */}
<Typography variant="body1" align="center" style={{ marginTop: '10px' }} color={auth.isRegistered ? 'secondary' : 'error'}>
{auth.regErrors}
{ auth.isRegistered &&
<>
<br />
<Link component={RouterLink} to="/login">
{'Back to Login'}
</Link>
</>
}
</Typography>
<form className={classes.form} onSubmit={handleSignup} noValidate>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="username"
label="Username"
name="username"
autoComplete="email"
value={username}
onChange={e => setUsername(e.target.value)}
autoFocus
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="email"
name="email"
type="email"
autoComplete="email"
value={email}
onChange={e => setEmail(e.target.value)}
autoFocus
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
size="small"
aria-label="toggle password visibility"
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
>
{showPassword ? <Visibility fontSize="small" /> : <VisibilityOff fontSize="small" />} {/* handle password visibility */}
</IconButton>
</InputAdornment>
)
}}
type={showPassword ? 'text' : 'password'}
id="password"
value={password}
onChange={e => setPassword(e.target.value)}
autoComplete="current-password"
/>
<FormControlLabel
control={<Checkbox checked={accept} onChange={e => setAccept(e.target.checked)} color="primary" />}
label="I accept the Terms of Use & Privacy Policy"
/>
<Button
fullWidth
variant="contained"
color="primary"
type="submit"
className={classes.submit}
disabled={!accept}
>
Sign Up
</Button>
<Typography variant="body2" color="secondary" align="center" >Or</Typography>
{/* Google oAuth Sign Up option */}
<Button
fullWidth
variant="outlined"
color="primary"
onClick={handleGoogleSignup}
className={classes.submit}
>
<img alt="G" src={google} height="20" />  Sign Up With Google
</Button>
</form>
<Grid container>
<Grid item style={{ margin: 'auto' }} >
<Link component={RouterLink} to="/login" variant="body2">
{'Already have account? Login'}
</Link>
</Grid>
</Grid>
</Card>
<Button
fullWidth
onClick={() => { window.open(homeURL, '_self') }}
color="default"
className={classes.submit}
>
Back to home
</Button>
</Container>
)
}
Example #27
Source File: SearchPage.js From Octave with MIT License | 4 votes |
// Search Page
function Search() {
const [input, setInput] = useState("");
const [infoText, setInfoText] = useState("");
const [songs, setSongs] = useState(null);
const [artists, setArtists] = useState(null);
useEffect(() => {
setInfoText("");
}, [input]);
const handleSearch = async (event) => {
event.preventDefault();
if (!input) return;
let searchText = capitalize(input);
await searchSong(searchText).then((snapshot) => {
setSongs(
snapshot.docs.map((doc) => ({
id: doc.id,
data: doc.data(),
}))
);
});
searchText = capitalizeAllWords(input);
await searchArtist(searchText).then((snapshot) => {
setArtists(
snapshot.docs.map((doc) => ({
id: doc.id,
data: doc.data(),
}))
);
});
setInfoText(`Search Result for ${input}`);
};
return (
<div className="search">
<div className="search__bar">
<form className="search__barForm" onSubmit={handleSearch}>
<TextField
onChange={(e) => setInput(e.target.value)}
value={input}
variant="filled"
label="Search for Songs or Artists"
fullWidth
margin="dense"
size="medium"
color="secondary"
InputProps={{
endAdornment: (
<InputAdornment>
<IconButton
className="search__barSearchIcon"
onClick={handleSearch}
>
<SearchIcon />
</IconButton>
</InputAdornment>
),
}}
/>
</form>
</div>
{/* Results Info Text ------------------------*/}
<Typography variant="h6" align="center">
{infoText}
</Typography>
<Typography variant="subtitle1" align="center">
{songs?.length === 0 &&
artists?.length === 0 &&
infoText &&
`No Results`}
</Typography>
{/* Songs Results ------------------------*/}
<Typography variant="h6">{songs?.length > 0 && `Songs`}</Typography>
<div className="search__grid">
{songs?.length > 0 &&
songs.map((song) => (
<PlayListSong key={song.id} data={song.data} fromSearchPage />
))}
</div>
<br />
{/* Artists Results----------------------------------- */}
<Typography variant="h6">{artists?.length > 0 && `Artists`}</Typography>
<div className="search__results">
{artists?.length > 0 &&
artists.map((artist) => (
<Artist key={artist.id} id={artist.id} data={artist.data} />
))}
</div>
</div>
);
}
Example #28
Source File: App.js From fruitionsite with MIT License | 4 votes |
export default function App() {
const [slugs, setSlugs] = useState([]);
const [myDomain, setMyDomain] = useState("");
const [notionUrl, setNotionUrl] = useState("");
const [pageTitle, setPageTitle] = useState("");
const [pageDescription, setPageDescription] = useState("");
const [googleFont, setGoogleFont] = useState("");
const [customScript, setCustomScript] = useState("");
const [optional, setOptional] = useState(false);
const [copied, setCopied] = useState(false);
const handleMyDomain = e => {
setMyDomain(e.target.value);
setCopied(false);
};
const handleNotionUrl = e => {
setNotionUrl(e.target.value);
setCopied(false);
};
const handlePageTitle = e => {
setPageTitle(e.target.value);
setCopied(false);
};
const handlePageDescription = e => {
setPageDescription(e.target.value);
setCopied(false);
};
const handleGoogleFont = e => {
setGoogleFont(e.target.value);
setCopied(false);
};
const handleCustomScript = e => {
setCustomScript(e.target.value);
setCopied(false);
};
const addSlug = () => {
setSlugs([...slugs, ["", ""]]);
setCopied(false);
};
const deleteSlug = index => {
setSlugs([...slugs.slice(0, index), ...slugs.slice(index + 1)]);
setCopied(false);
};
const handleCustomURL = (value, index) => {
setSlugs([
...slugs.slice(0, index),
[value, slugs[index][1]],
...slugs.slice(index + 1)
]);
setCopied(false);
};
const handleNotionPageURL = (value, index) => {
setSlugs([
...slugs.slice(0, index),
[slugs[index][0], value],
...slugs.slice(index + 1)
]);
setCopied(false);
};
const handleOptional = () => {
setOptional(!optional);
};
const domain = myDomain || DEFAULT_DOMAIN;
const url = notionUrl || DEFAULT_NOTION_URL;
const myDomainHelperText = !validDomain(domain)
? "Please enter a valid domain"
: undefined;
const notionUrlHelperText = !validNotionUrl(notionUrl)
? "Please enter a valid Notion Page URL"
: undefined;
const noError = !myDomainHelperText && !notionUrlHelperText;
const script = noError
? code({
myDomain: domain,
notionUrl: url,
slugs,
pageTitle,
pageDescription,
googleFont,
customScript
})
: undefined;
const textarea = useRef("");
const copy = () => {
if (!noError) return;
textarea.current.select();
document.execCommand("copy");
setCopied(true);
};
return (
<section style={{ maxWidth: 666 }}>
<TextField
fullWidth
helperText={myDomainHelperText}
label="Your Domain (e.g. example.org)"
onChange={handleMyDomain}
margin="normal"
placeholder={DEFAULT_DOMAIN}
value={myDomain}
variant="outlined"
/>
<TextField
fullWidth
helperText={notionUrlHelperText}
label={`Notion URL for ${domain}`}
margin="normal"
onChange={handleNotionUrl}
placeholder={DEFAULT_NOTION_URL}
value={notionUrl}
variant="outlined"
/>
{slugs.map(([customUrl, notionPageUrl], index) => {
return (
<section>
<TextField
fullWidth
InputProps={{
startAdornment: (
<InputAdornment position="start">{`${domain}/`}</InputAdornment>
)
}}
key="key"
label="Pretty Link"
margin="normal"
placeholder="about"
onChange={e => handleCustomURL(e.target.value, index)}
value={customUrl}
variant="outlined"
/>
<TextField
fullWidth
label={`Notion URL for ${domain}/${customUrl || "about"}`}
key="value"
margin="normal"
placeholder={DEFAULT_NOTION_URL}
onChange={e => handleNotionPageURL(e.target.value, index)}
value={notionPageUrl}
variant="outlined"
/>
<Button
onClick={() => deleteSlug(index)}
variant="outlined"
color="secondary"
size="small"
>
Delete this pretty link
</Button>
</section>
);
})}
<section>
<Button
onClick={addSlug}
size="small"
variant="outlined"
color="primary"
>
Add a pretty link
</Button>
</section>
<section>
<Button
onClick={handleOptional}
size="small"
variant="outlined"
color="primary"
>
Toggle Style And Script Settings
</Button>
</section>
<Collapse in={optional} timeout="auto" unmountOnExit>
<TextField
fullWidth
label="Page Title"
margin="normal"
onChange={handlePageTitle}
value={pageTitle}
variant="outlined"
/>
<TextField
fullWidth
label="Page Description"
margin="normal"
onChange={handlePageDescription}
value={pageDescription}
variant="outlined"
/>
<TextField
fullWidth
label="Custom Google Font"
margin="normal"
placeholder="Open Sans"
onChange={handleGoogleFont}
value={googleFont}
variant="outlined"
/>
<TextField
fullWidth
label="Paste Your Custom Script"
margin="normal"
multiline
placeholder="e.g. Google Analytics"
onChange={handleCustomScript}
rows={2}
value={customScript}
variant="outlined"
/>
</Collapse>
<section>
<Button
disabled={!noError}
variant="contained"
color="primary"
disableElevation
onClick={copy}
>
{copied ? "Copied!" : "Copy the code"}
</Button>
</section>
{noError ? (
<>
<TextField
fullWidth
margin="normal"
rowsMax={5}
multiline
inputRef={textarea}
value={script}
variant="outlined"
/>
</>
) : (
""
)}
</section>
);
}
Example #29
Source File: index.js From whaticket with MIT License | 4 votes |
QueueModal = ({ open, onClose, queueId }) => {
const classes = useStyles();
const initialState = {
name: "",
color: "",
greetingMessage: "",
};
const [colorPickerModalOpen, setColorPickerModalOpen] = useState(false);
const [queue, setQueue] = useState(initialState);
const greetingRef = useRef();
useEffect(() => {
(async () => {
if (!queueId) return;
try {
const { data } = await api.get(`/queue/${queueId}`);
setQueue(prevState => {
return { ...prevState, ...data };
});
} catch (err) {
toastError(err);
}
})();
return () => {
setQueue({
name: "",
color: "",
greetingMessage: "",
});
};
}, [queueId, open]);
const handleClose = () => {
onClose();
setQueue(initialState);
};
const handleSaveQueue = async values => {
try {
if (queueId) {
await api.put(`/queue/${queueId}`, values);
} else {
await api.post("/queue", values);
}
toast.success("Queue saved successfully");
handleClose();
} catch (err) {
toastError(err);
}
};
return (
<div className={classes.root}>
<Dialog open={open} onClose={handleClose} scroll="paper">
<DialogTitle>
{queueId
? `${i18n.t("queueModal.title.edit")}`
: `${i18n.t("queueModal.title.add")}`}
</DialogTitle>
<Formik
initialValues={queue}
enableReinitialize={true}
validationSchema={QueueSchema}
onSubmit={(values, actions) => {
setTimeout(() => {
handleSaveQueue(values);
actions.setSubmitting(false);
}, 400);
}}
>
{({ touched, errors, isSubmitting, values }) => (
<Form>
<DialogContent dividers>
<Field
as={TextField}
label={i18n.t("queueModal.form.name")}
autoFocus
name="name"
error={touched.name && Boolean(errors.name)}
helperText={touched.name && errors.name}
variant="outlined"
margin="dense"
className={classes.textField}
/>
<Field
as={TextField}
label={i18n.t("queueModal.form.color")}
name="color"
id="color"
onFocus={() => {
setColorPickerModalOpen(true);
greetingRef.current.focus();
}}
error={touched.color && Boolean(errors.color)}
helperText={touched.color && errors.color}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<div
style={{ backgroundColor: values.color }}
className={classes.colorAdorment}
></div>
</InputAdornment>
),
endAdornment: (
<IconButton
size="small"
color="default"
onClick={() => setColorPickerModalOpen(true)}
>
<Colorize />
</IconButton>
),
}}
variant="outlined"
margin="dense"
/>
<ColorPicker
open={colorPickerModalOpen}
handleClose={() => setColorPickerModalOpen(false)}
onChange={color => {
values.color = color;
setQueue(() => {
return { ...values, color };
});
}}
/>
<div>
<Field
as={TextField}
label={i18n.t("queueModal.form.greetingMessage")}
type="greetingMessage"
multiline
inputRef={greetingRef}
rows={5}
fullWidth
name="greetingMessage"
error={
touched.greetingMessage && Boolean(errors.greetingMessage)
}
helperText={
touched.greetingMessage && errors.greetingMessage
}
variant="outlined"
margin="dense"
/>
</div>
</DialogContent>
<DialogActions>
<Button
onClick={handleClose}
color="secondary"
disabled={isSubmitting}
variant="outlined"
>
{i18n.t("queueModal.buttons.cancel")}
</Button>
<Button
type="submit"
color="primary"
disabled={isSubmitting}
variant="contained"
className={classes.btnWrapper}
>
{queueId
? `${i18n.t("queueModal.buttons.okEdit")}`
: `${i18n.t("queueModal.buttons.okAdd")}`}
{isSubmitting && (
<CircularProgress
size={24}
className={classes.buttonProgress}
/>
)}
</Button>
</DialogActions>
</Form>
)}
</Formik>
</Dialog>
</div>
);
}