@material-ui/core#RadioGroup JavaScript Examples

The following examples show how to use @material-ui/core#RadioGroup. 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: Question.js    From Quizzie with MIT License 6 votes vote down vote up
function Question(props) {
    const [value, setValue] = React.useState('none');
	const handleChange = (event) => {
		setValue(event.target.value);
	};
	return (
        <Grid item xs={10} md={8} lg={7} style={{margin: 0, padding: '2%', backgroundColor: '#111', borderBottom: '5px solid #222', minHeight: '50vh'}}>
            <FormControl style={{margin: 'auto', width:"100%"}} component="fieldset">
                <FormLabel className="label" component="legend">{props.id}</FormLabel>
                <RadioGroup aria-label="correct-choice" value={value} onChange={handleChange}>
                    <FormControlLabel value="op1" control={<Radio className="radio" />} label="Option 1" style={{margin: 0}} />
                    <FormControlLabel value="op2" control={<Radio className="radio" />} label="Option 2" style={{margin: 0}} />
                    <FormControlLabel value="op3" control={<Radio className="radio" />} label="Option 3" style={{margin: 0}} />
                    <FormControlLabel value="op4" control={<Radio className="radio" />} label="Option 4" style={{margin: 0}} />
                </RadioGroup>
            </FormControl>
        </Grid>
	)
}
Example #2
Source File: tagger.js    From graphql-sample-apps with Apache License 2.0 6 votes vote down vote up
Tagger = ({ tags, onChange, selected, expand }) => {
  const classes = useStyles();
  return (
    <Accordion defaultExpanded={expand}>
      <AccordionSummary expandIcon={<ExpandMoreIcon />}>
        <Typography>Filter by Tags</Typography>
      </AccordionSummary>
      <AccordionDetails className={classes.root}>
        <FormControl component="fieldset">
          <RadioGroup onClick={onChange} value={selected}>
            {tags.map(({ name, value }) => (
              <FormControlLabel
                key={value}
                value={value}
                control={<Radio />}
                label={name}
              />
            ))}
          </RadioGroup>
        </FormControl>
      </AccordionDetails>
    </Accordion>
  );
}
Example #3
Source File: FolioHeader.jsx    From archeage-tools with The Unlicense 5 votes vote down vote up
render() {
    const { open, loading, searchType, options } = this.state;
    const { items, mobile } = this.props;

    return (
      <AppBar position="static" className="section folio-header">
        <Toolbar>
          {!mobile &&
          <Typography variant="h5" className="title-text">Folio</Typography>}
          <Autocomplete
            open={open}
            onOpen={() => this.setOpen(true)}
            onClose={() => this.setOpen(false)}
            onChange={this.handleSearch}
            loading={loading}
            options={options}
            getOptionLabel={option => option.name || option}
            filterOptions={(options) => options}
            classes={{
              noOptions: 'folio-no-option',
            }}
            renderOption={option => (
              <div className="item-result" key={option.id}>
                <Item id={option.id} inline />
                {items[option.id]
                  ? <Typography variant="body2">{items[option.id].name}</Typography>
                  : <Skeleton variant="text" />}
              </div>
            )}
            freeSolo
            onInputChange={(e, value) => {
              this._handleQuery(value);
            }}
            renderInput={params => (
              <TextField
                {...params}
                label={`Search by ${searchTypes.find(type => type.value === searchType).label}`}
                fullWidth
                variant="standard"
                size="small"
                margin="none"
                InputProps={{
                  ...params.InputProps,
                  endAdornment: (
                    <>
                      {loading ? <CircularProgress color="inherit" size={20} /> : null}
                      {params.InputProps.endAdornment}
                    </>
                  ),
                }}
                InputLabelProps={{
                  ...params.InputLabelProps,
                }}
              />
            )}
          />
          <RadioGroup name="search-type" value={searchType} onChange={this.handleTypeChange} row={!mobile}>
            {searchTypes.map(searchType => (
              <FormControlLabel
                control={<Radio size="small" color="primary" />}
                {...searchType}
                key={searchType.value}
              />
            ))}
          </RadioGroup>
        </Toolbar>
      </AppBar>
    );
  }
