@material-ui/core#LinearProgress JavaScript Examples
The following examples show how to use
@material-ui/core#LinearProgress.
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: SpecDetailNew.js From akashlytics-deploy with GNU General Public License v3.0 | 6 votes |
export function SpecDetailNew({ cpuAmount, memoryAmount, storageAmount, isActive }) {
const classes = useStyles();
return (
<Paper className={classes.root} elevation={isActive ? 2 : 0}>
<div className={clsx(classes.serverTop, classes.defaultColor, { [classes.activeColor]: isActive })}>
{isActive && (
<>
<LinearProgress className={clsx(classes.progressActive, classes.activeColor)} />
<PowerSettingsNewIcon className={clsx(classes.statusIcon, classes.activeIcon)} />
</>
)}
{!isActive && <BlockIcon className={classes.statusIcon} />}
<Box className={clsx(classes.serverDot, { [classes.serverDotActive]: isActive })} left="6px" />
<Box className={clsx(classes.serverDot, { [classes.serverDotActive]: isActive })} left="12px" />
<Box className={clsx(classes.serverDot, { [classes.serverDotActive]: isActive })} left="18px" />
</div>
<div className={clsx(classes.serverRow, classes.defaultColor, { [classes.activeColor]: isActive })}>
<SpeedIcon className={clsx(classes.specIcon, classes.defaultColor, { [classes.activeColor]: isActive, [classes.activeIcon]: isActive })} />
<div className={clsx(classes.specDetail, classes.defaultColor, { [classes.activeColor]: isActive })}>{cpuAmount + " vcpu"}</div>
</div>
<div className={clsx(classes.serverRow, classes.defaultColor, { [classes.activeColor]: isActive })}>
<MemoryIcon className={clsx(classes.specIcon, classes.defaultColor, { [classes.activeColor]: isActive, [classes.activeIcon]: isActive })} />
<div className={clsx(classes.specDetail, classes.defaultColor, { [classes.activeColor]: isActive })}>{humanFileSize(memoryAmount)}</div>
</div>
<div className={clsx(classes.serverRow, classes.defaultColor, { [classes.activeColor]: isActive })}>
<StorageIcon className={clsx(classes.specIcon, classes.defaultColor, { [classes.activeColor]: isActive, [classes.activeIcon]: isActive })} />
<div className={clsx(classes.specDetail, classes.defaultColor, { [classes.activeColor]: isActive })}>{humanFileSize(storageAmount)}</div>
</div>
<Box width="100%" display="flex" borderBottom="4px solid" className={clsx(classes.defaultColor, { [classes.activeColor]: isActive })} />
</Paper>
);
}
Example #2
Source File: Loader.js From grants-fe with MIT License | 6 votes |
Loader = () => {
const classes = useStyles();
return (
<div className={classes.container}>
<h4 className={classes.h4}>Loading...</h4>
<LinearProgress />
</div>
)
}
Example #3
Source File: LogoutPage.js From app with MIT License | 6 votes |
function LogoutPage() {
const classes = useStyles();
const auth = useAuth();
const history = useHistory();
useEffect(() => {
auth.signOut().then(() => {
history.replace('/');
});
}, [auth, history]);
return (
<Container maxWidth="md">
<Helmet>
<title>Logging Out</title>
</Helmet>
<Paper className={classes.paper}>
<Typography
variant="h5"
align="center"
color="textPrimary"
gutterBottom>
Logging out...
</Typography>
<LinearProgress />
</Paper>
</Container>
);
}
Example #4
Source File: FileUploadProgress.js From Edlib with GNU General Public License v3.0 | 6 votes |
FileUploadProgress = ({
total = 0,
inProgress,
show,
done,
}) => {
const progress = total > 0 ? (done / total) * 100 : 0;
return (
<Dialog
open={show}
>
<DialogTitle>
<FormattedMessage id="FILEUPLOADPROGRESS.GETTING_MEDIA_FILES_READY"/>
</DialogTitle>
<DialogContent>
<LinearProgress variant="determinate" value={progress} valueBuffer={(done + inProgress)} />
<Typography variant="body2" color="textSecondary">{`${done}`} / {`${total}`}</Typography>
</DialogContent>
</Dialog>
);
}
Example #5
Source File: LinearProgress.js From jobtriage with MIT License | 6 votes |
LinearProgressWrapper = props => {
const classes = useStyles();
const { color } = props;
return (
<div>
<LinearProgress color={color || 'primary'} className={classes.progress} />
</div>
);
}
Example #6
Source File: loading-screen.js From react-redux-jsonplaceholder with MIT License | 6 votes |
LoadingScreen = () => {
const classes = useStyles();
useEffect(() => {
NProgress.start();
return () => {
NProgress.done();
};
}, []);
return (
<div className={classes.root}>
<Box width={360}>
<LinearProgress />
</Box>
</div>
);
}
Example #7
Source File: withLoading.js From resilience-app with GNU General Public License v3.0 | 6 votes |
withLoading = (BaseComponent) => {
/**
* Return an enhanced component that show loading abilities
* @param {bool} isEmpty- if there is no data.
* @param {bool} isLoaded - if isLoaded -> we have load in data
* @param {string} isEmptyText- if isEmpty -> we will display why with isEmptyText
* @param {Component} LoadingComponent- In case we want to use other loading component than CircularProgress
* @return {Component} the enhanced component
*/
const EnhancedComponent = ({
children,
isEmpty,
isEmptyText,
isLoaded,
LoadingComponent,
...rest
}) => (
<BaseComponent {...rest}>
{!isLoaded ? <LoadingComponent /> : isEmpty ? isEmptyText : children}
</BaseComponent>
);
EnhancedComponent.defaultProps = {
isEmpty: false,
isLoaded: true,
LoadingComponent: LinearProgress,
};
EnhancedComponent.propTypes = {
children: PropTypes.node,
isEmpty: PropTypes.bool,
isEmptyText: PropTypes.string,
isLoaded: PropTypes.bool,
LoadingComponent: PropTypes.elementType,
};
return EnhancedComponent;
}
Example #8
Source File: progressBar.js From Queen with MIT License | 6 votes |
CustomProgressBar = withStyles(theme => ({
root: {
height: 10,
borderRadius: 5,
},
colorPrimary: {
backgroundColor: theme.palette.grey[theme.palette.type === 'light' ? 200 : 700],
},
bar: {
borderRadius: 5,
backgroundColor: '#47b52c',
},
}))(LinearProgress)
Example #9
Source File: VisualizerContainer.js From Otto with MIT License | 6 votes |
BorderLinearProgress = withStyles((theme) => ({
root: {
height: 10,
borderRadius: 5,
margin: "0px 28px 0px 28px",
},
colorPrimary: {
backgroundColor:
theme.palette.grey[theme.palette.type === "light" ? 200 : 700],
},
bar: {
borderRadius: 5,
backgroundImage: "linear-gradient(to right, #00c3cc, #7c2ae8)",
},
}))(LinearProgress)
Example #10
Source File: loader.jsx From crv.finance with MIT License | 5 votes |
render() {
return (
<div style={{ position: 'absolute', left: '0px', right: '0px', top: '0px'}}>
<LinearProgress />
</div>
)
}
Example #11
Source File: App.js From Gameplayer with MIT License | 5 votes |
render() {
const { withImage, withName, orderBy, showHelpDialog } = this.state
return (
<ApolloProvider client={client}>
<div className="App">
<Grid container direction="column">
<Header onHelp={this.toggleHelpDialog} />
<Filter
orderBy={orderBy}
withImage={withImage}
withName={withName}
onOrderBy={field => this.setState(state => ({ ...state, orderBy: field }))}
onToggleWithImage={() =>
this.setState(state => ({ ...state, withImage: !state.withImage }))
}
onToggleWithName={() =>
this.setState(state => ({ ...state, withName: !state.withName }))
}
/>
<Grid item>
<Grid container>
<Query
query={GRAVATARS_QUERY}
variables={{
where: {
...(withImage ? { imageUrl_starts_with: 'http' } : {}),
...(withName ? { displayName_not: '' } : {}),
},
orderBy: orderBy,
}}
>
{({ data, error, loading }) => {
return loading ? (
<LinearProgress variant="query" style={{ width: '100%' }} />
) : error ? (
<Error error={error} />
) : (
<Gravatars gravatars={data.gravatars} />
)
}}
</Query>
</Grid>
</Grid>
</Grid>
<Dialog
fullScreen={false}
open={showHelpDialog}
onClose={this.toggleHelpDialog}
aria-labelledby="help-dialog"
>
<DialogTitle id="help-dialog">{'Show Quick Guide?'}</DialogTitle>
<DialogContent>
<DialogContentText>
We have prepared a quick guide for you to get started with The Graph at
this hackathon. Shall we take you there now?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.toggleHelpDialog} color="primary">
Nah, I'm good
</Button>
<Button onClick={this.gotoQuickStartGuide} color="primary" autoFocus>
Yes, pease
</Button>
</DialogActions>
</Dialog>
</div>
</ApolloProvider>
)
}
Example #12
Source File: ImageLayout.js From Edlib with GNU General Public License v3.0 | 5 votes |
function ImageLayout(props) {
const {
onDrop,
previewImage,
enlargeImage = false,
onClick,
anchorElement,
onRemoveImage,
uploadProgress,
readOnly = false,
uploading,
} = props;
let icon = null;
if ( previewImage === null) {
icon = <ImageIcon />;
if ( readOnly === false ) {
icon = (
<DropZone
onDropAccepted={onDrop}
multiple={false}
className="imageDropzone"
disabled={readOnly}
>
{icon}
</DropZone>);
}
}
return (
<div
className={'imageContainer ' + (previewImage !== null ? 'withImage' : null)}
>
{icon}
{previewImage !== null && (
<div>
{uploading === true && uploadProgress < 100 && (
<LinearProgress
variant="determinate"
value={uploadProgress}
className="uploadProgress"
/>
)}
<img src={previewImage} onClick={onClick} alt="assigment_image" />
<Popover
open={enlargeImage}
onClose={onClick}
anchorEl={anchorElement}
anchorOrigin={{
vertical: 'center',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'center',
horizontal: 'center',
}}
>
<div className="popoverContainer">
<img src={previewImage} />
{readOnly === false && (
<div onClick={onRemoveImage}>
<DeleteIcon />
</div>
)}
</div>
</Popover>
</div>
)}
</div>
);
}
Example #13
Source File: Job.jsx From Edlib with GNU General Public License v3.0 | 5 votes |
Job = ({
start,
status,
name,
onStop,
showKillButton,
showResumeButton,
showInput,
onResume,
data,
setData,
}) => {
return (
<>
<h2>{name}</h2>
{showInput && (
<Box>
<TextareaAutosize
value={data}
onChange={(e) => setData(e.target.value)}
/>
</Box>
)}
{status.loading && (
<>
<div>
<CircularProgress />
</div>
<div>
<LinearProgress
variant="determinate"
value={status.percentDone || 0}
/>
</div>
<div>{status.message}</div>
{!status.killingStarted && showKillButton && (
<div>
<Button variant="contained" onClick={onStop}>
Stop
</Button>
</div>
)}
</>
)}
{status.done && <Alert severity="success">{status.message}</Alert>}
{status.error && <Alert severity="error">{status.message}</Alert>}
{!status.loading && (
<Button
onClick={start}
disabled={showInput && data === ''}
variant="contained"
color="primary"
>
Start
</Button>
)}
{!status.loading &&
!status.done &&
!status.error &&
showResumeButton && <Button onClick={onResume}>Resume</Button>}
</>
);
}
Example #14
Source File: OpenFolder.js From algo-book with GNU General Public License v3.0 | 5 votes |
OpenFolder = () => {
useEffect(() => {
async function getFiles() {
const { data } = await api.get(
`/local/path/${
query.get("topic") === "algo" ? "algorithms" : "ds"
}/${query.get("folder")}`
);
setList(data);
}
getFiles();
}, []);
let query = useQuery();
const [list, setList] = useState([]);
const [file, setFile] = useState({
type: "",
value: "",
});
const [loading, setLoading] = useState(false);
const handler = async (file) => {
// console.log(file);
setLoading(true);
const { data } = await api.get(
`/local/path/${
query.get("topic") === "algo" ? "algorithms" : "ds"
}/${query.get("folder")}/${file}`
);
// console.log(data);
setLoading(false);
const checker = /(?:\.([^.]+))?$/;
const ext =
checker.exec(file)[1] && checker.exec(file)[1].trim().toLowerCase();
setFile({
type: ext,
value: data,
});
};
const renderViewer = () => {
if (loading) return <LinearProgress />;
else {
if (file.type == "md") return <FIleViewer file={file} />;
else return <CodeView file={file} />;
}
};
return (
<>
<BreadCrumbs
crumbs={[
{ name: "HOME", link: "/" },
{
name: query.get("topic").toUpperCase(),
link: `/${query.get("topic")}`,
},
]}
active={query.get("topic") && query.get("folder").toUpperCase()}
/>
<Grid container>
{list.map((l, index) => (
<File name={l.name} key={index} handler={handler} />
))}
</Grid>
<br />
{renderViewer()}
</>
);
}
Example #15
Source File: Dialog.jsx From Turnip-Calculator with MIT License | 5 votes |
ShareDialog = ({ open, filters, onClose, ...props }) => {
const { t } = useTranslation();
const [loading, setLoadingState] = useState(true);
const inputRef = useRef();
const location = window.location.toString();
const handleCopy = useCallback(() => {
if (inputRef.current) {
inputRef.current.select();
inputRef.current.setSelectionRange(0, location.length, "backward");
document.execCommand("copy");
}
}, [location]);
let result = useCalculation({
filters: open ? filters : null,
immediate: true,
});
useEffect(() => {
if (open) {
setLoadingState(true);
}
}, [open]);
const actions = (
<>
<Typography>{t("shareClipboard")}</Typography>
<Box mx={{ xs: "0", sm: "1" }} width="50%">
<TextField
id="url"
type="text"
fullWidth
inputRef={inputRef}
onTouchEnd={handleCopy}
onClick={handleCopy}
onFocus={handleCopy}
value={location}
/>
</Box>
<Button onClick={handleCopy}>{t("copyButton")}</Button>
<Button onClick={onClose}>{t("closeButton")}</Button>
</>
);
const description = t("shareDialogV2");
return (
<CustomDialog
open={open}
maxWidth="md"
fullWidth
actions={actions}
description={description}
{...props}
>
{open && (
<Box mx={[-2.5, 0]}>
<Box
borderRadius={16}
bgcolor="bkgs.chart"
overflow="hidden"
maxWidth="600px"
maxHeight="315px"
>
{loading && <LinearProgress />}
<img
style={{ width: "100%" }}
onLoad={() => setLoadingState(false)}
src={`https://ac-turnip.com/p-${toHash(filters)}.png`}
alt=""
/>
</Box>
<Chart {...result} />
<Table {...result} expanded />
</Box>
)}
</CustomDialog>
);
}
Example #16
Source File: TasksProgress.js From EMP with MIT License | 5 votes |
TasksProgress = () => {
const classes = useStyles();
return (
<Card>
<CardContent>
<Grid
container
justify="space-between"
spacing={3}
>
<Grid item>
<Typography
color="textSecondary"
gutterBottom
variant="h6"
>
TASKS PROGRESS
</Typography>
<Typography
color="textPrimary"
variant="h3"
>
75.5%
</Typography>
</Grid>
<Grid item>
<Avatar className={classes.avatar}>
<InsertChartIcon />
</Avatar>
</Grid>
</Grid>
<Box mt={3}>
<LinearProgress
value={75.5}
variant="determinate"
/>
</Box>
</CardContent>
</Card>
);
}
Example #17
Source File: App.jsx From resilience-app with GNU General Public License v3.0 | 5 votes |
function App() {
const [org, setOrg] = useState();
useEffect(() => {
Organization.init(ORGANIZATION_ID)
.then((org) => setOrg(org))
.catch((error) => {
console.error(error);
setOrg(null);
});
}, []);
if (org === undefined) {
return <LinearProgress />;
}
return (
<>
<ThemeProvider theme={theme}>
<CssBaseline />
<Router>
<div className="App">
<OrganizationContext.Provider value={org}>
<Snackbar.Context.SnackbarProvider>
{org === null && <Redirect to={routes.organizer.signup} />}
<Switch>
<AppRoute exact path={routes.home} component={Home} />
<AppRoute path={routes.about} component={AboutPage} />
<AppRoute path={routes.login} component={Login} />
<AppRoute path={routes.logout} component={Logout} />
<AppRoute path={routes.organizer.signup} component={OrganizerSignupPage} />
<AppRoute path={routes.volunteer.status} component={Status} />
<AppRoute path={routes.user.signup} component={Signup} />
<AppRoute path={routes.request.start} component={RequestPage} />
<AppRoute path={routes.donate} component={DonationPage} />
<AppRoute path={routes.missions.createNew} component={MissionCreate} />
<AppRoute path={routes.missions.completed} component={MissionsCompleted} />
<AppRoute path={routes.missions.delivered} component={MissionsDelivered} />
<AppRoute path={routes.missions.details} component={MissionDetails} />
<AppRoute path={routes.user.profile} component={UserProfile} />
{/* ⬇ BASE routes below ⬇ */}
<AppRoute path={routes.organizer.dashboard.home} component={Dashboard} />
<AppRoute path={routes.recipient.dashboard.home} component={RecipientDashboard} />
<AppRoute path={routes.volunteer.dashboard.home} component={VolunteerHome} />
<AppRoute path={routes.unauthorized}>
<ErrorLanding errorCode={401} />
</AppRoute>
<AppRoute path={routes.pageNotFound}>
<ErrorLanding errorCode={404} />
</AppRoute>
<AppRoute path="*">
<ErrorLanding errorCode={404} />
</AppRoute>
</Switch>
<Snackbar.Context.SnackbarConsumer>
{(value) => {
return <Snackbar handleClose={value.closeSnackbar} {...value.snackbar} />;
}}
</Snackbar.Context.SnackbarConsumer>
</Snackbar.Context.SnackbarProvider>
</OrganizationContext.Provider>
</div>
</Router>
</ThemeProvider>
</>
);
}
Example #18
Source File: AccountProfile.js From git-insights with MIT License | 5 votes |
AccountProfile = props => {
const { className, ...rest } = props;
const classes = useStyles();
const user = {
name: 'Shen Zhi',
city: 'Los Angeles',
country: 'USA',
timezone: 'GTM-7',
avatar: '/images/avatars/avatar_11.png'
};
return (
<Card
{...rest}
className={clsx(classes.root, className)}
>
<CardContent>
<div className={classes.details}>
<div>
<Typography
gutterBottom
variant="h2"
>
John Doe
</Typography>
<Typography
className={classes.locationText}
color="textSecondary"
variant="body1"
>
{user.city}, {user.country}
</Typography>
<Typography
className={classes.dateText}
color="textSecondary"
variant="body1"
>
{moment().format('hh:mm A')} ({user.timezone})
</Typography>
</div>
<Avatar
className={classes.avatar}
src={user.avatar}
/>
</div>
<div className={classes.progress}>
<Typography variant="body1">Profile Completeness: 70%</Typography>
<LinearProgress
value={70}
variant="determinate"
/>
</div>
</CardContent>
<Divider />
<CardActions>
<Button
className={classes.uploadButton}
color="primary"
variant="text"
>
Upload picture
</Button>
<Button variant="text">Remove picture</Button>
</CardActions>
</Card>
);
}
Example #19
Source File: index.js From yi-note with GNU General Public License v3.0 | 5 votes |
StyledProgress = styled(LinearProgress)`
width: 100%;
`
Example #20
Source File: LinearLoadingSkeleton.js From akashlytics-deploy with GNU General Public License v3.0 | 5 votes |
export function LinearLoadingSkeleton({ isLoading }) {
const classes = useStyles();
return <>{isLoading ? <LinearProgress /> : <Box className={classes.loadingSkeleton} />}</>;
}
Example #21
Source File: Forgot.js From Athavani with MIT License | 5 votes |
function Forgot(props) {
useEffect(() => {
props.setLogout(false);
return () => {
props.setLogout(true);
}
},[props]);
const history = useHistory();
const [email, setEmail] = useState("");
const [isLoading, setIsLoading] = useState(false);
async function submitHandle() {
if(validator.empty(email)) {
return toast.error("Email Field is Empty!");
}
if(!validator.email(email)) {
return toast.error("Invalid Email!");
}
setIsLoading(true);
try {
const {data} = await api.forgot({email});
// console.log(data);
toast.success(data.message);
setIsLoading(false);
history.push('/signin');
} catch(error) {
if(error.response) {
toast.error(error.response.data.message);
} else if(error.request) {
toast.error("Server is not Responding!");
// console.log(error.request);
} else {
toast.error(error.message);
// console.log(error.message);
}
setIsLoading(false);
}
}
if (localStorage.getItem('token')) {
return <Redirect to="/" />
}
return (
<div className={styles.Forgot}>
<div className={styles.title}>
Forgot Password?
</div>
<div className={styles.body}>
<input type="text" name="email" placeholder="Enter email" className={styles.email}
value={email} onChange={(e) => setEmail(e.target.value)}
/>
<button className={styles.reset}
onClick={submitHandle}
disabled={isLoading}
style={{cursor: `${isLoading ? "not-allowed" : "pointer"}`}}
>
Mail Reset Link
{
isLoading &&
<LinearProgress color="secondary" />
}
</button>
<Link to='/signin' className={styles.back}>
Back
</Link>
</div>
</div>
)
}
Example #22
Source File: FormikStepper.js From dscbppimt-official-website with MIT License | 5 votes |
export function FormikStepper({ children, ...props}) {
console.log(props.renderFormikForm)
const [step, setStep] = useState(0);
const [completed, setCompleted] = useState(false);
function isLastStep() {
return step === props.labels.length - 2;
}
return (
<Formik
{...props}
validationSchema={props.validationSchemas[step]}
onSubmit={async (values, helpers) => {
if (isLastStep()) {
helpers.setSubmitting(true);
try{
await props.onSubmit(values, helpers);
}catch(e){
console.log(e)
}
helpers.setSubmitting(false);
setStep((s) => s + 1);
setCompleted(true);
} else {
setStep((s) => s + 1);
}
}}
>
{({ values, isSubmitting, errors, touched, status }) => (
<Form autoComplete="off" noValidate>
{ isSubmitting && <LinearProgress />}
<Stepper alternativeLabel activeStep={step}>
{props.labels.map((index) => (
<Step key={index} completed={step > index || completed}>
<StepLabel>{index}</StepLabel>
</Step>
))}
</Stepper>
{ props.renderFormikForm(step, values, errors, touched, status) }
{ step <= props.labels.length - 2 &&
<Grid container spacing={2} justifyContent="flex-end" style={{marginTop : '2em'}}>
{step > 0 ? (
<Grid item>
<Button
style={{width : '110px'}}
disabled={isSubmitting}
variant="contained"
color="primary"
onClick={() => setStep((s) => s - 1)}
>
Back
</Button>
</Grid>
) : null}
<Grid item>
<Button
style={{width : '110px'}}
disabled={isSubmitting}
variant="contained"
color="primary"
type="submit"
>
{isSubmitting ? 'Submitting' : step === props.labels.length - 2 ? 'Submit' : 'Next'}
</Button>
</Grid>
</Grid>
}
</Form>
)}
</Formik>
);
}
Example #23
Source File: Budget.js From Simplify-Testing-with-React-Testing-Library with MIT License | 5 votes |
Budget = ({
classes,
categoryName,
totalBudget,
setAmtSpent,
amtSpent,
deleteBudget,
id,
}) => {
const addExpense = () => {
return amtSpent + 5 <= totalBudget ? setAmtSpent(id, 'add') : null;
};
const subtractExpense = () => {
return amtSpent - 5 >= 0 ? setAmtSpent(id, 'subtract') : null;
};
const handleDeleteBudget = () => deleteBudget(id, totalBudget);
// This method transforms a value in any range to a scale of 0 - 100:
const normalize = (value) => ((value - 0) * 100) / (totalBudget - 0);
return (
<ListItem style={{ paddingRight: 0, paddingLeft: 0 }} divider>
<Grid alignItems='center' container>
<Grid item xs={1}>
<DeleteForeverTwoToneIcon
onClick={handleDeleteBudget}
className={classes.icon}
/>
</Grid>
<Grid item xs={3}>
<ListItemText
classes={{ primary: classes.primary }}
primary={categoryName}
/>
</Grid>
<Grid style={{ textAlign: 'right' }} item xs={8}>
<Typography classes={{ root: classes.root }} variant='title'>
<IconButton aria-label='ArrowLeft' onClick={subtractExpense}>
<ArrowLeft />
</IconButton>
${amtSpent}
<IconButton aria-label='ArrowRight' onClick={addExpense}>
<ArrowRight />
</IconButton>
<span className={classes.span}>of</span>${totalBudget}
</Typography>
</Grid>
<Grid item xs={12}>
<LinearProgress
style={{ width: '100%', height: '10px', background: 'green' }}
color='secondary'
variant='determinate'
value={normalize(amtSpent)}
/>
</Grid>
</Grid>
</ListItem>
);
}
Example #24
Source File: Budget.js From Simplify-Testing-with-React-Testing-Library with MIT License | 5 votes |
Budget = ({
classes,
categoryName,
totalBudget,
setAmtSpent,
amtSpent,
deleteBudget,
id,
}) => {
const addExpense = () => {
return amtSpent + 5 <= totalBudget ? setAmtSpent(id, 'add') : null;
};
const subtractExpense = () => {
return amtSpent - 5 >= 0 ? setAmtSpent(id, 'subtract') : null;
};
const handleDeleteBudget = () => deleteBudget(id, totalBudget);
// This method transforms a value in any range to a scale of 0 - 100:
const normalize = (value) => ((value - 0) * 100) / (totalBudget - 0);
return (
<ListItem style={{ paddingRight: 0, paddingLeft: 0 }} divider>
<Grid alignItems='center' container>
<Grid item xs={1}>
<DeleteForeverTwoToneIcon
aria-label='trash can'
onClick={handleDeleteBudget}
className={classes.icon}
/>
</Grid>
<Grid item xs={3}>
<ListItemText
classes={{ primary: classes.primary }}
primary={categoryName}
/>
</Grid>
<Grid style={{ textAlign: 'right' }} item xs={8}>
<Typography classes={{ root: classes.root }} variant='h6'>
<IconButton aria-label='ArrowLeft' onClick={subtractExpense}>
<ArrowLeft />
</IconButton>
${amtSpent}
<IconButton aria-label='ArrowRight' onClick={addExpense}>
<ArrowRight />
</IconButton>
<span className={classes.span}>of</span>${totalBudget}
</Typography>
</Grid>
<Grid item xs={12}>
<LinearProgress
style={{ width: '100%', height: '10px', background: 'green' }}
color='secondary'
variant='determinate'
value={normalize(amtSpent)}
/>
</Grid>
</Grid>
</ListItem>
);
}
Example #25
Source File: viewer.js From healthcare-api-dicom-viewer with Apache License 2.0 | 5 votes |
/**
* Renders the component
* @return {ReactComponent} <Viewer/>
*/
render() {
return (
<Box p={2} display="flex" flexWrap="wrap">
<Box mr={2}>
<div id="cornerstone-div"
ref={(input) => {
this.canvasElement = input;
}}
style={{
width: 500,
height: 500,
background: 'black',
}}
>
<canvas className="cornerstone-canvas"></canvas>
</div>
<LinearProgress variant="buffer"
value={this.state.renderedImagesProgress}
valueBuffer={this.state.readyImagesProgress} /><br/>
<TextField
label="Max Simultaneous Requests"
style={{width: 250}}
defaultValue={this.state.maxSimultaneousRequests}
onChange={(e) => {
this.setState({maxSimultaneousRequests: Number(e.target.value)});
}} /><br/><br/>
<Button
variant="contained"
color="primary"
disabled={this.state.isDisplaying}
onClick={() => this.getInstances()}>
Start
</Button>
</Box>
<Box>
<Typography variant="h5">
Frames Loaded: {this.state.numReadyImages}
</Typography>
<Typography variant="h5">
Frames Displayed: {this.state.numRenderedImages}
</Typography>
<Typography variant="h5">
Total Time: {(this.state.totalTimer / 1000).toFixed(2)}s
</Typography>
<Typography variant="h5">
Time to First Image: {
(this.state.timeToFirstImage / 1000).toFixed(2)
}s
</Typography>
<Typography variant="h5">
Average FPS: {(this.state.numRenderedImages /
(this.state.renderTimer / 1000)).toFixed(2)}
</Typography>
<Typography variant="body1">
Use your browser's developer tools to see bandwidth usage.
</Typography>
</Box>
</Box>
);
}
Example #26
Source File: CaptureMatchingView.js From treetracker-admin-client with GNU Affero General Public License v3.0 | 4 votes |
function CaptureMatchingView() {
const initialFilter = {
startDate: '',
endDate: '',
stakeholderUUID: null,
};
const classes = useStyle();
const appContext = useContext(AppContext);
const matchingToolContext = useContext(MatchingToolContext);
const [captureImage, setCaptureImage] = useState(null);
const [currentPage, setCurrentPage] = useState(1);
const [loading, setLoading] = useState(false);
const [candidateImgData, setCandidateImgData] = useState([]);
const [noOfPages, setNoOfPages] = useState(null); //for pagination
const [imgCount, setImgCount] = useState(null); //for header icon
const [treesCount, setTreesCount] = useState(0);
const [startDate, setStartDate] = useState('');
const [endDate, setEndDate] = useState('');
const [organizationId, setOrganizationId] = useState(null);
const [stakeholderUUID, setStakeholderUUID] = useState(null);
const [filter, setFilter] = useState(initialFilter);
const [growerAccount, setGrowerAccount] = useState({});
// To get total tree count on candidate capture image icon
// const treesCount = candidateImgData.length;
const [screenWidth, setScreenWidth] = useState(window.innerWidth);
const resizeWindow = useCallback(() => {
setScreenWidth(window.innerWidth);
}, []);
useEffect(() => {
window.addEventListener('resize', resizeWindow);
return () => {
window.removeEventListener('resize', resizeWindow);
};
}, [resizeWindow]);
async function fetchCandidateTrees(captureId, abortController) {
const data = await api.fetchCandidateTrees(captureId, abortController);
if (data) {
setCandidateImgData(data.matches);
setTreesCount(data.matches.length);
setLoading(false);
}
}
async function clean() {
setCandidateImgData([]);
setTreesCount(0);
setCaptureImage(null);
setTreesCount(0);
setImgCount(null);
// setCurrentPage(1);
// setNoOfPages(null);
}
async function fetchCaptures(currentPage, abortController) {
clean();
setLoading(true);
// log.debug('fetchCaptures filter', filter);
const filterParameters = {
captured_at_start_date: filter.startDate,
captured_at_end_date: filter.endDate,
'organization_ids[]': filter.stakeholderUUID && [filter.stakeholderUUID],
};
// log.debug('fetchCaptures filterParameters', filterParameters);
const data = await api.fetchCapturesToMatch(
currentPage,
abortController,
filterParameters
);
// log.debug('fetchCptures data', currentPage, data);
if (data?.captures?.length > 0) {
setCaptureImage(data.captures[0]);
setNoOfPages(data.count);
setImgCount(data.count);
} else {
setLoading(false);
setNoOfPages(0);
setImgCount(0);
log.warn('no data:', data);
}
}
async function loadGrowerInfo() {
if (captureImage) {
// log.warn('loadGrowerInfo...');
if (captureImage.grower_account_id) {
const data = await api.getGrowerAccountById(
captureImage.grower_account_id
);
setGrowerAccount(data);
} else {
log.warn('No grower account id found');
}
}
}
useEffect(() => {
document.title = `Capture Matching - ${documentTitle}`;
}, []);
useEffect(() => {
const abortController = new AbortController();
fetchCaptures(currentPage, abortController);
return () => abortController.abort();
}, [currentPage, filter]);
useEffect(() => {
if (currentPage <= 0 || currentPage > noOfPages) {
setCurrentPage(1);
}
}, [noOfPages, currentPage]);
useEffect(() => {
const abortController = new AbortController();
if (captureImage) {
const captureId = captureImage.id;
fetchCandidateTrees(captureId, abortController);
// load grower info
loadGrowerInfo();
}
return () => abortController.abort();
}, [captureImage]);
// Capture Image Pagination function
const handleChange = (e, value) => {
setCurrentPage(value);
};
// Same Tree Capture function
const sameTreeHandler = async (treeId) => {
const captureId = captureImage.id;
// log.debug('captureId treeId', captureId, treeId);
await fetch(`${CAPTURE_API}/captures/${captureId}`, {
method: 'PATCH',
headers: {
'content-type': 'application/json',
// Authorization: session.token,
},
body: JSON.stringify({
tree_id: treeId,
}),
});
// make sure new captures are loaded by updating page or if it's the first page reloading directly
if (currentPage === 1) {
fetchCaptures(currentPage);
} else {
setCurrentPage((page) => page + 1);
}
};
// Skip button
const handleSkip = () => {
setCurrentPage((page) => page + 1);
};
function handleStartDateChange(e) {
setStartDate(e.target.value);
}
function handleEndDateChange(e) {
setEndDate(e.target.value);
}
function handleFilterSubmit() {
log.debug('filter submit -----> ', organizationId, stakeholderUUID);
setFilter({
startDate,
endDate,
stakeholderUUID,
});
matchingToolContext.handleFilterToggle();
}
function handleFilterReset() {
setFilter(initialFilter);
matchingToolContext.handleFilterToggle();
}
// components
function currentCaptureNumber(text, icon, count, tooltip) {
return (
<Box>
<Paper elevation={3} className={classes.currentNumberBox1}>
<Box className={classes.currentNumberBox2}>
<Box>
<Box className={classes.currentNumberBox3}>{icon}</Box>
</Box>
<Box>
<Box className={classes.currentNumberBox4}>
<Typography
variant="h6"
className={`${classes.currentNumberText} ${classes.currentNumberBold}`}
>
{count}
</Typography>
{tooltip && (
<Tooltip placement="right-start" title={tooltip}>
<QuestionMarkIcon />
</Tooltip>
)}
</Box>
<Typography variant="body1" className={classes.currentNumberText}>
{text}
</Typography>
</Box>
</Box>
</Paper>
</Box>
);
}
const CaptureHeader = (
<Box>
<Box>
<Grid container className={classes.currentHeaderBox1}>
{currentCaptureNumber(
`Unmatched Capture${(imgCount !== 1 && 's') || ''}`,
<PhotoCameraOutlinedIcon
className={classes.currentHeaderCaptureImgIcon}
/>,
imgCount,
''
)}
<Box className={classes.currentHeaderBox2}>
<Box>
{(filter.startDate || filter.endDate) && (
<Chip
label={`${filter.startDate || 'Start Date'} - ${
filter.endDate || 'End Date'
}`}
className={classes.currentHeaderChip}
onDelete={() =>
setFilter({
...filter,
startDate: undefined,
endDate: undefined,
})
}
/>
)}
{filter.stakeholderUUID && (
<Chip
label={appContext.orgList.reduce((a, c) => {
return c.stakeholder_uuid === filter.stakeholderUUID
? c.name
: a;
}, '')}
className={classes.currentHeaderChip}
onDelete={() =>
setFilter({
...filter,
stakeholderUUID: undefined,
})
}
/>
)}
</Box>
<IconButton
onClick={matchingToolContext.handleFilterToggle}
className={classes.currentHeaderClass1}
>
<FilterListIcon htmlColor="#6E6E6E" />
</IconButton>
<Pagination
count={noOfPages}
page={currentPage}
onChange={handleChange}
defaultPage={1}
size="small"
siblingCount={0}
/>
</Box>
</Grid>
</Box>
</Box>
);
const CaptureImage = (
<Box className={classes.captureImageBox1}>
{CaptureHeader}
<Box height={16} />
{!loading && !captureImage && (
//captureImage && treesCount === 0 && (
<Box>
<Typography variant="h5">No capture found.</Typography>
</Box>
)}
{captureImage && (
<Paper
elevation={4}
key={`capture_${captureImage.id}`}
className={classes.captureImageContainerBox}
>
<Box className={classes.captureImageHeaderBox}>
<Box className={classes.box2}>
<Tooltip title={captureImage.id} interactive>
<Typography variant="h5">
Capture {(captureImage.id + '').substring(0, 10) + '...'}
</Typography>
</Tooltip>
<Box className={classes.captureImageCaptureInfo}>
<Box className={classes.captureImageBox3}>
<AccessTimeIcon />
<Typography variant="body1">
{getDateTimeStringLocale(captureImage.created_at)}
</Typography>
</Box>
<Box className={classes.captureImageBox3}>
<LocationOnOutlinedIcon
style={{
cursor: 'pointer',
}}
onClick={() => {
window.open(
`https://www.google.com/maps/search/?api=1&query=${captureImage.latitude},${captureImage.longitude}`
);
}}
/>
<Typography variant="body1">
<Country
lat={captureImage.latitude}
lon={captureImage.longitude}
/>
</Typography>
</Box>
</Box>
</Box>
{!loading && growerAccount && (
<Box className={classes.growerBox1}>
<Avatar
className={classes.growerAvatar}
src={growerAccount.image_url}
/>
<Box className={classes.growerBox2}>
<Typography variant="h5">
{growerAccount.first_name}
</Typography>
<Typography variant="body1">
Joined at{' '}
{moment(
growerAccount.first_registration_at ||
growerAccount.created_at
).format('MM/DD/YYYY')}
</Typography>
</Box>
</Box>
)}
{loading && <Box>...</Box>}
{!loading && !growerAccount && <Box>no grower info</Box>}
<Button
variant="text"
color="primary"
onClick={handleSkip}
className={classes.captureImageButton}
>
Skip
<SkipNextIcon />
</Button>
</Box>
<Box className={classes.captureImageImgBox}>
<OptimizedImage
key={captureImage.id}
className={classes.captureImageImgContainer}
src={captureImage.image_url}
alt={`Capture ${captureImage.id}`}
objectFit="contain"
width={screenWidth * 0.5}
fixed
alertWidth="100%"
alertHeight="30%"
alertPadding="2rem"
alertTitleSize="1.6rem"
alertTextSize="1rem"
/>
</Box>
</Paper>
)}
</Box>
);
return (
<>
<Grid
container
direction="column"
style={{
flexWrap: 'nowrap',
height: '100%',
overflow: 'hidden',
}}
>
<Navbar />
<Box className={classes.container}>
<Paper elevation={8} className={classes.box1}>
{CaptureImage}
</Paper>
<Box className={classes.box2}>
<Box className={classes.candidateIconBox}>
{currentCaptureNumber(
`Candidate Match${(treesCount !== 1 && 'es') || ''}`,
<NatureOutlinedIcon className={classes.candidateImgIcon} />,
treesCount,
`Any tree within 6m of the capture`
)}
</Box>
<Box height={14} />
{loading ? null : (
<CandidateImages
capture={captureImage}
candidateImgData={candidateImgData}
sameTreeHandler={sameTreeHandler}
/>
)}
{!loading &&
captureImage &&
candidateImgData &&
candidateImgData.length === 0 && (
//captureImage && treesCount === 0 && (
<Box className={classes.noCandidateBox}>
<Typography variant="h5">
No candidate match found, this capture might be a new tree
</Typography>
</Box>
)}
</Box>
</Box>
{loading && (
<AppBar position="fixed" style={{ zIndex: 10000 }}>
<LinearProgress color="primary" />
</AppBar>
)}
</Grid>
<Drawer
anchor="right"
BackdropProps={{ invisible: false }}
open={matchingToolContext.isFilterOpen}
>
<Grid
container
direction="column"
className={classes.customTableFilterForm}
>
{/* start filter header */}
<Grid item className={classes.customTableFilterHeader}>
<Grid container direction="row" justify="space-between">
<Grid item>
<Grid container direction="row">
<Typography variant="h6">Filter</Typography>
</Grid>
</Grid>
<CloseIcon
onClick={matchingToolContext.handleFilterToggle}
className={classes.customTableFilterCloseIcon}
/>
</Grid>
</Grid>
{/* end filter header */}
{/* start filter body */}
<>
<FormControl
variant="outlined"
className={classes.customTableFilterSelectFormControl}
>
<TextField
id="start_date"
name="start_date"
value={startDate}
label="Start Date"
type="date"
onChange={handleStartDateChange}
InputLabelProps={{
shrink: true,
}}
/>
</FormControl>
<FormControl
variant="outlined"
className={classes.customTableFilterSelectFormControl}
>
<TextField
id="end_date"
name="end_date"
label="End Date"
value={endDate}
onChange={handleEndDateChange}
type="date"
InputLabelProps={{
shrink: true,
}}
/>
</FormControl>
</>
<FormControl
variant="outlined"
className={classes.customTableFilterSelectFormControl}
>
<SelectOrg
orgId={organizationId || 'ORGANIZATION_NOT_SET'}
defaultOrgs={[
{
id: 'ORGANIZATION_NOT_SET',
stakeholder_uuid: null,
name: 'Not set',
value: null,
},
]}
handleSelection={(org) => {
setOrganizationId(org.id);
setStakeholderUUID(org.stakeholder_uuid);
}}
/>
</FormControl>
<Divider
style={{
margin: '50px 0 20px 0',
}}
/>
<Grid
container
direction="column"
className={classes.customTableFilterActions}
>
<Button
variant="contained"
color="primary"
disableElevation
className={classes.customTableFilterSubmitButton}
onClick={handleFilterSubmit}
>
APPLY
</Button>
<Button
color="primary"
variant="text"
onClick={handleFilterReset}
className={classes.customTableFilterResetButton}
>
RESET
</Button>
</Grid>
</Grid>
</Drawer>
</>
);
}
Example #27
Source File: SearchPage.js From app with MIT License | 4 votes |
function SearchPage() {
const classes = useStyles();
const { showError } = useNotifications();
// State
const [showAddressPicker, setShowAddressPicker] = useState(false);
const [nearbyRequests, setNearbyRequests] = useState(null);
const [currentLatLong, setCurrentLatLong] = useState({
latitude: DEFAULT_LATITUDE,
longitude: DEFAULT_LONGITUDE,
});
const [currentPlaceLabel, setCurrentPlaceLabel] = React.useState(
`Using default location: ${DEFAULT_LOCATION_NAME}`,
);
const [distance, setDistance] = useState(defaultDistance);
const [searching, setSearching] = useState(false);
const [onSearch$] = useState(() => new Subject());
// Data
const user = useUser();
const firestore = useFirestore();
const analytics = useAnalytics();
const { GeoPoint } = useFirestore;
async function searchForNearbyRequests({ searchLocation, searchDistance }) {
if (!searchLocation) return;
// Use lat/long set to state (either from profile or default)
const { latitude, longitude } = searchLocation;
setSearching(true);
analytics.logEvent('search', {
search_term: `latitude=${latitude}&longitude=${longitude}`,
});
try {
// Query for nearby requests
const geofirestore = new GeoFirestore(firestore);
const nearbyRequestsSnap = await geofirestore
.collection(REQUESTS_PUBLIC_COLLECTION)
.near({
center: new GeoPoint(latitude, longitude),
radius: KM_TO_MILES * searchDistance,
})
.where('status', '==', 1)
.limit(30)
.get();
const sortedByDistance = nearbyRequestsSnap.docs.sort(
(a, b) => a.distance - b.distance,
);
setNearbyRequests(
sortedByDistance.map((docSnap) => ({
...docSnap.data(),
id: docSnap.id,
distance: kmToMiles(docSnap.distance).toFixed(2),
})),
);
setSearching(false);
} catch (err) {
showError('Error searching for nearby requests');
// eslint-disable-next-line no-console
console.log(err);
setSearching(false);
}
}
// Setup an observable for debouncing the search requests.
useEffect(() => {
const subscription = onSearch$
.pipe(debounceTime(500))
.subscribe(searchForNearbyRequests);
return () => subscription.unsubscribe();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// This pushes new empty values to the observable when the distance or location changes.
useEffect(() => {
onSearch$.next({
searchLocation: currentLatLong,
searchDistance: distance,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentLatLong, distance]);
useEffect(() => {
async function loadLatLongFromProfile() {
// TODO: Search is triggered twice when the user is logged in. Once with the first render,
// and then again when the user is assigned. Need to fix this behavior.
// Set lat/long from profile or fallback to defaults
if (user && user.uid) {
const profileRef = firestore.doc(`${USERS_COLLECTION}/${user.uid}`);
const profileSnap = await profileRef.get();
const geopoint = profileSnap.get('preciseLocation');
if (geopoint) {
const userLocation = {
latitude: geopoint.latitude,
longitude: geopoint.longitude,
};
setCurrentLatLong(userLocation);
setCurrentPlaceLabel(
`Near ${profileSnap.get('generalLocationName')}`,
);
onSearch$.next({
searchLocation: userLocation,
searchDistance: defaultDistance,
});
} else {
onSearch$.next({
searchLocation: currentLatLong,
searchDistance: defaultDistance,
});
}
} else {
onSearch$.next({
searchLocation: currentLatLong,
searchDistance: defaultDistance,
});
}
}
// NOTE: useEffect is used to load data so it can be done conditionally based
// on whether current user is logged in
loadLatLongFromProfile();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [user]);
function handleCopyNeedLink(id) {
const el = document.createElement('textarea');
document.body.appendChild(el);
el.value = `${window.location.origin}${generatePath(REQUEST_PATH, {
requestId: id,
})}`;
el.select();
document.execCommand('copy');
document.body.removeChild(el);
}
// Gets the lat/lng for the selected address.
function handlePlaceSelect(_event, selection) {
if (!selection) return;
geocodeByAddress(selection.description)
.then((results) => getLatLng(results[0]))
.then((latLng) => {
setCurrentLatLong({ latitude: latLng.lat, longitude: latLng.lng });
})
.catch((error) => {
showError('Failed to get the location from address.');
// eslint-disable-next-line no-console
console.error('Error', error);
});
}
function handlePlaceChange(address) {
setCurrentPlaceLabel(address);
}
return (
<Container maxWidth="md">
<Helmet>
<title>Find Opportunities</title>
</Helmet>
<Typography variant="h6">Search Criteria</Typography>
<Paper className={classes.filterPaper}>
{!showAddressPicker && (
<div className={classes.searchLocation}>
<Typography id="continuous-slider">{currentPlaceLabel}</Typography>
<Button
data-test="new-location-button"
onClick={() => setShowAddressPicker(true)}
className={classes.enterAddressButton}>
Select new location
</Button>
</div>
)}
{showAddressPicker && (
<>
<LoadScript
id="script-loader"
libraries={USED_GOOGLE_MAPS_LIBRARIES}
googleMapsApiKey={process.env.REACT_APP_FIREBASE_API_KEY}>
<PlacesAutocomplete
value={currentPlaceLabel}
onChange={handlePlaceChange}>
{({ getInputProps, suggestions, loading }) => (
<>
{/* {console.log(suggestions)} */}
<Autocomplete
data-test="places-autocomplete"
onChange={handlePlaceSelect}
options={suggestions}
loading={loading}
getOptionLabel={(sug) => sug.description}
noOptionsText="No matches"
renderInput={(params) => (
<TextField
margin="none"
data-test="address-entry"
{...getInputProps({
...params,
label: 'Address',
className: classes.searchInput,
})}
InputProps={{
...params.InputProps,
endAdornment: (
<>
{loading && (
<CircularProgress color="inherit" size={20} />
)}
</>
),
}}
/>
)}
/>
</>
)}
</PlacesAutocomplete>
</LoadScript>
<Typography align="right" variant="caption" display="block">
Powered by Google Maps
</Typography>
</>
)}
<Divider className={classes.divider} />
<Typography id="continuous-slider" gutterBottom>
Distance (in miles)
</Typography>
<div className={classes.distance}>
<Slider
defaultValue={defaultDistance}
valueLabelDisplay="on"
// valueLabelFormat={x => `${x} mi`}
marks={markValues}
onChange={(_event, value) => setDistance(value)}
min={1}
max={markValues[markValues.length - 1].value}
/>
</div>
</Paper>
{searching && (
<Paper className={classes.simplePaper}>
<LinearProgress />
</Paper>
)}
{nearbyRequests && nearbyRequests.length === 0 && (
<Paper className={classes.simplePaper}>
<Typography data-test="no-requests-found">
No requests found with {distance} miles. You can try expanding the
search area or try entering a new location.
</Typography>
</Paper>
)}
{nearbyRequests &&
nearbyRequests.map((result) => (
<Paper className={classes.resultPaper} key={result.id}>
<Grid container>
<Hidden xsDown>
<Grid item className={classes.distanceContainer} sm={2}>
{result.distance}
<br />
miles
</Grid>
</Hidden>
<Grid item className={classes.requestSummary} xs={12} sm={10}>
{parseInt(result.immediacy, 10) > 5 && (
<img
align="right"
src="/taskIcon.png"
width="50px"
height="50px"
alt="Urgent"
title="Urgent"
/>
)}
<Typography variant="h6">
{result.name ? result.name : result.firstName} –{' '}
{result.generalLocationName}
</Typography>
<Typography variant="caption" gutterBottom>
Requested {format(result.createdAt.toDate(), 'p - PPPP')}
</Typography>
<Typography variant="h5" className={classes.needs} gutterBottom>
{result.needs.map((item) => (
<React.Fragment key={item}>
{allCategoryMap[item] ? (
<Chip
size="small"
variant="outlined"
icon={
item === 'grocery-pickup' ? <GroceryIcon /> : null
}
label={allCategoryMap[item].shortDescription}
/>
) : (
<Alert severity="error">
Could not find '{item}' in all category map.
</Alert>
)}
</React.Fragment>
))}
{result.needFinancialAssistance && (
<Chip
variant="outlined"
size="small"
icon={<FinancialAssitanceIcon />}
label="Need financial assistance"
/>
)}
</Typography>
<Hidden smUp>
<Typography
align="right"
variant="h5"
className={classes.TaskTitle}>
{result.distance} miles
</Typography>
</Hidden>
<Grid container justify="flex-end">
<Grid item>
{navigator.share ? (
<Button
size="small"
onClick={() => {
navigator.share({
title: 'CV19 Assist Need Link',
text: 'CV19 Assist Need Link',
url: `${window.location.origin}${generatePath(
REQUEST_PATH,
{
requestId: result.id,
},
)}`,
});
}}>
SHARE
</Button>
) : (
<Button
size="small"
onClick={() => handleCopyNeedLink(result.id)}>
COPY LINK FOR SHARING
</Button>
)}{' '}
<Button
component={Link}
to={generatePath(REQUEST_PATH, {
requestId: result.id,
})}
size="small"
color="primary"
disableElevation>
DETAILS...
</Button>
</Grid>
</Grid>
</Grid>
</Grid>
</Paper>
))}
</Container>
);
}
Example #28
Source File: Dashboard.js From Registration-Login-and-CRUD-Action-using-MERN-stack with GNU General Public License v3.0 | 4 votes |
render() {
return (
<div>
{this.state.loading && <LinearProgress size={40} />}
<div>
<h2>Dashboard</h2>
<Button
className="button_style"
variant="contained"
color="primary"
size="small"
onClick={this.handleProductOpen}
>
Add Product
</Button>
<Button
className="button_style"
variant="contained"
size="small"
onClick={this.logOut}
>
Log Out
</Button>
</div>
{/* Edit Product */}
<Dialog
open={this.state.openProductEditModal}
onClose={this.handleProductClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">Edit Product</DialogTitle>
<DialogContent>
<TextField
id="standard-basic"
type="text"
autoComplete="off"
name="name"
value={this.state.name}
onChange={this.onChange}
placeholder="Product Name"
required
/><br />
<TextField
id="standard-basic"
type="text"
autoComplete="off"
name="desc"
value={this.state.desc}
onChange={this.onChange}
placeholder="Description"
required
/><br />
<TextField
id="standard-basic"
type="number"
autoComplete="off"
name="price"
value={this.state.price}
onChange={this.onChange}
placeholder="Price"
required
/><br />
<TextField
id="standard-basic"
type="number"
autoComplete="off"
name="discount"
value={this.state.discount}
onChange={this.onChange}
placeholder="Discount"
required
/><br /><br />
<Button
variant="contained"
component="label"
> Upload
<input
id="standard-basic"
type="file"
accept="image/*"
name="file"
value={this.state.file}
onChange={this.onChange}
id="fileInput"
placeholder="File"
hidden
/>
</Button>
{this.state.fileName}
</DialogContent>
<DialogActions>
<Button onClick={this.handleProductEditClose} color="primary">
Cancel
</Button>
<Button
disabled={this.state.name == '' || this.state.desc == '' || this.state.discount == '' || this.state.price == ''}
onClick={(e) => this.updateProduct()} color="primary" autoFocus>
Edit Product
</Button>
</DialogActions>
</Dialog>
{/* Add Product */}
<Dialog
open={this.state.openProductModal}
onClose={this.handleProductClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">Add Product</DialogTitle>
<DialogContent>
<TextField
id="standard-basic"
type="text"
autoComplete="off"
name="name"
value={this.state.name}
onChange={this.onChange}
placeholder="Product Name"
required
/><br />
<TextField
id="standard-basic"
type="text"
autoComplete="off"
name="desc"
value={this.state.desc}
onChange={this.onChange}
placeholder="Description"
required
/><br />
<TextField
id="standard-basic"
type="number"
autoComplete="off"
name="price"
value={this.state.price}
onChange={this.onChange}
placeholder="Price"
required
/><br />
<TextField
id="standard-basic"
type="number"
autoComplete="off"
name="discount"
value={this.state.discount}
onChange={this.onChange}
placeholder="Discount"
required
/><br /><br />
<Button
variant="contained"
component="label"
> Upload
<input
id="standard-basic"
type="file"
accept="image/*"
// inputProps={{
// accept: "image/*"
// }}
name="file"
value={this.state.file}
onChange={this.onChange}
id="fileInput"
placeholder="File"
hidden
required
/>
</Button>
{this.state.fileName}
</DialogContent>
<DialogActions>
<Button onClick={this.handleProductClose} color="primary">
Cancel
</Button>
<Button
disabled={this.state.name == '' || this.state.desc == '' || this.state.discount == '' || this.state.price == '' || this.state.file == null}
onClick={(e) => this.addProduct()} color="primary" autoFocus>
Add Product
</Button>
</DialogActions>
</Dialog>
<br />
<TableContainer>
<TextField
id="standard-basic"
type="search"
autoComplete="off"
name="search"
value={this.state.search}
onChange={this.onChange}
placeholder="Search by product name"
required
/>
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell align="center">Name</TableCell>
<TableCell align="center">Image</TableCell>
<TableCell align="center">Description</TableCell>
<TableCell align="center">Price</TableCell>
<TableCell align="center">Discount</TableCell>
<TableCell align="center">Action</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.products.map((row) => (
<TableRow key={row.name}>
<TableCell align="center" component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="center"><img src={`http://localhost:2000/${row.image}`} width="70" height="70" /></TableCell>
<TableCell align="center">{row.desc}</TableCell>
<TableCell align="center">{row.price}</TableCell>
<TableCell align="center">{row.discount}</TableCell>
<TableCell align="center">
<Button
className="button_style"
variant="outlined"
color="primary"
size="small"
onClick={(e) => this.handleProductEditOpen(row)}
>
Edit
</Button>
<Button
className="button_style"
variant="outlined"
color="secondary"
size="small"
onClick={(e) => this.deleteProduct(row._id)}
>
Delete
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<br />
<Pagination count={this.state.pages} page={this.state.page} onChange={this.pageChange} color="primary" />
</TableContainer>
</div>
);
}
Example #29
Source File: Dashboard.js From react-code-splitting-2021-04-26 with MIT License | 4 votes |
export default function Dashboard(props) {
var classes = useStyles();
var theme = useTheme();
// local
var [mainChartState, setMainChartState] = useState("monthly");
return (
<>
<PageTitle title="Dashboard" button={<Button
variant="contained"
size="medium"
color="secondary"
>
Latest Reports
</Button>} />
<Grid container spacing={4}>
<Grid item lg={3} md={4} sm={6} xs={12}>
<Widget
title="Visits Today"
upperTitle
bodyClass={classes.fullHeightBody}
className={classes.card}
>
<div className={classes.visitsNumberContainer}>
<Grid container item alignItems={"center"}>
<Grid item xs={6}>
<Typography size="xl" weight="medium" noWrap>
12, 678
</Typography>
</Grid>
<Grid item xs={6}>
<LineChart
width={100}
height={30}
data={[
{ value: 10 },
{ value: 15 },
{ value: 10 },
{ value: 17 },
{ value: 18 },
]}
>
<Line
type="natural"
dataKey="value"
stroke={theme.palette.success.main}
strokeWidth={2}
dot={false}
/>
</LineChart>
</Grid>
</Grid>
</div>
<Grid
container
direction="row"
justify="space-between"
alignItems="center"
>
<Grid item xs={4}>
<Typography color="text" colorBrightness="secondary" noWrap>
Registrations
</Typography>
<Typography size="md">860</Typography>
</Grid>
<Grid item xs={4}>
<Typography color="text" colorBrightness="secondary" noWrap>
Sign Out
</Typography>
<Typography size="md">32</Typography>
</Grid>
<Grid item xs={4}>
<Typography color="text" colorBrightness="secondary" noWrap>
Rate
</Typography>
<Typography size="md">3.25%</Typography>
</Grid>
</Grid>
</Widget>
</Grid>
<Grid item lg={3} md={8} sm={6} xs={12}>
<Widget
title="App Performance"
upperTitle
className={classes.card}
bodyClass={classes.fullHeightBody}
>
<div className={classes.performanceLegendWrapper}>
<div className={classes.legendElement}>
<Dot color="warning" />
<Typography
color="text"
colorBrightness="secondary"
className={classes.legendElementText}
>
Integration
</Typography>
</div>
<div className={classes.legendElement}>
<Dot color="primary" />
<Typography
color="text"
colorBrightness="secondary"
className={classes.legendElementText}
>
SDK
</Typography>
</div>
</div>
<div className={classes.progressSection}>
<Typography
size="md"
color="text"
colorBrightness="secondary"
className={classes.progressSectionTitle}
>
Integration
</Typography>
<LinearProgress
variant="determinate"
value={77}
classes={{ barColorPrimary: classes.progressBarPrimary }}
className={classes.progress}
/>
</div>
<div>
<Typography
size="md"
color="text"
colorBrightness="secondary"
className={classes.progressSectionTitle}
>
SDK
</Typography>
<LinearProgress
variant="determinate"
value={73}
classes={{ barColorPrimary: classes.progressBarWarning }}
className={classes.progress}
/>
</div>
</Widget>
</Grid>
<Grid item lg={3} md={8} sm={6} xs={12}>
<Widget
title="Server Overview"
upperTitle
className={classes.card}
bodyClass={classes.fullHeightBody}
>
<div className={classes.serverOverviewElement}>
<Typography
color="text"
colorBrightness="secondary"
className={classes.serverOverviewElementText}
noWrap
>
60% / 37°С / 3.3 Ghz
</Typography>
<div className={classes.serverOverviewElementChartWrapper}>
<ResponsiveContainer height={50} width="99%">
<AreaChart data={getRandomData(10)}>
<Area
type="natural"
dataKey="value"
stroke={theme.palette.secondary.main}
fill={theme.palette.secondary.light}
strokeWidth={2}
fillOpacity="0.25"
/>
</AreaChart>
</ResponsiveContainer>
</div>
</div>
<div className={classes.serverOverviewElement}>
<Typography
color="text"
colorBrightness="secondary"
className={classes.serverOverviewElementText}
noWrap
>
54% / 31°С / 3.3 Ghz
</Typography>
<div className={classes.serverOverviewElementChartWrapper}>
<ResponsiveContainer height={50} width="99%">
<AreaChart data={getRandomData(10)}>
<Area
type="natural"
dataKey="value"
stroke={theme.palette.primary.main}
fill={theme.palette.primary.light}
strokeWidth={2}
fillOpacity="0.25"
/>
</AreaChart>
</ResponsiveContainer>
</div>
</div>
<div className={classes.serverOverviewElement}>
<Typography
color="text"
colorBrightness="secondary"
className={classes.serverOverviewElementText}
noWrap
>
57% / 21°С / 3.3 Ghz
</Typography>
<div className={classes.serverOverviewElementChartWrapper}>
<ResponsiveContainer height={50} width="99%">
<AreaChart data={getRandomData(10)}>
<Area
type="natural"
dataKey="value"
stroke={theme.palette.warning.main}
fill={theme.palette.warning.light}
strokeWidth={2}
fillOpacity="0.25"
/>
</AreaChart>
</ResponsiveContainer>
</div>
</div>
</Widget>
</Grid>
<Grid item lg={3} md={4} sm={6} xs={12}>
<Widget title="Revenue Breakdown" upperTitle className={classes.card}>
<Grid container spacing={2}>
<Grid item xs={6}>
<ResponsiveContainer width="100%" height={144}>
<PieChart>
<Pie
data={PieChartData}
innerRadius={30}
outerRadius={40}
dataKey="value"
>
{PieChartData.map((entry, index) => (
<Cell
key={`cell-${index}`}
fill={theme.palette[entry.color].main}
/>
))}
</Pie>
</PieChart>
</ResponsiveContainer>
</Grid>
<Grid item xs={6}>
<div className={classes.pieChartLegendWrapper}>
{PieChartData.map(({ name, value, color }, index) => (
<div key={color} className={classes.legendItemContainer}>
<Dot color={color} />
<Typography style={{ whiteSpace: "nowrap", fontSize: 12 }} >
{name}
</Typography>
<Typography color="text" colorBrightness="secondary">
{value}
</Typography>
</div>
))}
</div>
</Grid>
</Grid>
</Widget>
</Grid>
<Grid item xs={12}>
<Widget
bodyClass={classes.mainChartBody}
header={
<div className={classes.mainChartHeader}>
<Typography
variant="h5"
color="text"
colorBrightness="secondary"
>
Daily Line Chart
</Typography>
<div className={classes.mainChartHeaderLabels}>
<div className={classes.mainChartHeaderLabel}>
<Dot color="warning" />
<Typography className={classes.mainChartLegentElement}>
Tablet
</Typography>
</div>
<div className={classes.mainChartHeaderLabel}>
<Dot color="primary" />
<Typography className={classes.mainChartLegentElement}>
Mobile
</Typography>
</div>
<div className={classes.mainChartHeaderLabel}>
<Dot color="secondary" />
<Typography className={classes.mainChartLegentElement}>
Desktop
</Typography>
</div>
</div>
<Select
value={mainChartState}
onChange={e => setMainChartState(e.target.value)}
input={
<OutlinedInput
labelWidth={0}
classes={{
notchedOutline: classes.mainChartSelectRoot,
input: classes.mainChartSelect,
}}
/>
}
autoWidth
>
<MenuItem value="daily">Daily</MenuItem>
<MenuItem value="weekly">Weekly</MenuItem>
<MenuItem value="monthly">Monthly</MenuItem>
</Select>
</div>
}
>
<ResponsiveContainer width="100%" minWidth={500} height={350}>
<ComposedChart
margin={{ top: 0, right: -15, left: -15, bottom: 0 }}
data={mainChartData}
>
<YAxis
ticks={[0, 2500, 5000, 7500]}
tick={{ fill: theme.palette.text.hint + "80", fontSize: 14 }}
stroke={theme.palette.text.hint + "80"}
tickLine={false}
/>
<XAxis
tickFormatter={i => i + 1}
tick={{ fill: theme.palette.text.hint + "80", fontSize: 14 }}
stroke={theme.palette.text.hint + "80"}
tickLine={false}
/>
<Area
type="natural"
dataKey="desktop"
fill={theme.palette.background.light}
strokeWidth={0}
activeDot={false}
/>
<Line
type="natural"
dataKey="mobile"
stroke={theme.palette.primary.main}
strokeWidth={2}
dot={false}
activeDot={false}
/>
<Line
type="linear"
dataKey="tablet"
stroke={theme.palette.warning.main}
strokeWidth={2}
dot={{
stroke: theme.palette.warning.dark,
strokeWidth: 2,
fill: theme.palette.warning.main,
}}
/>
</ComposedChart>
</ResponsiveContainer>
</Widget>
</Grid>
{mock.bigStat.map(stat => (
<Grid item md={4} sm={6} xs={12} key={stat.product}>
<BigStat {...stat} />
</Grid>
))}
<Grid item xs={12}>
<Widget
title="Support Requests"
upperTitle
noBodyPadding
bodyClass={classes.tableWidget}
>
<Table data={mock.table} />
</Widget>
</Grid>
</Grid>
</>
);
}