@mui/material#FormGroup TypeScript Examples

The following examples show how to use @mui/material#FormGroup. 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: OptionsCheck.tsx    From ui-schema with MIT License 6 votes vote down vote up
OptionsCheck: React.ComponentType<WidgetProps<MuiWidgetBinding> & OptionsCheckRendererProps> = (
    {
        schema, storeKeys, showValidity, valid, required, errors,
        row, widgets,
    }
) => {
    const oneOfVal = schema.getIn(['items', 'oneOf'])
    if (!oneOfVal) return null
    const InfoRenderer = widgets?.InfoRenderer
    return <FormControl
        required={required} error={!valid && showValidity} component="fieldset" fullWidth
        size={schema.getIn(['view', 'dense']) ? 'small' : undefined}
        disabled={schema.get('readOnly') as boolean}
    >
        <FormLabel component="legend" style={{width: '100%'}}>
            <TransTitle schema={schema} storeKeys={storeKeys}/>
            {InfoRenderer && schema?.get('info') ?
                <InfoRenderer
                    schema={schema} variant={'icon'} openAs={'modal'}
                    storeKeys={storeKeys} valid={valid} errors={errors}
                    align={'right'} dense
                /> :
                undefined}
        </FormLabel>
        <FormGroup row={row}>
            <OptionsCheckValue
                oneOfValues={oneOfVal as List<OrderedMap<string, string>>} storeKeys={storeKeys}
                required={required} schema={schema}
                disabled={schema.get('readOnly') as boolean}
            />
        </FormGroup>

        <ValidityHelperText errors={errors} showValidity={showValidity} schema={schema}/>
    </FormControl>
}
Example #2
Source File: SettingsModal.tsx    From rewind with MIT License 6 votes vote down vote up
function BeatmapRenderSettings() {
  const { beatmapRenderSettingsStore } = useCommonManagers();
  const settings = useObservable(() => beatmapRenderSettingsStore.settings$, DEFAULT_BEATMAP_RENDER_SETTINGS);

  return (
    <Stack>
      <FormGroup>
        <FormControlLabel
          control={
            <Switch
              checked={settings.sliderDevMode}
              onChange={(event) => beatmapRenderSettingsStore.setSliderDevMode(event.target.checked)}
            />
          }
          label={"Slider Dev Mode"}
        />
      </FormGroup>
      {/*  draw slider ends*/}
    </Stack>
  );
}
Example #3
Source File: SettingsModal.tsx    From rewind with MIT License 6 votes vote down vote up
function AnalysisCursorSettingsSection() {
  const { analysisCursorSettingsStore } = useCommonManagers();
  const settings = useObservable(() => analysisCursorSettingsStore.settings$, DEFAULT_ANALYSIS_CURSOR_SETTINGS);

  return (
    <Paper sx={{ boxShadow: "none", p: 2 }}>
      <Stack gap={1}>
        <Typography variant={"h6"}>Analysis Cursor</Typography>
        <FormGroup>
          <FormControlLabel
            control={
              <Switch
                checked={settings.enabled}
                onChange={(event) => analysisCursorSettingsStore.setEnabled(event.target.checked)}
              />
            }
            label={"Enabled"}
          />
        </FormGroup>
      </Stack>
    </Paper>
  );
}
Example #4
Source File: SettingsModal.tsx    From rewind with MIT License 6 votes vote down vote up
function PlaybarSettingsSection() {
  const { playbarSettingsStore } = useCommonManagers();
  const settings = useObservable(() => playbarSettingsStore.settings$, DEFAULT_PLAY_BAR_SETTINGS);

  return (
    <Paper elevation={1} sx={{ boxShadow: "none", p: 2 }}>
      <Stack gap={1}>
        <Typography variant={"h6"}>Playbar</Typography>
        <FormGroup>
          <FormControlLabel
            control={
              <Switch
                checked={settings.difficultyGraphEnabled}
                onChange={(event) =>
                  playbarSettingsStore.changeSettings((s) => (s.difficultyGraphEnabled = event.target.checked))
                }
              />
            }
            label={"Show difficulty graph"}
          />
        </FormGroup>
      </Stack>
    </Paper>
  );
}
Example #5
Source File: AdditionalQuestions.tsx    From frontend with MIT License 6 votes vote down vote up
Question = ({ question }: QuestionProps) => {
  const { t } = useTranslation()
  const formik = useFormikContext<SupportFormData>()
  if (!question) {
    return null
  }
  return (
    <FormControl fullWidth required error={Boolean(formik.errors.roles)} component="fieldset">
      <FormGroup>
        <FormLabel component="legend">{t(question.title)}</FormLabel>
        {question.options.map((option: Option, index) => (
          <React.Fragment key={index}>
            <CheckboxField label={option.label} name={option.name} />
            {option.textFieldOptions && option.value ? (
              <FormTextField
                type="text"
                name={option.textFieldOptions.name}
                label={option.textFieldOptions.placeholder}
                placeholder={t(option.textFieldOptions.placeholder)}
              />
            ) : null}
          </React.Fragment>
        ))}
      </FormGroup>
      {Boolean(formik.errors[question.key]) && (
        <FormHelperText error>{t(question.errorMessage)}</FormHelperText>
      )}
    </FormControl>
  )
}
Example #6
Source File: Channel.tsx    From sapio-studio with Mozilla Public License 2.0 5 votes vote down vote up
function Typing(props: { channel_id: string }) {
    const [typed, set_typed] = React.useState('');
    const { focused } = useFormControl() || {};
    return (
        <Box
            component="form"
            noValidate
            autoComplete="off"
            onSubmit={(ev: React.FormEvent) => {
                ev.preventDefault();
            }}
        >
            <FormControl fullWidth={true}>
                <FormGroup row={true} sx={{ width: '100%' }} className="Typing">
                    <FilledInput
                        sx={{ width: '75%' }}
                        onChange={(ev) => set_typed(ev.currentTarget.value)}
                        value={typed}
                        autoFocus
                        type="text"
                    />
                    <Button
                        type="submit"
                        color="success"
                        onClick={async (ev) => {
                            ev.preventDefault();
                            if (typed !== '') {
                                window.electron.chat.send({
                                    msg: { Data: typed },
                                    channel: props.channel_id,
                                    sent_time_ms: Date.now(),
                                });
                                set_typed('');
                            }
                        }}
                    >
                        Send
                    </Button>
                </FormGroup>
            </FormControl>
        </Box>
    );
}
Example #7
Source File: SettingsModal.tsx    From rewind with MIT License 5 votes vote down vote up
function ReplayCursorSettingsSection() {
  const { replayCursorSettingsStore } = useCommonManagers();
  const settings = useObservable(() => replayCursorSettingsStore.settings$, DEFAULT_REPLAY_CURSOR_SETTINGS);

  return (
    <Paper sx={{ boxShadow: "none", p: 2 }}>
      <Stack gap={1}>
        <Typography variant={"h6"}>Replay Cursor</Typography>
        <FormGroup>
          <FormControlLabel
            control={
              <Switch
                checked={settings.enabled}
                onChange={(event) =>
                  replayCursorSettingsStore.changeSettings((s) => (s.enabled = event.target.checked))
                }
              />
            }
            label={"Enabled"}
          />
        </FormGroup>
        <FormGroup>
          <FormControlLabel
            disabled={!settings.enabled}
            control={
              <Switch
                checked={settings.smoothCursorTrail}
                onChange={(event) =>
                  replayCursorSettingsStore.changeSettings((s) => (s.smoothCursorTrail = event.target.checked))
                }
              />
            }
            label={"Smooth Cursor Trail"}
          />
        </FormGroup>
        <Typography>Scale</Typography>
        <Slider
          value={Math.round(settings.scale * 100)}
          valueLabelFormat={formatToPercent}
          disabled={!settings.enabled}
          min={10}
          max={200}
          onChange={(_, v) => replayCursorSettingsStore.changeSettings((s) => (s.scale = (v as number) / 100))}
          valueLabelDisplay={"auto"}
        />
      </Stack>
    </Paper>
  );
}
Example #8
Source File: Roles.tsx    From frontend with MIT License 5 votes vote down vote up
export default function Roles() {
  const [, { error }] = useField('roles')
  const { t } = useTranslation()

  return (
    <Grid container spacing={6} justifyContent="center">
      <Grid item xs={12} md={8}>
        <HeaderTypography>{t('support:steps.role.subtitle')}</HeaderTypography>
      </Grid>
      <Grid item xs={12} md={8}>
        <Typography variant="h5" paragraph>
          {t('support:steps.role.first-subtitle')}
        </Typography>
        <Divider />
        <div>
          <BankTransfer />
        </div>
      </Grid>
      <Grid item xs={12} md={8}>
        <Typography variant="h5" paragraph>
          {t('support:steps.role.second-subtitle')}
        </Typography>
        <Divider />
        <FormControl fullWidth required error={!!error} component="fieldset">
          <FormGroup>
            <Role name="roles.benefactor" label={t('support:steps.role.fields.benefactor.title')} />
            <Role label={t('support:steps.role.fields.volunteer.title')} name="roles.volunteer" />
            <Role
              label={t('support:steps.role.fields.associationMember.title')}
              name="roles.associationMember"
            />
            <Role label={t('support:steps.role.fields.partner.title')} name="roles.partner" />
            <Role label={t('support:steps.role.fields.company.title')} name="roles.company" />
          </FormGroup>
          {error && <FormHelperText>{t('validation:select-role')}</FormHelperText>}
        </FormControl>
      </Grid>
    </Grid>
  )
}
Example #9
Source File: CheckboxElement.tsx    From react-hook-form-mui with MIT License 5 votes vote down vote up
export default function CheckboxElement({
  name,
  validation = {},
  required,
  parseError,
  label,
  control,
  ...rest
}: CheckboxElementProps): JSX.Element {

  if (required) {
    validation.required = 'This field is required'
  }

  return (
    <Controller
      name={name}
      rules={validation}
      control={control}
      render={({ field: { value, onChange }, fieldState: { invalid, error } }) => {
        const helperText = error ? (typeof parseError === 'function' ? parseError(error) : error.message) : rest.helperText
        return (
          <FormControl required={required} error={invalid}>
            <FormGroup row>
              <FormControlLabel
                label={label || ''}
                control={
                  <Checkbox
                    color={'primary'}
                    sx={{
                      color: invalid ? "error.main" : undefined,
                    }}
                    value={value}
                    checked={!!value}
                    onChange={() => {
                      onChange(!value)
                      //setValue(name, !formValue, { shouldValidate: true })
                    }}
                  />
                }
              />
            </FormGroup>
            {helperText && <FormHelperText error={invalid}>{helperText}</FormHelperText>}
          </FormControl>
        )
      }}
    />
  )
}
Example #10
Source File: Create.tsx    From metaplex with Apache License 2.0 4 votes vote down vote up
Create = () => {
  const connection = useConnection();
  const wallet = useWallet();
  const anchorWallet = useMemo(() => {
    if (
      !wallet ||
      !wallet.publicKey ||
      !wallet.signAllTransactions ||
      !wallet.signTransaction
    ) {
      return;
    }

    return {
      publicKey: wallet.publicKey,
      signAllTransactions: wallet.signAllTransactions,
      signTransaction: wallet.signTransaction,
    } as anchor.Wallet;
  }, [wallet]);

  const [mintA, setMintA] = React.useState(localStorage.getItem('mintA') || '');
  const [mintB, setMintB] = React.useState(localStorage.getItem('mintB') || '');
  const [price, setPrice] = React.useState(localStorage.getItem('price') || '');
  const [paysEveryTime, setPaysEveryTime] = React.useState(false);
  const [authority, setAuthority] = React.useState(
    localStorage.getItem('authority') || '',
  );

  useEffect(() => {
    (async () => {
      if (!anchorWallet) {
        return;
      }
      setAuthority(anchorWallet.publicKey.toString());
    })();
  }, [anchorWallet]);

  const handleSubmit = async (event: React.MouseEvent<HTMLElement>) => {
    event.preventDefault();
    if (!anchorWallet) {
      return;
    }
    const res = await createEntanglement(
      anchorWallet,
      connection,
      null,
      authority,
      paysEveryTime,
      price,
      mintA,
      mintB,
    );
    console.log(res);
  };

  const isEnable = (
    mintA: string,
    mintB: string,
    authority: string,
    price: string,
  ): boolean => {
    return (
      // eslint-disable-next-line no-extra-boolean-cast
      !!mintA && !!mintB && !!price && !!authority
    );
  };

  return (
    <React.Fragment>
      <Typography variant="h4" color="text.primary" gutterBottom>
        Create Entanglement
      </Typography>
      <p>
        Create an entanglement between two NFTs. Using connected wallet as
        entanglement authority.
      </p>

      <Box
        component="form"
        sx={{
          '& .MuiTextField-root': { m: 1, width: '25ch' },
        }}
        noValidate
        autoComplete="off"
      >
        <TextField
          required
          id="mintA-text-field"
          label="MintA"
          helperText="You do not even need to own this token to create this entanglement."
          value={mintA}
          onChange={e => {
            localStorage.setItem('mintA', e.target.value);
            setMintA(e.target.value);
          }}
        />
        <TextField
          required
          id="mintB-text-field"
          label="MintB"
          helperText="This token will be removed from your token account right now."
          value={mintB}
          onChange={e => {
            localStorage.setItem('mintB', e.target.value);
            setMintB(e.target.value);
          }}
        />
        <TextField
          required
          id="authority-text-field"
          label="Authority"
          helperText="Entanglement Authority"
          value={authority}
          onChange={e => {
            localStorage.setItem('authority', e.target.value);
            setAuthority(e.target.value);
          }}
        />
        <TextField
          required
          id="price-text-field"
          helperText="Price for a swap"
          label="Price"
          value={price}
          onChange={e => {
            localStorage.setItem('price', e.target.value);
            setPrice(e.target.value);
          }}
        />
        <FormGroup>
          <FormControlLabel
            control={
              <Checkbox
                checked={paysEveryTime}
                onChange={e => {
                  setPaysEveryTime(e.target.checked);
                }}
              />
            }
            label="Pay the swapping fee each swap"
          />
        </FormGroup>
        <FormGroup>
          <Button
            variant="contained"
            onClick={async e => await handleSubmit(e)}
            endIcon={<SendIcon />}
            disabled={!isEnable(mintA, mintB, price, authority)}
          >
            Entangle
          </Button>
        </FormGroup>
        {!isEnable(mintA, mintB, price, authority) && (
          <Alert severity="warning" style={{ marginTop: '1rem' }}>
            <AlertTitle>Warning</AlertTitle>
            You should fill the four inputs.
          </Alert>
        )}
      </Box>
    </React.Fragment>
  );
}
Example #11
Source File: SettingsView.tsx    From react-flight-tracker with MIT License 4 votes vote down vote up
SettingsView: React.FC<Props> = (props) => {

  // Fields
  const contextName: string = ViewKeys.SettingsView;

  // Contexts
  const systemContext = useContext(SystemContext);
  const appContext = useContext(AppContext);

  const getSetting = (key: string, type: string) => {

    const value = systemContext.getSetting(key)
    if (typeof (value) === type)
      return value;

    return false;
  };

  const handleChange = (e: SelectChangeEvent) => {
    appContext.changeTheme(e.target.value);
  };

  const handleSettingsChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    systemContext.storeSetting(e.target.name, e.target.checked);
  };

  const renderAppSettings = () => {

    return (
      <Card>

        <CardContent>

          <Typography
            variant={'h6'}
            gutterBottom={true}>
            {'App settings'}
          </Typography>

          <FormGroup>
            <FormControl
              color='secondary'
              variant="filled"
              sx={{ m: 1, minWidth: 120 }}>

              <InputLabel
                id="demo-simple-select-filled-label">
                Theme change
              </InputLabel>
              <Select
                labelId="demo-simple-select-filled-label"
                id="demo-simple-select-filled"
                value={appContext.activeThemeName}
                onChange={handleChange}>

                <MenuItem
                  value={ThemeKeys.DarkTheme}>
                  {ThemeKeys.DarkTheme}
                </MenuItem>
                <MenuItem
                  value={ThemeKeys.LightTheme}>
                  {ThemeKeys.LightTheme}
                </MenuItem>
                <MenuItem
                  value={ThemeKeys.PineappleTheme}>
                  {ThemeKeys.PineappleTheme}
                </MenuItem>
              </Select>
            </FormControl>

          </FormGroup>
        </CardContent>
      </Card>
    );
  };

  const renderMapSettings = () => {

    return (
      <Card>

        <CardContent>

          <Typography
            variant={'h6'}
            gutterBottom={true}>
            {'Map settings'}
          </Typography>

          <FormGroup>
            <FormControlLabel
              control={
                <Switch
                  color='secondary'
                  name={SettingKeys.ShowDataOverlayOnMap}
                  checked={getSetting(SettingKeys.ShowDataOverlayOnMap, 'boolean')}
                  onChange={handleSettingsChange} />
              }
              label="Show data overlay on map"
            />
            <FormControlLabel
              control={
                <Switch
                  color='secondary'
                  name={SettingKeys.ShowLogOverlayOnMap}
                  checked={getSetting(SettingKeys.ShowLogOverlayOnMap, 'boolean')}
                  onChange={handleSettingsChange} />
              }
              label="Show log overlay on map"
            />
          </FormGroup>
        </CardContent>
      </Card>
    );
  };

  return (

    <ViewContainer
      isScrollLocked={true}>

      {renderAppSettings()}

      <Box sx={{ height: (theme) => theme.spacing(1) }} />

      {renderMapSettings()}
    </ViewContainer>
  );
}
Example #12
Source File: Wizard.tsx    From metaplex with Apache License 2.0 4 votes vote down vote up
Wizard = () => {
  const connection = useConnection();
  const wallet = useWallet();
  const history = useHistory();

  const [entanglements, setEntanglements] = React.useState<Array<object>>([]);
  const [myNFTs, setMyNFTs] = React.useState<Array<object>>([]);
  const [loading, setLoading] = useState(false);

  const authority = process.env.REACT_APP_WHITELISTED_AUTHORITY!;

  const anchorWallet = useMemo(() => {
    if (
      !wallet ||
      !wallet.publicKey ||
      !wallet.signAllTransactions ||
      !wallet.signTransaction
    ) {
      return;
    }

    return {
      publicKey: wallet.publicKey,
      signAllTransactions: wallet.signAllTransactions,
      signTransaction: wallet.signTransaction,
    } as anchor.Wallet;
  }, [wallet]);

  const handleSubmit = async (event: React.MouseEvent<HTMLElement>) => {
    event.preventDefault();
    if (!anchorWallet) {
      return;
    }
    setLoading(true);
    setEntanglements([]);
    const res = await getOwnedNFTMints(anchorWallet, connection);
    const walletNFTMints = res.map(token => token.info.mint);
    setMyNFTs(walletNFTMints);
    const allEntanglementsMap: any[] = [];
    for (let i = 0; i < walletNFTMints.length; i++) {
      const { entanglements, metadata } = await searchEntanglements(
        anchorWallet,
        connection,
        walletNFTMints[i],
        authority,
      );
      allEntanglementsMap.push({
        mint: walletNFTMints[i],
        entanglements,
        metadata,
      });
    }
    console.log('Entangle', allEntanglementsMap);
    setEntanglements([...(await allEntanglementsMap)]);
    setLoading(false);
  };

  const handleEntanglementClick = async (
    event: React.MouseEvent<HTMLElement>,
    entanglement: any,
  ) => {
    event.preventDefault();
    localStorage.setItem('mintA', entanglement.mintA.toString());
    localStorage.setItem('mintB', entanglement.mintB.toString());
    localStorage.setItem('entanglement', '');
    history.push(`swap/`);
  };

  return (
    <React.Fragment>
      <Typography variant="h4" color="text.primary" gutterBottom>
        Search NFT Entanglements{' '}
      </Typography>

      <p>Searches entanglements of your NFT </p>

      <Box
        component="form"
        sx={{
          '& .MuiTextField-root': { m: 1, width: '25ch' },
        }}
        noValidate
        autoComplete="off"
      >
        <FormGroup>
          <Button
            disabled={!anchorWallet || loading || !!!authority}
            variant="contained"
            onClick={async e => await handleSubmit(e)}
            endIcon={<SearchIcon />}
          >
            Search Entanglements
          </Button>
          {!!!authority && (
            <Alert severity="error" style={{ marginTop: '1rem' }}>
              <AlertTitle>Error</AlertTitle>
              Please set the whitelisted entanglement authority using the
              environment variable <b>REACT_APP_WHITELISTED_AUTHORITY</b>.
            </Alert>
          )}
        </FormGroup>
      </Box>
      <Box sx={{ maxWidth: 'md', display: 'block', marginTop: '2rem' }}>
        <Typography variant="h5" color="text.primary" gutterBottom>
          My NFT mints:{' '}
        </Typography>
        {loading && <LinearProgress />}

        {
          //@ts-ignore
          entanglements.map((e: any) => {
            return (
              <Card sx={{ minWidth: 275, boxShadow: 3, mb: 3 }} key={e.mint}>
                <CardContent>
                  <Typography
                    sx={{ fontSize: 19 }}
                    component="div"
                    gutterBottom
                  >
                    <strong>{e.mint}</strong>
                  </Typography>
                  {e.entanglements.length > 0 && (
                    <React.Fragment>
                      <Typography sx={{ mb: 1.5 }} color="text.secondary">
                        Mints
                      </Typography>
                      {e.entanglements.map((m: any) => (
                        <Typography
                          variant="body2"
                          color="text.secondary"
                          key={m.mintA.toString()}
                          sx={{ marginBottom: '2rem' }}
                        >
                          <strong>MintA</strong> : {`${m.mintA.toString()}`}{' '}
                          <br />
                          <strong>MintB</strong> : {`${m.mintB.toString()}`}{' '}
                          <br />
                          <strong>Price</strong> : {`${m.price.toString()}`}{' '}
                          <br />
                          <strong>Pays Every Time</strong> :{' '}
                          {`${m.paysEveryTime}`} <br />
                          <div
                            style={{
                              display: 'flex',
                              flexDirection: myNFTs.find(
                                (d: any) => d === m.mintA.toBase58(),
                              )
                                ? 'row'
                                : 'row-reverse',
                              justifyContent: 'space-evenly',
                              alignItems: 'center',
                            }}
                          >
                            <img
                              alt="Mint A Icon"
                              style={{ width: '100px', height: '100px' }}
                              src={
                                e.metadata.find(d => d.mint.equals(m.mintA))
                                  .imageUrl
                              }
                            />
                            <p>becomes</p>
                            <img
                              alt="Mint B Icon"
                              style={{ width: '100px', height: '100px' }}
                              src={
                                e.metadata.find(d => d.mint.equals(m.mintB))
                                  .imageUrl
                              }
                            />
                          </div>
                          <Button
                            onClick={event => handleEntanglementClick(event, m)}
                            variant="contained"
                            startIcon={<SwapHorizIcon />}
                            sx={{ marginTop: '1rem' }}
                          >
                            SWAP
                          </Button>
                        </Typography>
                      ))}
                    </React.Fragment>
                  )}
                </CardContent>
              </Card>
            );
          })
        }
      </Box>
    </React.Fragment>
  );
}
Example #13
Source File: Swap.tsx    From metaplex with Apache License 2.0 4 votes vote down vote up
Swap = () => {
  const connection = useConnection();
  const wallet = useWallet();

  const [mintA, setMintA] = React.useState(localStorage.getItem('mintA') || '');
  const [mintB, setMintB] = React.useState(localStorage.getItem('mintB') || '');
  const [entangledPair, setEntangledPair] = React.useState(
    localStorage.getItem('entangledPair') || '',
  );

  const anchorWallet = useMemo(() => {
    if (
      !wallet ||
      !wallet.publicKey ||
      !wallet.signAllTransactions ||
      !wallet.signTransaction
    ) {
      return;
    }

    return {
      publicKey: wallet.publicKey,
      signAllTransactions: wallet.signAllTransactions,
      signTransaction: wallet.signTransaction,
    } as anchor.Wallet;
  }, [wallet]);

  useEffect(() => {
    (async () => {
      if (!anchorWallet) {
        return;
      }
    })();
  }, [anchorWallet]);

  const handleSubmit = async (event: React.MouseEvent<HTMLElement>) => {
    event.preventDefault();
    if (!anchorWallet) {
      return;
    }
    const txnResult = await swapEntanglement(
      anchorWallet,
      connection,
      mintA,
      mintB,
      entangledPair,
    );
    setEntangledPair(txnResult.epkey);
  };

  const isEnable = (
    mintA: string,
    mintB: string,
    entangledPair: string,
  ): boolean => {
    return (
      // eslint-disable-next-line no-extra-boolean-cast
      (!!mintA && !!mintB && !!!entangledPair) ||
      (!(!!mintA || !!mintB) && !!entangledPair)
    );
  };

  return (
    <React.Fragment>
      <Typography variant="h4" color="text.primary" gutterBottom>
        Swap Entanglement
      </Typography>
      <p>Enter MintA and MintB or Entangled Pair.</p>

      <Box
        component="form"
        sx={{
          '& .MuiTextField-root': { m: 1, width: '25ch' },
        }}
        noValidate
        autoComplete="off"
      >
        <TextField
          id="mintA-text-field"
          label="MintA"
          value={mintA}
          onChange={e => {
            localStorage.setItem('mintA', e.target.value);
            setMintA(e.target.value);
          }}
        />
        <TextField
          id="mintB-text-field"
          label="MintB"
          value={mintB}
          onChange={e => {
            localStorage.setItem('mintB', e.target.value);
            setMintB(e.target.value);
          }}
        />
        <TextField
          id="price-text-field"
          helperText="Entangled pair"
          label="Entangled pair"
          value={entangledPair}
          onChange={e => {
            localStorage.setItem('entangledPair', e.target.value);
            setEntangledPair(e.target.value);
          }}
        />

        <FormGroup>
          <Button
            variant="contained"
            onClick={async e => await handleSubmit(e)}
            endIcon={<SendIcon />}
            disabled={!isEnable(mintA, mintB, entangledPair)}
          >
            Swap
          </Button>
        </FormGroup>
      </Box>

      <Box component="span" sx={{ display: 'block', marginTop: '2rem' }}>
        {!entangledPair ? (
          ''
        ) : (
          <Typography variant="h5" color="text.primary" gutterBottom>
            Entangled Pair swap complete!
          </Typography>
        )}
        <p>{entangledPair}</p>
      </Box>
    </React.Fragment>
  );
}
Example #14
Source File: Show.tsx    From metaplex with Apache License 2.0 4 votes vote down vote up
Show = () => {
  const connection = useConnection();
  const wallet = useWallet();

  const [mintA, setMintA] = React.useState(localStorage.getItem('mintA') || '');
  const [mintB, setMintB] = React.useState(localStorage.getItem('mintB') || '');
  const [entangledPair, setEntangledPair] = React.useState(
    localStorage.getItem('entangledPair') || '',
  );
  const [entangledPairInfo, setEntangledPairInfo] = React.useState({});

  const anchorWallet = useMemo(() => {
    if (
      !wallet ||
      !wallet.publicKey ||
      !wallet.signAllTransactions ||
      !wallet.signTransaction
    ) {
      return;
    }

    return {
      publicKey: wallet.publicKey,
      signAllTransactions: wallet.signAllTransactions,
      signTransaction: wallet.signTransaction,
    } as anchor.Wallet;
  }, [wallet]);

  useEffect(() => {
    (async () => {
      if (!anchorWallet) {
        return;
      }
    })();
  }, [anchorWallet]);

  const displayEntanglement = (e: any) => {
    return (
      <Card
        sx={{ minWidth: 275, boxShadow: 3, mb: 3 }}
        key={e.mintA.toString()}
      >
        <CardContent>
          <Typography sx={{ fontSize: 19 }} component="div" gutterBottom>
            <strong>Entanglement Info</strong>
          </Typography>
          {displayEntanglementContent(e)}
        </CardContent>
      </Card>
    );
  };

  const displayEntanglementContent = (e: any) => {
    return (
      <Typography
        variant="body2"
        color="text.secondary"
        key={e.mintB.toString()}
        gutterBottom
      >
        <strong>Treasury Mint</strong> : {e.treasuryMint} <br />
        <strong>Authority</strong> : {e.authority} <br />
        <strong>Mint A</strong> : {e.mintA} <br />
        <strong>Mint B</strong> : {e.mintB} <br />
        <strong>Token A Escrow</strong> : {e.tokenAEscrow} <br />
        <strong>Token B Escrow</strong> : {e.tokenBEscrow} <br />
        <strong>Price</strong> : {e.price} <br />
        <strong>Paid At Least Once</strong> : {e.paid} <br />
        <strong>Paid Every Time</strong> : {e.paysEveryTime} <br />
        <strong>Bump</strong> : {e.bump} <br />
      </Typography>
    );
  };

  const handleSubmit = async (event: React.MouseEvent<HTMLElement>) => {
    event.preventDefault();
    if (!anchorWallet) {
      return;
    }
    try {
      const epObj: any = await showEntanglement(
        anchorWallet,
        connection,
        entangledPair,
        mintA,
        mintB,
      );
      const info = {
        treasuryMint: epObj.treasuryMint.toBase58(),
        authority: epObj.authority.toBase58(),
        mintA: epObj.mintA.toBase58(),
        mintB: epObj.mintB.toBase58(),
        tokenAEscrow: epObj.tokenAEscrow.toBase58(),
        tokenBEscrow: epObj.tokenBEscrow.toBase58(),
        price: epObj.price.toNumber(),
        paid: epObj.paid.toString(),
        paysEveryTime: epObj.paysEveryTime.toString(),
        bump: epObj.bump,
      };

      setEntangledPairInfo(info);
    } catch (e) {
      // TODO Show Error
      if (e instanceof Error) {
        console.error(e.message);
      }
    }
  };

  const isEnable = (
    mintA: string,
    mintB: string,
    entangledPair: string,
  ): boolean => {
    return (
      // eslint-disable-next-line no-extra-boolean-cast
      (!!mintA && !!mintB && !!!entangledPair) ||
      (!(!!mintA || !!mintB) && !!entangledPair)
    );
  };

  return (
    <React.Fragment>
      <Typography variant="h4" color="text.primary" gutterBottom>
        Show Entanglement
      </Typography>
      <p>Enter MintA and MintB or Entangled Pair.</p>

      <Box
        component="form"
        sx={{
          '& .MuiTextField-root': { m: 1, width: '25ch' },
        }}
        noValidate
        autoComplete="off"
      >
        <TextField
          id="mintA-text-field"
          label="MintA"
          value={mintA}
          onChange={e => {
            localStorage.setItem('mintA', e.target.value);
            setMintA(e.target.value);
          }}
        />
        <TextField
          id="mintB-text-field"
          label="MintB"
          value={mintB}
          onChange={e => {
            localStorage.setItem('mintB', e.target.value);
            setMintB(e.target.value);
          }}
        />
        <TextField
          id="price-text-field"
          helperText="Entangled pair"
          label="Entangled pair"
          value={entangledPair}
          onChange={e => {
            localStorage.setItem('entangledPair', e.target.value);
            setEntangledPair(e.target.value);
          }}
        />
        <FormGroup>
          <Button
            variant="contained"
            onClick={async e => await handleSubmit(e)}
            endIcon={<SendIcon />}
            disabled={!isEnable(mintA, mintB, entangledPair)}
          >
            Show Entanglement
          </Button>
        </FormGroup>
        {!isEnable(mintA, mintB, entangledPair) && (
          <Alert severity="warning" style={{ marginTop: '1rem' }}>
            <AlertTitle>Warning</AlertTitle>
            The three input are filled. You should enter MintA and MintB or
            Entangled Pair.
          </Alert>
        )}
      </Box>
      <Box sx={{ maxWidth: 'md', display: 'block', marginTop: '2rem' }}>
        {Object.keys(entangledPairInfo).length > 0 &&
          displayEntanglement(entangledPairInfo)}
      </Box>
    </React.Fragment>
  );
}
Example #15
Source File: Search.tsx    From metaplex with Apache License 2.0 4 votes vote down vote up
Search = () => {
  const connection = useConnection();
  console.log(connection);
  const wallet = useWallet();
  const [entangledPairs, setEntangledPairs] = React.useState<Array<any>>([]);

  const anchorWallet = useMemo(() => {
    if (
      !wallet ||
      !wallet.publicKey ||
      !wallet.signAllTransactions ||
      !wallet.signTransaction
    ) {
      return;
    }

    return {
      publicKey: wallet.publicKey,
      signAllTransactions: wallet.signAllTransactions,
      signTransaction: wallet.signTransaction,
    } as anchor.Wallet;
  }, [wallet]);

  useEffect(() => {
    (async () => {
      if (!anchorWallet) {
        return;
      }
      setAuthority(anchorWallet.publicKey.toString());
    })();
  }, [anchorWallet]);

  const displayEntanglements = (e: any) => {
    return (
      <Card
        sx={{ minWidth: 275, boxShadow: 3, mb: 3 }}
        key={e.mintA.toString()}
      >
        <CardContent>
          <Typography sx={{ fontSize: 19 }} component="div" gutterBottom>
            <strong>{e.mintB}</strong>
          </Typography>
          {displayEntangledPairContent(e)}
        </CardContent>
      </Card>
    );
  };

  const displayEntangledPairContent = (e: any) => {
    return (
      <Typography
        variant="body2"
        color="text.secondary"
        key={e.mintB.toString()}
        gutterBottom
      >
        <strong>Treasury Mint</strong> : {e.treasuryMint} <br />
        <strong>Authority</strong> : {e.authority} <br />
        <strong>Mint A</strong> : {e.mintA} <br />
        <strong>Mint B</strong> : {e.mintB} <br />
        <strong>Token A Escrow</strong> : {e.tokenAEscrow} <br />
        <strong>Token B Escrow</strong> : {e.tokenBEscrow} <br />
        <strong>Price</strong> : {e.price} <br />
        <strong>Paid At Least Once</strong> : {e.paid} <br />
        <strong>Paid Every Time</strong> : {e.paysEveryTime} <br />
        <strong>Bump</strong> : {e.bump} <br />
      </Typography>
    );
  };

  const handleSubmit = async (event: React.MouseEvent<HTMLElement>) => {
    event.preventDefault();
    if (!anchorWallet) {
      return;
    }
    const { entanglements: foundEntanglements } = await searchEntanglements(
      anchorWallet,
      connection,
      mintA,
      authority,
    );
    const entanglements = foundEntanglements.map((entanglement: any) => ({
      treasuryMint: entanglement.treasuryMint.toBase58(),
      authority: entanglement.authority.toBase58(),
      mintA: entanglement.mintA.toBase58(),
      mintB: entanglement.mintB.toBase58(),
      tokenAEscrow: entanglement.tokenAEscrow.toBase58(),
      tokenBEscrow: entanglement.tokenBEscrow.toBase58(),
      price: entanglement.price.toNumber(),
      paid: entanglement.paid.toString(),
      paysEveryTime: entanglement.paysEveryTime.toString(),
      bump: entanglement.bump,
    }));
    setEntangledPairs(entanglements);
  };

  const [mintA, setMintA] = React.useState(localStorage.getItem('mintA') || '');
  const [authority, setAuthority] = React.useState(
    localStorage.getItem('authority') || '',
  );

  return (
    <React.Fragment>
      <Typography variant="h4" color="text.primary" gutterBottom>
        Search Entanglements
      </Typography>
      <p>Search for entanglements by mint address and authority</p>

      <Box
        component="form"
        sx={{
          '& .MuiTextField-root': { m: 1, width: '25ch' },
        }}
        noValidate
        autoComplete="off"
      >
        <TextField
          id="mintA-text-field"
          label="MintA"
          value={mintA}
          onChange={e => {
            localStorage.setItem('mintA', e.target.value);
            setMintA(e.target.value);
          }}
        />
        <TextField
          id="mintA-text-field"
          label="Authority"
          value={authority}
          onChange={e => {
            localStorage.setItem('authority', e.target.value);
            setAuthority(e.target.value);
          }}
        />
        <FormGroup>
          <Button
            disabled={!authority || !mintA}
            variant="contained"
            onClick={async e => await handleSubmit(e)}
            endIcon={<SearchIcon />}
          >
            Search Entanglements
          </Button>
        </FormGroup>
        <Box sx={{ maxWidth: 'md', display: 'block', marginTop: '2rem' }}>
          <Typography variant="h5" color="text.primary" gutterBottom>
            Entanglements
          </Typography>
        </Box>
      </Box>
      <Box sx={{ maxWidth: 'md', display: 'block', marginTop: '2rem' }}>
        {entangledPairs.map((e: any) => displayEntanglements(e))}
      </Box>
    </React.Fragment>
  );
}
Example #16
Source File: MainInfoCard.tsx    From Cromwell with MIT License 4 votes vote down vote up
MainInfoCard = (props: {
    product: TProduct | TProductVariant,
    setProdData: (data: TProduct | TProductVariant) => void;
    isProductVariant?: boolean;
    canValidate?: boolean;
}) => {
    const productPrevRef = React.useRef<TProductVariant | TProduct | null>(props.product);
    const cardIdRef = React.useRef<string>(getRandStr(10));
    const productRef = React.useRef<TProductVariant | TProduct | null>(props.product);
    if (props.product !== productPrevRef.current) {
        productPrevRef.current = props.product;
        productRef.current = props.product;
    }
    const forceUpdate = useForceUpdate();
    const editorId = "prod-text-editor_" + cardIdRef.current;
    const product = productRef.current;

    const setProdData = (data: TProduct) => {
        Object.keys(data).forEach(key => { productRef.current[key] = data[key] })
        props.setProdData(data);
        forceUpdate();
    }

    const fullSave = async () => {
        setProdData({
            ...(product as TProduct),
            description: await getEditorHtml(editorId),
            descriptionDelta: JSON.stringify(await getEditorData(editorId)),
        });
    }

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

    const init = async () => {
        let descriptionDelta;
        if (product?.descriptionDelta) {
            try {
                descriptionDelta = JSON.parse(product.descriptionDelta);
            } catch (e) { console.error(e) }
        }

        const updateText = debounce(600, () => {
            fullSave();
        })

        await initTextEditor({
            htmlId: editorId,
            data: descriptionDelta,
            placeholder: 'Product description...',
            onChange: updateText,
        });
    }

    const handleChange = (prop: keyof TProduct, val: any) => {
        if (product) {
            const prod = Object.assign({}, product);
            (prod[prop] as any) = val;

            if (prop === 'images') {
                prod.mainImage = val?.[0];
            }
            setProdData(prod as TProduct);
        }
    }

    if (!product) return null;

    let pageFullUrl;
    if ((product as TProduct)?.slug) {
        pageFullUrl = serviceLocator.getFrontendUrl() + resolvePageRoute('product', {
            slug: (product as TProduct).slug ?? (product as TProduct).id + '',
        });
    }

    return (
        <Grid container spacing={3}>
            <Grid item xs={12} sm={12}>
                <TextField label="Name" variant="standard"
                    value={product.name ?? ''}
                    className={styles.textField}
                    onChange={(e) => { handleChange('name', e.target.value) }}
                    error={props.canValidate && !product?.name}
                />
            </Grid>
            <Grid item xs={12} sm={6}>
                <TextField label="SKU" variant="standard"
                    value={product.sku ?? ''}
                    className={styles.textField}
                    onChange={(e) => { handleChange('sku', e.target.value) }}
                />
            </Grid>
            <Grid item xs={12} sm={6}></Grid>
            <Grid item xs={12} sm={6}>
                <Select
                    fullWidth
                    label="Stock status"
                    variant="standard"
                    value={product.stockStatus}
                    onChange={(e) => { handleChange('stockStatus', e.target.value) }}
                    options={['In stock', 'Out of stock', 'On backorder'] as TStockStatus[]}
                />
            </Grid>
            <Grid item xs={12} sm={6}>
                <TextField label="Stock amount" variant="standard"
                    value={product.stockAmount ?? ''}
                    className={styles.textField}
                    type="number"
                    onChange={(e) => {
                        let val = parseInt(e.target.value);
                        if (isNaN(val)) val = null;
                        if (val && val < 0) val = 0;
                        handleChange('stockAmount', val);
                    }}
                />
            </Grid>
            <Grid item xs={12} sm={12} style={{ display: 'flex', alignItems: 'center' }}>
                <FormGroup>
                    <FormControlLabel control={<Checkbox defaultChecked />}
                        label="Manage stock"
                        checked={!!product?.manageStock}
                        onChange={() => handleChange('manageStock', !product?.manageStock)}
                    />
                </FormGroup>
                <Tooltip title="Automatically manage stock amount when new orders placed">
                    <InfoOutlinedIcon />
                </Tooltip>
            </Grid>
            <Grid item xs={12} sm={6}>
                <TextField label="Price" variant="standard"
                    value={product.price ?? ''}
                    className={styles.textField}
                    onChange={(e) => { handleChange('price', e.target.value) }}
                    InputProps={{
                        inputComponent: NumberFormatCustom as any,
                    }}
                />
            </Grid>
            <Grid item xs={12} sm={6}>
                <TextField label="Old price" variant="standard"
                    value={product.oldPrice ?? ''}
                    className={styles.textField}
                    onChange={(e) => {
                        const val = e.target.value;
                        handleChange('oldPrice', (val && val !== '') ? val : null);
                    }}
                    InputProps={{
                        inputComponent: NumberFormatCustom as any,
                    }}
                />
            </Grid>
            <Grid item xs={12} sm={12}>
                <div className={styles.imageBlock}>
                    <GalleryPicker
                        classes={{
                            imagePicker: {
                                root: styles.imageItem
                            }
                        }}
                        label="Gallery"
                        images={((product as TProduct)?.images ?? []).map(src => ({ src }))}
                        onChange={(val) => handleChange('images', val.map(s => s.src))}
                    />
                </div>
            </Grid>
            <Grid item xs={12} sm={12}>
                <div className={styles.descriptionEditor}>
                    <div style={{ minHeight: '300px' }} id={editorId}></div>
                </div>
            </Grid>
            <Grid item xs={12} sm={12}>
                {props.isProductVariant !== true && (
                    <TextField label="Page URL" variant="standard"
                        value={(product as TProduct).slug ?? ''}
                        className={styles.textField}
                        onChange={(e) => { handleChange('slug', e.target.value) }}
                        helperText={pageFullUrl}
                    />
                )}
            </Grid>
            <Grid item xs={12} sm={12}>
                {props.isProductVariant !== true && (
                    <TextField label="Meta title" variant="standard"
                        value={(product as TProduct).pageTitle ?? ''}
                        className={styles.textField}
                        onChange={(e) => { handleChange('pageTitle', e.target.value) }}
                    />
                )}
            </Grid>
            <Grid item xs={12} sm={12}>
                {props.isProductVariant !== true && (
                    <TextField label="Meta description" variant="standard"
                        multiline
                        value={(product as TProduct).pageDescription ?? ''}
                        className={styles.textField}
                        onChange={(e) => { handleChange('pageDescription', e.target.value) }}
                    />
                )}
            </Grid>
            <Grid item xs={12} sm={12}>
                {props.isProductVariant !== true && (
                    <Autocomplete
                        multiple
                        freeSolo
                        options={[]}
                        className={styles.textField}
                        value={((product as TProduct).meta?.keywords ?? []) as any}
                        getOptionLabel={(option) => option}
                        onChange={(e, newVal) => {
                            handleChange('meta', {
                                ...((product as TProduct).meta ?? {}),
                                keywords: newVal
                            })
                        }}
                        renderInput={(params) => (
                            <Tooltip title="Press ENTER to add">
                                <TextField
                                    {...params}
                                    variant="standard"
                                    label="Meta keywords"
                                />
                            </Tooltip>
                        )}
                    />
                )}
            </Grid>
        </Grid>
    )
}
Example #17
Source File: CheckboxButtonGroup.tsx    From react-hook-form-mui with MIT License 4 votes vote down vote up
export default function CheckboxButtonGroup({
  helperText,
  options,
  label,
  name,
  parseError,
  required,
  labelKey = 'label',
  valueKey = 'id',
  returnObject,
  disabled,
  row,
  control,
  checkboxColor,
  ...rest
}: CheckboxButtonGroupProps): JSX.Element {
  const theme = useTheme()
  const { field: { value = [], onChange }, fieldState: { invalid, error } } = useController({
    name,
    rules: required ? { required: 'This field is required' } : undefined,
    control
  })

  helperText = error ? (typeof parseError === 'function' ? parseError(error) : error.message) : helperText

  const handleChange = (index: number | string) => {
    const newArray = [...value]
    const exists =
      value.findIndex((i: any) =>
        returnObject ? i[valueKey] === index : i === index
      ) === -1
    if (exists) {
      newArray.push(
        returnObject ? options.find(i => i[valueKey] === index) : index
      )
    } else {
      newArray.splice(
        value.findIndex((i: any) =>
          returnObject ? i[valueKey] === index : i === index
        ),
        1
      )
    }
    // setValue(name, newArray, { shouldValidate: true })
    onChange(newArray)
    if (typeof rest.onChange === 'function') {
      rest.onChange(newArray)
    }
  }

  return (
    <FormControl error={invalid} required={required}>
      {label && <FormLabel error={invalid}>{label}</FormLabel>}
      <FormGroup row={row}>
        {options.map((option: any) => {
          const optionKey = option[valueKey]
          if (!optionKey) {
            console.error(
              `CheckboxButtonGroup: valueKey ${valueKey} does not exist on option`,
              option
            )
          }
          const isChecked =
            value.findIndex((item: any) =>
              returnObject ? item[valueKey] === optionKey : item === optionKey
            ) !== -1
          return (
            <FormControlLabel
              control={
                <Checkbox
                  sx={{
                    color: invalid ? theme.palette.error.main : undefined
                  }}
                  color={checkboxColor || 'primary'}
                  value={optionKey}
                  checked={isChecked}
                  disabled={disabled}
                  onChange={() => handleChange(optionKey)}
                />
              }
              label={option[labelKey]}
              key={optionKey}
            />
          )
        })}
      </FormGroup>
      {helperText && <FormHelperText>{helperText}</FormHelperText>}
    </FormControl>
  )
}
Example #18
Source File: Settings.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function Settings() {
    const [theme, setTheme] = useRecoilState(themeSettings);

    useTitle("Abrechnung - Settings");

    const [confirmClearCacheOpen, setConfirmClearCacheOpen] = useState(false);

    const handleConfirmClearCacheOpen = () => {
        setConfirmClearCacheOpen(true);
    };

    const handleConfirmClearCacheClose = () => {
        setConfirmClearCacheOpen(false);
    };

    const handleConfirmClearCache = () => {
        clearCache();
        setConfirmClearCacheOpen(false);
        window.location.reload();
    };

    const handleDarkModeChange = (event) => {
        const val = event.target.value;
        setTheme({
            ...theme,
            darkMode: val,
        });
    };

    return (
        <MobilePaper>
            <Typography component="h3" variant="h5">
                Settings
            </Typography>
            <Alert sx={{ mt: 1 }} severity="info">
                These settings are stored locally on your device. Clearing your Browser's local storage will reset them.
            </Alert>
            <Box sx={{ mt: 2 }}>
                <FormControl sx={{ width: 200 }}>
                    <FormGroup>
                        <FormLabel component="legend">Theme</FormLabel>
                        <Select
                            id="dark-mode-select"
                            labelId="dark-mode-select-label"
                            value={theme.darkMode}
                            label="Dark Mode"
                            variant="standard"
                            onChange={handleDarkModeChange}
                        >
                            <MenuItem value="browser">System Default</MenuItem>
                            <MenuItem value="dark">Dark Mode</MenuItem>
                            <MenuItem value="light">Light Mode</MenuItem>
                        </Select>
                    </FormGroup>
                </FormControl>
            </Box>
            <Divider sx={{ mt: 1 }} />
            <Box sx={{ mt: 1 }}>
                <FormControl component="fieldset" variant="standard">
                    <FormLabel component="legend">Clear Cache</FormLabel>
                    <FormGroup>
                        <Button variant="contained" color="error" onClick={handleConfirmClearCacheOpen}>
                            Clear
                        </Button>
                    </FormGroup>
                    {/*<FormHelperText>ACHTUNG!</FormHelperText>*/}
                </FormControl>
            </Box>

            <Dialog
                open={confirmClearCacheOpen}
                onClose={handleConfirmClearCacheClose}
                aria-labelledby="dialog-confirm-clear-cache"
                aria-describedby="dialog-confirm-clear-cache-description"
            >
                <DialogTitle id="dialog-confirm-clear-cache">{"Clear Cache?"}</DialogTitle>
                <DialogContent>
                    <DialogContentText id="dialog-confirm-clear-cache-description">
                        This action will clear your local cache. All your settings (this page) will not be reset.
                    </DialogContentText>
                </DialogContent>
                <DialogActions>
                    <Button onClick={handleConfirmClearCache} autoFocus>
                        Yes
                    </Button>
                    <Button onClick={handleConfirmClearCacheClose}>Cancel</Button>
                </DialogActions>
            </Dialog>
        </MobilePaper>
    );
}
Example #19
Source File: GroupSettings.tsx    From abrechnung with GNU Affero General Public License v3.0 4 votes vote down vote up
export default function GroupSettings({ group }) {
    const [showLeaveModal, setShowLeaveModal] = useState(false);
    const history = useHistory();

    const userPermissions = useRecoilValue(currUserPermissions(group.id));

    const [isEditing, setIsEditing] = useState(false);

    useTitle(`${group.name} - Settings`);

    const startEdit = () => {
        setIsEditing(true);
    };

    const stopEdit = () => {
        setIsEditing(false);
    };

    const handleSubmit = (values, { setSubmitting }) => {
        updateGroupMetadata({
            groupID: group.id,
            name: values.name,
            description: values.description,
            currencySymbol: values.currencySymbol,
            terms: values.terms,
            addUserAccountOnJoin: values.addUserAccountOnJoin,
        })
            .then((res) => {
                setSubmitting(false);
                setIsEditing(false);
            })
            .catch((err) => {
                setSubmitting(false);
                toast.error(err);
            });
    };

    const confirmLeaveGroup = () => {
        leaveGroup({ groupID: group.id })
            .then((res) => {
                history.push("/");
            })
            .catch((err) => {
                toast.error(err);
            });
    };

    return (
        <MobilePaper>
            {userPermissions.is_owner ? (
                <Alert severity="info">You are an owner of this group</Alert>
            ) : !userPermissions.can_write ? (
                <Alert severity="info">You only have read access to this group</Alert>
            ) : null}

            <Formik
                initialValues={{
                    name: group.name,
                    description: group.description,
                    terms: group.terms,
                    currencySymbol: group.currency_symbol,
                    addUserAccountOnJoin: group.add_user_account_on_join,
                }}
                onSubmit={handleSubmit}
                validationSchema={validationSchema}
                enableReinitialize={true}
            >
                {({ values, handleBlur, handleChange, handleSubmit, isSubmitting }) => (
                    <Form onSubmit={handleSubmit}>
                        <DisabledTextField
                            variant="standard"
                            margin="normal"
                            required
                            fullWidth
                            type="text"
                            label="Name"
                            name="name"
                            disabled={!userPermissions.can_write || !isEditing}
                            onBlur={handleBlur}
                            onChange={handleChange}
                            value={values.name}
                        />

                        <DisabledTextField
                            variant="standard"
                            margin="normal"
                            fullWidth
                            type="text"
                            name="description"
                            label="Description"
                            disabled={!userPermissions.can_write || !isEditing}
                            onBlur={handleBlur}
                            onChange={handleChange}
                            value={values.description}
                        />
                        <DisabledTextField
                            variant="standard"
                            margin="normal"
                            required
                            fullWidth
                            type="text"
                            name="currencySymbol"
                            label="Currency"
                            disabled={!userPermissions.can_write || !isEditing}
                            onBlur={handleBlur}
                            onChange={handleChange}
                            value={values.currencySymbol}
                        />
                        <DisabledTextField
                            variant="standard"
                            multiline={true}
                            margin="normal"
                            fullWidth
                            type="text"
                            name="terms"
                            label="Terms"
                            disabled={!userPermissions.can_write || !isEditing}
                            onBlur={handleBlur}
                            onChange={handleChange}
                            value={values.terms}
                        />
                        <FormGroup>
                            <DisabledFormControlLabel
                                control={
                                    <Checkbox
                                        name="addUserAccountOnJoin"
                                        disabled={!userPermissions.can_write || !isEditing}
                                        onBlur={handleBlur}
                                        onChange={handleChange}
                                        checked={values.addUserAccountOnJoin}
                                    />
                                }
                                label="Automatically add accounts for newly joined group members"
                            />
                        </FormGroup>

                        {isSubmitting && <LinearProgress />}
                        <Grid container justifyContent="space-between" style={{ marginTop: 10 }}>
                            <div>
                                {userPermissions.can_write && isEditing && (
                                    <>
                                        <Button
                                            type="submit"
                                            variant="contained"
                                            color="primary"
                                            disabled={isSubmitting}
                                            startIcon={<Save />}
                                        >
                                            Save
                                        </Button>
                                        <Button
                                            variant="contained"
                                            color="error"
                                            disabled={isSubmitting}
                                            onClick={stopEdit}
                                            startIcon={<Cancel />}
                                            sx={{ ml: 1 }}
                                        >
                                            Cancel
                                        </Button>
                                    </>
                                )}
                                {userPermissions.can_write && !isEditing && (
                                    <Button
                                        variant="contained"
                                        color="primary"
                                        disabled={isSubmitting}
                                        onClick={startEdit}
                                        startIcon={<Edit />}
                                    >
                                        Edit
                                    </Button>
                                )}
                            </div>
                            <Button variant="contained" onClick={() => setShowLeaveModal(true)}>
                                Leave Group
                            </Button>
                        </Grid>
                    </Form>
                )}
            </Formik>

            {/*<List>*/}
            {/*    <ListItem>*/}
            {/*        <ListItemText primary="Created" secondary={group.created}/>*/}
            {/*    </ListItem>*/}
            {/*    <ListItem>*/}
            {/*        <ListItemText primary="Joined" secondary={group.joined}/>*/}
            {/*    </ListItem>*/}
            {/*</List>*/}

            <Dialog open={showLeaveModal} onClose={() => setShowLeaveModal(false)}>
                <DialogTitle>Leave Group</DialogTitle>
                <DialogContent>
                    <DialogContentText>
                        <span>
                            Are you sure you want to leave the group {group.name}. If you are the last member to leave
                            this group it will be deleted and its transaction will be lost forever...
                        </span>
                    </DialogContentText>
                </DialogContent>
                <DialogActions>
                    <Button color="secondary" onClick={confirmLeaveGroup}>
                        Yes pls
                    </Button>
                    <Button color="primary" onClick={() => setShowLeaveModal(false)}>
                        No
                    </Button>
                </DialogActions>
            </Dialog>
        </MobilePaper>
    );
}
Example #20
Source File: Language.tsx    From GTAV-NativeDB with MIT License 4 votes vote down vote up
export default 
function Language<TSettings extends CodeGeneratorBaseSettings>({ name, defaultSettings, generator, options, advancedOptions, extension }: Props<TSettings>) {
  const natives = useNatives()
  const namespaces = useNamespaces()
  const [settings, setSettings] = useLocalStorageState(`Pages.GenerateCode.${name}`, defaultSettings)
  const [previewNative, setPreviewNative] = useState('0xD49F9B0955C367DE')
  const nativeData = useNative(previewNative)

  const preview = useMemo(() => (
    new NativeExporter(
      new generator(settings)
    ).exportNatives({
      namespaces: {
        [nativeData.namespace]: {
          name: nativeData.namespace,
          natives: [nativeData.hash]
        }
      },
      natives: {
        [nativeData.hash]: nativeData
      }
    })
  ), [settings, nativeData, generator])

  const handleChange = useCallback((event: ChangeEvent<HTMLInputElement> | SelectChangeEvent) => {
    if (!(event.target.name in settings)) {
      return
    }

    const type = typeof settings[event.target.name as (keyof TSettings)]
    if (type === 'boolean' && 'checked' in event.target) {
      setSettings({
        ...settings,
        [event.target.name]: event.target.checked
      })
    }
    else {
      setSettings({
        ...settings,
        [event.target.name]: event.target.value
      })
    }
  }, [settings, setSettings])

  const handleDownload = useCallback(() => {
    const exporter = new NativeExporter(
      new generator(settings)
    )

    const code = exporter.exportNatives({
      natives, 
      namespaces
    })

    download(code, `natives.${extension}`, 'text/plain')
  }, [settings, natives, namespaces, generator, extension])

  if (!nativeData) {
    setPreviewNative('0x4EDE34FBADD967A6')
    return null
  }

  return (
    <Grid spacing={3} container>
      <Grid xs={12} md={6} item sx={{ display: 'flex', flexDirection: 'column' }}>
        <Typography 
          variant="h5" 
          component="h2" 
          gutterBottom
        >
          settings
        </Typography>
        <FormGroup>
          <Stack gap={2}>
            {options.map(props => (
              <CodeGenOptionComponent 
                value={settings[props.prop]}
                onChange={handleChange}
                {...props}
                key={props.prop}
              />
            ))}
            <Collapsible label="Advanced">
              <Stack gap={2} sx={{ pt: 1, mb: 2 }}>
                {advancedOptions.map(props => (
                  <CodeGenOptionComponent 
                    value={settings[props.prop]}
                    onChange={handleChange}
                    {...props}
                    key={props.prop}
                  />
                ))}
              </Stack>
            </Collapsible>
          </Stack>
        </FormGroup>
        <Box sx={{ flexGrow: 1 }} />
        <Divider />
        <NativeSelect
          sx={{ mt: 2 }}
          value={previewNative}
          onChange={setPreviewNative}
        />
        <Button
          sx={{ mt: 2 }}
          variant="contained"
          onClick={handleDownload}
          fullWidth
        >
          Download
        </Button>
      </Grid>
      <Grid xs={12} md={6} sx={{ display: 'flex', flexDirection: 'column' }} item>
        <Typography 
          variant="h5" 
          component="h2" 
          gutterBottom
        >
          preview
        </Typography>
        <Paper elevation={4} sx={{ p: 0, flexGrow: 1, overflow: 'hidden' }}>
          <SyntaxHighlighter 
            language={name}
            customStyle={{
              height: '100%',
              overflow: 'auto'
            }}
          >
            {preview}
          </SyntaxHighlighter>
        </Paper>
      </Grid>
    </Grid>
  )
}