Example #4
Source File: ShippingOptions.js    From beluga with GNU General Public License v3.0 5 votes vote down vote up
function ShippingOptions(props) {
  const { options, shippingOption } = props;

  const selectOption = e => {
    const newOption = options.find(o => o.name === e.target.value);
    props.setShippingOption(newOption)
  }

  const getLabel = o => (
    <div>
      <Label>{o.name}</Label>
      <span>{(o.price/100).toLocaleString('en-US', { style: 'currency', currency: 'USD' })}</span>
    </div>
  )

  return (
    <div style={{ marginTop: "20px"}}>
      <RadioGroup
        value={shippingOption ? shippingOption.name : ""}
        onChange={selectOption}
      >
        { options.map((o,i) => (
          <FormControlLabel
            key={`radio${i}`}
            value={o.name}
            control={<Radio />}
            label={getLabel(o)}
          />
        ))}
      </RadioGroup>
      <Button
        variant="contained" color="primary"
        style={{ marginTop: "40px" }}
        disabled={!shippingOption}
        onClick={props.createOrder}
      >
        Continue
      </Button>
    </div>
  );
}
Example #5
Source File: Theme.js    From beluga with GNU General Public License v3.0 5 votes vote down vote up
Theme = ({ storeConfig, handleChange, updateStoreConfig }) => {
  return (
    <div>
      <Flex>
        <div>
          <div>Banner Color:</div>
          <ColorPicker
            value={storeConfig.colors.secondary.main}
            onChange={color => handleChange("colors.secondary.main", color)}
          />
        </div>
        <div>
          <div>Banner Text</div>
          <RadioGroup row
            value={storeConfig.colors.secondary.contrastText}
            onChange={e => handleChange("colors.secondary.contrastText", e.target.value)}
          >
            <FormControlLabel value="#FFF" control={<Radio />} label="White" />
            <FormControlLabel value="#000" control={<Radio />} label="Black" />
          </RadioGroup>
        </div>
      </Flex>

      <Flex>
        <div>
          <div>Button Color</div>
          <ColorPicker
            value={storeConfig.colors.primary.main}
            onChange={color => handleChange("colors.primary.main", color)}
          />
        </div>
        <div>
          <div>Button Hover</div>
          <ColorPicker
            value={storeConfig.colors.primary.dark}
            onChange={color => handleChange("colors.primary.dark", color)}
          />
        </div>
        <div>
          <div>Button Text</div>
          <RadioGroup row
            value={storeConfig.colors.primary.contrastText}
            onChange={e => handleChange("colors.primary.contrastText", e.target.value)}
          >
            <FormControlLabel value="#FFF" control={<Radio />} label="White" />
            <FormControlLabel value="#000" control={<Radio />} label="Black" />
          </RadioGroup>
        </div>
      </Flex>

      <Button variant="contained" color="primary"
        style={{ marginTop: "20px" }}
        onClick={() => updateStoreConfig(null, true)}
      >
        Save
      </Button>
    </div>
  );
}
Example #6
Source File: delivery.js    From horondi_admin with MIT License 5 votes vote down vote up
Delivery = ({ data, handleChange, setFieldValue }) => {
  const { deliveryTypes } = config;
  const classes = useStyles();
  const { deliveryLabels } = labels;
  const radioButtons = Object.entries(deliveryLabels).map((type) => (
    <FormControlLabel
      value={type[0].toUpperCase()}
      control={<Radio color='default' size='small' />}
      label={type[1]}
      key={type[0]}
    />
  ));
  return (
    <div className={classes.delivery}>
      <RadioGroup
        name={inputName.sentByInput}
        value={data.delivery.sentBy}
        onChange={handleChange}
      >
        {radioButtons}
      </RadioGroup>
      {(data.delivery.sentBy === deliveryTypes.ukrPostCourier ||
        data.delivery.sentBy === deliveryTypes.novaPostCourier) && (
        <Courier
          deliveryType={data.delivery.sentBy}
          values={data.delivery.courier}
          handleChange={handleChange}
        />
      )}
      {data.delivery.sentBy === deliveryTypes.novaPost && (
        <NovaPost
          setFieldValue={setFieldValue}
          values={data.delivery.novaPost}
        />
      )}

      {data.delivery.sentBy === deliveryTypes.ukrPost && (
        <UkrPost setFieldValue={setFieldValue} values={data.delivery.ukrPost} />
      )}
      {data.delivery.sentBy === deliveryTypes.worldWide && (
        <Worldwide
          handleChange={handleChange}
          setFieldValue={setFieldValue}
          values={data.delivery.worldWide}
        />
      )}
    </div>
  );
}
Example #7
Source File: additional-price-container.js    From horondi_admin with MIT License 5 votes vote down vote up
AdditionalPriceContainer = ({
  values,
  labels,
  onChange,
  onBlur,
  errors,
  touched,
  radio
}) => {
  const styles = useStyles();
  const dispatch = useDispatch();
  const exchangeRate = useSelector(({ Currencies }) => Currencies.exchangeRate);
  const { materialUiConstants } = config;

  useEffect(() => {
    dispatch(getCurrencies());
  }, [dispatch]);
  return (
    <Paper className={styles.additionalPricePaper}>
      <Box>
        <Typography>{labels.enterPrice}</Typography>
      </Box>
      {radio && (
        <FormControl component='fieldset'>
          <RadioGroup
            name='additionalPriceType'
            className={styles.textField}
            onChange={onChange}
            value={values.additionalPriceType}
          >
            <FormControlLabel
              value='ABSOLUTE'
              label={labels.additionalPriceType.absolutePrice[0].value}
              control={<Radio />}
              key={2}
            />
            <FormControlLabel
              value='RELATIVE'
              label={labels.additionalPriceType.relativePrice[0].value}
              control={<Radio />}
              key={1}
            />
          </RadioGroup>
        </FormControl>
      )}
      <TextField
        data-cy='additionalPrice'
        className={`
                  ${styles.textField}
                  ${styles.additionalPrice} 
                  `}
        id='additionalPrice'
        variant='outlined'
        label={getLabelValue(values, labels.additionalPriceType)}
        type={materialUiConstants.types.number}
        value={values.additionalPrice}
        onChange={onChange}
        onBlur={onBlur}
        error={touched.additionalPrice && errors.additionalPrice}
      />
      {touched.additionalPrice && errors.additionalPrice && (
        <div data-cy='additionalPrice-error' className={styles.error}>
          {errors.additionalPrice}
        </div>
      )}
      <TextField
        id='outlined-basic'
        variant='outlined'
        label={labels.convertationTitle}
        className={`
                  ${styles.textField} 
                  ${styles.currencyField}
                  `}
        value={calculateAddittionalPriceValue(values, exchangeRate)}
        disabled
      />
    </Paper>
  );
}
Example #8
Source File: CreateGameDialog.js    From dipact with GNU General Public License v3.0 4 votes vote down vote up
render() {
		return (
			<React.Fragment>
				<Dialog
					onEntered={helpers.genOnback(this.close)}
					open={this.state.open}
					disableBackdropClick={false}
					onClose={this.close}
					fullScreen
				>
					<AppBar>
						<Toolbar>
							<IconButton
								edge="start"
								color="inherit"
								onClick={this.close}
								aria-label="close"
							>
								<CloseIcon />
							</IconButton>
							<Typography variant="h6" style={{ paddingLeft: "16px" }}>
								Create new game
							</Typography>
						</Toolbar>
					</AppBar>

					<div
						style={{
							maxWidth: "920px",
							marginTop: "72px",
							marginLeft: "auto",
							marginRight: "auto",
						}}
					>
						<div
							style={{
								margin: "auto",
								width: "calc(100% - 32px)",
							}}
						>
							<div
								id="step1"
								style={{
									display: "flex",
									flexDirection: "column",
								}}
							>
								<div style={{ display: "flex" }}>
									<TextField
										key="Desc"
										label="Name"
										margin="dense"
										value={this.state.newGameProperties["Desc"]}
										onChange={this.newGamePropertyUpdater("Desc")}
										style={{
											marginBottom: "8px",
											flexGrow: "1",
										}}
									/>
									<IconButton
										onClick={(_) => {
											this.setState((state, props) => {
												state = Object.assign({}, state);
												state.newGameProperties.Desc = helpers.randomGameName();
												return state;
											});
										}}
									>
										<RandomGameNameIcon />
									</IconButton>
								</div>

								<FormControlLabel
									control={
										<Checkbox
											checked={this.state.newGameProperties["Private"]}
											onChange={this.newGamePropertyUpdater("Private")}
										/>
									}
									label="Private game"
									style={{ marginBottom: "8px" }}
								/>

								<React.Fragment>
									<FormControlLabel
										control={
											<Checkbox
												disabled={!this.state.newGameProperties.Private}
												checked={
													this.state.newGameProperties["GameMasterEnabled"]
												}
												onChange={this.newGamePropertyUpdater(
													"GameMasterEnabled"
												)}
											/>
										}
										label="Manage as Game Master"
										style={{ marginBottom: "8px" }}
									/>

									{this.state.newGameProperties.Private ? (
										<FormHelperText>
											As game master, you can pause/resume games and control who
											joins (and as what nation). To play yourself, you need to
											join as a player after creating your game.
										</FormHelperText>
									) : (
										<FormHelperText>
											Game master only allowed in private games (risk of abuse)
										</FormHelperText>
									)}

									{this.state.newGameProperties.Private &&
									this.state.newGameProperties.GameMasterEnabled ? (
										<React.Fragment>
											<FormControlLabel
												control={
													<Checkbox
														checked={
															this.state.newGameProperties[
																"RequireGameMasterInvitation"
															]
														}
														onChange={this.newGamePropertyUpdater(
															"RequireGameMasterInvitation"
														)}
													/>
												}
												label="Require assignment to join"
												style={{ marginBottom: "8px" }}
											/>
											<FormHelperText>
												Only players assigned (a nation) by you can join
												(whitelist).
											</FormHelperText>
										</React.Fragment>
									) : (
										""
									)}
								</React.Fragment>

								<InputLabel
									shrink
									id="variantlabel"
									style={{
										marginTop: "16px",
									}}
								>
									Variant
								</InputLabel>
								<Select
									key="Variant"
									labelId="variantlabel"
									value={this.state.newGameProperties["Variant"]}
									onChange={this.newGamePropertyUpdater("Variant")}
									style={{ marginBottom: "16px" }}
								>
									{Globals.variants.map((variant) => {
										return (
											<MenuItem
												key={variant.Properties.Name}
												value={variant.Properties.Name}
											>
												{variant.Properties.Name} {" ("}
												{variant.Properties.Nations.length} players)
											</MenuItem>
										);
									})}
								</Select>

								<Typography
									style={{ paddingBottom: "4px" }}
									variant="body2"
									fontStyle="italic"
								>
									<i>{this.state.variant.Properties.Description}</i>
								</Typography>
								<img
									src={this.state.variant.Links[3].URL}
									alt="Variant"
									style={{
										paddingBottom: "4px",
										maxHeight: "300px",
									}}
								/>
								<Typography variant="body2" style={{ paddingBottom: "4px" }}>
									Start year: {this.state.variant.Properties.Start.Year}
								</Typography>
								<Typography variant="body2" style={{ paddingBottom: "16px" }}>
									Original author: {this.state.variant.Properties.CreatedBy}
								</Typography>

								<Typography
									variant="caption"
									style={{ color: "rgba(0,0,0,0.57)" }}
								>
									Variant Rules
								</Typography>
								<Typography
									style={{
										paddingBottom: "16px",
										overflowWrap: "break-word",
									}}
									variant="body1"
								>
									{this.state.variant.Properties.Rules}
								</Typography>

								<Typography
									variant="caption"
									style={{ color: "rgba(0,0,0,0.57)" }}
								>
									Nation selection
								</Typography>

								<RadioGroup
									key="NationAllocation"
									value={parseInt(
										this.state.newGameProperties["NationAllocation"]
									)}
									onChange={this.newGamePropertyUpdater("NationAllocation", {
										int: true,
									})}
									style={{
										flexDirection: "row",
										flexWrap: "wrap",
										width: "calc(100% - 32px)",
									}}
								>
									<FormControlLabel
										value={0}
										key={0}
										control={<Radio />}
										label="Random"
									/>
									<FormControlLabel
										value={1}
										key={1}
										control={<Radio />}
										label="Preference based"
									/>
								</RadioGroup>
							</div>
							<div>
								<Typography
									variant="subtitle2"
									style={{
										marginTop: "16px",
										marginBottom: "16px",
									}}
								>
									Game length
								</Typography>
							</div>

							<div
								id="step2"
								style={{
									display: "flex",
									flexDirection: "column",
								}}
							>
								<Box display="flex" key="PhaseLengthMinutes">
									<TextField
										name="phase-length-multiplier"
										label="Phase length"
										type="number"
										inputProps={{ min: 1 }}
										value={this.state.phaseLengthMultiplier}
										onChange={this.setPhaseLength}
										style={{ minWidth: "170px" }}
									/>
									<Select
										name="phase-length-unit"
										value={this.state.phaseLengthUnit}
										onChange={this.setPhaseLength}
									>
										<MenuItem key={1} value={1}>
											{this.state.phaseLengthMultiplier === 1
												? "Minute"
												: "Minutes"}
										</MenuItem>
										<MenuItem key={60} value={60}>
											{this.state.phaseLengthMultiplier === 1
												? "Hour"
												: "Hours"}
										</MenuItem>
										<MenuItem key={60 * 24} value={60 * 24}>
											{this.state.phaseLengthMultiplier === 1 ? "Day" : "Days"}
										</MenuItem>
									</Select>
								</Box>

								<FormControlLabel
									key="samePhaseLength"
									control={
										<Checkbox
											name="same-phase-length"
											checked={!this.state.samePhaseLength}
											onChange={this.setNonMovementPhaseLength}
										/>
									}
									label="Shorter adjustment phases"
								/>
								{this.state.samePhaseLength ? (
									""
								) : (
									<Box
										display="flex"
										key="nonmovementPhaseLengthMinutes"
										style={{ paddingLeft: "32px" }}
									>
										<TextField
											name="non-movement-phase-length-multiplier"
											label="Adjustment phase length"
											type="number"
											inputProps={{ min: 1 }}
											value={this.state.nonMovementPhaseLengthMultiplier}
											onChange={this.setNonMovementPhaseLength}
											style={{ minWidth: "170px" }}
										/>
										<Select
											name="non-movement-phase-length-unit"
											value={this.state.nonMovementPhaseLengthUnit}
											onChange={this.setNonMovementPhaseLength}
										>
											<MenuItem key={1} value={1}>
												{this.state.nonMovementPhaseLengthMultiplier === 1
													? "Minute"
													: "Minutes"}
											</MenuItem>
											<MenuItem key={60} value={60}>
												{this.state.nonMovementPhaseLengthMultiplier === 1
													? "Hour"
													: "Hours"}
											</MenuItem>
											<MenuItem key={60 * 24} value={60 * 24}>
												{this.state.nonMovementPhaseLengthMultiplier === 1
													? "Day"
													: "Days"}
											</MenuItem>
										</Select>
									</Box>
								)}

								<FormControlLabel
									control={
										<Checkbox
											checked={this.state.newGameProperties["SkipMuster"]}
											onChange={this.newGamePropertyUpdater("SkipMuster")}
										/>
									}
									label="Skip Get Ready phase"
									style={{ marginBottom: "8px" }}
								/>
								<FormHelperText>
									The Get Ready phase asks players to confirm they're ready. If
									players don't respond, they are removed and the game goes back
									to try to find replacements before the game can start. This
									prevents absent people ruining a game.
								</FormHelperText>

								<FormControlLabel
									key="endEarly"
									control={
										<Checkbox
											name="end-game-early"
											onChange={(ev) => {
												ev.persist();
												this.setState((state, props) => {
													state = Object.assign({}, state);
													state.endEarly = ev.target.checked;
													state.newGameProperties.LastYear = ev.target.checked
														? this.state.variant.Properties.Start.Year + 7
														: 0;
													return state;
												});
											}}
											checked={this.state.endEarly}
										/>
									}
									label="End in draw after number of years"
								/>
								{this.state.endEarly ? (
									<Box
										display="flex"
										key="last-year"
										style={{ paddingLeft: "32px" }}
									>
										<TextField
											type="number"
											style={{ minWidth: "240px" }}
											error={
												this.state.newGameProperties.LastYear <
												this.state.variant.Properties.Start.Year + 1
													? true
													: false
											}
											helperText={
												this.state.newGameProperties.LastYear <
												this.state.variant.Properties.Start.Year + 1
													? "Must be after the start year"
													: ""
											}
											label={
												"End after year (game starts " +
												this.state.variant.Properties.Start.Year +
												")"
											}
											value={this.state.newGameProperties.LastYear}
											onChange={this.newGamePropertyUpdater("LastYear", {
												int: true,
											})}
										/>
									</Box>
								) : (
									""
								)}
							</div>
							<div>
								<Typography
									variant="subtitle2"
									style={{
										marginTop: "16px",
										marginBottom: "16px",
									}}
								>
									Chat
								</Typography>
							</div>
							<div id="part3">
								<Typography
									variant="caption"
									style={{ color: "rgba(0,0,0,0.57)" }}
								>
									Allow chats:
								</Typography>
								<FormGroup>
									{this.checkboxField("DisableConferenceChat", {
										invert: true,
										label: "Conference (all players)",
									})}
									{this.checkboxField("DisableGroupChat", {
										invert: true,
										label: "Group",
									})}
									{this.checkboxField("DisablePrivateChat", {
										invert: true,
										label: "Individual",
									})}
									<FormControlLabel
										control={
											<Checkbox
												disabled={!this.state.newGameProperties["Private"]}
												checked={
													this.state.newGameProperties["Private"]
														? this.state.newGameProperties["Anonymous"]
														: this.state.newGameProperties[
																"DisableConferenceChat"
														  ] &&
														  this.state.newGameProperties[
																"DisableGroupChat"
														  ] &&
														  this.state.newGameProperties["DisablePrivateChat"]
												}
												onChange={this.newGamePropertyUpdater("Anonymous")}
											/>
										}
										label="Anonymous"
									/>
								</FormGroup>
								{this.state.newGameProperties["Private"] ? (
									""
								) : (
									<FormHelperText style={{ marginBottom: "12px" }}>
										Anonymous only allowed in private games (risk of abuse)
									</FormHelperText>
								)}
							</div>
							<div>
								<InputLabel shrink id="chatLanguageLabel">
									Chat language
								</InputLabel>

								<Select
									key="ChatLanguageISO639_1"
									labelId="chatLanguageLabel"
									disabled={
										this.state.newGameProperties["DisableConferenceChat"] &&
										this.state.newGameProperties["DisableGroupChat"] &&
										this.state.newGameProperties["DisablePrivateChat"]
									}
									value={
										this.state.newGameProperties["ChatLanguageISO639_1"]
											? this.state.newGameProperties["ChatLanguageISO639_1"]
											: "players_choice"
									}
									onChange={this.newGamePropertyUpdater("ChatLanguageISO639_1")}
									style={{
										marginBottom: "16px",
										minWidth: "220px",
									}}
								>
									<MenuItem key="players_choice" value="players_choice">
										Players choice
									</MenuItem>
									{helpers.iso639_1Codes.map((lang) => {
										return (
											<MenuItem key={lang.name} value={lang.code}>
												{lang.name}
											</MenuItem>
										);
									})}
								</Select>
								<Typography
									variant="subtitle2"
									style={{
										marginTop: "16px",
										marginBottom: "16px",
									}}
								>
									Player requirements
								</Typography>
							</div>
							<div id="part4">
								{this.state.newGameProperties["Private"] ? (
									<Typography
										variant="body1"
										style={{
											marginTop: "4px",
											marginBottom: "8px",
											color: "#f44336",
										}}
									>
										For private games we advise you to not add requirements, so
										your friends can all join your game.
									</Typography>
								) : (
									""
								)}
								{this.limitedCheckboxedFloatField("MinReliability", {
									defaultValue: Math.min(
										10,
										Math.floor(Globals.userStats.Properties.Reliability)
									),
									checkbox: {
										label: "Reliability (important)",
										caption: "Find players that keep playing",
									},
									textfield: {
										label: "Minimum reliability score",
									},
									max: {
										value: this.state.userStats.Properties.Reliability,
										helperText:
											"Can't be higher than your own reliability (" +
											helpers.twoDecimals(
												this.state.userStats.Properties.Reliability
											) +
											")",
									},
									min: null,
								})}
								{this.limitedCheckboxedFloatField("MinQuickness", {
									defaultValue: Math.min(
										10,
										Math.floor(Globals.userStats.Properties.Quickness)
									),
									checkbox: {
										label: "Quickness",
										caption:
											"Find players that confirm their orders before deadline",
									},
									textfield: {
										label: "Minimum quickness score",
									},
									max: {
										value: this.state.userStats.Properties.Quickness,
										helperText:
											"Can't be higher than your own quickness (" +
											helpers.twoDecimals(
												this.state.userStats.Properties.Quickness
											) +
											")",
									},
									min: null,
								})}

								{this.limitedCheckboxedFloatField("MinRating", {
									defaultValue: 0,
									checkbox: {
										label: "Minimum rating",
										caption: "Find players that are challenging",
									},
									textfield: {
										label: "Minimum rating",
									},
									helperText:
										"Removes the least challenging " +
										(100 -
											helpers.ratingPercentile(
												this.state.newGameProperties.MinRating
											)) +
										"% of active players",
									max: {
										value: this.state.userStats.Properties.TrueSkill.Rating,
										helperText:
											"Can't be higher than your own rating (" +
											helpers.twoDecimals(
												this.state.userStats.Properties.TrueSkill.Rating
											) +
											")",
									},
									min: null,
								})}

								{this.limitedCheckboxedFloatField("MaxRating", {
									defaultValue: helpers.twoDecimals(
										this.state.userStats.Properties.TrueSkill.Rating,
										true
									),
									checkbox: {
										label: "Maximum rating",
										caption: "Find players that aren't too challenging",
									},
									helperText:
										"Removes the most challenging " +
										helpers.ratingPercentile(
											this.state.newGameProperties.MaxRating
										) +
										"% of active players",
									textfield: {
										label: "Maximum rating",
									},
									min: {
										value: this.state.userStats.Properties.TrueSkill.Rating,
										helperText:
											"Can't be lower than your own rating (" +
											helpers.twoDecimals(
												this.state.userStats.Properties.TrueSkill.Rating,
												true
											) +
											")",
									},
									max: null,
								})}
							</div>
						</div>
						<div style={{ padding: "16px", textAlign: "center" }}>
							<Button
								variant="contained"
								onClick={this.createGame}
								color="primary"
							>
								Create
							</Button>
						</div>
					</div>
				</Dialog>
				<NationPreferencesDialog
					parentCB={(c) => {
						this.nationPreferencesDialog = c;
					}}
					onSelected={null}
				/>
			</React.Fragment>
		);
	}
