@material-ui/core#Slider JavaScript Examples

The following examples show how to use @material-ui/core#Slider. 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: VolumeController.js    From qasong with ISC License 6 votes vote down vote up
function volumeBar({ volume, setVolume, condensed }) {
  function handleChange(e, newValue) {
    setVolume(newValue / 100);
  }
  const classes = useStyles();
  return (
    <Box className={classes.root} px={3}>
      <Grid container justify="center" spacing={2}>
        <Grid item>
          <VolumeDown onClick={() => setVolume(0)} />
        </Grid>
        <Grid item xs align="center">
          <Slider color="secondary" value={volume * 100} onChange={handleChange} />
        </Grid>
        {!condensed && (
          <Grid item>
            <VolumeUp onClick={() => setVolume(1)} />
          </Grid>
        )}
      </Grid>
    </Box>
  );
}
Example #2
Source File: ProgressBar.js    From qasong with ISC License 6 votes vote down vote up
//import { formatSeconds } from "../../../functions";

function ProgressBar({ songProgress, songDuration, changeTime }) {
  function handleChange(e, newValue) {
    changeTime(newValue);
  }

  return (
    <Box px={3}>
      <Grid container spacing={2}>
        {/*<Grid item>
          <Typography style={{ fontSize: 12 }} color="textSecondary">
            {formatSeconds(songProgress)}
          </Typography>
        </Grid>*/}
        <Grid item xs>
          <Slider
            color="secondary"
            value={songProgress}
            max={songDuration}
            onChange={handleChange}
          />
        </Grid>
        {/* <Grid item>
          <Typography style={{ fontSize: 12 }} color="textSecondary">
            {formatSeconds(songDuration)}
          </Typography>
        </Grid> */}
      </Grid>
    </Box>
  );
}
Example #3
Source File: SurveyPage4.jsx    From Corona-tracker with MIT License 5 votes vote down vote up
WellnessSlider = withStyles({
  markLabel: {
    fontSize: '1.17rem',
  },
})(Slider)
Example #4
Source File: analysis.jsx    From GraphVega with MIT License 5 votes vote down vote up
render() {
    return(
      <>
        <Positions 
          positions={this.props.positions}
          quantity={this.props.quantity}
          quote={this.props.quote}
        />
        <br />
        <Row>
          <Col sm={{span:5, offset:1}}>
            <Card>
              <CardContent>
                <h6>
                  Implied volatility: {this.state.iv}% (avg: {this.state.originalIV}%) 
                </h6>
                <Slider 
                  defaultValue={this.state.originalIV}
                  value={this.state.iv}
                  onChange={this.handleIVChange}
                  min={0}
                  max={150}
                />
              </CardContent>
            </Card>
          </Col>
          <Col sm={{span:5}}>
            <Card>
              <CardContent>
                <h6>
                  Days till last option expiry: {this.state.maxDateNum - this.state.dateNum} ({this.state.date})
                </h6>
                <Slider 
                  value={this.state.dateNum}
                  onChange={this.handleDateChange}
                  min={0}
                  max={this.state.maxDateNum}
                />
              </CardContent>
            </Card>
          </Col>
        </Row>
        <br />
        <Row>
          <Col sm={{span:12}}>
            <LineChart data={this.state.chartData}/>
          </Col>
        </Row>
      </>
    )
  }
Example #5
Source File: VerticalSliderView.js    From Nemesis with GNU General Public License v3.0 5 votes vote down vote up
render() {
    return (
      <div className="vertical-slider-view">
        <Typography
          variant="caption"
          className={this.props.labelClassName}
          style={{ whiteSpace: "nowrap" }}
        >
          <FormattedMessage id={this.props.item.id} />
        </Typography>
        <Slider
          className={this.props.sliderClassName}
          value={this.parser(this.props.item.current)}
          disabled={!!this.state.isDirty}
          min={this.parser(this.props.item.min)}
          max={this.parser(this.props.item.max)}
          step={this.props.item.step}
          //vertical={this.props.item.axis === "y"}
          orientation="vertical"
          reverse="true"
          onChange={(event, inputVal) => {
            this.setState({ inputVal: this.parser(inputVal) });
            this.props.item.current = this.parser(inputVal);
            this.props.onChange && this.props.onChange(event, inputVal);
          }}
          onDragEnd={() => {
            this.updateValue(this.state.inputVal);
          }}
        />
        <TextField
          name={this.props.item.id}
          inputProps={this.props.textInputProps}
          type="number"
          disabled={this.props.inputDisabled}
          value={this.parser(this.state.inputVal)}
          onBlur={() => {
            this.updateValue(this.state.inputVal);
          }}
          onChange={event => {
            this.setState({ inputVal: this.parser(event.target.value) });
          }}
        />
      </div>
    );
  }
Example #6
Source File: SliderView.js    From Nemesis with GNU General Public License v3.0 5 votes vote down vote up
render() {
    return (
      <div className={`slider-control ${this.props.item.id}`}>
        <div className="slider-control-inner">
          <Typography className="slider-control-label">
            <FormattedMessage id={this.props.item.id} />
          </Typography>
          <Slider
            value={this.parser(this.props.item.current)}
            disabled={!!this.state.isDirty}
            min={this.parser(this.props.item.min)}
            max={this.parser(this.props.item.max)}
            step={this.props.item.step}
            vertical={this.props.item.axis === "y"}
            onChange={(event, inputVal) => {
              this.setState({ inputVal: this.parser(inputVal) });
              this.props.item.current = this.parser(inputVal);
              this.props.onChange && this.props.onChange(event, inputVal);
            }}
            onDragEnd={() => {
              this.updateValue(this.state.inputVal);
            }}
          />
        </div>
        <TextField
          className="slider-control-input"
          classes={{ padding: 0 }}
          inputProps={{
            className: "slider-control-input"
          }}
          name={this.props.item.id}
          type="number"
          disabled={this.props.inputDisabled}
          value={this.parser(this.state.inputVal)}
          onBlur={() => {
            this.updateValue(this.state.inputVal);
          }}
          onChange={event => {
            this.setState({ inputVal: this.parser(event.target.value) });
          }}
        />
      </div>
    );
  }
Example #7
Source File: Volume.jsx    From archeage-tools with The Unlicense 5 votes vote down vote up
render() {
    const { volume: _volume, setVolume } = this.props;
    const { menu, volume } = this.state;

    return (
      <>
        <Tooltip title={`Volume: ${_volume}%`}>
          <IconButton
            size="small"
            onClick={this.handleOpenMenu}
            color="inherit"
            ref={this.menuRef}
          >
            <div>
              {_volume > 49 && <VolumeUpIcon />}
              {_volume < 50 && _volume > 0 && <VolumeDownIcon />}
              {_volume === 0 && <VolumeMuteIcon />}
            </div>
          </IconButton>
        </Tooltip>
        <Popover
          anchorEl={menu}
          anchorOrigin={{
            vertical: 'bottom',
            horizontal: 'center',
          }}
          transformOrigin={{
            vertical: 'top',
            horizontal: 'center',
          }}
          getContentAnchorEl={null}
          open={Boolean(menu)}
          onClose={this.handleCloseMenu}
        >
          <div className="volume-column">
            <VolumeUpIcon />
            <Slider
              defaultValue={volume}
              onChange={setVolume}
              min={0}
              max={100}
              step={1}
              orientation="vertical"
              className="vol-slider"
            />
            <VolumeDownIcon />
            <Typography variant="subtitle2">{_volume}%</Typography>
          </div>
        </Popover>
      </>
    );
  }
