@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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
StyledProgress = styled(LinearProgress)`
  width: 100%;
`
Example #20
Source File: LinearLoadingSkeleton.js    From akashlytics-deploy with GNU General Public License v3.0 5 votes vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
/**
   * 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&apos;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 vote down vote up
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 vote down vote up
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} &ndash;{' '}
                  {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 &apos;{item}&apos; 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 vote down vote up
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>&nbsp;
            {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>&nbsp;
            {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 vote down vote up
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 }} >
                        &nbsp;{name}&nbsp;
                      </Typography>
                      <Typography color="text" colorBrightness="secondary">
                        &nbsp;{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>
    </>
  );
}