Example #9
Source File: Quiz.js    From Quizzie with MIT License 4 votes vote down vote up
function Quiz(props) {
	const [quizId, setQuizId] = useState(null);
	const [currentStep, setStep] = useState(1);

	const [loading, setLoading] = useState(true);
	const [allQuestions, setQuestions] = useState([]);
	const [currentQuestion, setCurrentQuestion] = useState(0);
	const [currentAns, setCurrentAns] = useState(null);

	const [duration, setDuration] = useState(-1);
	const [startTime, setStartTime] = useState(-1);
	const [timeRemaining, setTimeRemaining] = useState("");
	const [timeUp, setTimeUp] = useState(false);

	const [tabChange, setTabChange] = useState(false);

	const [allChosenAns, setAllAns] = useState(null);
	const [redirect, setRedirect] = useState(false);
	const [resultRedirect, setResultRedirect] = useState(false);

	const [submitLoading, setSubmitLoading] = useState(false);

	const [confirmModal, setConfirmModal] = useState(false);
	const [empty, setEmpty] = useState(false);
	const [restartStatus, setRestartStatus] = useState(-1);

	const pageVisible = usePageVisibility();
	const { executeRecaptcha } = useGoogleReCaptcha();

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

		let captcha = await executeRecaptcha("submit_token");

		let data = {
			quizId: quizId,
			questions: allChosenAns,
			timeStarted: props.location.state.timeStarted,
			timeEnded: Date.now(),
			captcha: captcha,
		};

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

	const onCloseHandle = () => {
		setConfirmModal(false);
	};

	const handleSubmitBtn = () => {
		setConfirmModal(true);
	};

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

		let data = {
			quizId: quizId,
		};

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

	const _next = () => {
		let currQues = currentQuestion + 1;
		setStep(currentStep + 1);
		setCurrentQuestion(currentQuestion + 1);
		setCurrentAns(allChosenAns[currQues].selectedOption);
	};
	const _prev = () => {
		let currQues = currentQuestion - 1;
		setStep(currentStep - 1);
		setCurrentQuestion(currentQuestion - 1);
		setCurrentAns(allChosenAns[currQues].selectedOption);
	};
	const previousButton = () => {
		if (currentStep !== 1) {
			return (
				<button className="quiz-btn prev-button" onClick={_prev}>
					<p>Previous</p>
				</button>
			);
		}
		return null;
	};

	const nextButton = () => {
		if (currentStep < allQuestions.length) {
			return (
				<button className="quiz-btn next-button" onClick={_next}>
					<p>Next</p>
				</button>
			);
		} else if (currentStep === allQuestions.length) {
			return (
				<button
					className="quiz-btn submit-button"
					onClick={handleSubmitBtn}
				>
					<p>Submit</p>
				</button>
			);
		}
		return null;
	};

	const handleOptionChange = (event) => {
		setCurrentAns(event.target.value);

		let newState = allChosenAns;
		newState[currentQuestion].selectedOption = event.target.value;

		setAllAns(newState);
	};

	const setupQuiz = (questions) => {
		let questionsData = [];
		let answerData = [];

		if (questions.length === 0) {
			setEmpty(true);
			setRedirect(true);
			return;
		}

		questions.map((question) => {
			let questionObj = {
				q_id: question.questionId,
				text: question.description,
				options: question.options,
			};
			questionsData.push(questionObj);

			let ansObj = {
				quesId: question.questionId,
				selectedOption: null,
			};

			answerData.push(ansObj);
		});

		setQuestions(questionsData);
		setAllAns(answerData);

		setLoading(false);
	};

	useEffect(() => {
		if (!pageVisible) {
			setTabChange(true);
			setRedirect(true);
			return;
		}
	}, [pageVisible]);

	useEffect(() => {
		if (restartStatus !== 1) {
			let endTime = Number(startTime) + duration * 60 * 1000;
			if (
				!loading &&
				endTime > 0 &&
				Number(endTime) < Number(Date.now())
			) {
				timesUp();
				return;
			} else {
				setTimeout(() => {
					setTimeRemaining(
						countdown(
							new Date(),
							new Date(Number(endTime)),
							countdown.MINUTES | countdown.SECONDS
						).toString()
					);
				}, 1000);
			}
		}
	});

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

		if (props.location.state === undefined) {
			setRedirect(true);
			return;
		} else {
			setQuizId(props.location.state.id);
			setDuration(props.location.state.duration);
			setStartTime(props.location.state.start);
			setQuestions(props.location.state.questions);
			setupQuiz(props.location.state.questions);
			setRestartStatus(props.location.state.restartStatus);
		}
	}, []);

	if (redirect) {
		return (
			<Redirect
				to={{
					pathname: "/dashboard",
					state: {
						blocked: tabChange,
						timeUp: timeUp,
						emptyQuiz: empty,
					},
				}}
			/>
		);
	} else if (resultRedirect) {
		return <Redirect to={`/results/${quizId}`} />;
	} else if (submitLoading) {
		return <SubmitLoading />;
	} else {
		return loading ? (
			<Loading />
		) : (
			<div className="quiz-page">
				<Grid container xs={12} spacing={5} className="quiz-container">
					<Grid item xs={10} md={8} lg={7} className="q-count">
						<h2 style={{ padding: 0 }}>
							QUESTION {currentStep} OF {allQuestions.length}
						</h2>
					</Grid>
					<Grid item xs={10} md={8} lg={7} className="timer">
						<p style={{ margin: 0 }}>
							Time Remaining{" "}
							<h2 className="rem-time-display">
								{restartStatus !== 1
									? timeRemaining
									: "Until organizer closes the quiz"}
							</h2>
						</p>
					</Grid>
					<Grid
						item
						xs={10}
						md={8}
						lg={7}
						style={{
							margin: 0,
							padding: "2%",
							borderBottom: "3px solid #222",
							minHeight: "30vh",
						}}
					>
						<FormControl
							style={{ margin: "auto", width: "100%" }}
							component="fieldset"
						>
							<FormLabel className="label" component="legend">
								<p className="question">
									{allQuestions[currentQuestion].text}
								</p>
							</FormLabel>
							<RadioGroup
								aria-label="correct-choice"
								value={currentAns}
								onChange={handleOptionChange}
							>
								{allQuestions[currentQuestion].options.map(
									(option) => {
										return (
											<FormControlLabel
												key={option._id}
												value={option.text}
												control={
													<Radio className="radio" />
												}
												label={option.text}
												style={{ margin: 0 }}
											/>
										);
									}
								)}
							</RadioGroup>
						</FormControl>
					</Grid>
					<Grid item xs={10} md={8} lg={7} className="button">
						<Grid item xs={6} className="button">
							{previousButton()}
						</Grid>
						<Grid item xs={6} className="button">
							{nextButton()}
						</Grid>
					</Grid>
				</Grid>

				<Dialog
					open={confirmModal}
					onClose={onCloseHandle}
					aria-labelledby="form-dialog-title"
					PaperProps={{
						style: {
							backgroundColor: "white",
							color: "#333",
							minWidth: "10%",
						},
					}}
				>
					<DialogTitle>
						Are you sure you want to submit the quiz?
					</DialogTitle>
					<div className="btn-div">
						<Button
							className="logout-btn m-right"
							onClick={handleSubmit}
						>
							Yes
						</Button>
						<Button
							className="cancel-btn m-left"
							onClick={onCloseHandle}
						>
							No
						</Button>
					</div>
				</Dialog>
			</div>
		);
	}
}
Example #10
Source File: index.js    From yi-note with GNU General Public License v3.0 4 votes vote down vote up
Bookmarks = () => {
  const { t } = useTranslation('options');
  const { search } = useLocation();
  const {
    bookmarks: {
      bookmarks,
      tags,
      toolbar: { filtering, exporting, exportFormat }
    }
  } = useStoreState(state => state);
  const {
    fetchBookmarks,
    fetchTags,
    selectTag,
    toolbar: { setExportFormat }
  } = useStoreActions(actions => actions.bookmarks);

  useEffect(() => {
    let tagsFromUrl = [];
    const tagsStr = new URLSearchParams(search).get('tags');
    if (tagsStr) {
      tagsFromUrl = tagsStr.split(',');
    }
    fetchBookmarks();
    fetchTags(tagsFromUrl);
  }, [fetchBookmarks, fetchTags, search]);

  const handleSelectTag = tag => {
    selectTag(tag);
  };

  const handleExportFormatChange = e => setExportFormat(e.target.value);

  return (
    <StyledContainer>
      {bookmarks.length === 0 && !filtering ? (
        <NoBookmark />
      ) : (
        <Grid container>
          {exporting && (
            <Grid
              item
              container
              direction="row"
              alignItems="center"
              spacing={1}
            >
              <Grid item>
                <FormLabel>{t('bookmarks.export.format.label')}</FormLabel>
              </Grid>
              <Grid item>
                <RadioGroup
                  row
                  value={exportFormat}
                  onChange={handleExportFormatChange}
                >
                  <FormControlLabel
                    value="json"
                    control={<Radio size="small" />}
                    label="JSON"
                  />
                  <FormControlLabel
                    value="markdown"
                    control={<Radio size="small" />}
                    label="Markdown (no image)"
                  />
                </RadioGroup>
              </Grid>
            </Grid>
          )}
          {filtering && (
            <Grid item container spacing={1}>
              {tags.map(({ tag, selected }) => (
                <Grid item key={tag}>
                  <Chip
                    label={tag}
                    color={selected ? 'primary' : 'default'}
                    clickable
                    onClick={handleSelectTag.bind(null, tag)}
                  />
                </Grid>
              ))}
            </Grid>
          )}
          <Grid item>
            <List>
              {bookmarks.map(
                ({ id, title, description, url, image, selected }) => {
                  return (
                    <ListItem key={id}>
                      <BookmarkItem
                        id={id}
                        title={title}
                        description={description}
                        url={url}
                        image={image}
                        selected={selected}
                      />
                    </ListItem>
                  );
                }
              )}
            </List>
          </Grid>
        </Grid>
      )}
    </StyledContainer>
  );
}
Example #11
Source File: App.js    From cloud-dapr-demo with MIT License 4 votes vote down vote up
export default function App() {
  const classes = useStyles();
  const [activeStep, setActiveStep] = useState(0);
  const [food, setFood] = useState('');
  const [drink, setDrink] = useState('');
  const [loading, setLoading] = useState(false);
  const [orderId, setOrderId] = useState(null);
  const [status, setStatus] = useState(null);

  const steps = getSteps();

  function submitOrder() {
    setLoading(true);
    axios.post(`${baseUrl}/order`, {
      food, drink
    }).then((res) => {
      setOrderId(res.data.id);
    }).finally(() => setLoading(false));
  }

  useEffect(() => {
    if (orderId) {
      pollStatus(orderId);
    }
  }, [orderId]);

  useEffect(() => {
    if (status) {
      let activeIndex = 0;
      switch (status) {
        case 'OrderReceived':
          activeIndex = 0;
          break;
        case 'Processing':
          activeIndex = 1;
          break;
        case 'ReadyToPickup':
          activeIndex = 2;
          break;
        case 'DeliveryOnWay':
          activeIndex = 3;
          break;
        case 'Delivered':
          activeIndex = 4;
          break;
      }
      setActiveStep(activeIndex);
    }
  }, [status]);

  function pollStatus(id) {
    setTimeout(async () => {
      const status = await fetchStatus(id);
      setStatus(status);
      if (status !== 'Delivered') {
        pollStatus(id);
      }
    }, 500);
  }

  async function fetchStatus(id) {
    return axios.get(`${baseUrl}/order/${id}`)
      .then(res => res.data)
      .then(data => data.status)
      .catch((e) => console.error(e));
  }

  return (
    <div className={classes.root}>
      <AppBar position="static">
        <Toolbar>
          <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu">
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" className={classes.title}>
            Demo: Event Driven Apps with Dapr in Kubernetes
          </Typography>
        </Toolbar>
      </AppBar>
      <Container maxWidth="sm">
        <Grid container style={{ marginTop: 40 }}>
          <Grid item xs={6} spacing={3}>
            <FormControl component="fieldset" className={classes.formControl}>
              <FormLabel component="legend">Food</FormLabel>
              <RadioGroup aria-label="food" name="food" value={food}
                onChange={(e) => setFood(e.target.value)}>
                <FormControlLabel value="pizza" control={<Radio />} label="Pizza ?" />
                <FormControlLabel value="burger" control={<Radio />} label="Burger ?" />
                <FormControlLabel value="sandwich" control={<Radio />} label="Sandwich ?" />
                <FormControlLabel value="hotdog" control={<Radio />} label="HotDog ?" />
                <FormControlLabel value="fries" control={<Radio />} label="Fries ?" />
              </RadioGroup>
            </FormControl>
          </Grid>
          <Grid item xs={6}>
            <FormControl component="fieldset" className={classes.formControl}>
              <FormLabel component="legend">Drink</FormLabel>
              <RadioGroup aria-label="drink" name="drink" value={drink}
                onChange={(e) => setDrink(e.target.value)}>
                <FormControlLabel value="drink1" control={<Radio />} label="Diet Coke" />
                <FormControlLabel value="drink2" control={<Radio />} label="Coke" />
                <FormControlLabel value="drink3" control={<Radio />} label="Coffee" />
                <FormControlLabel value="drink4" control={<Radio />} label="Iced Tea" />
                <FormControlLabel value="drink5" control={<Radio />} label="Beer" />
                <FormControlLabel value="drink6" control={<Radio />} label="Orange Juice" />
              </RadioGroup>
              <FormHelperText></FormHelperText>
            </FormControl>
          </Grid>
          <Button type="submit" variant="outlined" disabled={!(food && drink)}
            color="primary" className={classes.button}
            onClick={submitOrder}>
            {loading && <CircularProgress
              className={classes.spinner}
              size={20}
            />}
            Submit Order
          </Button>
        </Grid>
        {orderId && <Grid container style={{ marginTop: 50 }}>
          <Grid item>
            <Typography variant="h6" className={classes.title}>
              Order ID: {orderId}
            </Typography>
          </Grid>
          <Grid item>
            <Stepper activeStep={activeStep} alternativeLabel>
              {steps.map((label) => (
                <Step key={label}>
                  <StepLabel StepIconComponent={QontoStepIcon}>{label}</StepLabel>
                </Step>
              ))}
            </Stepper>
          </Grid>
        </Grid>
        }
      </Container>
    </div >
  );
}
Example #12
Source File: delivery-type.js    From horondi_client_fe with MIT License 4 votes vote down vote up
DeliveryType = ({ setFieldValue, touched, errors, deliveryType, setDeliveryType }) => {
  const styles = useStyles();
  const { t } = useTranslation();

  const [deliveryTypeValue, setDeliveryTypeValue] = useState(deliveryType);
  const [courierOrganization, setcourierOrganization] = useState(deliveryTypes.NOVAPOSTCOURIER);

  const handleCourierOrganizationChange = (eventValue) => {
    setFieldValue('courierOrganization', eventValue);
    setcourierOrganization(eventValue);
  };

  useEffect(() => {
    const handleAddDeliveryType = () => {
      if (deliveryTypeValue === deliveryTypes.COURIER && courierOrganization) {
        setDeliveryType(courierOrganization);
      } else {
        setDeliveryType(deliveryTypeValue);
      }
      setDeliveryTypeToStorage(deliveryTypeValue);
    };
    handleAddDeliveryType();
  }, [deliveryTypeValue, courierOrganization, setDeliveryType]);

  const getDeliveryType = t('checkout.deliveryType', { returnObjects: true });
  const getCourierOrganization = t('checkout.courierOrganization', { returnObjects: true });
  const radioButtons = Object.entries(getDeliveryType).map((type) => (
    <FormControlLabel
      value={type[0].toUpperCase()}
      control={<Radio color='default' size='small' />}
      label={type[1]}
      key={type[0]}
      classes={{ label: styles.radioBtn }}
    />
  ));

  return (
    <div className={styles.deliveryTypeContainer}>
      <FormControl component='fieldset' classes={{ root: styles.radioBtnWrapper }}>
        <RadioGroup
          data-testid='delivery-type'
          aria-label='Delivery type'
          name='delivery-type'
          value={deliveryTypeValue}
          onChange={(e) => setDeliveryTypeValue(e.target.value)}
        >
          {radioButtons}
        </RadioGroup>
      </FormControl>
      {deliveryTypeValue === deliveryTypes.COURIER && (
        <div>
          <FormControl
            error={touched.courierOrganization && !!errors.courierOrganization}
            variant={TEXT_FIELD_VARIANT.OUTLINED}
            className={styles.formControl}
          >
            <InputLabel variant={TEXT_FIELD_VARIANT.OUTLINED}>
              {t('checkout.checkoutTextFields.courier')}
            </InputLabel>
            <Select
              label={t('checkout.checkoutTextFields.courier')}
              className={styles.courierSelect}
              data-testid='courierOrganization'
              name='courierOrganization'
              value={courierOrganization}
              onChange={(e) => handleCourierOrganizationChange(e.target.value)}
            >
              {Object.entries(getCourierOrganization).map((value) => (
                <MenuItem key={value} value={value[0].toUpperCase()}>
                  {value[1]}
                </MenuItem>
              ))}
            </Select>
            {touched.courierOrganization && errors.courierOrganization && (
              <div data-cy={CY_CODE_ERR} className={styles.error}>
                {t(errors.courierOrganization)}
              </div>
            )}
          </FormControl>
        </div>
      )}
    </div>
  );
}
Example #13
Source File: constructor-list-restrictions.js    From horondi_admin with MIT License 4 votes vote down vote up
ConstructorListRestrictions = ({
  restrictionsToAdd,
  setRestrictionsToAdd
}) => {
  const classes = useStyles();
  const dispatch = useDispatch();

  const [isHiding, setHiding] = useState(true);
  const [activePocket, setActivePocket] = useState({ _id: '', positions: [] });
  const [activePosition, setActivePosition] = useState({ _id: '', name: '' });
  const [currentRestrictions, setCurrentRestrictions] = useState([]);

  const {
    items: pockets,
    currentPage: pocketCurrentPage,
    rowsPerPage: pocketRowsPerPage,
    filter: pocketFilter
  } = useSelector(pocketsSelectorWithPagination);
  const {
    items: positions,
    currentPage: positionCurrentPage,
    rowsPerPage: positionRowsPerPage,
    filter: positionFilter
  } = useSelector(positionsSelectorWithPagination);

  const handleToggleRestrictions = () => {
    setActivePocket(pockets[0]);
    setHiding(!isHiding);
  };

  const handlePocketChange = (e) => {
    const pocket = pockets.filter(({ _id }) => _id === e.target.value)[0];
    setActivePocket(pocket);
    setCurrentRestrictions([]);
  };

  const handlePositionChange = (position) => {
    setActivePosition(position);
    setCurrentRestrictions([]);
  };

  const createTitles = () => {
    const titles = ['Кишеня'];
    if (positions) {
      for (const position of positions) {
        titles.push(position.name[0].value);
      }
    }
    return titles;
  };

  const checkboxChangeHandler = (positionId, pocketId) => {
    const possibleItems = currentRestrictions.find(
      (item) => item.pocket._id === pocketId && item.position._id === positionId
    );
    if (possibleItems) {
      setCurrentRestrictions(
        currentRestrictions.filter(
          (item) =>
            item.pocket._id !== pocketId || item.position._id !== positionId
        )
      );
    } else {
      setCurrentRestrictions([
        ...currentRestrictions,
        { pocket: { _id: pocketId }, position: { _id: positionId } }
      ]);
    }
  };

  const findCheckboxRestriction = (pocketId, positionId) => {
    const item = currentRestrictions.find(
      (restriction) =>
        restriction.pocket._id === pocketId &&
        restriction.position._id === positionId
    );
    return !!item;
  };

  const handleAddRestriction = () => {
    const pocket = pockets.filter(({ _id }) => _id === activePocket._id)[0];
    const position = positions.filter(
      ({ _id }) => _id === activePosition._id
    )[0];

    const possibleItems = restrictionsToAdd.find(
      (item) =>
        item.currentPocketWithPosition.pocket._id === pocket._id &&
        item.currentPocketWithPosition.position._id === position._id
    );
    let newRestrictionsToAdd = restrictionsToAdd;
    if (possibleItems) {
      newRestrictionsToAdd = restrictionsToAdd.filter(
        (item) =>
          item.currentPocketWithPosition.pocket._id !== pocket._id ||
          item.currentPocketWithPosition.position._id !== position._id
      );
    }
    setRestrictionsToAdd([
      ...newRestrictionsToAdd,
      {
        currentPocketWithPosition: { pocket, position },
        otherPocketsWithAvailablePositions: currentRestrictions
      }
    ]);
    setCurrentRestrictions([]);
    handleToggleRestrictions();
  };

  useEffect(() => {
    setActivePosition(activePocket.positions[0]);
  }, [activePocket]);

  useEffect(() => {
    dispatch(
      getAllPositions({
        pagination: {
          limit: positionRowsPerPage,
          skip: positionCurrentPage * positionRowsPerPage
        },
        positionFilter
      })
    );
    dispatch(
      getAllPockets({
        pagination: {
          limit: pocketRowsPerPage,
          skip: pocketCurrentPage * pocketRowsPerPage
        },
        pocketFilter
      })
    );
  }, [
    dispatch,
    pocketCurrentPage,
    pocketRowsPerPage,
    pocketFilter,
    positionCurrentPage,
    positionRowsPerPage,
    positionFilter
  ]);

  const pocketItems = map(pockets, (pocket) => {
    const positionCheckboxes = map(positions, (position, index) => {
      for (const pocketPosition of pocket.positions) {
        if (pocketPosition._id === position._id) {
          return (
            <TableCell key={index}>
              <Checkbox
                color='default'
                inputProps={{ 'aria-label': 'checkbox with default color' }}
                onChange={(e) =>
                  checkboxChangeHandler(pocketPosition._id, pocket._id)
                }
                checked={findCheckboxRestriction(
                  pocket._id,
                  pocketPosition._id
                )}
              />
            </TableCell>
          );
        }
      }
      return (
        <TableCell key={index}>
          <div />
        </TableCell>
      );
    });

    return (
      <TableRow key={pocket._id} hover>
        <TableCell>
          <p>{pocket.name[0].value}</p>
        </TableCell>
        {positionCheckboxes}
      </TableRow>
    );
  });

  const pocketOptions = useMemo(() => handleMenuItem(pockets), [pockets]);

  const positionOptions = map(activePocket.positions, (position) => (
    <FormControlLabel
      className={classes.label}
      value={position._id}
      control={
        <Radio
          onChange={() => {
            handlePositionChange(position);
          }}
          color='default'
          size='small'
        />
      }
      label={position.name[0].value}
      key={position._id}
    />
  ));

  return (
    <div>
      <button
        type='submit'
        className={
          isHiding ? `${classes.addPocketBtn} ${classes.show}` : classes.hide
        }
        onClick={handleToggleRestrictions}
      >
        <img src={addIcon} alt='add icon' />
        <p>Додати кишеню</p>
      </button>
      <div
        className={
          isHiding ? classes.hide : `${classes.addPocketForm} ${classes.show}`
        }
      >
        <div className='option'>
          Опція:
          <Select
            onChange={handlePocketChange}
            name='pockets'
            value={activePocket._id}
            className={classes.select}
          >
            {pocketOptions}
          </Select>
        </div>
        <div className='option'>
          Розміщення:
          <RadioGroup
            name='restrictions'
            value={activePosition?._id}
            className={classes.radioButtons}
          >
            {positionOptions}
          </RadioGroup>
        </div>
        <div className='option'>
          {pocketItems?.length ? (
            <TableContainerGenerator
              data-cy='restrictionstable'
              tableTitles={createTitles()}
              tableItems={pocketItems}
            />
          ) : (
            <p>Обмеження відсутні</p>
          )}
        </div>
        <Button
          data-cy={materialUiConstants.save}
          type={materialUiConstants.types.submit}
          variant='contained'
          color='primary'
          onClick={handleAddRestriction}
          className={classes.saveButton}
        >
          Зберегти
        </Button>
      </div>
    </div>
  );
}
Example #14
Source File: Signup.jsx    From EMP with MIT License 4 votes vote down vote up
export default function SignUp () {
  const [user, setUser] = useState({
    user_id: '',
    password: '',
    name: '',
    gender: '',
    age: '',
    phone: '',
    email: ''
  });
  
  // const options = [
  //   { value: '10', label: '10대' },
  //   { value: '20', label: '20대' },
  //   { value: '30', label: '30대' },
  //   { value: '40', label: '40대' },
  //   { value: '50', label: '50대' },
  //   { value: '60', label: '60대' },
  //   { value: '70', label: '70대' },
  //   { value: '80', label: '80대' }
  // ]

  const [submitted, setSubmitted] = useState(false);
  // const registering = useSelector(state => state.registering.registering);
  const dispatch = useDispatch();

  // reset login status
  /*
  useEffect(() => {
      dispatch(userActions.logout());
  }, [])
  */

  function handleChange(e) {
    const { name, value } = e.target;
    setUser(user => ({...user, [name]: value}));
  }

  function handleSubmit(e) {
    e.preventDefault();

    setSubmitted(true);
    if (user.user_id && user.password && user.name && user.gender && user.age && user.phone && user.email) {
      dispatch(userActions.register(user));
    }
}


  return (
  <div>
    {/* <Header/> */}
    {/* <AnimationRevealPage> */}
      <Container>
        <Content>
          <MainContainer>
            <MainContent>
              <Heading>{headingText}</Heading>
              <FormContainer>
                <DividerTextContainer>
                  <DividerText>Sign up with your Information</DividerText>
                </DividerTextContainer>
                <Form name="form" onSubmit={handleSubmit}>
                  {/* <Input type="email" placeholder="Email" />  */}
                  <Input type="text" placeholder="Id" name= "user_id" value={user.user_id} onChange={handleChange}
                  className={'form-control' + (submitted && !user.user_id ? 'is-invalid' : '')}/>
                  {submitted && !user.user_id &&
                      <div className="invalied-feedback">User Id is required</div>}

                  <Input type="password" placeholder="Password" name="password" value={user.password} onChange={handleChange}
                  className={'form-control' + (submitted && !user.password ? ' is-invalid' : '')} />
                  {submitted && !user.password &&
                      <div className="invalid-feedback">Password is required</div>
                  }

                  <Input type="text" placeholder="Your name" name="name" value={user.name} onChange={handleChange} 
                  className={'form-control' + (submitted && !user.name ? 'is-invalid' : '')}/>
                  {submitted && !user.name &&
                      <div className="invalid-feedback">User Name is required</div>
                  }
     
                  <RadioGroup defaultValue="female" aria-label="gender" name="gender" value={user.gender} onChange={handleChange}>
                    <FormControlLabel value="F" control={<Radio />} label="Female" />
                    <FormControlLabel value="M" control={<Radio />} label="Male" />
                  </RadioGroup>

                  {/* <Select options={options} placeholder="Age" name="age" value={user.age} onChange={handleChange} /> */}

                  <Input type="text" placeholder="Age" name="age" value={user.age} onChange={handleChange}
                  className={'form-control' + (submitted && !user.name ? 'is-invalid' : '')}/>
                  {submitted && !user.name &&
                      <div className="invalid-feedback">User Name is required</div>
                  }


                  <Input type="text" placeholder="Tel" name="phone" value={user.phone} onChange={handleChange} 
                  size="small"
                  control={<Radio color="yellow" />}
                  className={'form-control' + (submitted && !user.phone ? 'is-invalid' : '')}/>
                  {submitted && !user.phone &&
                    <div className="invalid-feedback">Tel is required</div>
                  }           

                  <Input type="email" placeholder="Email" name="email" value={user.email} onChange={handleChange} 
                  className= {'form-control' + (submitted && !user.email ? 'is-invalid' : '')}/>
                  {submitted && !user.email &&  
                    <div className="invalid-feedback">Email is required</div>
                  }  

                  <SubmitButton type="submit" onClick={userActions.register}>
                    <SubmitButtonIcon className="icon" />
                    <span className="text" >{submitButtonText}</span>
                  </SubmitButton>


                  <p tw="mt-6 text-xs text-gray-600 text-center">
                    I agree to abide by treact's{" "}
                    <a href={tosUrl} tw="border-b border-gray-500 border-dotted">
                      Terms of Service
                    </a>{" "}
                    and its{" "}
                    <a href={privacyPolicyUrl} tw="border-b border-gray-500 border-dotted">
                      Privacy Policy
                    </a>
                  </p>

                  <p tw="mt-8 text-sm text-gray-600 text-center">
                    Already have an account?{" "}
                    <a href="/login" tw="border-b border-gray-500 border-dotted">
                        Sign In
                      </a>
                  </p>
                </Form>
              </FormContainer>
            </MainContent>
          </MainContainer>
          <IllustrationContainer>
            <IllustrationImage imageSrc={cheeseRegisterImageSrc} />
          </IllustrationContainer>
        </Content>
      </Container>
    {/* </AnimationRevealPage> */}
  </div>
  );
}
Example #15
Source File: UpdateProductForm.js    From inventory-management-web with MIT License 4 votes vote down vote up
UpdateProduct = () => {
  // get state from location
  const location = useLocation();
  const {
    name,
    sellingPrice,
    id,
    loose,
    upperLimit,
    lowerLimit,
  } = location.state;
  // Use custom hook for form state management
  const { handleChange, handleSubmit, error, values, isLoading } = useForm({
    name,
    sellingPrice,
    loose,
    id,
    upperLimit,
    lowerLimit,
  });

  const classes = useStyles();

  return (
    <>
      {isLoading ? <Spinner /> : null}
      <Paper className={classes.paper}>
        <Typography variant='h4' className={classes.heading}>
          Update Product
        </Typography>
        <form
          noValidate
          onSubmit={handleSubmit}
          autoComplete='off'
          className={classes.gridContainer}
        >
          <Divider />
          <Typography variant='h5' className={classes.formHeading}>
            Product
          </Typography>
          <div className={classes.form}>
            <TextField
              required
              variant='filled'
              id='name-input'
              name='name'
              label='Name'
              value={values.name}
              onChange={handleChange}
              error={!(error.name === ' ')}
              helperText={error.name}
            />
            <TextField
              required
              variant='filled'
              id='sellingPrice-input'
              type='number'
              name='sellingPrice'
              label='Selling Price'
              InputProps={{
                inputProps: {
                  min: 0,
                },
              }}
              value={values.sellingPrice}
              onChange={handleChange}
              error={!(error.sellingPrice === ' ')}
              helperText={error.sellingPrice}
            />
            <TextField
              variant='filled'
              id='upperLimit-input'
              type='number'
              name='upperLimit'
              label='Recommended Limit'
              InputProps={{
                inputProps: {
                  min: 0,
                },
              }}
              value={values.upperLimit}
              onChange={handleChange}
              error={!(error.upperLimit === ' ')}
              helperText={error.upperLimit}
            />
            <TextField
              variant='filled'
              id='lowerLimit-input'
              type='number'
              name='lowerLimit'
              label='Critical Limit'
              InputProps={{
                inputProps: {
                  min: 0,
                },
              }}
              value={values.lowerLimit}
              onChange={handleChange}
              error={!(error.lowerLimit === ' ')}
              helperText={error.lowerLimit}
            />
            <FormControl component='fieldset'>
              <FormLabel component='legend'>Type</FormLabel>
              <RadioGroup
                name='loose'
                value={values.loose}
                onChange={handleChange}
                className={classes.radio}
              >
                <FormControlLabel
                  value='true'
                  control={<Radio />}
                  label='Loose'
                />
                <FormControlLabel
                  value='false'
                  control={<Radio />}
                  label='Packed'
                />
              </RadioGroup>
            </FormControl>
          </div>
          <Button
            type='submit'
            color='primary'
            variant='contained'
            className={classes.button}
            onClick={handleSubmit}
          >
            Update
          </Button>
        </form>
      </Paper>
    </>
  );
}
Example #16
Source File: UpdateEmployeeForm.js    From inventory-management-web with MIT License 4 votes vote down vote up
UpdateEmployee = () => {
  // get state from location
  const location = useLocation();
  const { firstName, lastName, age, isStaff, email } = location.state;
  // Use custom hook for form state management
  const {
    handleChange,
    handleSubmit,
    error,
    invalidCred,
    values,
    isLoading,
  } = useForm({ firstName, lastName, age, isStaff, email });

  const classes = useStyles({ invalid: invalidCred });

  return (
    <>
      {isLoading ? <Spinner /> : null}
      <Paper className={classes.paper}>
        <Typography variant='h4' className={classes.heading}>
          User Update
        </Typography>
        <Typography
          variant='h6'
          color='error'
          className={classes.invalid}
          gutterBottom
        >
          {invalidCred}
        </Typography>
        <form
          noValidate
          onSubmit={handleSubmit}
          autoComplete='off'
          className={classes.gridContainer}
        >
          <Divider />
          <Typography variant='h5' className={classes.formHeading}>
            Account
          </Typography>
          <div className={classes.form}>
            <TextField
              disabled
              variant='filled'
              id='email-input'
              name='email'
              type='email'
              label='Email'
              value={email}
              onChange={handleChange}
              helperText={' '}
            />
            <TextField
              required
              variant='filled'
              id='last-name-input'
              name='firstName'
              label='First Name'
              value={values.firstName}
              onChange={handleChange}
              error={!(error.firstName === ' ')}
              helperText={error.firstName}
            />
            <TextField
              required
              variant='filled'
              id='first-name-input'
              name='lastName'
              label='Last Name'
              value={values.lastName}
              onChange={handleChange}
              error={!(error.lastName === ' ')}
              helperText={error.lastName}
            />
            <TextField
              required
              variant='filled'
              id='age-input'
              name='age'
              type='number'
              label='Employee Age'
              InputProps={{
                inputProps: {
                  min: 0,
                },
              }}
              value={values.age}
              onChange={handleChange}
              error={!(error.age === ' ')}
              helperText={error.age}
            />
            <FormControl component='fieldset'>
              <FormLabel component='legend'>Type</FormLabel>
              <RadioGroup
                name='isStaff'
                value={values.isStaff}
                onChange={handleChange}
                className={classes.radio}
              >
                <FormControlLabel
                  value='True'
                  control={<Radio />}
                  label='Manager'
                />
                <FormControlLabel
                  value='False'
                  control={<Radio />}
                  label='Employee'
                />
              </RadioGroup>
            </FormControl>
          </div>
          <Button
            type='submit'
            color='primary'
            variant='contained'
            className={classes.button}
            onClick={handleSubmit}
          >
            Update
          </Button>
        </form>
      </Paper>
    </>
  );
}
Example #17
Source File: Register.js    From inventory-management-web with MIT License 4 votes vote down vote up
Register = () => {
  // Use custom hook for form state management
  const {
    handleChange,
    handleSubmit,
    error,
    invalidCred,
    values,
    showConfirmPassword,
    showPassword,
    toggleShowPassword,
    toggleShowconfirmPassword,
    isLoading,
  } = useForm();

  const classes = useStyles({ invalid: invalidCred });

  return (
    <>
      {isLoading ? <Spinner /> : null}
      <Paper className={classes.paper}>
        <Typography variant='h4' className={classes.heading}>
          Add New Employee
        </Typography>
        <Typography
          variant='h6'
          color='error'
          className={classes.invalid}
          gutterBottom
        >
          {invalidCred}
        </Typography>
        <form
          noValidate
          onSubmit={handleSubmit}
          autoComplete='off'
          className={classes.gridContainer}
        >
          <Divider />
          <Typography variant='h5' className={classes.formHeading}>
            Account
          </Typography>
          <div className={classes.form}>
            <TextField
              required
              variant='filled'
              id='last-name-input'
              name='firstName'
              label='First Name'
              value={values.firstName}
              onChange={handleChange}
              error={!(error.firstName === ' ')}
              helperText={error.firstName}
            />
            <TextField
              required
              variant='filled'
              id='first-name-input'
              name='lastName'
              label='Last Name'
              value={values.lastName}
              onChange={handleChange}
              error={!(error.lastName === ' ')}
              helperText={error.lastName}
            />
            <TextField
              required
              variant='filled'
              id='email-input'
              name='email'
              type='email'
              label='Email'
              value={values.email}
              onChange={handleChange}
              error={!(error.email === ' ')}
              helperText={error.email}
            />
            <TextField
              required
              variant='filled'
              id='password-input'
              name='password'
              type={showPassword ? 'text' : 'password'}
              label='Password'
              value={values.password}
              onChange={handleChange}
              error={!(error.password === ' ')}
              helperText={error.password}
              InputProps={{
                endAdornment: (
                  <InputAdornment position='end'>
                    <IconButton onClick={toggleShowPassword} tabIndex='-1'>
                      {showPassword ? <Visibility /> : <VisibilityOff />}
                    </IconButton>
                  </InputAdornment>
                ),
              }}
            />
            <TextField
              required
              variant='filled'
              id='confirm-password-input'
              name='confirmPassword'
              type={showConfirmPassword ? 'text' : 'password'}
              label='Confirm Password'
              value={values.confirmPassword}
              onChange={handleChange}
              error={!(error.confirmPassword === ' ')}
              helperText={error.confirmPassword}
              InputProps={{
                endAdornment: (
                  <InputAdornment position='end'>
                    <IconButton
                      onClick={toggleShowconfirmPassword}
                      tabIndex='-1'
                    >
                      {showConfirmPassword ? <Visibility /> : <VisibilityOff />}
                    </IconButton>
                  </InputAdornment>
                ),
              }}
            />
            <TextField
              required
              variant='filled'
              id='gender-input'
              name='gender'
              select
              label='Employee Gender'
              value={values.gender}
              onChange={handleChange}
              error={!(error.gender === ' ')}
              helperText={error.gender}
            >
              {['Male', 'Female', 'Other'].map((option, index) => (
                <MenuItem key={option} value={['M', 'F', 'Other'][index]}>
                  {option}
                </MenuItem>
              ))}
            </TextField>
            <TextField
              required
              variant='filled'
              id='age-input'
              name='age'
              type='number'
              label='Employee Age'
              InputProps={{
                inputProps: {
                  min: 0,
                },
              }}
              value={values.age}
              onChange={handleChange}
              error={!(error.age === ' ')}
              helperText={error.age}
            />
            <FormControl component='fieldset'>
              <FormLabel component='legend'>Type</FormLabel>
              <RadioGroup
                name='isStaff'
                value={values.isStaff}
                onChange={handleChange}
                className={classes.radio}
              >
                <FormControlLabel
                  value='true'
                  control={<Radio />}
                  label='Manager'
                />
                <FormControlLabel
                  value='false'
                  control={<Radio />}
                  label='Employee'
                />
              </RadioGroup>
            </FormControl>
          </div>
          <Button
            type='submit'
            color='primary'
            variant='contained'
            className={classes.button}
            onClick={handleSubmit}
          >
            Register
          </Button>
        </form>
      </Paper>
    </>
  );
}
Example #18
Source File: NewRequestPage.js    From app with MIT License 4 votes vote down vote up
function NewRequestPage() {
  const classes = useStyles();
  const location = useLocation();
  const qs = queryString.parse(location.search);
  const defaultValues = {
    needs: {},
    immediacy: '1',
    needFinancialAssistance: 'false',
  };

  // Append needs from query string type
  if (qs && qs.type) {
    defaultValues.needs = { [qs.type]: true };
  }

  const {
    register,
    handleSubmit,
    errors,
    watch,
    control,
    formState: { isValid, isSubmitting, dirty },
  } = useForm({
    validationSchema: requestValidationSchema,
    defaultValues,
  });

  const {
    submitRequest,
    handleLocationChange,
    requestLocation,
    requestLocationLoading,
  } = useNewRequestPage();
  const currentNeeds = watch('needs');
  const groceryPickup = currentNeeds && currentNeeds['grocery-pickup'];

  return (
    <Container maxWidth="md">
      <Helmet>
        <title>Request Assistance</title>
      </Helmet>
      <Typography variant="h5" color="textPrimary" gutterBottom>
        Request Help
      </Typography>
      <Paper className={classes.paper} data-test="request-form">
        <div className={classes.heroContent}>
          <Container maxWidth="md">
            <form onSubmit={handleSubmit(submitRequest)}>
              <Container>
                <FormGroup>
                  <Typography
                    variant="h5"
                    gutterBottom
                    className={classes.otherComments}>
                    What do you need help with?
                  </Typography>
                  {Object.keys(activeCategoryMap).map((optionKey) => (
                    <FormControlLabel
                      key={optionKey}
                      control={
                        <Checkbox
                          inputRef={register}
                          name={`needs.${optionKey}`}
                          data-test={`need-${optionKey}`}
                          defaultChecked={defaultValues.needs[optionKey]}
                        />
                      }
                      label={
                        activeCategoryMap[optionKey].inputCaption
                          ? activeCategoryMap[optionKey].inputCaption
                          : activeCategoryMap[optionKey].description
                      }
                    />
                  ))}
                </FormGroup>
                {!!errors.needs && (
                  <FormHelperText error>{errors.needs.message}</FormHelperText>
                )}

                <Typography
                  variant="h5"
                  className={classes.otherComments}
                  gutterBottom={!groceryPickup}>
                  Details
                </Typography>
                <Zoom in={groceryPickup} unmountOnExit>
                  <Typography variant="subtitle1" gutterBottom>
                    For grocery pickup, please provide the list of groceries
                    that you would like the volunteer to get. Please be as
                    specific as possible.
                  </Typography>
                </Zoom>
                <Grid container spacing={3}>
                  <Grid item xs={12}>
                    <TextField
                      name="otherDetails"
                      data-test="otherDetails"
                      multiline
                      placeholder="Please be as specific as possible."
                      fullWidth
                      rows="4"
                      variant="outlined"
                      inputRef={register}
                    />
                  </Grid>
                </Grid>

                {/* <Zoom in={hasFinancialComponent} unmountOnExit> */}
                <div>
                  <Divider className={classes.optionalDivider} />
                  <Typography variant="h5" gutterBottom>
                    Will you be able to pay for your items?
                  </Typography>
                  <Typography variant="body1" gutterBottom>
                    This service is free, but the items still cost money. Are
                    you able to pay for your items? If not, we will do our best
                    to match you with organizations and volunteers who can also
                    provide financial assistance.
                  </Typography>
                  <Controller
                    as={
                      <RadioGroup
                        aria-label="Need Financial Assistance"
                        component="fieldset">
                        <FormControlLabel
                          value="false"
                          control={<Radio />}
                          label="Yes, I can pay and only need help with the delivery."
                        />
                        <FormControlLabel
                          value="true"
                          control={<Radio />}
                          label="No, I need help paying for the items."
                        />
                      </RadioGroup>
                    }
                    control={control}
                    onChange={([event]) => event.target.value}
                    name="needFinancialAssistance"
                  />
                  {!!errors.needFinancialAssistance && (
                    <FormHelperText error>
                      {errors.needFinancialAssistance}
                    </FormHelperText>
                  )}
                </div>
                {/* </Zoom> */}

                <Divider className={classes.optionalDivider} />
                <Typography variant="h5" gutterBottom>
                  Immediacy of Need
                </Typography>
                <Typography variant="body1" gutterBottom>
                  Please let us know how urgently you need us to fulfill the
                  request. We will do our best to connect you with a volunteer
                  as soon as possible, however, we cannot guarantee anything
                  because we are dependent on volunteer availability.
                </Typography>
                <Controller
                  as={
                    <RadioGroup>
                      <FormControlLabel
                        value="1"
                        control={<Radio />}
                        label="Low"
                      />
                      <FormControlLabel
                        value="5"
                        control={<Radio />}
                        label="Medium - Not very urgent"
                      />
                      <FormControlLabel
                        value="10"
                        control={<Radio />}
                        label="High - Urgent"
                      />
                    </RadioGroup>
                  }
                  control={control}
                  name="immediacy"
                />

                {!!errors.immediacy && (
                  <FormHelperText error>
                    {errors.immediacy.message}
                  </FormHelperText>
                )}

                <Divider className={classes.optionalDivider} />
                <Typography variant="h5" gutterBottom>
                  Your Location
                </Typography>
                <Typography className={classes.intro}>
                  A rough location is needed to allow us to efficiently and
                  quickly find a match for your need. You can do this in three
                  ways: by entering your address in the address field, by
                  clicking the &quot;Detect Location&quot; button, or by
                  clicking on the map. If you decide to enter the address, we
                  will not save the actual address and instead use it to get the
                  location.
                </Typography>
                <Grid container spacing={3}>
                  <Grid item xs={12}>
                    <Card>
                      {requestLocationLoading ? (
                        <LoadingSpinner />
                      ) : (
                        <ClickableMap
                          locationInfo={requestLocation}
                          onLocationChange={handleLocationChange}
                        />
                      )}
                    </Card>
                  </Grid>
                </Grid>
                <Divider className={classes.optionalDivider} />
                <Typography variant="h5" gutterBottom>
                  Contact Information
                </Typography>
                <Typography gutterBottom>
                  To minimize exposing your contact information, we do not
                  display it unless a volunteer specifically requests to see it.
                  To further discourage any abuse, we do not display your last
                  name and also keep track of all the volunteers who have looked
                  up your contact information.
                </Typography>

                <Grid container spacing={2}>
                  <Grid item xs={12} sm={6}>
                    <TextField
                      name="firstName"
                      data-test="firstName"
                      type="text"
                      label="First Name"
                      variant="outlined"
                      inputRef={register}
                      error={!!errors.firstName}
                      fullWidth
                      helperText={errors?.firstName?.message}
                    />
                  </Grid>
                  <Grid item xs={12} sm={6}>
                    <TextField
                      name="lastName"
                      data-test="lastName"
                      type="text"
                      label="Last Name"
                      variant="outlined"
                      fullWidth
                      inputRef={register}
                      error={!!errors.lastName}
                      helperText={errors?.firstName?.message}
                    />
                  </Grid>
                  <Grid item xs={12} sm={6}>
                    <TextField
                      name="phone"
                      data-test="phone"
                      type="text"
                      label="Phone Number"
                      variant="outlined"
                      fullWidth
                      inputRef={register}
                      error={!!errors.phone}
                      helperText={errors?.phone?.message}
                    />
                  </Grid>
                  <Grid item xs={12} sm={6}>
                    <TextField
                      name="email"
                      type="text"
                      data-test="email"
                      label="Email"
                      variant="outlined"
                      fullWidth
                      inputRef={register}
                      error={!!errors.email}
                      helperText={errors?.email?.message}
                    />
                  </Grid>
                </Grid>

                <Typography className={classes.warrantyInfo}>
                  Note: This website and all related work products are provided
                  &quot;AS IS&quot;. The provider of this service makes no other
                  warranties, express or implied, and hereby disclaims all
                  implied warranties, including any warranty of merchantability
                  and warranty of fitness for a particular purpose.
                </Typography>

                {dirty && !!Object.keys(errors).length && !isValid && (
                  <Typography variant="body2" className={classes.errorText}>
                    Please fix the errors above.
                  </Typography>
                )}

                <div className={classes.buttons}>
                  <Button
                    type="submit"
                    variant="contained"
                    color="primary"
                    data-test="submit-request"
                    disabled={isSubmitting}>
                    Submit Request
                  </Button>
                </div>
              </Container>
            </form>
          </Container>
        </div>
      </Paper>
    </Container>
  );
}
Example #19
Source File: MockLogin.jsx    From Edlib with GNU General Public License v3.0 4 votes vote down vote up
MockLogin = () => {
    const history = useHistory();
    const [firstName, setFirstName] = React.useState(() => {
        const stored = store.get('firstName');
        return stored ? stored : '';
    });
    const [lastName, setLastName] = React.useState(() => {
        const stored = store.get('lastName');
        return stored ? stored : '';
    });
    const [email, setEmail] = React.useState(() => {
        const stored = store.get('email');
        return stored ? stored : '';
    });
    const [id, setId] = React.useState(() => {
        const stored = store.get('userId');
        return stored ? stored : '';
    });
    const [language, setLanguage] = React.useState(() => {
        const stored = store.get('language');
        return stored ? stored : 'nb';
    });

    React.useEffect(() => {
        store.set('firstName', firstName);
        store.set('lastName', lastName);
        store.set('email', email);
        store.set('userId', id);
        store.set('language', language);
    }, [firstName, lastName, email, id, language]);

    return (
        <div style={{ maxWidth: 500 }}>
            <div>
                <TextField
                    label="First name"
                    value={firstName}
                    onChange={(e) => setFirstName(e.target.value)}
                    margin="normal"
                />
                <TextField
                    label="Last name"
                    value={lastName}
                    onChange={(e) => setLastName(e.target.value)}
                    margin="normal"
                />
            </div>
            <div>
                <TextField
                    label="Email"
                    value={email}
                    onChange={(e) => setEmail(e.target.value)}
                    margin="normal"
                    fullWidth
                />
                <TextField
                    label="User ID"
                    value={id}
                    onChange={(e) => setId(e.target.value)}
                    margin="normal"
                    fullWidth
                />
            </div>
            <div>
                <FormControl component="fieldset">
                    <FormLabel component="legend">Language</FormLabel>
                    <RadioGroup
                        name="language"
                        value={language}
                        onChange={(e) => setLanguage(e.target.value)}
                    >
                        <FormControlLabel
                            value="nb"
                            control={<Radio />}
                            label="Norsk"
                        />
                        <FormControlLabel
                            value="en"
                            control={<Radio />}
                            label="English"
                        />
                    </RadioGroup>
                </FormControl>
            </div>
            <Button
                color="primary"
                variant="contained"
                onClick={() => {
                    history.push(
                        `/login/callback?jwt=${sign(
                            {
                                exp: Math.floor(Date.now() / 1000) + 60 * 60,
                                data: {
                                    isFakeToken: true,
                                    user: {
                                        firstName:
                                            firstName.length !== 0
                                                ? firstName
                                                : null,
                                        lastName:
                                            lastName.length !== 0
                                                ? lastName
                                                : null,
                                        email:
                                            email.length !== 0 ? email : null,
                                        id,
                                        isAdmin: true,
                                    },
                                },
                                iss: 'fake',
                            },
                            'anything'
                        )}`
                    );
                }}
            >
                Start new session
            </Button>
        </div>
    );
}
Example #20
Source File: AuthWrapper.jsx    From Edlib with GNU General Public License v3.0 4 votes vote down vote up
AuthWrapper = ({ children }) => {
    const [jwtToken, setJwtToken] = React.useState(null);

    const [firstName, setFirstName] = React.useState(() => {
        const stored = store.get('firstName');
        return stored ? stored : '';
    });
    const [lastName, setLastName] = React.useState(() => {
        const stored = store.get('lastName');
        return stored ? stored : '';
    });
    const [email, setEmail] = React.useState(() => {
        const stored = store.get('email');
        return stored ? stored : '';
    });
    const [id, setId] = React.useState(() => {
        const stored = store.get('userId');
        return stored ? stored : '';
    });
    const [language, setLanguage] = React.useState(() => {
        const stored = store.get('language');
        return stored ? stored : 'nb';
    });

    React.useEffect(() => {
        store.set('firstName', firstName);
        store.set('lastName', lastName);
        store.set('email', email);
        store.set('userId', id);
        store.set('language', language);
    }, [firstName, lastName, email, id, language]);

    if (!jwtToken) {
        return (
            <div style={{ maxWidth: 500 }}>
                <div>
                    <TextField
                        label="First name"
                        value={firstName}
                        onChange={(e) => setFirstName(e.target.value)}
                        margin="normal"
                    />
                    <TextField
                        label="Last name"
                        value={lastName}
                        onChange={(e) => setLastName(e.target.value)}
                        margin="normal"
                    />
                </div>
                <div>
                    <TextField
                        label="Email"
                        value={email}
                        onChange={(e) => setEmail(e.target.value)}
                        margin="normal"
                        fullWidth
                    />
                    <TextField
                        label="User ID"
                        value={id}
                        onChange={(e) => setId(e.target.value)}
                        margin="normal"
                        fullWidth
                    />
                </div>
                <div>
                    <FormControl component="fieldset">
                        <FormLabel component="legend">Language</FormLabel>
                        <RadioGroup
                            name="language"
                            value={language}
                            onChange={(e) => setLanguage(e.target.value)}
                        >
                            <FormControlLabel
                                value="nb"
                                control={<Radio />}
                                label="Norsk"
                            />
                            <FormControlLabel
                                value="en"
                                control={<Radio />}
                                label="English"
                            />
                        </RadioGroup>
                    </FormControl>
                </div>
                <Button
                    color="primary"
                    variant="contained"
                    onClick={() => {
                        setJwtToken(
                            sign(
                                {
                                    exp:
                                        Math.floor(Date.now() / 1000) + 60 * 60,
                                    data: {
                                        isFakeToken: true,
                                        user: {
                                            firstName:
                                                firstName.length !== 0
                                                    ? firstName
                                                    : null,
                                            lastName:
                                                lastName.length !== 0
                                                    ? lastName
                                                    : null,
                                            email:
                                                email.length !== 0
                                                    ? email
                                                    : null,
                                            id,
                                            isAdmin: true,
                                        },
                                    },
                                    iss: 'fake',
                                },
                                'anything'
                            )
                        );
                    }}
                >
                    Start new session
                </Button>
            </div>
        );
    }

    return children({
        getJwt: async () => {
            if (jwtToken && isTokenExpired(jwtToken)) {
                setJwtToken(null);
                return null;
            }

            return jwtToken;
        },
        getLanguage: () => {
            return language;
        },
    });
}
Example #21
Source File: CourseFilterSidebar.js    From course-manager with MIT License 4 votes vote down vote up
export default function ShopFilterSidebar({
  isOpenFilter,
  onResetFilter,
  onOpenFilter,
  onCloseFilter,
  formik
}) {
  const { values, getFieldProps, handleChange } = formik;

  return (
    <>
      <Button
        disableRipple
        color="inherit"
        endIcon={<Icon icon={roundFilterList} />}
        onClick={onOpenFilter}
      >
        Filters&nbsp;
      </Button>

      <FormikProvider value={formik}>
        <Form autoComplete="off" noValidate>
          <Drawer
            anchor="right"
            open={isOpenFilter}
            onClose={onCloseFilter}
            PaperProps={{
              sx: { width: 280, border: 'none', overflow: 'hidden' }
            }}
          >
            <Stack
              direction="row"
              alignItems="center"
              justifyContent="space-between"
              sx={{ px: 1, py: 2 }}
            >
              <Typography variant="subtitle1" sx={{ ml: 1 }}>
                Filters
              </Typography>
              <IconButton onClick={onCloseFilter}>
                <Icon icon={closeFill} width={20} height={20} />
              </IconButton>
            </Stack>

            <Divider />

            <Scrollbar>
              <Stack spacing={3} sx={{ p: 3 }}>
                <div>
                  <Typography variant="subtitle1" gutterBottom>
                    Gender
                  </Typography>
                  <FormGroup>
                    {FILTER_GENDER_OPTIONS.map((item) => (
                      <FormControlLabel
                        key={item}
                        control={
                          <Checkbox
                            {...getFieldProps('gender')}
                            value={item}
                            checked={values.gender.includes(item)}
                          />
                        }
                        label={item}
                      />
                    ))}
                  </FormGroup>
                </div>

                <div>
                  <Typography variant="subtitle1" gutterBottom>
                    Category
                  </Typography>
                  <RadioGroup {...getFieldProps('category')}>
                    {FILTER_CATEGORY_OPTIONS.map((item) => (
                      <FormControlLabel key={item} value={item} control={<Radio />} label={item} />
                    ))}
                  </RadioGroup>
                </div>

                <div>
                  <Typography variant="subtitle1" gutterBottom>
                    Colour
                  </Typography>
                  <ColorManyPicker
                    name="colors"
                    colors={FILTER_COLOR_OPTIONS}
                    onChange={handleChange}
                    onChecked={(color) => values.colors.includes(color)}
                    sx={{ maxWidth: 36 * 4 }}
                  />
                </div>

                <div>
                  <Typography variant="subtitle1" gutterBottom>
                    Price
                  </Typography>
                  <RadioGroup {...getFieldProps('priceRange')}>
                    {FILTER_PRICE_OPTIONS.map((item) => (
                      <FormControlLabel
                        key={item.value}
                        value={item.value}
                        control={<Radio />}
                        label={item.label}
                      />
                    ))}
                  </RadioGroup>
                </div>

                <div>
                  <Typography variant="subtitle1" gutterBottom>
                    Rating
                  </Typography>
                  <RadioGroup {...getFieldProps('rating')}>
                    {FILTER_RATING_OPTIONS.map((item, index) => (
                      <FormControlLabel
                        key={item}
                        value={item}
                        control={
                          <Radio
                            disableRipple
                            color="default"
                            icon={<Rating readOnly value={4 - index} />}
                            checkedIcon={<Rating readOnly value={4 - index} />}
                          />
                        }
                        label="& Up"
                        sx={{
                          my: 0.5,
                          borderRadius: 1,
                          '& > :first-of-type': { py: 0.5 },
                          '&:hover': {
                            opacity: 0.48,
                            '& > *': { bgcolor: 'transparent' }
                          },
                          ...(values.rating.includes(item) && {
                            bgcolor: 'background.neutral'
                          })
                        }}
                      />
                    ))}
                  </RadioGroup>
                </div>
              </Stack>
            </Scrollbar>

            <Box sx={{ p: 3 }}>
              <Button
                fullWidth
                size="large"
                type="submit"
                color="inherit"
                variant="outlined"
                onClick={onResetFilter}
                startIcon={<Icon icon={roundClearAll} />}
              >
                Clear All
              </Button>
            </Box>
          </Drawer>
        </Form>
      </FormikProvider>
    </>
  );
}
Example #22
Source File: CargoShip.jsx    From archeage-tools with The Unlicense 4 votes vote down vote up
render() {
    const { alerts, setAlert, speak, setSpeak, servers, server: serverId, mobile, openDialog } = this.props;
    const { open, setup, stepIndex, endTime, shipPosition, menu, updated } = this.state;
    const now = moment();
    let eventStepTime = moment(endTime);
    const step = CARGO_SCHEDULE[stepIndex];

    const server = servers[serverId];
    const serverName = pathOr('???', ['name'])(server);

    return [
      <Paper className="cargo-ship event-list" key="cargo-timer">
        <AppBar position="static">
          <Toolbar variant="dense">
            <Icon><img src={'/images/event_type/exploration.png'} alt="Cargo Ship" /></Icon>
            <Typography variant="subtitle1" className="title-text">[{serverName}] Cargo Ship</Typography>
            <IfPerm permission={`cargo.${serverName.toLowerCase()}`}>
              <Tooltip title={`Edit ${serverName} Timer`}>
                <IconButton onClick={this.toggleDialog} color="inherit">
                  <EditIcon />
                </IconButton>
              </Tooltip>
            </IfPerm>
            <Tooltip title="Change Server">
              <IconButton onClick={() => openDialog(DIALOG_MY_GAME, SERVER)} color="inherit">
                <HomeIcon />
              </IconButton>
            </Tooltip>
            <Tooltip title="Configure alerts">
              <IconButton
                onClick={this.handleOpenMenu}
                className="super-btn"
              >
                <NotificationsIcon
                  className={cn({ 'notif-fade': alerts.length === 0 })}
                  color="inherit"
                />
                {alerts.length > 0 &&
                <Typography className="super-text" color="primary">{alerts.length}</Typography>}
              </IconButton>
            </Tooltip>
          </Toolbar>
        </AppBar>
        <div className="cargo-slider">
          <div className="cargo-rail" />
          <Tooltip title="Solis Headlands Trade Outlet">
            <div className="cargo-icon austera" />
          </Tooltip>
          <Tooltip title="Two Crowns Trade Outlet">
            <div className="cargo-icon two-crowns" />
          </Tooltip>
          <div
            className={cn('cargo-icon ship', { moving: !step.port, reverse: step.reverse })}
            style={{ [step.reverse ? 'left' : 'right']: `${(shipPosition / step.duration) * 100}%` }}
          />
        </div>
        <div className="cargo-text">
          {!server &&
          <Typography>Select a server to see the cargo ship location.</Typography>}
          {server && !updated &&
          <Typography>The cargo ship has not been updated since the last maintenance.</Typography>}
          {server && updated &&
          <>
            <Typography>Cargo ship is {step.text}.</Typography>
            <br />
            <Table size="small" stickyHeader className="timer-table">
              <TableHead>
                <TableRow>
                  <TableCell>
                    Event
                  </TableCell>
                  <TableCell>
                    Time
                  </TableCell>
                  <TableCell align="right">
                    Countdown
                  </TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {Array.from(Array(CARGO_SCHEDULE.length).keys()).map((_, i) => {
                  const index = getNextIndex(stepIndex + i - 1);
                  const step = CARGO_SCHEDULE[index];
                  if (i > 0) {
                    eventStepTime.add(step.duration, 'seconds');
                  }
                  return (
                    <TableRow key={`cargo-${i}`}>
                      <TableCell>{step.next}</TableCell>
                      <TableCell>{eventStepTime.format('h:mm A')}</TableCell>
                      <TableCell align="right">{hhmmssFromDate(eventStepTime.diff(now))}</TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          </>}
        </div>
      </Paper>,
      <Dialog
        open={open}
        key="cargo-settings"
        onClose={this.toggleDialog}
        maxWidth="sm"
      >
        <AppBar position="static">
          <Toolbar variant="dense">
            <Typography variant="subtitle1" className="title-text">Cargo Ship Setup</Typography>
            <Tooltip title="Close">
              <IconButton onClick={this.toggleDialog}>
                <CloseIcon />
              </IconButton>
            </Tooltip>
          </Toolbar>
        </AppBar>
        <DialogContent>
          <Typography>To setup the timer, the ship must currently be docked at a port.</Typography>
          <br />
          <FormControl component="fieldset">
            <FormLabel component="legend">What port is the ship at?</FormLabel>
            <RadioGroup name="port" value={Number.parseInt(setup.port)} onChange={this.handleSetupChange('port')} row>
              <FormControlLabel
                control={<Radio color="primary" />}
                label="Solis Headlands"
                value={ZONE.SOLIS_HEADLANDS}
              />
              <FormControlLabel
                control={<Radio color="primary" />}
                label="Two Crowns"
                value={ZONE.TWO_CROWNS}
              />
            </RadioGroup>
          </FormControl>
          <FormControl component="fieldset">
            <FormLabel component="legend">What is the remaining time on the &quot;Cargo Ship
              Anchored&quot; buff?</FormLabel>
            <div className="duration-pick">
              <Input
                id="mm"
                placeholder="20"
                endAdornment="m"
                inputProps={{
                  maxLength: 2,
                  ref: this.mm,
                }}
                value={setup.mm}
                onChange={this.handleTimeChange('mm')}
                onKeyPress={this.handleEnter}
              />
              <Input
                id="ss"
                placeholder="00"
                endAdornment="s"
                inputProps={{
                  maxLength: 2,
                  ref: this.ss,
                }}
                value={setup.ss}
                onChange={this.handleTimeChange('ss')}
                onKeyPress={this.handleEnter}
              />
            </div>
          </FormControl>
          <FormControl component="fieldset">
            <FormControlLabel
              control={<Checkbox color="primary" />}
              label="Don't Update Sibling Realms"
              checked={setup.noLinkedUpdate}
              onChange={this.handleNoLink}
            />
          </FormControl>
        </DialogContent>
        <DialogActions>
          <Button
            onClick={this.submitSetup}
            color="primary"
            disabled={!setup.port || (String(setup.mm).length === 0 && String(setup.ss).length === 0)}
          >
            Update
          </Button>
        </DialogActions>
      </Dialog>,
      <Menu
        id="alert-menu"
        anchorEl={menu}
        anchorOrigin={{
          vertical: 'top',
          horizontal: 'center',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'center',
        }}
        getContentAnchorEl={null}
        open={Boolean(menu)}
        onClose={this.handleCloseMenu}
        className="alert-menu"
        autoFocus={false}
        key="alert-menu"
        variant="menu"
      >
        <ListItem tabIndex={null} dense={!mobile}>
          <ListItemText>Alert Types:</ListItemText>
        </ListItem>
        <MenuItem disabled dense={!mobile}>
          <ListItemIcon>
            <CheckBoxIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText>Audio Cue</ListItemText>
        </MenuItem>
        <MenuItem
          onClick={setSpeak(CARGO_ID, !speak)}
          dense={!mobile}
          disabled={!CAN_SPEAK}
          divider
        >
          <ListItemIcon>
            {speak
              ? <CheckBoxIcon fontSize="small" color="primary" />
              : <CheckBoxOutlineBlankIcon fontSize="small" />}
          </ListItemIcon>
          <ListItemText>Audio Message</ListItemText>
        </MenuItem>
        <ListItem tabIndex={null} dense={!mobile}>
          <ListItemText>Alert Times:</ListItemText>
          <ListItemSecondaryAction>
            <Tooltip title="Clear all">
                <span>
                  <IconButton size="small" onClick={setAlert(CARGO_ID, '')} disabled={alerts.length === 0}>
                    <CloseIcon fontSize="small" />
                  </IconButton>
                </span>
            </Tooltip>
          </ListItemSecondaryAction>
        </ListItem>
        {Object.entries(CARGO_ALERTS).map(([key, option]) => (
          <MenuItem
            dense={!mobile}
            onClick={setAlert(CARGO_ID, key)}
            key={`alert-opt-${randomString(16)}-${key}`}
          >
            <ListItemIcon>
              {alerts.includes(key)
                ? <CheckBoxIcon fontSize="small" color="primary" />
                : <CheckBoxOutlineBlankIcon fontSize="small" />}
            </ListItemIcon>
            <ListItemText>{option.name}</ListItemText>
          </MenuItem>
        ))}
      </Menu>,
    ];
  }
Example #23
Source File: RecipeViewer.jsx    From archeage-tools with The Unlicense 4 votes vote down vote up
// eslint-disable-next-line complexity
  render() {
    const { items, recipes, proficiencies, itemPrice, categories, subCategories } = this.props;
    const { handleClose, calculateLabor, openDialog } = this.props;
    const { mobile, recipeId } = this.props;
    const { materials, quantity, inventory } = this.props;

    const { showBreakdown, auctionCut } = this.state;

    const recipe = recipes[recipeId] || {};

    if (recipe.name) {
      setTitle(`${recipe.name} - Folio`);
    }

    const materialList = {};
    let craftGold = Math.round(recipe.gold * (materials.sale ? CRAFT_GOLD_SALE : 1)) * quantity;
    let craftLabor = calculateLabor(recipe.labor, recipe.vocation) * quantity;
    const addMaterial = (itemId, quantity) => {
      if (!materialList[itemId]) {
        materialList[itemId] = 0;
      }
      materialList[itemId] += quantity;
    };
    const calculateMatStep = ((material, materials) => {
      const { item: itemId, quantity } = material;
      const options = materials[itemId] || {};
      const value = pathOr('gold', ['value'])(options);
      if (value === 'gold') {
        addMaterial(itemId, quantity);
        craftLabor += options.labor || 0;
      } else {
        const recipe = Object.values(recipes).find(r => String(r.id) === value);
        if (recipe) {
          recipe.materials.forEach((mat) => calculateMatStep({
            ...mat,
            quantity: Math.ceil(quantity / recipe.quantity) * mat.quantity,
          }, options));
          craftGold += Math.round(recipe.gold * (options.sale ? CRAFT_GOLD_SALE : 1)) *
            Math.ceil(quantity / recipe.quantity);
          craftLabor += calculateLabor(recipe.labor, recipe.vocation) * Math.ceil(quantity / recipe.quantity);
        }
      }
    });

    if (recipe.materials) {
      recipe.materials.forEach((mat) => {
        calculateMatStep({ ...mat, quantity: mat.quantity * quantity }, materials);
      });
    }

    let rankCategory = {};
    if (recipe.rank) {
      if ((recipe.subCat1 || recipe.subCat2) && objectHasProperties(subCategories)) {
        rankCategory = subCategories[recipe.subCat2 || recipe.subCat1];

        if (recipe.subCat2) {
          rankCategory.parent = subCategories[recipe.subCat1];
        } else {
          rankCategory.parent = categories[recipe.category];
        }
      } else {
        rankCategory = objectHasProperties(categories) ? categories[recipe.category] : {};
      }
    }
    let rankCategoryName = rankCategory.name || '';
    let rankRecipes = recipe.rank
      ? Object.values(recipes).filter(r => r.category === recipe.category && r.subCat1 === recipe.subCat1 && r.subCat2 === recipe.subCat2 && r.rank > 0).sort(sortBy('rank'))
      : [];
    if (rankRecipes.filter(r => r.rank === 1).length > 1) {
      rankRecipes = rankRecipes.filter(r => r.workbench === recipe.workbench);
    }
    if (rankCategoryName === 'Single Production') {
      rankCategory = rankCategory.parent;
      rankCategoryName = `${rankCategory.name} Production`;
    } else if (rankCategoryName === 'Mass Production') {
      rankCategory = rankCategory.parent;
      rankCategoryName = `${rankCategory.name} Mass Production`;
    }

    const totalGold = (craftGold || 0) + (objectHasProperties(materialList)
      ? Object.entries(materialList)
      .map(([itemId, quantity]) =>
        Math.max(quantity - (inventory[itemId] || 0), 0) * (itemPrice[itemId] || 0) * 10000)
      .reduce((a, b) => a + b)
      : 0);
    const salePrice = (quantity * recipe.quantity * (itemPrice[recipe.item] || 0) * 10000) * Number.parseFloat(auctionCut);

    return (
      <div ref={this.recipeRef}>
        <AppBar position="static">
          <Toolbar variant="dense">
            <Typography variant="h6" className="title-text">
              {recipe.name}
            </Typography>
            <Tooltip title="Configure Proficiency">
              <IconButton onClick={() => openDialog(DIALOG_MY_GAME, PROFICIENCIES)} color="inherit">
                <ListAltIcon />
              </IconButton>
            </Tooltip>
            {handleClose &&
            <Tooltip title="Close">
              <IconButton onClick={handleClose} color="inherit">
                <CloseIcon />
              </IconButton>
            </Tooltip>
            }
          </Toolbar>
        </AppBar>
        <DialogContent className="body-container">
          <div className="craft-container">
            <div className="craft-rank craft-section">
              <Typography className="craft-header">Crafting Rank</Typography>
              <Typography variant="subtitle2">{recipe.rank ? `${rankCategoryName} Rank ${recipe.rank}`
                : 'This item has no rank.'}</Typography>
              <RadioGroup row>
                {rankRecipes.map(r => (
                  <Tooltip title={`Rank ${r.rank}: ${r.name}`} key={`rank-${r.rank}-${r.id}`}>
                    <Radio
                      checked={r.rank === recipe.rank}
                      color="secondary"
                      onChange={(e, checked) => checked && this.goToRecipe(r.id)}
                    />
                  </Tooltip>
                ))}
                {rankRecipes.length === 0 &&
                <>
                  <Radio disabled />
                  <Radio disabled />
                  <Radio disabled />
                  <Radio disabled />
                  <Radio disabled />
                </>}
              </RadioGroup>
            </div>
            <div className="craft-result craft-section">
              <Typography className="craft-header">Craftable Item</Typography>
              <div className="item-block">
                <div className="craft-item">
                  {recipe.item && <Item id={recipe.item} count={recipe.quantity} grade={recipe.grade} />}
                </div>
                <Typography>
                  {recipe.quantity > 1 ? `[${recipe.quantity}]` : ''} {pathOr('', [recipe.item, 'name'])(items)}
                </Typography>
              </div>
            </div>
            <div className="craft-requirements craft-section">
              <Typography className="craft-header">Requirements</Typography>
              <Typography
                variant="subtitle2">{recipe.workbench && `Workbench: ${recipe.workbench}`}&nbsp;</Typography>
              <Typography
                variant="subtitle2"
                className={cn({ 'craft-locked': (proficiencies[recipe.vocation] || 0) < recipe.requiredProficiency })}
              >
                {recipe.requiredProficiency > 0 && `Proficiency: ${recipe.vocation}`}&nbsp;
              </Typography>
              <Typography
                variant="subtitle2"
                className={cn('craft-req-prof', { 'craft-locked': (proficiencies[recipe.vocation] || 0) < recipe.requiredProficiency })}
              >
                {recipe.requiredProficiency === 230000
                  ? <>
                    <div
                      className={cn('famed-icon', { locked: (proficiencies[recipe.vocation] || 0) < recipe.requiredProficiency })}
                    />
                    {(proficiencies[recipe.vocation] || 0) < recipe.requiredProficiency &&
                    <span>Max Proficiency Required</span>}
                  </>
                  : <>
                    {recipe.requiredProficiency > 0 && recipe.requiredProficiency}
                  </>}
                &nbsp;
              </Typography>
            </div>
            <div className="craft-resource craft-section">
              <Typography className="craft-header">Using Resource</Typography>
              <Typography
                variant="subtitle2"
                className={cn({ 'text-green': calculateLabor(recipe.labor, recipe.vocation) < recipe.labor })}
              >
                {recipe.name && `Labor Cost: ${calculateLabor(recipe.labor, recipe.vocation)}`}&nbsp;
              </Typography>
              <div className="craft-materials">
                {[0, 1, 2, 3, 4, 5].map((i) => (
                  <div
                    className="craft-item sm"
                    key={pathOr(`material-${i}`, ['materials', i, 'item'])(recipe)}
                    onClick={() => this.handleClickMaterial(pathOr(null, ['materials', i, 'item'])(recipe))}
                    style={{ cursor: recipe.materials && recipe.materials[i] ? 'pointer' : 'default' }}
                  >
                    {recipe.materials && recipe.materials[i] &&
                    <Item
                      id={recipe.materials[i].item}
                      grade={recipe.materials[i].grade}
                      count={recipe.materials[i].quantity}
                    />}
                  </div>
                ))}
              </div>
            </div>
            <div className="craft-cost">
              {!materials.sale &&
              <Typography variant="subtitle2" className="craft-header">Cost</Typography>}
              {materials.sale &&
              <div className="sale">
                <div className="icon" />
                <Typography>10%</Typography>
              </div>}
              <span className="craft-gold">
                <Currency
                  type={CURRENCY.COIN}
                  count={(recipe.gold || 0) * (materials.sale ? CRAFT_GOLD_SALE : 1)}
                  inline />
              </span>
            </div>
          </div>
          <div style={{ clear: 'both' }} />
          <Divider />
          <div className="material-breakdown">
            <div className="material-header">
              <Typography variant="h6">{!mobile && 'Crafting '}Breakdown</Typography>
              <div>
                <InputLabel htmlFor="craft-qty">Quantity:</InputLabel>
                <NumberField
                  id="craft-qty"
                  value={quantity}
                  onChange={this.handleQuantity}
                  min={1}
                  max={MAX_CRAFT_QTY}
                />
                <Tooltip
                  title={
                    <div>
                      <Typography variant="subtitle1">Sale:</Typography>
                      <div>Toggle the 10% gold cost bonus from workstation ownership.</div>
                    </div>
                  }
                >
                  <Checkbox
                    checked={materials.sale || false}
                    onChange={this.handleUpdateSale}
                    value="sale"
                    color="primary"
                  />
                </Tooltip>
                <IconButton
                  onClick={this.toggleBreakdown}
                >
                  {showBreakdown ? <ExpandLessIcon /> : <ExpandMoreIcon />}
                </IconButton>
              </div>
            </div>
            <Collapse in={showBreakdown} unmountOnExit>
              {recipe.materials && recipe.materials.map(mat => (
                <Material
                  key={`mat-${mat.item}`}
                  recipeId={recipe.id}
                  {...mat}
                  quantity={mat.quantity * quantity}
                  materials={materials[mat.item]}
                  recipes={recipes}
                  onUpdate={this.handleUpdateMaterial(mat.item)}
                  depth={1}
                />
              ))}
            </Collapse>
          </div>
          <AdContainer type="horizontal" data-id={recipeId} />
          <Divider />
          <div className="material-breakdown">
            <div className="material-header">
              <Typography variant="h6">Crafting Totals</Typography>
            </div>
            <Table size={mobile ? 'medium' : 'small'}>
              <TableHead>
                <TableRow>
                  <TableCell>Material</TableCell>
                  <TableCell align="right">Qty</TableCell>
                  <TableCell align="right">Have</TableCell>
                  <TableCell align="right">Need</TableCell>
                  <TableCell align="right">Gold per unit</TableCell>
                  <TableCell align="right" nowrap="true">Total Gold</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {Object.entries(materialList).map(([itemId, quantity]) => (
                  <TableRow
                    key={`mat-total-${itemId}`}
                    className={cn({ 'row-complete': (inventory[itemId] >= quantity) })}
                  >
                    <TableCell>
                      <ItemLink id={Number(itemId)} noLink name={mobile ? '' : null} />
                    </TableCell>
                    <TableCell align="right">
                      {quantity}
                    </TableCell>
                    <TableCell align="right">
                      <NumberField
                        value={inventory[itemId] || 0}
                        onChange={this.handleMaterialQuantity(itemId)}
                        min={0}
                        max={quantity}
                        inputStyle={{ width: 60 }}
                      />
                    </TableCell>
                    <TableCell align="right">
                      {Math.max(quantity - (inventory[itemId] || 0), 0)}
                    </TableCell>
                    <TableCell align="right">
                      <ItemPrice itemId={Number(itemId)} unitSize={1} />
                    </TableCell>
                    <TableCell align="right" nowrap="true">
                      <Currency
                        type={CURRENCY.COIN}
                        count={Math.max(quantity - (inventory[itemId] || 0), 0) * (itemPrice[itemId] || 0) * 10000}
                      />
                    </TableCell>
                  </TableRow>
                ))}
                <TableRow>
                  <TableCell colSpan={4} />
                  <TableCell align="right">Craft Gold:</TableCell>
                  <TableCell align="right" nowrap="true"><Currency type={CURRENCY.COIN} count={craftGold} /></TableCell>
                </TableRow>
                <TableRow>
                  <TableCell colSpan={4} />
                  <TableCell align="right">Total Gold:</TableCell>
                  <TableCell align="right" nowrap="true">
                    <Currency type={CURRENCY.COIN} count={totalGold} />
                  </TableCell>
                </TableRow>
                <TableRow>
                  <TableCell colSpan={4} />
                  <TableCell align="right">Total Labor:</TableCell>
                  <TableCell align="right">{craftLabor || 0}</TableCell>
                </TableRow>
              </TableBody>
            </Table>
          </div>
          {recipe.item && items[recipe.item] &&
          <>
            <Divider />
            <div className="material-breakdown">
              <div className="material-header">
                <Typography variant="h6" style={{ display: 'inline-block' }}>Crafting Profits</Typography>
                {items[recipe.item].bindsOnPickup &&
                <Typography
                  variant="body2"
                  style={{ placeSelf: 'start', flex: 1, marginLeft: 6 }}
                >
                  (Binds on Pickup)
                </Typography>}
              </div>
              <Table size={mobile ? 'medium' : 'small'}>
                <TableHead>
                  <TableRow>
                    <TableCell>Gold per unit</TableCell>
                    <TableCell>AH Cut</TableCell>
                    <TableCell />
                    <TableCell />
                  </TableRow>
                </TableHead>
                <TableBody>
                  <TableRow>
                    <TableCell>
                      <ItemPrice itemId={recipe.item} unitSize={1} />
                    </TableCell>
                    <TableCell>
                      <Tooltip title={<Typography variant="subtitle1">10% Auction Cut</Typography>}>
                        <Checkbox
                          checked={auctionCut === String(STANDARD_AH_CUT)}
                          onChange={this.setAuctionCut}
                          value={STANDARD_AH_CUT}
                          color="primary"
                        />
                      </Tooltip>
                      <Tooltip title={<Typography variant="subtitle1">5% Auction Cut</Typography>}>
                        <Checkbox
                          checked={auctionCut === String(PATRON_AH_CUT)}
                          onChange={this.setAuctionCut}
                          value={PATRON_AH_CUT}
                          color="primary"
                        />
                      </Tooltip>
                    </TableCell>
                    <TableCell align="right">Sale Price</TableCell>
                    <TableCell align="right">
                      <Currency
                        type={CURRENCY.COIN}
                        count={salePrice}
                      />
                    </TableCell>
                  </TableRow>
                  <TableRow>
                    <TableCell colSpan={2} />
                    <TableCell align="right">Profit:</TableCell>
                    <TableCell align="right">
                      <Currency type={CURRENCY.COIN} count={(salePrice - totalGold)} />
                    </TableCell>
                  </TableRow>
                  {craftLabor > 0 &&
                  <TableRow>
                    <TableCell colSpan={2} />
                    <TableCell align="right">Silver per Labor:</TableCell>
                    <TableCell align="right">
                      <Currency type={CURRENCY.COIN} count={(salePrice - totalGold) / craftLabor} />
                    </TableCell>
                  </TableRow>}
                </TableBody>
              </Table>
            </div>
          </>}
        </DialogContent>
      </div>
    );
  }