Example #8
Source File: NNFFBuildPanelDetails.js    From Otto with MIT License 5 votes vote down vote up
function LayerOption({ layer, layerIndex, nn_dispatch }) {
  const classes = useStyles();
  if (layer == null) {
    return null;
  }
  return (
    <Grid className={classes.layerInputItem} item>
      {/* <Grid style={{ "margin-top": "28px" }} item>
          <Divider />
        </Grid> */}
      <Grid item>
        <Grid direction="row" className={classes.nodesItem} container>
          <Grid item>
            <Typography className={classes.nodesLabel} gutterBottom>
              Nodes
            </Typography>
          </Grid>
          <Grid className={classes.sliderWidth} item>
            <Slider
              value={layer.units}
              valueLabelDisplay="on"
              ValueLabelComponent={ValueLabelDisplay}
              step={1}
              marks
              min={1}
              max={10}
              onChange={(event, units) =>
                onNodesChanged(layerIndex, units, nn_dispatch)
              }
            />
          </Grid>
        </Grid>
      </Grid>
      <Grid item className={classes.actionItem}>
        <FormControl className={classes.actionWidth}>
          <InputLabel>Activation Function</InputLabel>
          <Select
            value={layer.activation}
            onChange={(event) =>
              onLayerActivationChange(event, layerIndex, nn_dispatch)
            }
          >
            {Object.keys(Activations).map((key) => (
              <MenuItem value={Activations[key]}>{Activations[key]}</MenuItem>
            ))}
          </Select>
        </FormControl>
      </Grid>
      <Grid item className={classes.actionItem}>
        <FormControl className={classes.actionWidth}>
          <InputLabel>Weight Initializer</InputLabel>
          <Select
            value={layer.initializer}
            onChange={(event) =>
              onLayerInitializerChange(event, layerIndex, nn_dispatch)
            }
          >
            {Object.keys(Initializers).map((key) => (
              <MenuItem value={Initializers[key]}>{Initializers[key]}</MenuItem>
            ))}
          </Select>
        </FormControl>
      </Grid>
    </Grid>
  );
}
Example #9
Source File: SurveyPage1.jsx    From Corona-tracker with MIT License 5 votes vote down vote up
WellnessSlider = withStyles({
  markLabel: {
    fontSize: '1.17rem',
  },
})(Slider)
Example #10
Source File: ModeItemView.js    From Nemesis with GNU General Public License v3.0 4 votes vote down vote up
render() {
    return (
      <Accordion
        defaultExpanded={this.state.mappings && this.state.mappings.length > 0}
      >
        <AccordionSummary
          expandIcon={<ExpandMoreIcon />}
          aria-controls="panel1c-content"
          id="panel1c-header"
        >
          <Grid container spacing={3}>
            <Grid item xs={9}>
              <Typography className="heading">
                <FormattedMessage
                  id={`aux.title.${this.props.auxMode.label}`}
                />
                {false && (
                  <Chip
                    size="small"
                    color="primary"
                    label="Active"
                    style={{ marginLeft: "10px" }}
                  />
                )}
              </Typography>
            </Grid>
            <Grid item xs={1} />
            <Grid item xs={12} style={{ marginTop: "-24px" }}>
              <Typography className="secondaryHeading">
                <FormattedMessage
                  id={`aux.explanation.${this.props.auxMode.label}`}
                />
                <a
                  href="#secondary-heading-and-columns"
                  style={{ color: "#288FDA", marginLeft: "10px" }}
                  className="link"
                >
                  Learn more
                </a>
              </Typography>
            </Grid>
          </Grid>
        </AccordionSummary>

        {this.state.mappings &&
          this.state.mappings.map((mapping, i) => {
            let sliderLeft = 0;
            var active_mode = false;
            //set telemetry min and max

            if (mapping.channel > -1 && this.props.telemetry) {
              sliderLeft =
                ((this.props.telemetry[mapping.channel] - this.props.min) *
                  100) /
                (this.props.max - this.props.min);
              if (
                this.props.telemetry[mapping.channel] > mapping.range[0] &&
                this.props.telemetry[mapping.channel] < mapping.range[1]
              ) {
                active_mode = true;
              } else {
                active_mode = false;
              }
            }
            return (
              <AccordionDetails
                className={active_mode ? "active-mode details" : "details"}
                key={mapping.key}
              >
                <Grid container spacing={1}>
                  <Grid item xs>
                    <HelperSelect
                      id={this.props.id}
                      className={this.props.id}
                      label="Channel"
                      value={
                        this.props.channels.filter(
                          c => c.value === mapping.channel
                        )[0].value
                      }
                      items={this.props.channels}
                      onChange={(event, value) => {
                        this.channelChange(i, value.props.value); // the channel object has the channel number in its value
                        this.setState({ isDirty: true }); // also set info changed here
                      }}
                    />
                  </Grid>
                  <Grid item xs>
                    <Typography
                      style={{ margin: "20px", fontFamily: "inherit" }}
                    >
                      {this.props.min}
                    </Typography>
                  </Grid>
                  <Grid item xs={6}>
                    <ExpandMoreIcon //should not be grid item
                      style={{
                        position: "relative",
                        left: `${sliderLeft}%`
                      }}
                      color="secondary"
                      fontSize="large"
                    />
                    <Slider
                      aria-labelledby="range-slider"
                      value={[mapping.range[0], mapping.range[1]]}
                      min={this.props.min}
                      max={this.props.max}
                      marks
                      step={this.props.step}
                      valueLabelDisplay="on"
                      onChange={(event, value) => this.sliderChange(i, value)}
                      onChangeCommitted={(event, value) =>
                        this.sliderChangeCommitted(i, value)
                      } // onChangeCommitted == mouseUp
                    />
                  </Grid>
                  <Grid item xs>
                    <Typography style={{ margin: "20px" }}>
                      {this.props.max}
                    </Typography>
                  </Grid>
                  <Grid item xs>
                    <Tooltip title="Delete range">
                      <IconButton
                        aria-label="delete"
                        size="small"
                        style={{ marginTop: "20px" }}
                        onClick={() => this.deleteRange(i)}
                      >
                        <DeleteIcon style={{ fontSize: 18 }} />
                      </IconButton>
                    </Tooltip>
                    {i === this.state.mappings.length - 1 && (
                      <Tooltip title="Add another range">
                        <IconButton
                          aria-label="add"
                          size="small"
                          style={{ marginTop: "20px" }}
                          name="add_range"
                          onClick={() => this.addRange()}
                          color="primary"
                          variant="contained"
                        >
                          <AddCircleOutlineIcon />
                        </IconButton>
                      </Tooltip>
                    )}
                  </Grid>
                </Grid>
              </AccordionDetails>
            );
          })}
        <Divider />
        <AccordionActions>
          {this.state.mappings &&
            this.state.mappings.length === 0 && (
              <Tooltip title="Add a range to start using this mode.">
                <IconButton
                  aria-label="add"
                  name="add_range"
                  onClick={() => this.addRange()}
                  color="primary"
                  variant="contained"
                >
                  <AddCircleOutlineIcon />
                </IconButton>
              </Tooltip>
            )}
          <Tooltip title="Bring mode back to saved state">
            <Button size="small">Reset</Button>
          </Tooltip>
        </AccordionActions>
      </Accordion>
    );
  }
