@mui/material#Paper JavaScript Examples
The following examples show how to use
@mui/material#Paper.
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: SearchNotFound.js From Django-REST-Framework-React-BoilerPlate with MIT License | 6 votes |
export default function SearchNotFound({ searchQuery = '', ...other }) {
return (
<Paper {...other}>
<Typography gutterBottom align="center" variant="subtitle1">
Not found
</Typography>
<Typography variant="body2" align="center">
No results found for
<strong>"{searchQuery}"</strong>. Try checking for typos or using complete words.
</Typography>
</Paper>
);
}
Example #2
Source File: ActionPaper.js From react-saas-template with MIT License | 6 votes |
function ActionPaper(props) {
const {
theme,
classes,
title,
content,
maxWidth,
actions,
helpPadding,
fullWidthActions
} = props;
return (
<Box pt={1}>
<Paper style={{ maxWidth: theme.breakpoints.values[maxWidth] }}>
{title && <DialogTitle>{title}</DialogTitle>}
{content && (
<DialogContent
classes={helpPadding ? { root: classes.helpPadding } : null}
>
{content}
</DialogContent>
)}
{actions && (
<Box pb={2} pr={2}>
<DialogActions
classes={{ action: fullWidthActions ? classes.fullWidth : null }}
>
{actions}
</DialogActions>
</Box>
)}
</Paper>
</Box>
);
}
Example #3
Source File: index.js From fireact with MIT License | 6 votes |
DataTable = ({columns, rows, totalRows, pageSize, page, handlePageChane, handlePageSizeChange}) => {
return (
<>
<TableContainer component={Paper}>
<Table aria-label="simple table">
<TableHead>
<TableRow>
{columns.map((c,i) =>
<TableCell key={i} style={c.style}>{c.name}</TableCell>
)}
</TableRow>
</TableHead>
<TableBody>
{rows.map((r, i) =>
<TableRow key={i}>
{columns.map((c, k) =>
<TableCell key={k}>{r[c.field]}</TableCell>
)}
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[10,20,50,100]}
component="div"
count={totalRows}
rowsPerPage={pageSize}
page={page}
onPageChange={handlePageChane}
onRowsPerPageChange={handlePageSizeChange}
/>
</>
)
}
Example #4
Source File: Subscription.js From react-saas-template with MIT License | 6 votes |
function Subscription(props) {
const {
transactions,
classes,
openAddBalanceDialog,
selectSubscription
} = props;
useEffect(selectSubscription, [selectSubscription]);
return (
<Paper>
<List disablePadding>
<SubscriptionInfo openAddBalanceDialog={openAddBalanceDialog} />
<Divider className={classes.divider} />
<SubscriptionTable transactions={transactions} />
</List>
</Paper>
);
}
Example #5
Source File: LoadChart.js From admin-web with GNU Affero General Public License v3.0 | 6 votes |
function LoadChart(props) {
const { classes, t, load } = props;
return (
<Paper className={classes.paper}>
<div className={classes.root}>
<Typography className={classes.chartTitle}>{t("Load")}</Typography>
<ResponsiveContainer width="100%" height={200} >
<BarChart data={load} margin={{ top: 0, right: 32, left: 10, bottom: 16 }}>
<defs>
<linearGradient id="gradientBlue2" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={"#2980B9"} />
<stop offset="95%" stopColor={"#6DD5FA"} />
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="time" />
<YAxis />
<Legend />
<Tooltip labelStyle={{ color: 'black', fontSize: 18, paddingBottom: 4 }}/>
<Bar
dataKey="value"
fill="url(#gradientBlue)"/>
</BarChart>
</ResponsiveContainer>
</div>
</Paper>
);
}
Example #6
Source File: AccountInformationArea.js From react-saas-template with MIT License | 6 votes |
function AccountInformationArea(props) {
const { classes, toggleAccountActivation, isAccountActivated } = props;
return (
<Paper className={classes.paper}>
<Toolbar className={classes.toolbar}>
<Box display="flex" alignItems="center">
<Box mr={2}>
<ListItemText
primary="Status"
secondary={isAccountActivated ? "Activated" : "Not activated"}
className="mr-2"
/>
</Box>
<ListItemIcon>
<LoopIcon
className={classNames(
isAccountActivated ? classes.spin : null,
classes.scaleMinus
)}
/>
</ListItemIcon>
</Box>
<ListItemSecondaryAction className={classes.listItemSecondaryAction}>
<Switch
color="secondary"
checked={isAccountActivated}
onClick={toggleAccountActivation}
inputProps={{
"aria-label": isAccountActivated
? "Deactivate Account"
: "Activate Account"
}}
/>
</ListItemSecondaryAction>
</Toolbar>
</Paper>
);
}
Example #7
Source File: MailQ.js From admin-web with GNU Affero General Public License v3.0 | 6 votes |
render() {
const { classes, t } = this.props;
const { snackbar, postfixMailq, gromoxMailq } = this.state;
return (
<TableViewContainer
headline={t("Mail queue")}
subtitle={t("mailq_sub")}
href="https://docs.grommunio.com/admin/administration.html#id2"
snackbar={snackbar}
onSnackbarClose={() => this.setState({ snackbar: '' })}
>
<div className={classes.logViewer}>
<Paper elevation={1} className={classes.paper}>
<Typography variant="h6" className={classes.header}>Postfix {t("mail queue")}</Typography>
<pre
className={classes.log}
>
{postfixMailq}
</pre>
</Paper>
<Paper elevation={1} className={classes.paper}>
<Typography variant="h6" className={classes.header}>Gromox {t("mail queue")}</Typography>
<pre
className={classes.log}
>
{gromoxMailq}
</pre>
</Paper>
</div>
</TableViewContainer>
);
}
Example #8
Source File: virtualized.js From react-table-library with MIT License | 5 votes |
Component = () => {
const data = { nodes: manyNodes };
const materialTheme = getTheme(DEFAULT_OPTIONS, { isVirtualized: true });
const theme = useTheme(materialTheme);
const COLUMNS = [
{ label: 'Task', renderCell: (item) => item.name },
{
label: 'Deadline',
renderCell: (item) =>
item.deadline.toLocaleDateString('en-US', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
}),
},
{ label: 'Type', renderCell: (item) => item.type },
{
label: 'Complete',
renderCell: (item) => item.isComplete.toString(),
},
{ label: 'Tasks', renderCell: (item) => item.nodes?.length },
];
const VIRTUALIZED_OPTIONS = {
rowHeight: (_item, _index) => 54,
};
return (
<>
<Paper variant="outlined" square style={{ height: '300px' }}>
<CompactTable
columns={COLUMNS}
virtualizedOptions={VIRTUALIZED_OPTIONS}
data={data}
theme={theme}
layout={{ fixedHeader: true }}
/>
</Paper>
<br />
<DocumentationSee anchor={'Features/' + key} />
</>
);
}
Example #9
Source File: CustomizedSlider.jsx From matx-react with MIT License | 5 votes |
PaperRoot = styled(Paper)(({ theme }) => ({
width: 300 + 24 * 2,
padding: 24,
"& .margin": {
height: theme.spacing(3),
},
}))
Example #10
Source File: index.js From fireact with MIT License | 5 votes |
DataCreate = ({schema, validation, handleCreation, success, children}) => {
const mountedRef = useRef(true);
const [inSubmit, setInSubmit] = useState(false);
const [result, setResult] = useState({
response: null,
error: null
});
useEffect(() => {
return () => {
mountedRef.current = false
}
},[]);
return (
<form onSubmit={e => {
e.preventDefault();
setInSubmit(true);
if(validation()){
let data = {};
schema.forEach(field => {
data[field.name] = e.target.elements[field.name][field.prop]
});
handleCreation(data).then(res => {
if (!mountedRef.current) return null
setResult({
response: true,
error: null
});
setInSubmit(false);
}).catch(err => {
if (!mountedRef.current) return null
setResult({
response: false,
error: err
});
setInSubmit(false);
})
}else{
setResult({
response: false,
error: 'Please fill in the form in the correct format.'
})
setInSubmit(false);
}
}}>
<Paper>
<Box p={2}>
<Stack spacing={3}>
{result.response?(
<>{success}</>
):(
<>
{result.response === false &&
<Alert severity="error">{result.error}</Alert>
}
{children}
<Stack direction="row" spacing={1} mt={2}>
<Button variant="contained" type="submit" disabled={inSubmit}>{inSubmit && <Loader />} Create</Button>
</Stack>
</>
)}
</Stack>
</Box>
</Paper>
</form>
)
}
Example #11
Source File: About.js From admin-web with GNU Affero General Public License v3.0 | 5 votes |
render() {
const { classes, about } = this.props;
const { API, backend, schema } = about;
return (
<div className={classes.root}>
<div className={classes.flexItem}>
<Paper className={classes.paper}>
<Dashboard className={classes.icon}/>
<div className={classes.labeledData}>
<Typography className={classes.data}>{process.env.REACT_APP_BUILD_VERSION}</Typography>
<Typography className={classes.label}>Web UI</Typography>
</div>
</Paper>
</div>
<div className={classes.flexItem}>
<Paper className={classes.paper}>
<Power className={classes.icon}/>
<div className={classes.labeledData}>
<Typography className={classes.data}>{API}</Typography>
<Typography className={classes.label}>API</Typography>
</div>
</Paper>
</div>
<div className={classes.flexItem}>
<Paper className={classes.paper}>
<Outlet className={classes.icon}/>
<div className={classes.labeledData}>
<Typography className={classes.data}>{backend}</Typography>
<Typography className={classes.label}>Backend</Typography>
</div>
</Paper>
</div>
<div className={classes.flexItem}>
<Paper className={classes.paper}>
<StorageIcon className={classes.icon}/>
<div className={classes.labeledData}>
<Typography className={classes.data}>{this.formatBytes(schema)}</Typography>
<Typography className={classes.label}>Database</Typography>
</div>
</Paper>
</div>
</div>
);
}
Example #12
Source File: index.js From fireact with MIT License | 5 votes |
UserPageLayout = (props) => {
const {
title,
children
} = props
const { setBreadcrumb } = useContext(BreadcrumbContext);
useEffect(() => {
setBreadcrumb([
{
to: "/",
text: "Home",
active: false
},
{
to: "/user/profile",
text: "User",
active: false
},
{
to: null,
text: title,
active: true
}
]);
},[setBreadcrumb, title]);
return (
<Container>
<Paper>
<Box p={2}>
{children}
</Box>
</Paper>
</Container>
)
}
Example #13
Source File: RoleDetails.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, Users, Permissions, Domains, Orgs } = this.props;
const { snackbar, role, autocompleteInput } = this.state;
const { name, description, users, permissions } = role;
const domains = [{ ID: '*', domainname: 'All'}].concat(Domains);
const orgs = [{ ID: '*', name: 'All'}].concat(Orgs);
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
return (
<ViewWrapper
topbarTitle={t('Role')}
snackbar={snackbar}
onSnackbarClose={() => this.setState({ snackbar: '' })}
>
<Paper className={classes.paper} elevation={1}>
<Grid container>
<Typography
color="primary"
variant="h5"
>
{t('editHeadline', { item: 'Role' })}
</Typography>
</Grid>
<FormControl className={classes.form}>
<TextField
className={classes.input}
label={t("Name")}
fullWidth
autoFocus
value={name || ''}
onChange={this.handleRoleInput('name')}
/>
<TextField
className={classes.input}
label={t("Description")}
fullWidth
multiline
variant="outlined"
rows={4}
value={description || ''}
onChange={this.handleRoleInput('description')}
/>
<MagnitudeAutocomplete
multiple
inputValue={autocompleteInput}
value={users || []}
filterAttribute={'username'}
onChange={this.handleAutocomplete('users')}
onInputChange={this.handleACInput}
className={classes.input}
options={Users || []}
label={t('Users')}
placeholder={t("Search users") + "..."}
/>
{(permissions || []).map((permission, idx) =>
<div key={idx} className={classes.row}>
<TextField
select
label={t("Permission")}
value={permission.permission || ''}
onChange={this.handleSelectPermission(idx)}
fullWidth
variant="standard"
>
{Permissions.map((name) => (
<MenuItem key={name} value={name}>
{name}
</MenuItem>
))}
</TextField>
{permission.permission.includes('DomainAdmin') /*Read and Write*/ && <MagnitudeAutocomplete
value={permission.params}
getOptionLabel={(domainID) => domainID.domainname ||
(domains || []).find(d => d.ID === domainID)?.domainname || ''}
filterAttribute={'domainname'}
onChange={this.handleSetParams(idx, "domainname")}
inputValue={permission.autocompleteInput}
onInputChange={this.handleAutocompleteInput(idx)}
className={classes.rowTextfield}
options={domains || []}
label={t('Params')}
placeholder={t("Search domains") + "..."}
variant="standard"
fullWidth
autoSelect
/>}
{permission.permission === ORG_ADMIN && <MagnitudeAutocomplete
value={permission.params}
getOptionLabel={(orgID) => orgID.name ||
(orgs || []).find(o => o.ID === orgID)?.name || ''} // Because only ID is received
filterAttribute={'name'}
onChange={this.handleSetParams(idx, "name")}
inputValue={permission.autocompleteInput}
onInputChange={this.handleAutocompleteInput(idx)}
className={classes.rowTextfield}
options={orgs || []}
label={t('Params')}
placeholder={t("Search organizations") + "..."}
variant="standard"
fullWidth
autoSelect
/>}
<IconButton size="small" onClick={this.removeRow(idx)}>
<Delete fontSize="small" color="error" />
</IconButton>
</div>
)}
<Grid container justifyContent="center" className={classes.addButton}>
<Button size="small" onClick={this.handleNewRow}>
<Add color="primary" />
</Button>
</Grid>
</FormControl>
<Button
color="secondary"
onClick={() => this.props.history.push('/roles')}
style={{ marginRight: 8 }}
>
{t('Back')}
</Button>
<Button
variant="contained"
color="primary"
onClick={this.handleEdit}
disabled={!writable}
>
{t('Save')}
</Button>
</Paper>
</ViewWrapper>
);
}
Example #14
Source File: index.js From fireact with MIT License | 4 votes |
NewAccount = () => {
const title = 'Create New Account';
const mountedRef = useRef(true);
const [accountName, setAccountName] = useState({
hasError: false,
error: null,
value: null
});
const [errorMessage, setErrorMessage] = useState(null);
const [inSubmit, setInSubmit] = useState(false);
const [redirect, setRedirect] = useState(null);
const { setBreadcrumb } = useContext(BreadcrumbContext);
useEffect(() => {
setBreadcrumb([
{
to: "/",
text: "Home",
active: false
},
{
to: null,
text: title,
active: true
}
]);
}, [setBreadcrumb, title]);
useEffect(() => {
return () => {
mountedRef.current = false
}
},[]);
return (
<Container>
<Paper>
<Box p={2}>
{redirect === null &&
<>
{errorMessage !== null &&
<Alert severity="error" dismissible={true} onDismiss={() => setErrorMessage(null)}>{errorMessage}</Alert>
}
<div className="card-body">
<Form handleSubmit={e =>{
e.preventDefault();
setInSubmit(true);
setErrorMessage(null);
const createAccount = CloudFunctions.httpsCallable('createAccount');
createAccount({
accountName: accountName.value,
}).then(response => {
if (!mountedRef.current) return null
const accountId = response.data.accountId;
setRedirect('/account/'+accountId+'/billing/plan');
}).catch(err => {
if (!mountedRef.current) return null
setErrorMessage(err.message);
setInSubmit(false);
})
}}
disabled={accountName.hasError || accountName.value===null || inSubmit}
inSubmit={inSubmit}
enableDefaultButtons={true}>
<Input label="Account Name" type="text" name="account-name" maxLen={100} required={true} changeHandler={setAccountName} fullWidth variant="outlined" />
</Form>
</div>
</>
}
{redirect !== null &&
<Redirect to={redirect}></Redirect>
}
</Box>
</Paper>
</Container>
)
}
Example #15
Source File: Orgs.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, orgs, tableState, handleMatch, handleRequestSort,
handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
clearSnackbar, handleDelete, handleDeleteClose, handleDeleteError,
handleDeleteSuccess, handleEdit } = this.props;
const { order, orderBy, match, snackbar, adding, deleting } = tableState;
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={t("Organizations")}
href="https://docs.grommunio.com/admin/administration.html#organizations"
subtitle={t("orgs_sub")}
snackbar={snackbar}
onSnackbarClose={clearSnackbar}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={handleAdd}
disabled={!writable}
>
{t("New organization")}
</Button>
<div className={classes.actions}>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search organizations")}
variant={"outlined"}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<Typography className={classes.count} color="textPrimary">
{t("showingOrgs", { count: orgs.Orgs.length })}
</Typography>
<Paper elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
{this.columns.map((column) => (
<TableCell key={column.value}>
<TableSortLabel
active={orderBy === column.value}
align="left"
direction={orderBy === column.value ? order : "asc"}
onClick={handleRequestSort(column.value)}
>
{t(column.label)}
</TableSortLabel>
</TableCell>
))}
<TableCell padding="checkbox" />
</TableRow>
</TableHead>
<TableBody>
{orgs.Orgs.map((obj, idx) =>
<TableRow key={idx} hover onClick={handleEdit('/orgs/' + obj.ID)}>
<TableCell>{obj.name}</TableCell>
<TableCell>{obj.description}</TableCell>
<TableCell align="right">
{writable && <IconButton onClick={handleDelete(obj)} size="large">
<Delete color="error" />
</IconButton>}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
{orgs.Orgs.length < orgs.count && (
<Grid container justifyContent="center">
<CircularProgress
color="primary"
className={classes.circularProgress}
/>
</Grid>
)}
</Paper>
<AddOrg
open={adding}
onSuccess={handleAddingSuccess}
onError={handleAddingError}
onClose={handleAddingClose}
/>
<GeneralDelete
open={!!deleting}
delete={this.props.delete}
onSuccess={handleDeleteSuccess}
onError={handleDeleteError}
onClose={handleDeleteClose}
item={deleting.name}
id={deleting.ID}
/>
</TableViewContainer>
);
}
Example #16
Source File: Layout1Customizer.jsx From matx-react with MIT License | 4 votes |
Layout1Customizer = ({ settings, handleChange, handleControlChange }) => {
return (
<Fragment>
<Box mb="16px" mx="12px">
<ThemeName>Sidebar theme</ThemeName>
<ToolbarContainer>
{mainSidebarThemes.map((color, i) => (
<Tooltip key={i} title={color} placement="top">
<ToolbarContent
color={color}
onClick={() => handleChange('layout1Settings.leftSidebar.theme', color)}
>
{settings.layout1Settings.leftSidebar.theme === color && <Icon>done</Icon>}
<div className={settings.themes[color].palette.type}></div>
</ToolbarContent>
</Tooltip>
))}
</ToolbarContainer>
</Box>
<Box mb="32px" mx="12px">
<ThemeName>Sidebar theme</ThemeName>
<ToolbarContainer>
{topbarThemes.map((color, i) => (
<Tooltip key={i} title={color} placement="top">
<ToolbarContent
color={color}
onClick={() => handleChange('layout1Settings.topbar.theme', color)}
>
{settings.layout1Settings.topbar.theme === color && <Icon>done</Icon>}
<div className={settings.themes[color].palette.type}></div>
</ToolbarContent>
</Tooltip>
))}
</ToolbarContainer>
</Box>
<Box mb="18px" mx="12px">
<FormControl component="fieldset">
<FormLabel component="legend">Sidebar mode</FormLabel>
<RadioGroup
aria-label="Sidebar"
name="leftSidebar"
value={settings.layout1Settings.leftSidebar.mode}
onChange={handleControlChange('layout1Settings.leftSidebar.mode')}
>
<FormControlLabel value="full" control={<Radio />} label="Full" />
<FormControlLabel value="close" control={<Radio />} label="Close" />
<FormControlLabel value="compact" control={<Radio />} label="Compact" />
</RadioGroup>
</FormControl>
</Box>
<Box mb="32px" mx="12px">
<ThemeName sx={{ mb: 4 }}>Sidebar background image</ThemeName>
<div>
<Grid container spacing={3}>
{sidebarBG.map((bg, i) => (
<Grid item xs={4} key={i}>
<BadgeSelected
color="primary"
badgeContent={<Icon>done</Icon>}
invisible={settings.layout1Settings.leftSidebar.bgImgURL !== bg}
sx={{ width: '100%', height: '100%', cursor: 'pointer' }}
>
<Paper onClick={() => handleChange('layout1Settings.leftSidebar.bgImgURL', bg)}>
<IMG src={bg} alt="" />
</Paper>
</BadgeSelected>
</Grid>
))}
</Grid>
</div>
</Box>
<Box mb="24px" mx="12px">
<FormControl component="fieldset">
<FormLabel component="legend">Topbar</FormLabel>
<FormGroup>
<FormControlLabel
control={
<Switch
checked={get(settings.layout1Settings.topbar, 'show')}
onChange={handleControlChange('layout1Settings.topbar.show')}
/>
}
label="Show"
/>
<FormControlLabel
control={
<Switch
checked={get(settings.layout1Settings.topbar, 'fixed')}
onChange={handleControlChange('layout1Settings.topbar.fixed')}
/>
}
label="Fixed"
/>
</FormGroup>
</FormControl>
</Box>
</Fragment>
);
}
Example #17
Source File: Servers.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, servers, tableState, handleMatch, handleRequestSort,
handleAdd, handleAddingSuccess, handleAddingClose, handleAddingError,
handleDelete, handleDeleteClose, handleDeleteError,
handleDeleteSuccess, handleEdit } = this.props;
const { order, orderBy, match, adding, snackbar, deleting } = tableState;
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
return (
<TableViewContainer
handleScroll={this.handleScroll}
headline={<span>
{t("Servers")}
<IconButton
size="small"
href="https://docs.grommunio.com/admin/administration.html#id1"
target="_blank"
>
<HelpOutline fontSize="small"/>
</IconButton>
</span>
}
snackbar={snackbar || this.state.snackbar}
onSnackbarClose={this.handleSnackbarClose}
>
<Grid container alignItems="flex-end" className={classes.buttonGrid}>
<Button
variant="contained"
color="primary"
onClick={handleAdd}
disabled={!writable}
>
{t("New server")}
</Button>
<div className={classes.actions}>
<TextField
value={match}
onChange={handleMatch}
placeholder={t("Search")}
variant="outlined"
className={classes.textfield}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Search color="secondary" />
</InputAdornment>
),
}}
color="primary"
/>
</div>
</Grid>
<div>
<TextField
value={servers.policy || 'round-robin'}
onChange={this.handlePolicyChange}
select
label="Selection policy"
className={classes.policy}
>
<MenuItem value={"round-robin"}>round-robin</MenuItem>
<MenuItem value={"balanced"}>balanced</MenuItem>
<MenuItem value={"first"}>first</MenuItem>
<MenuItem value={"last"}>last</MenuItem>
<MenuItem value={"random"}>random</MenuItem>
</TextField>
</div>
<Typography className={classes.count} color="textPrimary">
{t("showingServers", { count: servers.Servers.length })}
</Typography>
<Paper elevation={1}>
<Table size="small">
<TableHead>
<TableRow>
{this.columns.map((column) => (
<TableCell key={column.value}>
<TableSortLabel
active={orderBy === column.value}
align="left"
direction={orderBy === column.value ? order : "asc"}
onClick={handleRequestSort(column.value)}
>
{t(column.label)}
</TableSortLabel>
</TableCell>
))}
<TableCell padding="checkbox" />
</TableRow>
</TableHead>
<TableBody>
{servers.Servers.map((obj, idx) =>
<TableRow key={idx} hover onClick={handleEdit('/servers/' + obj.ID)}>
<TableCell>{obj.hostname}</TableCell>
<TableCell>{obj.extname}</TableCell>
<TableCell align="right">
{writable && <IconButton onClick={handleDelete(obj)} size="large">
<Delete color="error"/>
</IconButton>}
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
{(servers.Servers.length < servers.count) && <Grid container justifyContent="center">
<CircularProgress color="primary" className={classes.circularProgress}/>
</Grid>}
</Paper>
<AddServer
open={adding}
onSuccess={handleAddingSuccess}
onError={handleAddingError}
onClose={handleAddingClose}
/>
<GeneralDelete
open={!!deleting}
delete={this.props.delete}
onSuccess={handleDeleteSuccess}
onError={handleDeleteError}
onClose={handleDeleteClose}
item={deleting.hostname}
id={deleting.ID}
/>
</TableViewContainer>
);
}
Example #18
Source File: CardView.jsx From Edlib with GNU General Public License v3.0 | 4 votes |
CardView = ({ resources, showDeleteButton = false, refetch }) => {
const { classes } = useStyles();
const { t } = useTranslation();
return (
<ViewContainer
showDeleteButton={showDeleteButton}
refetch={refetch}
resources={resources}
>
{({ cogProps, setSelectedResource, resources }) => (
<Grid container spacing={1}>
{resources.map((resource) => (
<Grid
key={resource.id}
item
xs={6}
lg={4}
className={classes.gridItem}
>
<Paper className={classes.paper}>
<Box
display="flex"
justifyContent="space-between"
>
<Box>
<div className={classes.title}>
{resource.version.title}
</div>
<Box
className={classes.subtitle}
mt={1}
>
{getResourceName(resource)}
</Box>
</Box>
<Box>
<ResourceIcon
contentTypeInfo={
resource.contentTypeInfo
}
resourceVersion={resource.version}
fontSizeRem={2}
/>
</Box>
</Box>
<Box
mt={1}
display="flex"
justifyContent="space-between"
>
<Box
display="flex"
flexDirection="column"
justifyContent="center"
>
<PublishedTag
isPublished={
resource.version.isPublished
}
isDraft={resource.version.isDraft}
/>
</Box>
<Box className={classes.buttons}>
<ResourceEditCog
{...cogProps(resource)}
>
{({ ref, onOpen }) => (
<Button
size="small"
color="grey"
variant="contained"
style={{ minWidth: 0 }}
onClick={onOpen}
ref={ref}
>
<MoreVertIcon />
</Button>
)}
</ResourceEditCog>
<Button
size="small"
color="secondary"
variant="contained"
onClick={() =>
setSelectedResource(resource)
}
>
{t('preview')}
</Button>
</Box>
</Box>
</Paper>
</Grid>
))}
</Grid>
)}
</ViewContainer>
);
}
Example #19
Source File: PostContent.js From react-saas-template with MIT License | 4 votes |
function PostContent(props) {
const {
pushMessageToSnackbar,
setPosts,
posts,
openAddPostModal,
classes,
} = props;
const [page, setPage] = useState(0);
const [isDeletePostDialogOpen, setIsDeletePostDialogOpen] = useState(false);
const [isDeletePostDialogLoading, setIsDeletePostDialogLoading] = useState(
false
);
const closeDeletePostDialog = useCallback(() => {
setIsDeletePostDialogOpen(false);
setIsDeletePostDialogLoading(false);
}, [setIsDeletePostDialogOpen, setIsDeletePostDialogLoading]);
const deletePost = useCallback(() => {
setIsDeletePostDialogLoading(true);
setTimeout(() => {
const _posts = [...posts];
const index = _posts.find((element) => element.id === deletePost.id);
_posts.splice(index, 1);
setPosts(_posts);
pushMessageToSnackbar({
text: "Your post has been deleted",
});
closeDeletePostDialog();
}, 1500);
}, [
posts,
setPosts,
setIsDeletePostDialogLoading,
pushMessageToSnackbar,
closeDeletePostDialog,
]);
const onDelete = useCallback(() => {
setIsDeletePostDialogOpen(true);
}, [setIsDeletePostDialogOpen]);
const handleChangePage = useCallback(
(__, page) => {
setPage(page);
},
[setPage]
);
const printImageGrid = useCallback(() => {
if (posts.length > 0) {
return (
<Box p={1}>
<Grid container spacing={1}>
{posts
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((post) => (
<Grid item xs={6} sm={4} md={3} key={post.id}>
<SelfAligningImage
src={post.src}
title={post.name}
timeStamp={post.timestamp}
options={[
{
name: "Delete",
onClick: () => {
onDelete(post);
},
icon: <DeleteIcon />,
},
]}
/>
</Grid>
))}
</Grid>
</Box>
);
}
return (
<Box m={2}>
<HighlightedInformation>
No posts added yet. Click on "NEW" to create your first one.
</HighlightedInformation>
</Box>
);
}, [posts, onDelete, page]);
return (
<Paper>
<Toolbar className={classes.toolbar}>
<Typography variant="h6">Your Posts</Typography>
<Button
variant="contained"
color="secondary"
onClick={openAddPostModal}
disableElevation
>
Add Post
</Button>
</Toolbar>
<Divider />
{printImageGrid()}
<TablePagination
component="div"
count={posts.length}
rowsPerPage={rowsPerPage}
page={page}
backIconButtonProps={{
"aria-label": "Previous Page",
}}
nextIconButtonProps={{
"aria-label": "Next Page",
}}
onPageChange={handleChangePage}
classes={{
select: classes.dNone,
selectIcon: classes.dNone,
actions: posts.length > 0 ? classes.dBlock : classes.dNone,
caption: posts.length > 0 ? classes.dBlock : classes.dNone,
}}
labelRowsPerPage=""
/>
<ConfirmationDialog
open={isDeletePostDialogOpen}
title="Confirmation"
content="Do you really want to delete the post?"
onClose={closeDeletePostDialog}
loading={isDeletePostDialogLoading}
onConfirm={deletePost}
/>
</Paper>
);
}
Example #20
Source File: ServicesChart.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, Services, t } = this.props;
const { starting, restarting, stoping, snackbar, service, action } = this.state;
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<Table size="small">
<TableHead>
<TableRow>
<TableCell>
{"Service"}
</TableCell>
<TableCell align="center" style={{ width: 124 }}>
{"State | Autostart"}
</TableCell>
<TableCell align="center" style={{ width: 132 }}>
{"Actions"}
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{Services.map((service, idx) => (
<TableRow key={idx} hover style={{cursor: "default"}}>
<TableCell>
<Tooltip
title={service.description ? <>
<Typography>{service.description}</Typography>
<Typography variant="caption">
{service.since ? `${t('since')} ${setDateTimeString(service.since)}` : ''}
</Typography>
</> : ''}
placement="top"
>
<Typography className={classes.serviceName}>
{service.name}
</Typography>
</Tooltip>
</TableCell>
<TableCell>
<Grid container justifyContent="center">
<div
style={{ marginRight: 4 }}
className={classes.label + " " + this.getChipColor(service.state)}
>
{service.state}
</div>
<div className={classes.label + " " +
this.getChipColor(service.autostart === "enabled" ? "active" : "error")}>
{service.autostart || 'error'}
</div>
</Grid>
</TableCell>
<TableCell align="right">
<Tooltip title={t("Enable/Disable")} placement="top">
<IconButton
onClick={this.handleServiceAction(service, service.autostart === "enabled" ?
"disable" : "enable")}
className={classes.chipIcon}
size="large">
<Enable className={classes.iconButton} fontSize="small" />
</IconButton>
</Tooltip>
{stoping !== service.name ? (
<Tooltip title={t("Stop")} placement="top">
<IconButton
onClick={this.handleDialog(service, "stop")}
className={classes.chipIcon}
size="large">
<Stop className={classes.iconButton} fontSize="small" />
</IconButton>
</Tooltip>
) : (
<IconButton className={classes.chipIcon} size="large">
<CircularProgress size={18} />
</IconButton>
)}
{restarting !== service.name ? (
<Tooltip title={t("Restart")}placement="top">
<IconButton
onClick={this.handleDialog(service, "restart")}
className={classes.chipIcon}
size="large">
<Restart
className={classes.iconButton}
fontSize="small"
/>
</IconButton>
</Tooltip>
) : (
<IconButton className={classes.chipIcon} size="large">
<CircularProgress size={18} />
</IconButton>
)}
{starting !== service.name ? (
<Tooltip title={t("Start")} placement="top">
<IconButton
onClick={this.handleServiceAction(service, "start")}
className={classes.chipIcon}
size="large">
<Start className={classes.iconButton} fontSize="small" />
</IconButton>
</Tooltip>
) : (
<IconButton className={classes.chipIcon} size="large">
<CircularProgress size={18} />
</IconButton>
)}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
<ConfirmRestartStop
open={!!service}
handleConfirm={this.handleServiceAction(service, action)}
onClose={this.handleCloseDialog}
service={service}
action={action}
/>
<Feedback
snackbar={snackbar}
onClose={() => this.setState({ snackbar: "" })}
/>
</div>
);
}
Example #21
Source File: index.js From fireact with MIT License | 4 votes |
Invite = () => {
const { code } = useParams();
const title = 'View Invite';
const history = useHistory();
const mountedRef = useRef(true);
const [invite, setInvite] = useState(null);
const [error, setError] = useState(null);
const [inSubmit, setInSubmit] = useState(false);
const [success, setSuccess] = useState(false);
const { setBreadcrumb } = useContext(BreadcrumbContext);
useEffect(() => {
setBreadcrumb([
{
to: "/",
text: "Home",
active: false
},
{
to: null,
text: title,
active: true
}
]);
if(code){
let isSubscribed = true;
setError(null);
const getInvite = CloudFunctions.httpsCallable('getInvite');
getInvite({
inviteId: code
}).then(res => {
if (!mountedRef.current) return null
if(isSubscribed){
setInvite(res.data);
}
}).catch(err => {
if (!mountedRef.current) return null
if(isSubscribed){
setError(err.message);
}
});
return () => (isSubscribed = false);
}
}, [code, setBreadcrumb, title]);
useEffect(() => {
return () => {
mountedRef.current = false
}
},[]);
return (
<>
{success?(
<Redirect to={"/account/"+invite.accountId+"/"}></Redirect>
):(
<Paper>
<Box p={2}>
<Stack spacing={3}>
{error !== null &&
<Alert severity="danger">{error}</Alert>
}
{invite === null?(
<Loader text="Loading the invite..."></Loader>
):(
<>
<Typography>This invite will grant you access to <strong>{invite.accountName}</strong>. Do you want to accept it?</Typography>
<Stack direction="row" spacing={1} mt={2}>
<Button disabled={inSubmit} variant="contained" onClick={e => {
e.preventDefault();
setInSubmit(true);
const acceptInvite = CloudFunctions.httpsCallable('acceptInvite');
acceptInvite({
inviteId: code
}).then(res => {
if (!mountedRef.current) return null
setSuccess(true);
}).catch(err => {
if (!mountedRef.current) return null
setError(err.message);
});
}}>{inSubmit && <Loader />}
Yes, accept the invite
</Button>
<Button color="secondary" variant="contained" disabled={inSubmit} onClick={() => history.push('/')}>Ignore</Button>
</Stack>
</>
)}
</Stack>
</Box>
</Paper>
)}
</>
)
}
Example #22
Source File: ClassDetails.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t, domain, _classes } = this.props;
const writable = this.context.includes(DOMAIN_ADMIN_WRITE);
const { _class, autocompleteInput, snackbar, stack } = this.state;
const { classname, parentClasses, members, filters, children } = _class;
return (
<ViewWrapper
topbarTitle={t('Groups')}
snackbar={snackbar}
onSnackbarClose={() => this.setState({ snackbar: '' })}
>
<Paper className={classes.paper} elevation={1}>
<Grid container>
<Typography
color="primary"
variant="h5"
>
{t('editHeadline', { item: 'Group' })}
</Typography>
</Grid>
<FormControl className={classes.form}>
<Breadcrumbs className={classes.breadcrumbs}>
{stack.map((_class, idx) =>
<Link
className={classes.breadcrumb}
key={_class.ID}
color="inherit"
onClick={this.handleBreadcrumb(_class.ID, idx)}
>
{_class.classname}
</Link>
)}
</Breadcrumbs>
<TextField
className={classes.input}
label={t("Groupname")}
fullWidth
value={classname || ''}
onChange={this.handleInput('classname')}
autoFocus
required
/>
<MagnitudeAutocomplete
value={parentClasses || []}
filterAttribute={'classname'}
inputValue={autocompleteInput}
onChange={this.handleAutocomplete('parentClasses')}
className={classes.input}
options={_classes || []}
onInputChange={this.handleAutocompleteInput}
label={t("Parent groups")}
placeholder={t("Search groups") + "..."}
multiple
autoSelect
/>
<TextField
className={classes.input}
label={t("Members (separate by comma)")}
fullWidth
value={members || ''}
onChange={this.handleMemberInput}
/>
</FormControl>
<div>
<Typography variant="body1">{t('Filters (All must be true)')}</Typography>
{filters && filters.map((ANDFilter, ANDidx) =>
<Accordion
className={classes.panel}
elevation={2 /* 1 has global overwrite */}
key={ANDidx}
defaultExpanded
>
<AccordionSummary>
<Grid container justifyContent="space-between">
<Typography body="body1">{t('Filter (One must be true)')}</Typography>
<IconButton onClick={this.handleRemoveAND(ANDidx)} size="large">
<Delete fontSize="small" color="error"/>
</IconButton>
</Grid>
</AccordionSummary>
<AccordionDetails>
<Grid container>
{ANDFilter.map((ORFilter, ORidx) =>
<Grid item xs={12} key={ORidx} className={classes.grid}>
<Autocomplete
value={ORFilter.prop || ''}
inputValue={ORFilter.prop || ''}
onChange={this.handleAutocomplete(ANDidx, ORidx, 'prop')}
onInputChange={this.handleFilterInput(ANDidx, ORidx, 'prop')}
freeSolo
className={classes.flexTextfield}
options={this.columns}
renderInput={(params) => (
<TextField
{...params}
label={t("Name of property to match")}
/>
)}
/>
<TextField
className={classes.flexTextfield}
label={t("Comparison operator")}
value={ORFilter.op || ''}
onChange={this.handleFilterInput(ANDidx, ORidx, 'op')}
select
>
{this.operators.map(op =>
<MenuItem value={op.value} key={op.label}>{op.label}</MenuItem>
)}
</TextField>
<TextField
className={classes.flexTextfield}
label={t("Compare value (binary operators)")}
value={ORFilter.val || ''}
onChange={this.handleFilterInput(ANDidx, ORidx, 'val')}
/>
{filters[ANDidx].length > 1 &&
<IconButton onClick={this.handleRemoveOR(ANDidx, ORidx)} size="large">
<Delete fontSize="small" color="error"/>
</IconButton>}
</Grid>
)}
<Grid container justifyContent="center">
<Button variant="outlined" onClick={this.handleAddOR(ANDidx)}>{t('Add or-statement')}</Button>
</Grid>
</Grid>
</AccordionDetails>
</Accordion>
)}
<Grid container justifyContent="center">
<Button variant="outlined" onClick={this.handleAddAND}>{t('Add and-statement')}</Button>
</Grid>
</div>
<Typography variant="h6">{t('Children')}</Typography>
<List>
{children && children.map(child =>
<ListItem
key={child.ID}
button
onClick={this.handleChildClicked(child)}
>
<ListItemText primary={child.classname} />
</ListItem>
)}
</List>
<Button
variant="text"
color="secondary"
onClick={this.handleNavigation(domain.ID + '/classes')}
style={{ marginRight: 8 }}
>
{t('Back')}
</Button>
<Button
variant="contained"
color="primary"
onClick={this.handleEdit}
disabled={!writable}
>
{t('Save')}
</Button>
</Paper>
</ViewWrapper>
);
}
Example #23
Source File: index.js From fireact with MIT License | 4 votes |
Plans = () => {
const title = 'Select a Plan';
const countries = countryJSON.countries;
const { userData, authUser } = useContext(AuthContext);
const stripe = useStripe();
const elements = useElements();
const mountedRef = useRef(true);
const { setBreadcrumb } = useContext(BreadcrumbContext);
const CARD_ELEMENT_OPTIONS = {
style: {
base: {
color: '#32325d',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
},
hidePostalCode: true
};
const [loading, setLoading] = useState(true);
const [processing, setProcessing] = useState(false);
const [plans, setPlans] = useState([]);
const [selectedPlan, setSelectedPlan] = useState({id: 0});
const [cardError, setCardError] = useState(null);
const [errorMessage, setErrorMessage] = useState(null);
const [country, setCountry] = useState("");
const [countryError, setCountryError] = useState(null);
const [state, setState] = useState("");
const [states, setStates] = useState([]);
const [stateError, setStateError] = useState(null);
useEffect(() => {
setBreadcrumb([
{
to: "/",
text: "Home",
active: false
},
{
to: "/account/"+userData.currentAccount.id+"/",
text: userData.currentAccount.name,
active: false
},
{
to: null,
text: title,
active: true
}
]);
setLoading(true);
const plansQuery = FirebaseAuth.firestore().collection('plans').orderBy('price', 'asc');
plansQuery.get().then(planSnapShots => {
if (!mountedRef.current) return null
let p = [];
planSnapShots.forEach(doc => {
p.push({
'id': doc.id,
'name': doc.data().name,
'price': doc.data().price,
'currency': doc.data().currency,
'paymentCycle': doc.data().paymentCycle,
'features': doc.data().features,
'stripePriceId': doc.data().stripePriceId,
'current': (userData.currentAccount.planId===doc.id)?true:false
});
});
if(p.length > 0){
const ascendingOrderPlans = p.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));
setPlans(ascendingOrderPlans);
}
setLoading(false);
});
},[userData, setBreadcrumb, title]);
useEffect(() => {
return () => {
mountedRef.current = false
}
},[]);
const subscribe = async(event) => {
event.preventDefault();
setProcessing(true);
setErrorMessage(null);
let hasError = false;
let paymentMethodId = '';
if(selectedPlan.price !== 0){
if(country === ''){
setCountryError('Please select a country.');
hasError = true;
}
if(state === '' && countries[country] && countries[country].states){
setStateError('Please select a state.');
hasError = true;
}
setCardError(null);
if (!stripe || !elements) {
// Stripe.js has not loaded yet. Make sure to disable
// form submission until Stripe.js has loaded.
return;
}
// Get a reference to a mounted CardElement. Elements knows how
// to find your CardElement because there can only ever be one of
// each type of element.
const cardElement = elements.getElement(CardElement);
// Use your card Element with other Stripe.js APIs
const {error, paymentMethod} = await stripe.createPaymentMethod({
type: 'card',
card: cardElement
});
if (error) {
setCardError(error.message);
hasError = true;
} else {
paymentMethodId = paymentMethod.id;
}
}
if(!hasError){
const createSubscription = CloudFunctions.httpsCallable('createSubscription');
createSubscription({
planId: selectedPlan.id,
accountId: userData.currentAccount.id,
paymentMethodId: paymentMethodId,
billing: {
country: country,
state: state
}
}).then(res => {
// physical page load to reload the account data
if (!mountedRef.current) return null
document.location = '/account/'+userData.currentAccount.id+'/';
}).catch(err => {
if (!mountedRef.current) return null
setProcessing(false);
setErrorMessage(err.message);
});
}else{
setProcessing(false);
}
}
return (
<>
{(!loading)?(
<>{(userData.currentAccount.owner === authUser.user.uid)?(
<>{plans.length > 0 ? (
<Paper>
<Box p={3} style={{textAlign: 'center'}} >
<h2>{title}</h2>
<Grid container spacing={3}>
<>
{plans.map((plan,i) =>
<Grid container item xs={12} md={4} key={i} >
<Card style={{
width: '100%',
display: 'flex',
flexDirection: 'column',
paddingBottom: '20px',
}}>
<CardHeader title={plan.name} subheader={"$"+plan.price+"/"+plan.paymentCycle} />
<CardContent>
<Divider />
<ul style={{listStyleType: 'none', paddingLeft: '0px'}}>
{plan.features.map((feature, i) =>
<li key={i}>
<i className="fa fa-check" style={{color: "#2e7d32"}} /> {feature}
</li>
)}
</ul>
</CardContent>
<CardActions style={{
marginTop: 'auto',
justifyContent: 'center',
}}>
{plan.current?(
<Button color="success" variant="contained" disabled={true}>Current Plan</Button>
):(
<Button color="success" variant={(plan.id!==selectedPlan.id)?"outlined":"contained"} onClick={() => {
for(let i=0; i<plans.length; i++){
if(plans[i].id === plan.id){
setSelectedPlan(plan);
}
}
}}>{plan.id===selectedPlan.id && <><i className="fa fa-check" /> </>}{(plan.id!==selectedPlan.id)?"Select":"Selected"}</Button>
)}
</CardActions>
</Card>
</Grid>
)}
</>
</Grid>
{selectedPlan.id !== 0 && selectedPlan.price > 0 &&
<div style={{justifyContent: 'center', marginTop: '50px'}}>
<h2>Billing Details</h2>
<Grid container spacing={3}>
<Grid container item xs={12}>
<Card style={{
width: '100%',
paddingBottom: '20px',
}}>
<CardContent>
<Container maxWidth="sm">
<Stack spacing={3}>
{countryError !== null &&
<Alert severity="error" onClose={() => setCountryError(null)}>{countryError}</Alert>
}
<Autocomplete
value={(country !== '')?(countries.find(obj =>{
return obj.code === country
})):(null)}
options={countries}
autoHighlight
getOptionLabel={(option) => option.label}
renderOption={(props, option) => (
<Box component="li" sx={{ '& > img': { mr: 2, flexShrink: 0 } }} {...props}>
<img
loading="lazy"
width="20"
src={`https://flagcdn.com/w20/${option.code.toLowerCase()}.png`}
srcSet={`https://flagcdn.com/w40/${option.code.toLowerCase()}.png 2x`}
alt=""
/>
{option.label}
</Box>
)}
renderInput={(params) => (
<TextField
{...params}
label="Country"
inputProps={{
...params.inputProps,
autoComplete: 'new-password',
}}
/>
)}
onChange={(event, newValue) => {
if(newValue && newValue.code){
setCountry(newValue.code);
setState("");
if(newValue.states){
setStates(newValue.states);
}else{
setStates([]);
}
setCountryError(null);
}
}}
/>
{states.length > 0 &&
<>
{stateError !== null &&
<Alert severity="error" onClose={() => setStateError(null)}>{stateError}</Alert>
}
<Autocomplete
value={(state !== '')?(states.find(obj =>{
return obj.code === state
})):(null)}
options={states}
autoHighlight
getOptionLabel={(option) => option.label}
renderOption={(props, option) => (
<Box component="li" {...props}>
{option.label}
</Box>
)}
renderInput={(params) => (
<TextField
{...params}
label="State"
inputProps={{
...params.inputProps,
autoComplete: 'new-password',
}}
/>
)}
onChange={(event, newValue) => {
if(newValue && newValue.code){
setState(newValue.code);
setStateError(null);
}
}}
/>
</>
}
{cardError !== null &&
<Alert severity="error" onClose={() => setCardError(null)}>{cardError}</Alert>
}
<div style={{position: "relative", minHeight: '56px', padding: '15px'}}>
<CardElement options={CARD_ELEMENT_OPTIONS}></CardElement>
<fieldset style={{
borderColor: 'rgba(0, 0, 0, 0.23)',
borderStyle: 'solid',
borderWidth: '1px',
borderRadius: '4px',
position: 'absolute',
top: '-5px',
left: '0',
right: '0',
bottom: '0',
margin: '0',
padding: '0 8px',
overflow: 'hidden',
pointerEvents: 'none'
}}></fieldset>
</div>
</Stack>
</Container>
</CardContent>
</Card>
</Grid>
</Grid>
</div>
}
{selectedPlan.id!==0 &&
<div style={{marginTop: '50px'}}>
<Container maxWidth="sm">
<Stack spacing={3}>
{errorMessage !== null &&
<Alert severity="error" onClose={() => setErrorMessage(null)}>{errorMessage}</Alert>
}
<Button color="success" size="large" variant="contained" disabled={selectedPlan.id===0||processing?true:false} onClick={e => {
subscribe(e);
}}>{processing?(<><Loader /> Processing...</>):(<>Subscribe Now</>)}</Button>
</Stack>
</Container>
</div>
}
</Box>
</Paper>
):(
<Alert severity="warning">No plan is found.</Alert>
)}</>
):(
<Alert severity="error" >Access Denied.</Alert>
)}</>
):(
<Loader text="loading plans..." />
)}
</>
)
}
Example #24
Source File: Dashboard.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const {
classes,
t,
cpuPercent,
disks,
memory,
swap,
swapPercent,
load,
statistics,
} = this.props;
const { snackbar } = this.state;
return (
<div className={classes.root}>
<TopBar />
<div className={classes.toolbar} />
{config?.loadAntispamData && <Typography variant="h2" className={classes.pageTitle}>
{t("Mail filter statistics")}
<IconButton
size="small"
href="https://docs.grommunio.com/admin/administration.html#antispam"
target="_blank"
>
<HelpOutline fontSize="small"/>
</IconButton>
</Typography>}
{config?.loadAntispamData && <Typography variant="caption" className={classes.subtitle}>
{t("mailfilter_sub")}
</Typography>}
<div className={classes.dashboardLayout}>
{config?.loadAntispamData && <div className={classes.antispam}>
<AntispamStatistics data={statistics}/>
</div>}
<div className={classes.services}>
<ServicesChart/>
</div>
<div className={classes.headline}>
<Typography variant="h2" className={classes.pageTitle}>
{t("Performance")}
<IconButton
size="small"
href="https://docs.grommunio.com/admin/administration.html#services"
target="_blank"
>
<HelpOutline fontSize="small"/>
</IconButton>
</Typography>
<Typography variant="caption" className={classes.subtitle}>
{t("performance_sub")}
</Typography>
</div>
<div className={classes.cpu}>
<Paper elevation={1} className={classes.donutAndLineChart}>
<div className={classes.donutChart}>
<CPUPieChart cpuPercent={cpuPercent} />
</div>
<div className={classes.lineChart}>
<CPULineChart cpuPercent={cpuPercent} />
</div>
</Paper>
</div>
<div className={classes.memory}>
<Paper elevation={1} className={classes.donutAndLineChart}>
<div className={classes.donutChart}>
<MemoryPieChart memory={memory} />
</div>
<div className={classes.lineChart}>
<MemoryChart memory={memory} />
</div>
</Paper>
</div>
<div className={classes.swap}>
<Paper elevation={1} className={classes.donutAndLineChart}>
{!!swapPercent && <div>
<SwapPieChart swap={swap} swapPercent={swapPercent} />
</div>}
<div className={!swapPercent ? classes.fullChart : classes.lineChart}>
<DisksChart disks={disks} />
</div>
</Paper>
</div>
<div className={classes.disk}>
<LoadChart load={load} />
</div>
</div>
<Typography variant="h2" className={classes.pageTitle}>
{t("Versions")}
</Typography>
<About />
<Feedback
snackbar={snackbar}
onClose={() => this.setState({ snackbar: "" })}
/>
</div>
);
}
Example #25
Source File: index.js From fireact with MIT License | 4 votes |
PaymentMethod = () => {
const title = 'Update Payment Method';
const mountedRef = useRef(true);
const history = useHistory();
const { userData, authUser } = useContext(AuthContext);
const stripe = useStripe();
const elements = useElements();
const { setBreadcrumb } = useContext(BreadcrumbContext);
const CARD_ELEMENT_OPTIONS = {
style: {
base: {
color: '#32325d',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
},
hidePostalCode: true
};
const [processing, setProcessing] = useState(false);
const [success, setSuccess] = useState(false);
const [cardError, setCardError] = useState(null);
const [errorMessage, setErrorMessage] = useState(null);
const subscribe = async(event) => {
event.preventDefault();
setProcessing(true);
setErrorMessage(null);
setSuccess(false);
let hasError = false;
let paymentMethodId = '';
setCardError(null);
if (!stripe || !elements) {
// Stripe.js has not loaded yet. Make sure to disable
// form submission until Stripe.js has loaded.
return;
}
// Get a reference to a mounted CardElement. Elements knows how
// to find your CardElement because there can only ever be one of
// each type of element.
const cardElement = elements.getElement(CardElement);
// Use your card Element with other Stripe.js APIs
const {error, paymentMethod} = await stripe.createPaymentMethod({
type: 'card',
card: cardElement,
});
if (error) {
setCardError(error.message);
hasError = true;
} else {
paymentMethodId = paymentMethod.id;
}
if(!hasError){
const updatePaymentMethod = CloudFunctions.httpsCallable('updatePaymentMethod');
updatePaymentMethod({
accountId: userData.currentAccount.id,
paymentMethodId: paymentMethodId
}).then(res => {
if (!mountedRef.current) return null
setSuccess(true);
setProcessing(false);
}).catch(err => {
if (!mountedRef.current) return null
setProcessing(false);
setErrorMessage(err.message);
});
}else{
setProcessing(false);
}
}
useEffect(() => {
setBreadcrumb([
{
to: "/",
text: "Home",
active: false
},
{
to: "/account/"+userData.currentAccount.id+"/",
text: userData.currentAccount.name,
active: false
},
{
to: "/account/"+userData.currentAccount.id+"/billing",
text: 'Billing',
active: false
},
{
to: null,
text: title,
active: true
}
]);
},[userData, setBreadcrumb, title]);
useEffect(() => {
return () => {
mountedRef.current = false
}
},[]);
return (
<>
<Paper>
<Box p={2}>
{userData.currentAccount.price > 0 ? (
<Stack spacing={3}>
{(userData.currentAccount.owner === authUser.user.uid)?(
<>
{success &&
<Alert severity="success" onClose={() => setSuccess(false)}>The payment method has been successfully updated.</Alert>
}
{errorMessage !== null &&
<Alert severity="error" onClose={() => setErrorMessage(null)}>{errorMessage}</Alert>
}
{cardError !== null &&
<Alert severity="error" onClose={() => setCardError(null)}>{cardError}</Alert>
}
<div style={{position: "relative", minHeight: '56px', padding: '15px', maxWidth: '500px'}}>
<CardElement options={CARD_ELEMENT_OPTIONS}></CardElement>
<fieldset style={{
borderColor: 'rgba(0, 0, 0, 0.23)',
borderStyle: 'solid',
borderWidth: '1px',
borderRadius: '4px',
position: 'absolute',
top: '-5px',
left: '0',
right: '0',
bottom: '0',
margin: '0',
padding: '0 8px',
overflow: 'hidden',
pointerEvents: 'none'
}}></fieldset>
</div>
<Stack direction="row" spacing={1} mt={2}>
<Button variant="contained" disabled={processing} onClick={(e) => subscribe(e)}>
{processing?(
<><Loader /> Processing...</>
):(
<>Save</>
)}
</Button>
<Button variant="contained" color="secondary" disabled={processing} onClick={() => history.push("/account/"+userData.currentAccount.id+"/billing")}>Back</Button>
</Stack>
</>
):(
<Alert type="danger" message="Access Denied." dismissible={false} ></Alert>
)}
</Stack>
):(
<Alert severity="error">The account doesn't support payment methods.</Alert>
)}
</Box>
</Paper>
</>
)
}
Example #26
Source File: LdapConfig.js From admin-web with GNU Affero General Public License v3.0 | 4 votes |
render() {
const { classes, t } = this.props;
const writable = this.context.includes(SYSTEM_ADMIN_WRITE);
const { available, force, deleting, snackbar, server, bindUser, bindPass, starttls, baseDn, objectID, disabled,
username, filter, templates, attributes, defaultQuota, displayName, searchAttributes,
authBackendSelection, aliases, taskMessage, taskID } = this.state;
return (
<div className={classes.root}>
<TopBar />
<div className={classes.toolbar}></div>
<form className={classes.base} onSubmit={this.handleSave}>
<Typography variant="h2" className={classes.pageTitle}>
{t("Directory")}
<Tooltip
className={classes.tooltip}
title={t("ldap_settingsHelp")}
placement="top"
>
<IconButton
size="small"
href="https://docs.grommunio.com/admin/administration.html#ldap"
target="_blank"
>
<Help fontSize="small"/>
</IconButton>
</Tooltip>
</Typography>
<Typography variant="caption" className={classes.subtitle}>
{t('ldap_sub')}
</Typography>
<Grid container className={classes.category}>
<FormControlLabel
control={
<Switch
checked={!disabled}
onChange={this.handleActive}
name="disabled"
color="primary"
/>
}
label={<span>
{t('LDAP enabled')}
<Tooltip
className={classes.tooltip}
title={t("Enable LDAP service")}
placement="top"
>
<IconButton size="small">
<Help fontSize="small"/>
</IconButton>
</Tooltip>
</span>}
/>
<div className={classes.flexContainer}>
<Tooltip placement="top" title={t("Synchronize already imported users")}>
<Button
variant="contained"
color="primary"
style={{ marginRight: 16 }}
onClick={this.handleSync(false)}
>
{t("Sync users")}
</Button>
</Tooltip>
<Tooltip
placement="top"
title={t("ldap_import_tooltip")}
>
<Button
variant="contained"
color="primary"
style={{ marginRight: 16 }}
onClick={this.handleSync(true)}
>
{t("Import users")}
</Button>
</Tooltip>
</div>
</Grid>
<Typography
color="inherit"
variant="caption"
style={{
marginLeft: 16,
color: available ? green['500'] : red['500'],
}}
>
{!disabled && (available ? t('LDAP connectivity check passed') : t('LDAP connectivity check failed'))}
</Typography>
<Paper elevation={1} className={classes.paper}>
<Typography variant="h6" className={classes.category}>{t('LDAP Server')}</Typography>
<FormControl className={classes.formControl}>
<div className={classes.flexRow}>
<LdapTextfield
flex
label='LDAP Server'
autoFocus
placeholder="ldap://[::1]:389/"
onChange={this.handleInput('server')}
value={server || ''}
desc={t("ldap_server_desc")}
id="url"
name="url"
autoComplete="url"
InputLabelProps={{
shrink: true,
}}
/>
<LdapTextfield
flex
label="LDAP Bind DN"
onChange={this.handleInput('bindUser')}
value={bindUser || ''}
desc={t("Distinguished Name used for binding")}
id="username"
name="username"
autoComplete="username"
/>
<LdapTextfield
flex
label={t('LDAP Bind Password')}
onChange={this.handleInput('bindPass')}
value={bindPass || ''}
desc={t("ldap_password_desc")}
id="password"
name="password"
type="password"
autoComplete="current-password"
/>
<FormControlLabel
control={
<Checkbox
checked={starttls || false}
onChange={this.handleCheckbox('starttls')}
name="starttls"
inputProps={{
autoComplete: 'starttls',
name: 'starttls',
id: 'starttls',
}}
color="primary"
/>
}
label={<span>
{'STARTTLS'}
<Tooltip
className={classes.tooltip}
title="Whether to issue a StartTLS extended operation"
placement="top"
>
<IconButton size="small">
<Help fontSize="small"/>
</IconButton>
</Tooltip>
</span>}
/>
</div>
<LdapTextfield
label='LDAP Base DN'
onChange={this.handleInput('baseDn')}
value={baseDn || ''}
desc={t("Base DN to use for searches")}
id="baseDn"
name="baseDn"
autoComplete="baseDn"
/>
</FormControl>
</Paper>
<Paper elevation={1} className={classes.paper}>
<Typography variant="h6" className={classes.category}>
{t('User authentication mechanism')}
</Typography>
<FormControl className={classes.formControl}>
<RadioGroup
name="authBackendSelection"
value={authBackendSelection}
onChange={this.handleInput("authBackendSelection")}
row
className={classes.radioGroup}
color="primary"
>
<FormControlLabel
value="externid"
control={<Radio color="primary"/>}
label={t("Automatic")}
/>
<FormControlLabel value="always_mysql" control={<Radio color="primary"/>} label={t("Only MySQL")} />
<FormControlLabel value="always_ldap" control={<Radio color="primary"/>} label={t("Only LDAP")} />
</RadioGroup>
</FormControl>
</Paper>
<Paper className={classes.paper} elevation={1}>
<FormControl className={classes.formControl}>
<Typography variant="h6" className={classes.category}>{t('Attribute Configuration')}</Typography>
<LdapTextfield
label={t('LDAP Template')}
onChange={this.handleTemplate}
value={templates}
select
desc={t("Mapping templates to use")}
id="templates"
name="templates"
autoComplete="templates"
>
<MenuItem value='none'>{t('No template')}</MenuItem>
<MenuItem value="OpenLDAP">OpenLDAP</MenuItem>
<MenuItem value="ActiveDirectory">ActiveDirectory</MenuItem>
</LdapTextfield>
<LdapTextfield
label={t('LDAP Filter')}
onChange={this.handleInput('filter')}
value={filter || ''}
desc={t("LDAP search filter to apply to user lookup")}
id="filter"
name="filter"
autoComplete="filter"
/>
<LdapTextfield
label={t('Unique Identifier Attribute')}
onChange={this.handleInput('objectID')}
value={objectID || ''}
desc={t("ldap_oID_desc")}
id="objectID"
name="objectID"
autoComplete="objectID"
/>
<LdapTextfield
label={t('LDAP Username Attribute')}
onChange={this.handleInput('username')}
value={username || ''}
desc={t("ldap_username_desc")}
id="username"
name="username"
autoComplete="username"
/>
<LdapTextfield
label={t('LDAP Display Name Attribute')}
onChange={this.handleInput('displayName')}
value={displayName || ''}
desc={t("Name of the attribute that contains the name")}
id="displayName"
name="displayName"
autoComplete="displayName"
/>
<LdapTextfield
label={t('LDAP Default Quota')}
onChange={this.handleInput('defaultQuota')}
value={defaultQuota}
desc={t("ldap_defaultQuota_desc")}
id="defaultQuota"
name="defaultQuota"
autoComplete="defaultQuota"
/>
<LdapTextfield
label={t('LDAP Aliases')}
onChange={this.handleInput('aliases')}
value={aliases}
desc={t("LDAP alias mapping")}
id="aliasMapping"
name="aliasMapping"
autoComplete="aliasMapping"
/>
</FormControl>
</Paper>
<Paper elevation={1} className={classes.paper}>
<Typography variant="h6" className={classes.category}>{t('LDAP Search Attributes')}</Typography>
<Typography variant="caption" className={classes.category}>
{t('ldap_attribute_desc')}
</Typography>
<Autocomplete
value={searchAttributes || []}
onChange={this.handleAutocomplete('searchAttributes')}
className={classes.textfield}
options={adminConfig.searchAttributes}
multiple
renderInput={(params) => (
<TextField
{...params}
/>
)}
/>
</Paper>
<Paper elevation={1} className={classes.paper}>
<Typography variant="h6" className={classes.category}>
{t('Custom Mapping')}
<Tooltip
className={classes.tooltip}
title={t('ldap_mapping_desc')}
placement="top"
>
<IconButton size="small">
<Help fontSize="small"/>
</IconButton>
</Tooltip>
</Typography>
{attributes.map((mapping, idx) =>
<Grid className={classes.attribute} container alignItems="center" key={idx}>
<LdapTextfield
label={t('Name')}
flex
onChange={this.handleAttributeInput('key', idx)}
value={mapping.key || ''}
desc={t("LDAP attribute to map")}
/>
<Typography className={classes.spacer}>:</Typography>
<LdapTextfield
label={t('Value')}
flex
onChange={this.handleAttributeInput('value', idx)}
value={mapping.value || ''}
desc={t("Name of the user property to map to")}
/>
<IconButton
onClick={this.removeRow(idx)}
className={classes.removeButton}
size="large">
<Delete color="error" />
</IconButton>
</Grid>
)}
<Grid container justifyContent="center" className={classes.addButton}>
<Button size="small" onClick={this.handleNewRow}>
<Add color="primary" />
</Button>
</Grid>
</Paper>
<div className={classes.bottomRow}>
<Button
variant="contained"
color="secondary"
onClick={this.handleDelete}
className={classes.deleteButton}
>
{t('Delete config')}
</Button>
<Button
variant="contained"
color="primary"
type="submit"
onClick={this.handleSave}
disabled={!writable}
>
{t('Save')}
</Button>
<FormControlLabel
className={classes.attribute}
control={
<Checkbox
checked={force || false}
onChange={this.handleCheckbox('force')}
name="disabled"
color="primary"
/>
}
label={<span>
{t('Force config save')}
<Tooltip
className={classes.tooltip}
title={t("Save LDAP configuration even if it's faulty")}
placement="top"
>
<IconButton size="small">
<Help fontSize="small"/>
</IconButton>
</Tooltip>
</span>}
/>
</div>
</form>
<DeleteConfig
open={deleting}
onSuccess={this.handleDeleteSuccess}
onError={this.handleDeleteError}
onClose={this.handleDeleteClose}
/>
<TaskCreated
message={taskMessage}
taskID={taskID}
onClose={this.handleTaskClose}
/>
<Feedback
snackbar={snackbar}
onClose={() => this.setState({ snackbar: '' })}
/>
</div>
);
}