Example #11
Source File: KNNToolbox.js    From Otto with MIT License 4 votes vote down vote up
export default function KNNToolbox() {
  const classes = useStyles();
  const { state } = useState();
  const { model_state, model_dispatch } = useModelState();
  const [kVal, setKVal] = React.useState(model_state.knn_k);
  const [col1, setCol1] = React.useState(model_state.knn_column1_index);
  const [col2, setCol2] = React.useState(model_state.knn_column2_index);

  function onUpdatePlot() {
    model_dispatch({
      type: ModelActions.SET_KNN_COLS,
      indices: [col1, col2],
    });
    if (kVal !== model_state.knn_k) {
      model_dispatch({
        type: ModelActions.SET_KNN_K,
        k: kVal,
      });
      invokeKNN(kVal, state.sample_dataset, model_dispatch);
    }
  }

  return (
    <Grid direction="column" container style={{ marginTop: "20px" }}>
      {/* K Value */}
      <Grid item>
        <Grid direction="row" className={classes.nodesItem} container>
          <Grid item>
            <Typography className={classes.nodesLabel} gutterBottom>
              K
            </Typography>
          </Grid>
          <Grid className={classes.sliderWidth} item>
            <Slider
              value={kVal}
              valueLabelDisplay="on"
              ValueLabelComponent={ValueLabelDisplay}
              step={1}
              marks
              min={1}
              max={20}
              onChange={(event, val) => setKVal(val)}
            />
          </Grid>
        </Grid>
      </Grid>
      {/* Column 1 */}
      <Grid item className={classes.actionItem}>
        <FormControl className={classes.actionWidth}>
          <InputLabel id="demo-simple-select-label">X-Axis</InputLabel>
          <Select
            value={model_state.knn_columns.length > 0 ? col1 : ""}
            onChange={(event) => setCol1(event.target.value)}
          >
            {model_state.knn_columns.map((column, index) => (
              <MenuItem key={index} value={index}>
                {model_state.knn_columns_map[column]}
              </MenuItem>
            ))}
          </Select>
        </FormControl>
      </Grid>
      {/* Column 2 */}
      <Grid item className={classes.actionItem}>
        <FormControl className={classes.actionWidth}>
          <InputLabel id="demo-simple-select-label">Y-Axis</InputLabel>
          <Select
            value={model_state.knn_columns.length > 0 ? col2 : ""}
            onChange={(event) => setCol2(event.target.value)}
          >
            {model_state.knn_columns.map((column, index) => (
              <MenuItem key={index} value={index}>
                {model_state.knn_columns_map[column]}
              </MenuItem>
            ))}
          </Select>
        </FormControl>
      </Grid>
      <Grid item>
        <Button
          color="primary"
          className={classes.button}
          variant="outlined"
          onClick={onUpdatePlot}
        >
          {model_state.knn_k !== kVal ? "Re-Train Model" : "Update Plot"}
        </Button>
      </Grid>
    </Grid>
  );
}
Example #12
Source File: updateQuizDetails.js    From Quizzie with MIT License 4 votes vote down vote up
function UpdateQuizDetails(props) {
	const [quizId, setQuizId] = useState(props.match.params.id);
	const [quizName, setQuizName] = useState("");
	const [quizDate, setQuizDate] = useState(new Date());
	const [duration, setDuration] = useState(5);
	const [type, setType] = useState("private");

	const [loading, setLoading] = useState(true);
	const [redirect, setRedirect] = useState(false);

	const { executeRecaptcha } = useGoogleReCaptcha();

	const onQuizNameChange = (event) => {
		setQuizName(event.target.value);
	};

	const handleDateChange = (date) => {
		setQuizDate(date);
	};

	const handleTimeChange = (e, val) => {
		setDuration(val);
	};

	const onTypeChange = (event) => {
		setType(event.target.value);
	};

	const handleSubmit = async () => {
		setLoading(true);
		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/quiz/updateDetails/${quizId}`;

		let captcha = await executeRecaptcha("update_quiz_details");

		let updateOps = [
			{ propName: "quizName", value: quizName },
			{ propName: "scheduledFor", value: quizDate.getTime() },
			{ propName: "quizDuration", value: duration },
		];

		let data = {
			updateOps,
			captcha,
		};

		try {
			await axios
				.patch(url, data, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setLoading(false);
					setRedirect(true);
				});
		} catch (error) {
			console.log(error);
			setLoading(false);
		}
	};

	const getQuizDetails = async () => {
		setLoading(true);
		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/quiz/${quizId}`;

		try {
			await axios
				.get(url, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					let details = res.data.result;
					setQuizName(details.quizName);
					setQuizDate(new Date(Number(details.scheduledFor)));
					setDuration(details.quizDuration);
					setType(details.quizType);
					setLoading(false);
				});
		} catch (error) {
			console.log(error);
			setLoading(false);
		}
	};

	useEffect(() => {
		getQuizDetails();
	}, []);

	useEffect(() => {
		let token = localStorage.getItem("authToken");
		if (token === null) {
			setLoading(false);
			setRedirect(true);
			return;
		}
	}, []);

	if (loading) {
		return <Loading />;
	} else if (redirect) {
		return <Redirect to={`/editQuiz/${quizId}`} />;
	} else {
		return (
			<Container className="create-quiz-page">
				<div className="create-form">
					<Typography variant="h4" className="create-head">
						Quiz Details
					</Typography>
					<div className="create-form-inputs">
						<TextInput
							variant="outlined"
							label="Quiz Name"
							value={quizName}
							onChange={onQuizNameChange}
							name="Quiz Name"
							className="form-input"
						/>

						<MuiPickersUtilsProvider utils={DateFnsUtils}>
							<Grid
								className="date-time-select"
								container
								spacing={3}
							>
								<Grid item xs={12} sm={6}>
									<KeyboardDatePicker
										disableToolbar
										variant="inline"
										format="MM/dd/yyyy"
										margin="normal"
										label="Select Quiz Date"
										value={quizDate}
										onChange={handleDateChange}
									/>
								</Grid>
								<Grid item xs={12} sm={6}>
									<KeyboardTimePicker
										margin="normal"
										label="Select Quiz Start Time"
										value={quizDate}
										onChange={handleDateChange}
									/>
								</Grid>
							</Grid>
						</MuiPickersUtilsProvider>
						<p style={{ marginTop: "5%", marginBottom: "5%" }}>
							Quiz Time (in minutes):
						</p>
						<Slider
							defaultValue={5}
							aria-labelledby="quiz time slider"
							step={5}
							min={5}
							max={60}
							valueLabelDisplay="on"
							marks
							className="time-slider"
							value={duration}
							onChange={handleTimeChange}
						/>
						<p style={{ color: "#777" }}>Select quiz type: </p>
						<Tooltip title="Cannot change quiz type">
							<Select
								disabled
								value={type}
								onChange={onTypeChange}
								className="type-select"
							>
								<MenuItem value="public">Public</MenuItem>
								<MenuItem value="private">Private</MenuItem>
							</Select>
						</Tooltip>

						<Button
							className="login-btn create-btn"
							onClick={handleSubmit}
						>
							Update Quiz
						</Button>
					</div>
				</div>
			</Container>
		);
	}
}
Example #13
Source File: Volume.js    From budgie-stream with MIT License 4 votes vote down vote up
VolumeSlider = () => {
  const classes = useStyles();

  const { playback } = useContext(ClientContext);
  const [state, setState] = playback;
  const devices = state.devices.filter((device) => device.selected === true);
  // Only control the volume if any devices are selected
  const disabled = !state.playing;

  const [masterValue, setMasterValue] = useState(30);
  const prevMasterValue = usePreviousValue(masterValue);

  const [anchorEl, setAnchorEl] = useState(null);
  const ref = createRef();
  const open = Boolean(anchorEl);

  const handleClose = () => {
    setAnchorEl(null);
  };

  const handleMasterVol = (newMasterValue) => {
    // Toggle multiple devices control
    if (devices.length > 1) {
      setAnchorEl(ref.current);
    }

    setMasterValue(newMasterValue);

    if (devices.length === 1) {
      handleVolChange(devices[0].name, newMasterValue, null);
    } else {
      const masterChange = newMasterValue - prevMasterValue;
      handleVolChange(null, null, masterChange);
    }
  };

  const handleVolChange = (deviceName, newValue, master = false) => {
    let newState = [...state.devices];
    if (!master) {
      const deviceIndex = state.devices.findIndex(
        (device) => device.name === deviceName
      );

      newState[deviceIndex] = { ...newState[deviceIndex], vol: newValue };
      const avgVol =
        devices.reduce(
          (totalCalories, device) => totalCalories + device.vol,
          0
        ) / devices.length;
      setMasterValue(avgVol);
    } else {
      newState.map((x) => (x.selected ? (x.vol = x.vol + master) : x));
    }

    setState((prevState) => ({
      ...prevState,
      devices: newState,
    }));
    setVolume(devices);
  };

  return (
    <>
      <div className={classes.root}>
        <Grid container className={classes.container} spacing={1}>
          <Grid item id="volume-icon">
            <VolumeUp />
          </Grid>
          <Grid item ref={ref} xs>
            <Slider
              className={classes.slider}
              value={masterValue}
              disabled={disabled}
              onChange={(event, value) => handleMasterVol(value)}
              aria-labelledby="volume-slider"
            />
          </Grid>
        </Grid>
      </div>
      <Popover
        className={classes.popover}
        open={open}
        anchorEl={anchorEl}
        onClose={handleClose}
        anchorOrigin={{
          vertical: "top",
          horizontal: "center",
        }}
        transformOrigin={{
          vertical: "bottom",
          horizontal: "center",
        }}
      >
        <DevicesVolume devices={devices} handleChange={handleVolChange} />
      </Popover>
    </>
  );
}
Example #14
Source File: FontConverter.js    From handReacting with Apache License 2.0 4 votes vote down vote up
function FontConverter() {

    const [text, setText] = useState("A hero can be anyone. Even a man doing something as simple and reassuring as putting a coat around a young boy's shoulders to let him know that the world hadn't ended. This is a sample text. Enter your text here to convert to handwritten font.")
    const [fontFamily, setFontFamily] = useState("'Beth Ellen', cursive")
    const [fontSize, setFontSize] = useState(17)
    const [color, setColor] = useState('blue')
    const [pageColor, setPageColor] = useState('white')
    const [letterSpacing, setLetterSpacing] = useState(1)
    const [wordSpacing, setWordSpacing] = useState(1)
    const [lineHeight, setLineHeight] = useState(30)
    const [fontWeight, setFontWeight] = useState(300)
    const [line, setLine] = useState(false)
    const [shadow, setShadow] = useState(false)
    const [margin, setMargin] = useState(false)
    const [marginTop, setMarginTop] = useState(false)

    const [showColorPicker1, setShowColorPicker1] = useState(false)
    const [showColorPicker2, setShowColorPicker2] = useState(false)

    const colorList = ['#ffffff', '#f2f2f2', '#e6e6e6', '#d9d9d9', '#cccccc', '#bfbfbf', '#ffffe6', ' #ffffcc', '#ffffb3', '#ffff99', '#e6ffff', '#e6ffe6']


    const handleLineHeight = (event, newValue) => {
        setLineHeight(newValue);
    };

    const handleFontWeight = (event, newValue) => {
        setFontWeight(newValue);
    };

    const handlePageLines = (event) => {
        setLine(!line);
      };

    const handleShadow = (event) => {
    setShadow(!shadow);
    };

    const handleMargin = (event) => {
        setMargin(!margin);
    };

    const handleMarginTop = (event) => {
        setMarginTop(!marginTop);
    };

    const generateJpeg = () => {
        domtoimage.toJpeg(document.getElementById('page'), { quality: 1 })
        .then(function (dataUrl) {
            var link = document.createElement('a');
            link.download = 'download.jpeg';
            link.href = dataUrl;
            link.click();
        });
   }

    return (
        <div className="fontConverter">
            <div className="fontStyler">
                <div className="input_container">
                    <Paper elevation={15} className="paper_input" >
                        <textarea onChange={e => setText(e.target.value)} 
                            className="inputTextField" cols='36' rows='19'>
                            {text}
                        </textarea>
                    </Paper>
                    <div className="usageButton">
                        <Usage />
                    </div>
                </div>
                <div className="font_selector">
                {/* <h2>Select Styles</h2> */}
                <div className="gridOne">
                    <div className="fontFamily" style={{marginBottom: "1.5rem"}}>
                            <FormControl style={{minWidth: 150}}>
                            <InputLabel id="font-label">Fonts</InputLabel>
                            <Select
                                    labelId="font-label"
                                    onChange={e => setFontFamily(e.target.value)}
                                    >
                                    <MenuItem style={{fontFamily: "'Architects Daughter', cursive"}} value={"'Architects Daughter', cursive"}>Architects Daughter</MenuItem>
                                    <MenuItem style={{fontFamily: "'Bad Script', cursive"}} value={"'Bad Script', cursive"}>Bad Script</MenuItem>
                                    <MenuItem style={{fontFamily: "'Beth Ellen', cursive"}} value={"'Beth Ellen', cursive"}>Beth Ellen</MenuItem>
                                    <MenuItem style={{fontFamily: "'Bilbo', cursive"}} value={"'Bilbo', cursive"}>Bilbo</MenuItem>
                                    <MenuItem style={{fontFamily: "'Calligraffitti', cursive"}} value={"'Calligraffitti', cursive"}>Calligraffitti</MenuItem>
                                    <MenuItem style={{fontFamily: "'Caveat', cursive"}} value={"'Caveat', cursive"}>Caveat</MenuItem>
                                    <MenuItem style={{fontFamily: "'Charmonman', cursive"}} value={"'Charmonman', cursive"}>Charmonman</MenuItem>
                                    <MenuItem style={{fontFamily: "'Dancing Script', cursive"}} value={"'Dancing Script', cursive"}>Dancing Script</MenuItem>
                                    <MenuItem style={{fontFamily: "'Dawning of a New Day', cursive"}} value={"'Dawning of a New Day', cursive"}>Dawning of a New Day</MenuItem>
                                    <MenuItem style={{fontFamily: "'Euphoria Script', cursive"}} value={"'Euphoria Script', cursive"}>Euphoria Script</MenuItem>
                                    <MenuItem style={{fontFamily: "'Homemade Apple', cursive"}} value={"'Homemade Apple', cursive"}>Homemade Apple</MenuItem>
                                    <MenuItem style={{fontFamily: "'Indie Flower', cursive"}} value={"'Indie Flower', cursive"}>Indie Flower</MenuItem>
                                    <MenuItem style={{fontFamily: "'Just Me Again Down Here', cursive"}} value={"'Just Me Again Down Here', cursive"}>Just Me Again Down Here</MenuItem>
                                    <MenuItem style={{fontFamily: "'Kristi', cursive"}} value={"'Kristi', cursive"}>Kristi</MenuItem>
                                    <MenuItem style={{fontFamily: "'Liu Jian Mao Cao', cursive"}} value={"'Liu Jian Mao Cao', cursive"}>Liu Jian Mao Cao</MenuItem>
                                    <MenuItem style={{fontFamily: "'Loved by the King', cursive"}} value={"'Loved by the King', cursive"}>Loved by the King</MenuItem>
                                    <MenuItem style={{fontFamily: "'Lovers Quarrel', cursive"}} value={"'Lovers Quarrel', cursive"}>Lovers Quarrel</MenuItem>
                                    <MenuItem style={{fontFamily: "'Marck Script', cursive"}} value={"'Marck Script', cursive"}>Marck Script</MenuItem>
                                    <MenuItem style={{fontFamily: "'Mr Dafoe', cursive"}} value={"'Mr Dafoe', cursive"}>Mr Dafoe</MenuItem>
                                    <MenuItem style={{fontFamily: "'Mr De Haviland', cursive"}} value={"'Mr De Haviland', cursive"}>Mr De Haviland</MenuItem>
                                    <MenuItem style={{fontFamily: "'Mrs Saint Delafield', cursive"}} value={"'Mrs Saint Delafield', cursive"}>Mrs Saint Delafield</MenuItem>
                                    <MenuItem style={{fontFamily: "'Nanum Brush Script', cursive"}} value={"'Nanum Brush Script', cursive"}>Nanum Brush Script</MenuItem>
                                    <MenuItem style={{fontFamily: "'Over the Rainbow', cursive"}} value={"'Over the Rainbow', cursive"}>Over the Rainbow</MenuItem>
                                    <MenuItem style={{fontFamily: "'Parisienne', cursive"}} value={"'Parisienne', cursive"}>Parisienne</MenuItem>
                                    <MenuItem style={{fontFamily: "'Qwigley', cursive"}} value={"'Qwigley', cursive"}>Qwigley</MenuItem>
                                    <MenuItem style={{fontFamily: "'Rancho', cursive"}} value={"'Rancho', cursive"}>Rancho</MenuItem>
                                    <MenuItem style={{fontFamily: "'ArchiReenie Beanietects', cursive"}} value={"'ArchiReenie Beanietects', cursive"}>Reenie Beanie</MenuItem>
                                    <MenuItem style={{fontFamily: "'Ruthie', cursive"}} value={"'Ruthie', cursive"}>Ruthie</MenuItem>
                                    <MenuItem style={{fontFamily: "'Sacramento', cursive"}} value={"'Sacramento', cursive"}>Sacramento</MenuItem>
                                    <MenuItem style={{fontFamily: "'Shadows Into Light', cursive"}} value={"'Shadows Into Light', cursive"}>Shadows Into Light</MenuItem>
                                    <MenuItem style={{fontFamily: "'Shadows Into Light Two', cursive"}} value={"'Shadows Into Light Two', cursive"}>Shadows Into Light Two</MenuItem>
                                    <MenuItem style={{fontFamily: "'Vibur', cursive"}} value={"'Vibur', cursive"}>Vibur</MenuItem>
                                    <MenuItem style={{fontFamily: "'Waiting for the Sunrise', cursive"}} value={"'Waiting for the Sunrise', cursive"}>Waiting for the Sunrise</MenuItem>
                                    <MenuItem style={{fontFamily: "'Yellowtail', cursive"}} value={"'Yellowtail', cursive"}>Yellowtail</MenuItem>
                                </Select> 
                                </FormControl>
                        </div>
                        <div className="fontSize" style={{marginBottom: "1.5rem"}}>
                            <FormControl style={{minWidth: 150}}>
                                <InputLabel id="fontSize-label" >Font Size</InputLabel>
                                <Select
                                value={fontSize}
                                labelId="fontSize-label"
                                onChange={e => setFontSize(e.target.value)}
                                >
                                <MenuItem value={14}>14</MenuItem>
                                <MenuItem value={15}>15</MenuItem>
                                <MenuItem value={16}>16</MenuItem>
                                <MenuItem value={17}>17</MenuItem>
                                <MenuItem value={18}>18</MenuItem>
                                <MenuItem value={19}>19</MenuItem>
                                <MenuItem value={20}>20</MenuItem>
                                <MenuItem value={21}>21</MenuItem>
                                <MenuItem value={22}>22</MenuItem>
                                <MenuItem value={23}>23</MenuItem>
                                <MenuItem value={24}>24</MenuItem>
                                </Select>
                            </FormControl>
                            </div>

                            <div className="fontWeight" style={{marginBottom: "1.5rem"}}>
                                <InputLabel id="fontWeight">Font Weight</InputLabel>
                                <Slider style={{width: 150}}
                                    defaultValue={200}
                                    value={fontWeight}
                                    aria-labelledby="discrete-slider"
                                    valueLabelDisplay="auto"
                                    onChange={handleFontWeight}
                                    step={100}
                                    min={100}
                                    max={900}
                                />
                            </div>

                            <div className="letterSpacing" style={{marginBottom: "1.5rem"}}>
                                <FormControl style={{minWidth: 150}}>
                                    <InputLabel id="letterSpacing-label">Letter Spacing</InputLabel>
                                    <Select
                                    value={letterSpacing}
                                    labelId="letterSpacing-label"
                                    onChange={e => setLetterSpacing(e.target.value)}
                                    >
                                    <MenuItem value={-2}>-2</MenuItem>
                                    <MenuItem value={-1.5}>-1.5</MenuItem>
                                    <MenuItem value={-1}>-1</MenuItem>
                                    <MenuItem value={-0.5}>-0.5</MenuItem>
                                    <MenuItem value={0}>0</MenuItem>
                                    <MenuItem value={0.5}>0.5</MenuItem>
                                    <MenuItem value={1}>1</MenuItem>
                                    <MenuItem value={1.5}>1.5</MenuItem>
                                    <MenuItem value={2}>2</MenuItem>
                                    <MenuItem value={3}>3</MenuItem>
                                    <MenuItem value={4}>4</MenuItem>
                                    </Select>
                                </FormControl>
                            </div>

                            <div className="wordSpacing" style={{marginBottom: "1.5rem"}}>
                                <FormControl style={{minWidth: 150}}>
                                    <InputLabel id="wordSpacing-label">Word Spacing</InputLabel>
                                    <Select
                                    value={wordSpacing}
                                    labelId="wordSpacing-label"
                                    onChange={e => setWordSpacing(e.target.value)}
                                    >
                                    <MenuItem value={-4}>-4</MenuItem>
                                    <MenuItem value={-3}>-3</MenuItem>
                                    <MenuItem value={-2}>-2</MenuItem>
                                    <MenuItem value={-1}>-1</MenuItem>
                                    <MenuItem value={0}>0</MenuItem>
                                    <MenuItem value={0.5}>0.5</MenuItem>
                                    <MenuItem value={1}>1</MenuItem>
                                    <MenuItem value={2}>2</MenuItem>
                                    <MenuItem value={3}>3</MenuItem>
                                    <MenuItem value={4}>4</MenuItem>
                                    <MenuItem value={5}>6</MenuItem>
                                    <MenuItem value={6}>8</MenuItem>
                                    </Select>
                                </FormControl>
                            </div>


                        </div>

                        <div className="gridTwo">
                            <div className="colorButton">
                                <Button style={{backgroundColor: `${color}`}} onClick={() => setShowColorPicker1(showColorPicker => !showColorPicker)} variant="contained" color="primary">
                                    {showColorPicker1 ? 'Close ' : 'Font Color'}
                                </Button>
                            </div>
                            <div className="colorPicker">
                                {
                                    showColorPicker1 && (
                                        <SketchPicker 
                                            color={color}
                                            onChange={targetColor => setColor(targetColor.hex)}
                                        />
                                    )
                                }
                            </div>

                            <div className="colorButton">
                                <Button style={{backgroundColor: `${pageColor}`, color: 'black'}} onClick={() => setShowColorPicker2(showColorPicker => !showColorPicker)} variant="contained" color="primary">
                                    {showColorPicker2 ? 'Close ' : 'Page Color'}
                                </Button>
                            </div>
                            <div className="colorPicker">
                                {
                                    showColorPicker2 && (
                                        <CirclePicker
                                            colors={colorList} 
                                            color={pageColor}
                                            onChange={targetColor => setPageColor(targetColor.hex)}
                                        />
                                    )
                                }
                            </div>
                        </div>
                        

                        <div className="gridThree">
                            <div className="lineHeight" style={{marginBottom: "1.5rem"}}>
                                <InputLabel id="lineHeight">Line Height</InputLabel>
                                <Slider style={{width: 150}}
                                    defaultValue={30}
                                    value={lineHeight}
                                    aria-labelledby="discrete-slider"
                                    valueLabelDisplay="auto"
                                    onChange={handleLineHeight}
                                    step={1}
                                    min={10}
                                    max={70}
                                    color="primary"
                                />
                            </div>

                            <div className="linesCheckbox">
                                <Tooltip title="Add Page Lines" placement="right" TransitionComponent={Fade} arrow>
                                    <FormControlLabel
                                        control={<Switch checked={line} onChange={handlePageLines} name="lines" color="primary"/>}
                                        label="Page Lines"
                                    />
                                </Tooltip>
                            </div>

                            <div className="shadowCheckbox">
                                <Tooltip title="Add Shadow To Paper" placement="left" TransitionComponent={Fade} arrow>
                                    <FormControlLabel
                                        control={<Switch checked={shadow} onChange={handleShadow} name="shadow" color="primary"/>}
                                        label="Scan Effect"
                                    />
                                </Tooltip>
                            </div>

                            <div className="marginCheckbox">
                                <Tooltip title="Insert Margin" placement="right" TransitionComponent={Fade} arrow>
                                    <FormControlLabel
                                        control={<Switch checked={margin} onChange={handleMargin} name="shadow" color="primary"/>}
                                        label="Page Margin"
                                    />
                                </Tooltip>
                            </div>

                            <div className="marginTopCheckbox">
                                <Tooltip title="Give Top Margin" placement="right" TransitionComponent={Fade} arrow>
                                    <FormControlLabel
                                        control={<Switch checked={marginTop} onChange={handleMarginTop} name="shadow" color="primary"/>}
                                        label="Top Space"
                                    />
                                </Tooltip>
                            </div>
                            
                        </div>
                        
                </div>
                <div className="output_container">
                    <Paper elevation={3} square={true} className="paper" id="page" style={{backgroundImage: 
                            line? 'repeating-linear-gradient(transparent 0px, transparent 24px, #333333 25px)' : 'none', backgroundColor: `${pageColor}`,
                            WebkitBoxShadow: shadow ? 'inset 18px 0px 50px -7px rgba(106,110,101,1)' : 'none', MozBoxShadow: shadow ? 'inset 18px 0px 50px -7px rgba(106,110,101,1)' : 'none',
                            boxShadow: shadow ? 'inset 18px 0px 50px -7px rgba(106,110,101,1)' : 'none'}}>
                        <p className="output_text" 
                            style={{fontFamily: `${fontFamily}`, fontSize: `${fontSize}px`, color: `${color}`, 
                                letterSpacing: `${letterSpacing}px`, wordSpacing: `${wordSpacing}px`, lineHeight: `${lineHeight}px`, paddingTop: marginTop? '2rem' : '0',
                                fontWeight: `${fontWeight}`, left: margin? '2rem' : '0', borderLeft: margin? '2px solid #666666' : 'none', paddingLeft: margin? '0.5rem' : '0'}}>
                            {text}
                        </p>
                    </Paper>
                    <div className="download_button">
                        <Button onClick={generateJpeg} variant="contained" style={{color: 'white', backgroundColor: '#ec4c4c'}}>Download Image </Button>
                    </div>
                </div>
            </div>
        </div>
    )
}
Example #15
Source File: Player.js    From Octave with MIT License 4 votes vote down vote up
// The Entire Bottom part where all the song controls are available
function Player({ show }) {
  // playing  0 -> paused  | 1 -> playing  | -1 -> loading
  const [playing, setPlaying] = useState(0);
  const [continuousTime, setContinuousTime] = useState(0);
  const [displayCurrentTime, setDisplayCurrentTime] = useState("0:00");
  const [displayDurationTime, setDisplayDurationTime] = useState("0:00");
  const [currentSong, setCurrentSong] = useState(null);
  const audioRef = useRef(null);
  const { newSong, songIndex } = useSelector((state) => state.currentSession);
  const dispatch = useDispatch();
  const isPlayingRef = useRef(false);
  const onTabCloseRef = useRef((e) => {
    if (isPlayingRef.current) {
      e.preventDefault();
      e.returnValue = "You have unfinished changes!";
    }
  });

  useEffect(() => {
    const fn = onTabCloseRef.current;
    window.addEventListener("beforeunload", fn);
    return () => {
      window.removeEventListener("beforeunload", fn);
    };
  }, []);

  useEffect(() => {
    if (currentSong) {
      document.title = `${currentSong.name} (${currentSong.artist}) | Octave`;
      dispatch(setPlayingSong(currentSong));
      setRecentSongsLocalStorage(currentSong);
    }
  }, [currentSong, dispatch]);

  useEffect(() => {
    if (newSong) {
      dispatch(setSongIndex(0));
      setCurrentSong(newSong);
      setPlaying(-1);
      dispatch(setNewSong(null));
    }
  }, [dispatch, newSong, songIndex]);

  // playing  0 -> paused  | 1 -> playing  | -1 -> loading
  const playPauseSong = () => {
    if (!currentSong) {
      playNextSong();
      return;
    }

    if (playing === 1) {
      audioRef.current.pause();
      setPlaying(0);
      isPlayingRef.current = false;
      document.title = `Octave`;
    } else {
      audioRef.current.play();
      setPlaying(1);
      isPlayingRef.current = true;
      document.title = `${currentSong?.name} (${currentSong?.artist}) | Octave`;
    }
  };

  const playNextSong = useCallback(() => {
    const nextSong = getNextSong(songIndex);
    if (nextSong) {
      setCurrentSong(nextSong);
      setPlaying(-1);
      dispatch(incSongIndex());
    }
  }, [songIndex, dispatch]);

  const playPreviousSong = useCallback(() => {
    const prevSong = getPreviousSong(songIndex);
    if (prevSong) {
      setCurrentSong(prevSong);
      dispatch(decSongIndex());
    }
  }, [songIndex, dispatch]);

  const playSongByMediaSession = useCallback(async () => {
    await audioRef.current.play();
    navigator.mediaSession.playbackState = "playing";
    setPlaying(1);
    isPlayingRef.current = true;
    document.title = `${currentSong?.name} (${currentSong?.artist}) | Octave`;
  }, [currentSong]);

  const pauseSongByMediaSession = async () => {
    await audioRef.current.pause();
    navigator.mediaSession.playbackState = "paused";
    setPlaying(0);
    isPlayingRef.current = false;
    document.title = `Octave`;
  };

  // MediaSession docs -> https://developer.mozilla.org/en-US/docs/Web/API/MediaSession
  const setupMediaSession = useCallback(() => {
    if ("mediaSession" in navigator) {
      navigator.mediaSession.metadata = new window.MediaMetadata({
        title: currentSong.name,
        artist: currentSong.artist,
      });
      navigator.mediaSession.setActionHandler("play", () => {
        playSongByMediaSession();
      });
      navigator.mediaSession.setActionHandler("pause", () => {
        pauseSongByMediaSession();
      });
      navigator.mediaSession.setActionHandler("previoustrack", () => {
        playPreviousSong();
      });
      navigator.mediaSession.setActionHandler("nexttrack", () => {
        playNextSong();
      });
    }
  }, [currentSong, playNextSong, playPreviousSong, playSongByMediaSession]);

  // When the audio element is rendered on the screen, this function gets executed
  const audioElementCallbackRef = useCallback(
    (node) => {
      if (!node) return;
      audioRef.current = node;
      audioRef.current.ontimeupdate = (event) => {
        const { duration, currentTime } = event.srcElement;
        let progressPercent = (currentTime / duration) * 100;
        // calculate current time of a song
        const currentRunningTime = calculateCurrentTime(currentTime);
        setContinuousTime(progressPercent);
        setDisplayCurrentTime(currentRunningTime);
      };

      audioRef.current.onended = () => {
        setPlaying(0);
        isPlayingRef.current = false;
        document.title = `Octave`;
        playNextSong();
      };

      // can also use oncanplay
      audioRef.current.onloadeddata = async () => {
        await audioRef.current.play();
        setPlaying(1);
        isPlayingRef.current = true;
        setupMediaSession();
        const durationTime = calculateDurationTime(audioRef.current.duration);
        setDisplayDurationTime(durationTime);
      };
    },
    [audioRef, playNextSong, setupMediaSession]
  );

  const songProgressChanged = useCallback(
    (event, value) => {
      if (!currentSong) return;
      const newProgressSeconds = (value / 100) * audioRef.current.duration;
      audioRef.current.currentTime = newProgressSeconds;
      setContinuousTime(newProgressSeconds);
    },
    [audioRef, currentSong]
  );

  if (!show) return null;

  return (
    <div className="player">
      <div className="player__progress">
        <Slider
          color="secondary"
          value={continuousTime}
          onChangeCommitted={songProgressChanged}
        />
      </div>

      <div className="player__main">
        <div className="player__song">
          {currentSong?.imageUrl && (
            <img
              src={currentSong.imageUrl}
              alt=""
              className="song__infoImage"
            />
          )}
          <div className="song__info">
            <p className="song__infoTrack">{currentSong?.name}</p>
            <p className="song__infoArtist">{currentSong?.artist}</p>
          </div>
        </div>

        <PlayerControls
          playPauseSong={playPauseSong}
          playing={playing}
          playNextSong={playNextSong}
          playPreviousSong={playPreviousSong}
        />

        <div className="player__left">
          <PlayerSongListButton />

          <div className="player__duration">
            <span className="duration__current">{displayCurrentTime}</span>
            <span>/</span>
            <span className="duration__total">{displayDurationTime}</span>
          </div>
        </div>
      </div>

      <audio ref={audioElementCallbackRef} src={currentSong?.url}></audio>
    </div>
  );
}
Example #16
Source File: CreateQuiz.js    From Quizzie with MIT License 4 votes vote down vote up
function CreateQuiz() {
	const [quizName, setQuizName] = useState("");
	const [quizDate, setQuizDate] = useState(new Date());
	const [duration, setDuration] = useState(5);
	const [type, setType] = useState("private");

	const [loading, setLoading] = useState(false);
	const [redirect, setRedirect] = useState(false);
	const [redirectEdit, setRedirectEdit] = useState(false);
	const [quizId, setQuizId] = useState("");

	const [error, setError] = useState(false);

	const { executeRecaptcha } = useGoogleReCaptcha();

	const onQuizNameChange = (event) => {
		setQuizName(event.target.value);
	};

	const handleDateChange = (date) => {
		setQuizDate(date);
	};

	const handleTimeChange = (e, val) => {
		setDuration(val);
	};

	const onTypeChange = (event) => {
		setType(event.target.value);
	};

	const handleSubmit = async () => {
		setLoading(true);
		let token = localStorage.getItem("authToken");
		let url = "https://quizzie-api.herokuapp.com/quiz/createQuiz";

		let captcha = await executeRecaptcha("create_quiz");

		let data = {
			quizName: quizName,
			scheduledFor: quizDate.getTime(),
			quizDuration: duration,
			quizType: type,
			captcha: captcha,
		};

		try {
			await axios
				.post(url, data, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setQuizId(res.data.result._id);
					setLoading(false);
					setRedirectEdit(true);
				});
		} catch (error) {
			console.log(error);
			setLoading(false);
		}
	};

	useEffect(() => {
		let token = localStorage.getItem("authToken");
		if (token === null) {
			setLoading(false);
			setRedirect(true);
			return;
		}
	}, []);

	if (loading) {
		return <Loading />;
	} else if (redirect) {
		return <Redirect to="/dashboard" />;
	} else if (redirectEdit) {
		return <Redirect to={`/editQuiz/${quizId}`} />;
	} else {
		return (
			<Container className="create-quiz-page">
				<div className="create-form">
					<Typography variant="h4" className="create-head">
						Quiz Details
					</Typography>
					<div className="create-form-inputs">
						<TextInput
							variant="outlined"
							label="Quiz Name"
							value={quizName}
							onChange={onQuizNameChange}
							name="Quiz Name"
							className="form-input"
						/>

						<MuiPickersUtilsProvider utils={DateFnsUtils}>
							<Grid
								className="date-time-select"
								container
								spacing={3}
							>
								<Grid item xs={12} sm={6}>
									<KeyboardDatePicker
										disableToolbar
										variant="inline"
										format="MM/dd/yyyy"
										margin="normal"
										label="Select Quiz Date"
										value={quizDate}
										onChange={handleDateChange}
									/>
								</Grid>
								<Grid item xs={12} sm={6}>
									<KeyboardTimePicker
										ampm={true}
										format="hh:mm:ss aa"
										views={["hours", "minutes", "seconds"]}
										margin="normal"
										label="Select Quiz Start Time"
										value={quizDate}
										onChange={handleDateChange}
										keyboardIcon={<AccessAlarm />}
									/>
								</Grid>
							</Grid>
						</MuiPickersUtilsProvider>
						<p style={{ marginTop: "5%", marginBottom: "5%" }}>
							Quiz Time (in minutes):
						</p>
						<Slider
							defaultValue={5}
							aria-labelledby="quiz time slider"
							step={5}
							min={5}
							max={60}
							valueLabelDisplay="on"
							marks
							className="time-slider"
							value={duration}
							onChange={handleTimeChange}
						/>
						<p>Select quiz type: </p>
						<Select
							value={type}
							onChange={onTypeChange}
							className="type-select"
						>
							<MenuItem value="public">Public</MenuItem>
							<MenuItem value="private">Private</MenuItem>
						</Select>

						<Button
							className="login-btn create-btn"
							onClick={handleSubmit}
						>
							Create Quiz
						</Button>
						<Typography
							variant="subtitle1"
							className="create-subtitle"
						>
							NOTE: After creating the quiz, you can add questions
							by editing the quiz in YOUR QUIZZES section of the
							dashboard.
						</Typography>
					</div>
				</div>
				<Snackbar
					open={error}
					autoHideDuration={5000}
					onClose={() => setError(false)}
				>
					<Alert
						variant="filled"
						severity="error"
						onClose={() => setError(false)}
					>
						There was a problem. Please try again!
					</Alert>
				</Snackbar>
			</Container>
		);
	}
}
Example #17
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 #18
Source File: DepositStepper.js    From lrc-staking-dapp with MIT License 4 votes vote down vote up
DepositStepper = React.memo(({
  classes, messages, maxAmount, onApprove, onStake, allowance, stake, approve, onDone,
}) => {
  const [step, setStep] = useState(0);
  const [amount, setAmount] = useState('0');
  const [isStaking, setIsStaking] = useState(false);
  const [isDone, setIsDone] = useState(false);
  const { width, height } = useWindowSize();

  useEffect(() => {
    checkEnoughAllowanceRedirectToStakeStep(amount, allowance, step, setStep);
  }, [amount, allowance, step, setStep]);

  useEffect(() => {
    checkAsyncStakeIsDone(step, isStaking, stake, setIsStaking, setIsDone, setStep);
  }, [step, isStaking, stake, setIsStaking, setIsDone, setStep]);

  useEffect(() => {
    timeoutConfetti(isDone, onDone);
  }, [isDone, onDone]);

  return (
    <div className={classes.root}>
      <Stepper activeStep={step} orientation="vertical">
        <Step>
          <StepLabel>{messages['Are you sure?']}</StepLabel>
          <StepContent>
            <Typography>{messages['Your tokens will be locked until your stake age is older than 90 day. If you add new tokens into your stake, your age will be weighted by the amount of tokens.']}</Typography>
            <div className={classes.actionsContainer}>
              <div>
                <Button
                  disabled
                  className={classes.button}
                >
                  {messages.Back}
                </Button>
                <Button
                  variant="contained"
                  color="primary"
                  onClick={() => setStep(STEP.AMOUNT)}
                  className={classes.button}
                >
                  {messages['I understand']}
                </Button>
              </div>
            </div>
          </StepContent>
        </Step>
        <Step>
          <StepLabel>{messages['Select amount']}</StepLabel>
          <StepContent>
            <Typography>{messages['Please fill in the amount of LRC you want to stake.']}</Typography>
            <TextField
              value={amount}
              variant="outlined"
              label="Amount"
              fullWidth
              type="number"
              placeholder={safeAmountToPrint(maxAmount)}
              className={classes.inputLRC}
              onChange={(e) => setAmount(safeAmount(e.target.value || 0)
                .isLessThanOrEqualTo(maxAmount)
                ? e.target.value : safeAmountToPrint(maxAmount))}
            />
            <Slider
              value={safeAmount(maxAmount).isZero()
                ? 0 : safeAmount(amount).div(maxAmount).multipliedBy(100).toFixed(0) * 1}
              defaultValue={0}
              valueLabelFormat={(value) => `${value}%`}
              getAriaValueText={() => '%'}
              aria-labelledby="discrete-slider-restrict"
              step={null}
              valueLabelDisplay="auto"
              marks={[{ label: '0%', value: 0 }, { label: '25%', value: 25 }, { label: '50%', value: 50 }, { label: '75%', value: 75 }, { label: '100%', value: 100 }]}
              className={classes.sliderAmount}
              onChange={(_, value) => setAmount(safeAmountToPrint(safeAmount(maxAmount)
                .multipliedBy(value / 100)))}
            />
            <div className={classes.actionsContainer}>
              <div>
                <Button
                  onClick={() => setStep(STEP.DISCLAIMER)}
                  className={classes.button}
                >
                  {messages.Back}
                </Button>
                <Button
                  disabled={safeAmount(amount).isLessThanOrEqualTo(0)}
                  variant="contained"
                  color="primary"
                  onClick={() => setStep(STEP.APPROVAL)}
                  className={classes.button}
                >
                  {messages.Next}
                </Button>
              </div>
            </div>
          </StepContent>
        </Step>
        <Step>
          <StepLabel>{messages.Approve}</StepLabel>
          <StepContent>
            <Typography>
              {messages['You need to allow the staking pool to take $LRC_AMOUNT from your wallet.'].split('$LRC_AMOUNT')[0]}
              <span className={`font-weight-bold ${classes.spanAmount}`}>
                {numeral(amount).format('(0.00a)')}
                {' '}
                LRC
              </span>
              {messages['You need to allow the staking pool to take $LRC_AMOUNT from your wallet.'].split('$LRC_AMOUNT')[1]}
            </Typography>
            <div className={classes.actionsContainer}>
              <div className={classes.divBackAndConfirm}>
                <Button
                  onClick={() => setStep(STEP.AMOUNT)}
                  className={classes.button}
                >
                  {messages.Back}
                </Button>
                <div className={classes.wrapper}>
                  <Button
                    disabled={approve.isLoading}
                    variant="contained"
                    color="primary"
                    onClick={() => onApprove(safeAmountFixed(amount))}
                    className={classes.button}
                  >
                    { approve.isLoading && messages.Approving }
                    { !approve.isLoading && messages.Approve }
                  </Button>
                  { approve.isLoading
                  && (<CircularProgress size={24} className={classes.buttonProgress} />)}
                </div>
              </div>
            </div>
          </StepContent>
        </Step>
        <Step>
          <StepLabel>{messages.Stake}</StepLabel>
          <StepContent>
            <Typography>{messages['You can now deposit your LRC to the staking pool.']}</Typography>
            <div className={classes.actionsContainer}>
              <div className={classes.divBackAndConfirm}>
                <Button
                  onClick={() => setStep(STEP.AMOUNT)}
                  className={classes.button}
                >
                  {messages.Back}
                </Button>
                <div className={classes.wrapper}>
                  <Button
                    disabled={stake.isLoading}
                    variant="contained"
                    color="primary"
                    onClick={() => onStake(safeAmountFixed(amount))}
                    className={classes.button}
                  >
                    { stake.isLoading && messages.Staking }
                    { !stake.isLoading && messages.Stake }
                  </Button>
                  { stake.isLoading
                  && (<CircularProgress size={24} className={classes.buttonProgress} />)}
                </div>
              </div>
            </div>
          </StepContent>
        </Step>
        <Step>
          <StepLabel>{messages.Done}</StepLabel>
          <StepContent>
            <Typography color="primary" className="animated infinite heartBeat delay-1s">
              {messages['Your Loopring token are now staked and you will start collecting fees on all trades !']}
            </Typography>
            <div className={classes.divConfetti}>
              <Confetti
                width={width}
                height={height}
              />
            </div>
          </StepContent>
        </Step>
      </Stepper>
    </div>
  );
})
Example #19
Source File: WithdrawStepper.js    From lrc-staking-dapp with MIT License 4 votes vote down vote up
WithdrawStepper = React.memo(({
  classes, messages, maxAmount, onWithdraw, withdraw, onDone,
}) => {
  const [step, setStep] = useState(0);
  const [amount, setAmount] = useState('0');
  const [isWithdrawing, setIsWithdrawing] = useState(false);
  const [isDone, setIsDone] = useState(false);

  useEffect(() => {
    checkAsyncWithdrawIsDone(step, isWithdrawing, withdraw, setIsWithdrawing, setIsDone, setStep);
  }, [step, isWithdrawing, withdraw, setIsWithdrawing, setIsDone, setStep]);

  useEffect(() => {
    timeoutRedirect(isDone, onDone);
  }, [isDone, onDone]);

  return (
    <div className={classes.root}>
      <Stepper activeStep={step} orientation="vertical">
        <Step>
          <StepLabel>{messages['Are you sure?']}</StepLabel>
          <StepContent>
            <Typography>{messages['When you make a withdrawal, the pending rewards will automatically be added to your stake which will result in resetting the age of your stake to today (this does not impact the age to make a withdrawal).']}</Typography>
            <div className={classes.actionsContainer}>
              <div>
                <Button
                  disabled
                  className={classes.button}
                >
                  {messages.Back}
                </Button>
                <Button
                  variant="contained"
                  color="primary"
                  onClick={() => setStep(STEP.AMOUNT)}
                  className={classes.button}
                >
                  {messages['I understand']}
                </Button>
              </div>
            </div>
          </StepContent>
        </Step>
        <Step>
          <StepLabel>{messages['Select amount']}</StepLabel>
          <StepContent>
            <Typography>{messages['Please fill in the amount of LRC you want to withdraw.']}</Typography>
            <TextField
              value={amount}
              variant="outlined"
              label="Amount"
              fullWidth
              type="number"
              placeholder={safeAmountToPrint(maxAmount)}
              className={classes.inputLRC}
              onChange={(e) => setAmount(safeAmount(e.target.value || 0)
                .isLessThanOrEqualTo(maxAmount)
                ? e.target.value : safeAmountToPrint(maxAmount))}
            />
            <Slider
              value={safeAmount(maxAmount).isZero()
                ? 0 : safeAmount(amount).div(maxAmount).multipliedBy(100).toFixed(0) * 1}
              defaultValue={0}
              valueLabelFormat={(value) => `${value}%`}
              getAriaValueText={() => '%'}
              aria-labelledby="discrete-slider-restrict"
              step={null}
              valueLabelDisplay="auto"
              marks={[{ label: '0%', value: 0 }, { label: '25%', value: 25 }, { label: '50%', value: 50 }, { label: '75%', value: 75 }, { label: '100%', value: 100 }]}
              className={classes.sliderAmount}
              onChange={(_, value) => setAmount(safeAmountToPrint(safeAmount(maxAmount)
                .multipliedBy(value / 100)))}
            />
            <div className={classes.actionsContainer}>
              <div>
                <Button
                  onClick={() => setStep(STEP.DISCLAIMER)}
                  className={classes.button}
                >
                  {messages.Back}
                </Button>
                <Button
                  disabled={safeAmount(amount).isLessThanOrEqualTo(0)}
                  variant="contained"
                  color="primary"
                  onClick={() => setStep(STEP.WITHDRAW)}
                  className={classes.button}
                >
                  {messages.Next}
                </Button>
              </div>
            </div>
          </StepContent>
        </Step>
        <Step>
          <StepLabel>{messages.Withdraw}</StepLabel>
          <StepContent>
            <Typography>
              <span className={`font-weight-bold ${classes.spanAmount}`}>
                {numeral(amount).format('(0.00a)')}
                {' '}
                LRC
              </span>
              {messages['$LRC_AMOUNT will be transferred from your stake to your wallet.'].split('$LRC_AMOUNT')[1]}
            </Typography>
            <div className={classes.actionsContainer}>
              <div className={classes.divBackAndConfirm}>
                <Button
                  onClick={() => setStep(STEP.AMOUNT)}
                  className={classes.button}
                >
                  {messages.Back}
                </Button>
                <div className={classes.wrapper}>
                  <Button
                    disabled={withdraw.isLoading}
                    variant="contained"
                    color="primary"
                    onClick={() => onWithdraw(safeAmountFixed(amount))}
                    className={classes.button}
                  >
                    { withdraw.isLoading && messages.Withdrawing }
                    { !withdraw.isLoading && messages.Withdraw }
                  </Button>
                  { withdraw.isLoading
                  && (<CircularProgress size={24} className={classes.buttonProgress} />)}
                </div>
              </div>
            </div>
          </StepContent>
        </Step>
        <Step>
          <StepLabel>{messages.Done}</StepLabel>
          <StepContent>
            <Typography color="primary">
              {messages['Your withdrawal has been processed, we hope to see you soon :(']}
            </Typography>
          </StepContent>
        </Step>
      </Stepper>
    </div>
  );
})