notistack#useSnackbar TypeScript Examples

The following examples show how to use notistack#useSnackbar. 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: useResetPasswordFormik.tsx    From bouncecode-cms with GNU General Public License v3.0 7 votes vote down vote up
function useResetPasswordFormik(
  onSubmit: (
    values: FormikValues,
    formikHelpers: FormikHelpers<FormikValues>,
  ) => void | Promise<any>,
  options?: Partial<FormikConfig<FormikValues>>,
) {
  const {enqueueSnackbar} = useSnackbar();

  const formik = useFormik({
    ...options,
    initialValues: {
      ...initialValues,
      ...options?.initialValues,
    },
    validationSchema,
    onSubmit,
  });

  useEffect(() => {
    if (formik.submitCount > 0 && !formik.isSubmitting && !formik.isValid) {
      enqueueSnackbar('누락된 입력 항목을 확인해주세요.', {
        variant: 'error',
      });
    }
  }, [formik.submitCount, formik.isSubmitting]);

  return formik;
}
Example #2
Source File: data-loading.ts    From abacus with GNU General Public License v2.0 7 votes vote down vote up
/**
 * Declaratively handles data loading errors.
 *
 * @param error
 * @param dataName (Optional) Name of the data to be included in the message
 */
export function useDataLoadingError<E extends Error | null>(error: E, dataName?: string): void {
  const { enqueueSnackbar } = useSnackbar()

  useEffect(() => {
    if (error) {
      console.error('DataLoadingError', dataName, error)
      const userErrorMessage = dataName
        ? `Oops! There was a problem loading: ${dataName}. ${serverErrorMessage(error)}`
        : `Oops! There was a problem loading data. ${serverErrorMessage(error)}`
      enqueueSnackbar(userErrorMessage, { variant: 'error', persist: true })
    }
  }, [error, enqueueSnackbar, dataName])
}
Example #3
Source File: project.context.tsx    From frontend with Apache License 2.0 6 votes vote down vote up
function ProjectProvider({ children }: ProjectProviderProps) {
  const initialState: State = {
    selectedProjectId: null,
    projectList: [],
    projectEditState: DEFAULT_PROJECT_EDIT_STATE,
  };

  const { loggedIn } = useUserState();
  const [state, dispatch] = React.useReducer(projectReducer, initialState);
  const { enqueueSnackbar } = useSnackbar();

  React.useEffect(() => {
    loggedIn &&
      getProjectList(dispatch).catch((err) =>
        enqueueSnackbar(err, {
          variant: "error",
        })
      );
  }, [enqueueSnackbar, loggedIn]);

  return (
    <ProjectStateContext.Provider value={state}>
      <ProjectDispatchContext.Provider value={dispatch}>
        {children}
      </ProjectDispatchContext.Provider>
    </ProjectStateContext.Provider>
  );
}
Example #4
Source File: ClipboardCopy.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
export default function ClipboardCopy({ value }: Props): ReactElement {
  const { enqueueSnackbar } = useSnackbar()
  const handleCopy = () => enqueueSnackbar(`Copied: ${value}`, { variant: 'success' })

  return (
    <div style={{ marginRight: '3px', marginLeft: '3px' }}>
      <IconButton color="primary" size="small" onClick={handleCopy}>
        <CopyToClipboard text={value}>
          <Clipboard style={{ height: '20px' }} />
        </CopyToClipboard>
      </IconButton>
    </div>
  )
}
Example #5
Source File: useNotification.tsx    From homebase-app with MIT License 6 votes vote down vote up
useNotification = () => {
  const { enqueueSnackbar, closeSnackbar } = useSnackbar();
  const open = ({ message, detailsLink, ...options }: NotificationParams) => {
    const key = enqueueSnackbar(message, {
      ...options,
      persist: true,
      action: (
        <NotificationActions
          detailsLink={detailsLink}
          onClose={() => closeSnackbar(key)}
        />
      ),
    });

    return { key, closeSnackbar };
  };

  return open;
}
Example #6
Source File: EnvironmentNotifier.tsx    From clearflask with Apache License 2.0 6 votes vote down vote up
EnvironmentNotifier = () => {
  const { enqueueSnackbar } = useSnackbar();

  if (isProd()) return null;

  if (wasShown) return null;
  wasShown = true;

  const env = detectEnv();
  console.log("Environment:", env);
  enqueueSnackbar("Environment: " + env, {
    preventDuplicate: true,
  });
  return null;
}
Example #7
Source File: index.tsx    From bouncecode-cms with GNU General Public License v3.0 6 votes vote down vote up
AdminLayout: IComponent = ({children}) => {
  const handleLogout = useSignOutCallback();
  const {enqueueSnackbar} = useSnackbar();
  const {data, loading, error} = useMeQuery({
    onCompleted: data => {
      if (!data?.me?.isAdmin) {
        enqueueSnackbar('권한이 없습니다.', {variant: 'error'});
        Router.push('/');
      }
    },
    onError: () => {
      Router.push('/signin');
    },
  });

  if (loading || !data || !data?.me?.isAdmin) {
    return <PageLoadingView />;
  }

  return (
    <AdminLayoutModule
      drawer={<AdminLayoutDrawerModule />}
      data={data}
      handleLogout={handleLogout}
      children={children}
    />
  );
}
Example #8
Source File: SnackBar.tsx    From parity-bridges-ui with GNU General Public License v3.0 6 votes vote down vote up
export default function SnackBar() {
  const { enqueueSnackbar, closeSnackbar } = useSnackbar();
  const { message, variant } = useMessageContext();
  const { dispatchMessage } = useUpdateMessageContext();

  useEffect(() => {
    if (message && variant) {
      enqueueSnackbar(message, {
        action: <CloseButton onClick={() => closeSnackbar()}>CLOSE</CloseButton>,
        anchorOrigin: { horizontal: 'right', vertical: 'top' },
        variant
      });
      dispatchMessage(MessageActionsCreators.clearMessage());
    }
  }, [closeSnackbar, message, variant, enqueueSnackbar, dispatchMessage]);

  return null;
}
Example #9
Source File: index.tsx    From lobis-frontend with MIT License 6 votes vote down vote up
// A component that displays error messages
function Messages() {
    const { enqueueSnackbar } = useSnackbar();
    const messages = useSelector<IReduxState, MessagesState>(state => state.messages);
    const dispatch = useDispatch();

    useEffect(() => {
        if (messages.message) {
            enqueueSnackbar(JSON.stringify(messages.message));
            dispatch(close());
        }
    }, [messages.message]);

    return <div></div>;
}
Example #10
Source File: index.tsx    From rugenerous-frontend with MIT License 6 votes vote down vote up
// A component that displays error messages
function Messages() {
  const { enqueueSnackbar } = useSnackbar();
  const messages = useSelector<IReduxState, MessagesState>(state => state.messages);
  const dispatch = useDispatch();

  useEffect(() => {
    if (messages.message) {
      enqueueSnackbar(JSON.stringify(messages.message));
      dispatch(close());
    }
  }, [messages.message]);

  return <div></div>;
}
Example #11
Source File: notify.tsx    From wallet-adapter with Apache License 2.0 6 votes vote down vote up
export function useNotify() {
    const { enqueueSnackbar } = useSnackbar();

    return useCallback(
        (variant: VariantType, message: string, signature?: string) => {
            enqueueSnackbar(
                <Notification>
                    {message}
                    {signature && (
                        <StyledLink href={`https://explorer.solana.com/tx/${signature}?cluster=devnet`} target="_blank">
                            Transaction
                            <StyledLaunchIcon />
                        </StyledLink>
                    )}
                </Notification>,
                { variant }
            );
        },
        [enqueueSnackbar]
    );
}
Example #12
Source File: snackbar.tsx    From rugenerous-frontend with MIT License 5 votes vote down vote up
SnackMessage = forwardRef<HTMLDivElement, { id: string | number; message: Message }>((props, ref) => {
  const classes = useStyles();
  const { closeSnackbar } = useSnackbar();
  const [expanded, setExpanded] = useState(false);
  const [isCopy, setIsCopy] = useState(false);

  const handleExpandClick = useCallback(() => {
    setExpanded(oldExpanded => !oldExpanded);
  }, []);

  const handleDismiss = useCallback(() => {
    closeSnackbar(props.id);
  }, [props.id, closeSnackbar]);

  const getIcon = (severity: Color) => {
    switch (severity) {
      case "error":
        return <ErrorIcon color="inherit" />;
      case "info":
        return <InfoIcon color="inherit" />;
      case "success":
        return <SuccessIcon color="inherit" />;
      case "warning":
        return <WarningIcon color="inherit" />;
      default:
        return <div />;
    }
  };

  return (
    <SnackbarContent ref={ref} className={classes.root}>
      <Card className={classnames(classes.card, classes[props.message.severity])}>
        <CardActions classes={{ root: classes.actionRoot }}>
          {getIcon(props.message.severity)}
          <Typography variant="subtitle2" className={classes.typography}>
            {props.message.text}
          </Typography>
          <div className={classes.icons}>
            {props.message.error && (
              <IconButton
                aria-label="Show more"
                className={classnames(classes.expand, { [classes.expandOpen]: expanded })}
                onClick={handleExpandClick}
              >
                <ExpandMoreIcon color="inherit" />
              </IconButton>
            )}
            <IconButton className={classes.expand} onClick={handleDismiss}>
              <CloseIcon color="inherit" />
            </IconButton>
          </div>
        </CardActions>
        <Collapse in={expanded} timeout="auto" unmountOnExit>
          <Paper className={classes.collapse}>
            <CopyToClipboard text={JSON.stringify(props.message.error)} onCopy={() => setIsCopy(true)}>
              <Button size="small" className={classes.button}>
                <CheckCircleIcon className={classnames(classes.checkIcon, { [classes.checkIconCopy]: isCopy })} />
                Copy to clipboard
              </Button>
            </CopyToClipboard>
            <div className={classes.errorWrap}>
              <Typography>Error message: </Typography>
              <Typography className={classes.errorText}>{JSON.stringify(props.message.error, null, 2)}</Typography>
            </div>
          </Paper>
        </Collapse>
      </Card>
    </SnackbarContent>
  );
})
Example #13
Source File: App.tsx    From swap-ui with Apache License 2.0 5 votes vote down vote up
function AppInner() {
  const styles = useStyles();
  const { enqueueSnackbar } = useSnackbar();
  const [isConnected, setIsConnected] = useState(false);
  const [tokenList, setTokenList] = useState<TokenListContainer | null>(null);

  const [provider, wallet] = useMemo(() => {
    const opts: ConfirmOptions = {
      preflightCommitment: "recent",
      commitment: "recent",
    };
    const network = "https://solana-api.projectserum.com";
    const wallet = new Wallet("https://www.sollet.io", network);
    const connection = new Connection(network, opts.preflightCommitment);
    const provider = new NotifyingProvider(
      connection,
      wallet,
      opts,
      (tx, err) => {
        if (err) {
          enqueueSnackbar(`Error: ${err.toString()}`, {
            variant: "error",
          });
        } else {
          enqueueSnackbar("Transaction sent", {
            variant: "success",
            action: (
              <Button
                color="inherit"
                component="a"
                target="_blank"
                rel="noopener"
                href={`https://explorer.solana.com/tx/${tx}`}
              >
                View on Solana Explorer
              </Button>
            ),
          });
        }
      }
    );
    return [provider, wallet];
  }, [enqueueSnackbar]);

  useEffect(() => {
    new TokenListProvider().resolve().then(setTokenList);
  }, [setTokenList]);

  // Connect to the wallet.
  useEffect(() => {
    wallet.on("connect", () => {
      enqueueSnackbar("Wallet connected", { variant: "success" });
      setIsConnected(true);
    });
    wallet.on("disconnect", () => {
      enqueueSnackbar("Wallet disconnected", { variant: "info" });
      setIsConnected(false);
    });
  }, [wallet, enqueueSnackbar]);

  return (
    <Grid
      container
      justify="center"
      alignItems="center"
      className={styles.root}
    >
      <Button
        variant="outlined"
        onClick={() => (!isConnected ? wallet.connect() : wallet.disconnect())}
        style={{ position: "fixed", right: 24, top: 24 }}
      >
        {!isConnected ? "Connect" : "Disconnect"}
      </Button>
      {tokenList && <Swap provider={provider} tokenList={tokenList} />}
    </Grid>
  );
}
Example #14
Source File: snackbar.tsx    From lobis-frontend with MIT License 5 votes vote down vote up
SnackMessage = forwardRef<HTMLDivElement, { id: string | number; message: Message }>((props, ref) => {
    const classes = useStyles();
    const { closeSnackbar } = useSnackbar();
    const [expanded, setExpanded] = useState(false);
    const [isCopy, setIsCopy] = useState(false);

    const handleExpandClick = useCallback(() => {
        setExpanded(oldExpanded => !oldExpanded);
    }, []);

    const handleDismiss = useCallback(() => {
        closeSnackbar(props.id);
    }, [props.id, closeSnackbar]);

    const getIcon = (severity: Color) => {
        switch (severity) {
            case "error":
                return <ErrorIcon color="inherit" />;
            case "info":
                return <InfoIcon color="inherit" />;
            case "success":
                return <SuccessIcon color="inherit" />;
            case "warning":
                return <WarningIcon color="inherit" />;
            default:
                return <div />;
        }
    };

    const copyToClipboard = (text: any) => () => {
        const textField = document.createElement("textarea");
        textField.innerText = text;
        document.body.appendChild(textField);
        textField.select();
        document.execCommand("copy");
        textField.remove();
        setIsCopy(true);
    };

    return (
        <SnackbarContent ref={ref} className={classes.root}>
            <Card className={classnames(classes.card, classes[props.message.severity])}>
                <CardActions classes={{ root: classes.actionRoot }}>
                    {getIcon(props.message.severity)}
                    <Typography variant="subtitle2" className={classes.typography}>
                        {props.message.text}
                    </Typography>
                    <div className={classes.icons}>
                        {props.message.error && (
                            <IconButton aria-label="Show more" className={classnames(classes.expand, { [classes.expandOpen]: expanded })} onClick={handleExpandClick}>
                                <ExpandMoreIcon color="inherit" />
                            </IconButton>
                        )}
                        <IconButton className={classes.expand} onClick={handleDismiss}>
                            <CloseIcon color="inherit" />
                        </IconButton>
                    </div>
                </CardActions>
                <Collapse in={expanded} timeout="auto" unmountOnExit>
                    <Paper className={classes.collapse}>
                        <Button size="small" className={classes.button} onClick={copyToClipboard(JSON.stringify(props.message.error))}>
                            <CheckCircleIcon className={classnames(classes.checkIcon, { [classes.checkIconCopy]: isCopy })} />
                            Copy to clipboard
                        </Button>
                        <div className={classes.errorWrap}>
                            <Typography>Error message: </Typography>
                            <Typography className={classes.errorText}>{JSON.stringify(props.message.error, null, 2)}</Typography>
                        </div>
                    </Paper>
                </Collapse>
            </Card>
        </SnackbarContent>
    );
})
Example #15
Source File: useCommentCreateFormik.tsx    From bouncecode-cms with GNU General Public License v3.0 5 votes vote down vote up
export function useCommentCreateFormik(
  postId: string,
  options?: Partial<FormikConfig<FormikValues>>,
) {
  const {enqueueSnackbar} = useSnackbar();
  const [create] = useCommentCreateMutation({
    onCompleted: () => {
      formik.handleReset(null);
    },
  });

  const onSubmit = async (
    values: FormikValues,
    formikHelpers: FormikHelpers<FormikValues>,
  ) => {
    return create({
      variables: {
        data: {
          postId,
          text: values.text,
          payload: {},
        },
      },
      refetchQueries: [CommentsDocument, CommentStatDocument],
    });
  };

  const formik = useFormik({
    ...options,
    initialValues: {
      ...initialValues,
      ...options?.initialValues,
    },
    validationSchema,
    onSubmit,
  });

  useEffect(() => {
    if (formik.submitCount > 0 && !formik.isSubmitting && !formik.isValid) {
      enqueueSnackbar('누락된 입력 항목을 확인해주세요.', {
        variant: 'error',
      });
    }
  }, [formik.submitCount, formik.isSubmitting]);

  return formik;
}
Example #16
Source File: ContextProvider.tsx    From wallet-adapter with Apache License 2.0 5 votes vote down vote up
WalletContextProvider: FC<{ children: ReactNode }> = ({ children }) => {
    const { autoConnect } = useAutoConnect();

    // Can be set to 'devnet', 'testnet', or 'mainnet-beta'
    const network = WalletAdapterNetwork.Devnet;

    // You can also provide a custom RPC endpoint
    const endpoint = useMemo(() => clusterApiUrl(network), [network]);

    // @solana/wallet-adapter-wallets includes all the adapters but supports tree shaking and lazy loading --
    // Only the wallets you configure here will be compiled into your application, and only the dependencies
    // of wallets that your users connect to will be loaded
    const wallets = useMemo(
        () => [
            new PhantomWalletAdapter(),
            new GlowWalletAdapter(),
            new SlopeWalletAdapter(),
            new SolflareWalletAdapter({ network }),
            new TorusWalletAdapter(),
            new WalletConnectWalletAdapter({
                options: {
                    relayUrl: 'wss://relay.walletconnect.com',
                    // example WC dapp project ID
                    projectId: 'e899c82be21d4acca2c8aec45e893598',
                    metadata: {
                        name: 'Example Dapp',
                        description: 'Example Dapp',
                        url: 'https://github.com/solana-labs/wallet-adapter',
                        icons: ['https://avatars.githubusercontent.com/u/35608259?s=200'],
                    },
                },
            }),
        ],
        [network]
    );

    const { enqueueSnackbar } = useSnackbar();
    const onError = useCallback(
        (error: WalletError) => {
            enqueueSnackbar(error.message ? `${error.name}: ${error.message}` : error.name, { variant: 'error' });
            console.error(error);
        },
        [enqueueSnackbar]
    );

    return (
        <ConnectionProvider endpoint={endpoint}>
            <WalletProvider wallets={wallets} onError={onError} autoConnect={autoConnect}>
                <MaterialUIWalletDialogProvider>
                    <AntDesignWalletModalProvider>
                        <ReactUIWalletModalProvider>{children}</ReactUIWalletModalProvider>
                    </AntDesignWalletModalProvider>
                </MaterialUIWalletDialogProvider>
            </WalletProvider>
        </ConnectionProvider>
    );
}
Example #17
Source File: snackbar.tsx    From wonderland-frontend with MIT License 5 votes vote down vote up
SnackMessage = forwardRef<HTMLDivElement, { id: string | number; message: Message }>((props, ref) => {
    const classes = useStyles();
    const { closeSnackbar } = useSnackbar();
    const [expanded, setExpanded] = useState(false);
    const [isCopy, setIsCopy] = useState(false);

    const handleExpandClick = useCallback(() => {
        setExpanded(oldExpanded => !oldExpanded);
    }, []);

    const handleDismiss = useCallback(() => {
        closeSnackbar(props.id);
    }, [props.id, closeSnackbar]);

    const getIcon = (severity: Color) => {
        switch (severity) {
            case "error":
                return <ErrorIcon color="inherit" />;
            case "info":
                return <InfoIcon color="inherit" />;
            case "success":
                return <SuccessIcon color="inherit" />;
            case "warning":
                return <WarningIcon color="inherit" />;
            default:
                return <div />;
        }
    };

    return (
        <SnackbarContent ref={ref} className={classes.root}>
            <Card className={classnames(classes.card, classes[props.message.severity])}>
                <CardActions classes={{ root: classes.actionRoot }}>
                    {getIcon(props.message.severity)}
                    <Typography variant="subtitle2" className={classes.typography}>
                        {props.message.text}
                    </Typography>
                    <div className={classes.icons}>
                        {props.message.error && (
                            <IconButton aria-label="Show more" className={classnames(classes.expand, { [classes.expandOpen]: expanded })} onClick={handleExpandClick}>
                                <ExpandMoreIcon color="inherit" />
                            </IconButton>
                        )}
                        <IconButton className={classes.expand} onClick={handleDismiss}>
                            <CloseIcon color="inherit" />
                        </IconButton>
                    </div>
                </CardActions>
                <Collapse in={expanded} timeout="auto" unmountOnExit>
                    <Paper className={classes.collapse}>
                        <CopyToClipboard text={JSON.stringify(props.message.error)} onCopy={() => setIsCopy(true)}>
                            <Button size="small" className={classes.button}>
                                <CheckCircleIcon className={classnames(classes.checkIcon, { [classes.checkIconCopy]: isCopy })} />
                                Copy to clipboard
                            </Button>
                        </CopyToClipboard>
                        <div className={classes.errorWrap}>
                            <Typography>Error message: </Typography>
                            <Typography className={classes.errorText}>{JSON.stringify(props.message.error, null, 2)}</Typography>
                        </div>
                    </Paper>
                </Collapse>
            </Card>
        </SnackbarContent>
    );
})
Example #18
Source File: Post.tsx    From clearflask with Apache License 2.0 5 votes vote down vote up
PostCoverEdit = (props: {
  onUploaded: (coverUrl: string) => void;
  server: Server;
  authorUserId?: string;
  content?: React.ReactNode;
}) => {
  const classes = useStyles();
  const { enqueueSnackbar } = useSnackbar();
  const imageUploadRef = useRef<RichEditorImageUpload>(null);

  return (
    <>
      <Dropzone
        minSize={1}
        maxFiles={1}
        onDrop={async (acceptedFiles, rejectedFiles, e) => {
          rejectedFiles.forEach(rejectedFile => {
            rejectedFile.errors.forEach(error => {
              enqueueSnackbar(
                `${rejectedFile.file.name}: ${error.message}`,
                { variant: 'error' });
            })
          })

          if (acceptedFiles.length < 1) return;
          const acceptedFile = acceptedFiles[0];

          const coverUrl = await imageUploadRef.current?.uploadImage(acceptedFile);
          if (!coverUrl) return;

          props.onUploaded(coverUrl);
        }}
      >
        {({ getRootProps, getInputProps }) => (
          <div className={classNames(!props.content && classes.dropzone)} {...getRootProps()}>
            <input {...getInputProps()} />
            {props.content ? props.content : (
              <>
                <ImgIcon color='inherit' className={classes.uploadIcon} />
                Upload a cover image
              </>
            )}
          </div>
        )}
      </Dropzone>
      <RichEditorImageUpload
        ref={imageUploadRef}
        server={props.server}
        asAuthorId={props.authorUserId}
      />
    </>
  );
}
Example #19
Source File: Notifier.tsx    From react-pwa with MIT License 5 votes vote down vote up
// NOTE: this is a workaround for a missing feature in notistack
// This will be removed once the new version of notistack is released
// But it works great for now :)
function Notifier() {
  const [notifications, actions] = useNotifications();
  const { enqueueSnackbar, closeSnackbar } = useSnackbar();
  const displayed = useRef<SnackbarKey[]>([]);

  function storeDisplayed(key: SnackbarKey) {
    displayed.current = [...displayed.current, key];
  }

  function removeDisplayed(key: SnackbarKey) {
    displayed.current = [...displayed.current.filter((_key) => key !== _key)];
  }

  useEffect(() => {
    notifications.forEach(({ message, options, dismissed }) => {
      if (dismissed) {
        // dismiss snackbar using notistack
        closeSnackbar(options.key);
        return;
      }

      // do nothing if snackbar is already displayed
      if (options.key && displayed.current.includes(options.key)) return;

      // display snackbar using notistack
      enqueueSnackbar(message, {
        ...options,
        onExited(event, key) {
          // removen this snackbar from the store
          actions.remove(key);
          removeDisplayed(key);
        },
      });

      // keep track of snackbars that we've displayed
      options.key && storeDisplayed(options.key);
    });
  });

  return null;
}
Example #20
Source File: SubscriptionStatusNotifier.tsx    From clearflask with Apache License 2.0 5 votes vote down vote up
SubscriptionStatusNotifier = (props: {
  account: Admin.AccountAdmin
}) => {
  const { enqueueSnackbar, closeSnackbar } = useSnackbar();
  const history = useHistory();

  if (lastShown === props.account.subscriptionStatus) return null;
  lastShown = props.account.subscriptionStatus;
  closeSnackbar(lastKey);

  var persist: boolean = true;
  var variant: VariantType = 'info';
  var content: string | undefined;
  var billingButtonTitle = 'Billing';
  switch (props.account.subscriptionStatus) {
    case Admin.SubscriptionStatus.Active:
    case Admin.SubscriptionStatus.ActiveTrial:
      break;
    case Admin.SubscriptionStatus.ActivePaymentRetry:
      variant = 'warning';
      content = 'We cannot process your payment';
      break;
    case Admin.SubscriptionStatus.ActiveNoRenewal:
      variant = 'warning';
      content = 'Your account will soon expire';
      persist = false;
      break;
    case Admin.SubscriptionStatus.Limited:
      variant = 'warning';
      content = 'You have reached your plan limit, please delete some posts';
      billingButtonTitle = 'Check again';
      break;
    case Admin.SubscriptionStatus.NoPaymentMethod:
      variant = 'warning';
      content = 'Please add a payment method';
      billingButtonTitle = 'Add';
      break;
    case Admin.SubscriptionStatus.Blocked:
      variant = 'error';
      content = 'Your account is blocked, contact support';
      break;
    case Admin.SubscriptionStatus.Cancelled:
      variant = 'error';
      content = 'Your account is cancelled, update your billing to continue';
      break;
  }

  if (content) {
    lastKey = enqueueSnackbar(content, {
      variant,
      preventDuplicate: true,
      persist,
      action: (key) => (
        <Button
          color='inherit'
          onClick={async () => {
            await ServerAdmin.get().getStore().dispatch({ type: 'billingClear' });
            history.push('/dashboard/settings/account/billing');
            !persist && closeSnackbar(key);
          }}
        >{billingButtonTitle}</Button>
      ),
    });
  }

  return null;
}
Example #21
Source File: ExportFeedDialog.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
export function ExportFeedDialog({ identity, onClose }: Props): ReactElement {
  const { enqueueSnackbar } = useSnackbar()

  const classes = useStyles()

  function onDownload() {
    saveAs(
      new Blob([identity.identity], {
        type: 'application/json',
      }),
      identity.name + '.json',
    )
  }

  function getExportText() {
    return identity.type === 'V3' ? 'JSON file' : 'the private key string'
  }

  function onCopy() {
    navigator.clipboard
      .writeText(identity.identity)
      .then(() => enqueueSnackbar('Copied to Clipboard', { variant: 'success' }))
  }

  return (
    <SwarmDialog>
      <Box mb={4}>
        <TitleWithClose onClose={onClose}>Export</TitleWithClose>
      </Box>
      <Box mb={2}>
        <Typography align="center">{`We exported the identity associated with this feed as ${getExportText()}.`}</Typography>
      </Box>
      <Box mb={4} className={classes.wrapper}>
        <Code prettify>{identity.identity}</Code>
      </Box>
      <ExpandableListItemActions>
        <SwarmButton iconType={Download} onClick={onDownload}>
          Download JSON File
        </SwarmButton>
        <SwarmButton iconType={Clipboard} onClick={onCopy}>
          Copy To Clipboard
        </SwarmButton>
      </ExpandableListItemActions>
    </SwarmDialog>
  )
}
Example #22
Source File: index.tsx    From frontend with Apache License 2.0 5 votes vote down vote up
UserList = () => {
  const { enqueueSnackbar } = useSnackbar();
  const userDispatch = useUserDispatch();
  const { userList } = useUserState();

  React.useEffect(() => {
    usersService
      .getAll()
      .then((users) => userDispatch({ type: "getAll", payload: users }));
  }, [userDispatch]);

  const handleEditCellChangeCommitted = React.useCallback(
    (params: GridCellEditCommitParams) => {
      const { id, field, value } = params;
      if (field === "role") {
        usersService
          .assignRole(id, value as Role)
          .then(() => {
            enqueueSnackbar("Updated", {
              variant: "success",
            });
          })
          .catch((err) =>
            enqueueSnackbar(err, {
              variant: "error",
            })
          );
      }
    },
    [enqueueSnackbar]
  );

  return (
    <DataGrid
      rows={userList}
      columns={columnsDef}
      checkboxSelection
      disableColumnMenu
      disableSelectionOnClick
      components={{
        Toolbar: DataGridCustomToolbar,
      }}
      onCellEditCommit={handleEditCellChangeCommitted}
    />
  );
}
Example #23
Source File: index.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
export default function Index(): ReactElement {
  const { jsonRpcProvider, setJsonRpcProvider } = useContext(Context)

  const [provider, setProvider] = useState(jsonRpcProvider)

  const { enqueueSnackbar } = useSnackbar()
  const navigate = useNavigate()

  async function onSubmit() {
    try {
      await Rpc.eth_getBlockByNumber(provider)
      enqueueSnackbar('Connected to RPC provider successfully.', { variant: 'success' })
      setJsonRpcProvider(provider)
      navigate(ROUTES.CONFIRMATION)
    } catch (error) {
      enqueueSnackbar('Could not connect to RPC provider.', { variant: 'error' })
    }
  }

  return (
    <>
      <HistoryHeader>Connect to the blockchain</HistoryHeader>
      <Box mb={1}>
        <Typography style={{ fontWeight: 'bold' }}>Set up RPC endpoint</Typography>
      </Box>
      <Box mb={4}>
        <Typography>
          To connect to and retrieve data from the blockchain, you&apos;ll need to connect to a publicly-provided node
          via the node&apos;s RPC endpoint. If you&apos;re not familiar with this, you may use{' '}
          <a href="https://getblock.io/" target="_blank" rel="noreferrer">
            https://getblock.io/
          </a>
          .
        </Typography>
      </Box>
      <Box mb={2}>
        <SwarmTextInput
          name="rpc-endpoint"
          label="RPC Endpoint"
          onChange={event => setProvider(event.target.value)}
          defaultValue={jsonRpcProvider}
        />
      </Box>
      <SwarmButton iconType={Check} onClick={onSubmit}>
        Connect
      </SwarmButton>
    </>
  )
}
Example #24
Source File: useNotifier.tsx    From shadowsocks-electron with GNU General Public License v3.0 5 votes vote down vote up
useNotifier = () => {
    const dispatch = useDispatch();

    const notifications = useTypedSelector(store => store.notifications);
    const { enqueueSnackbar, closeSnackbar } = useSnackbar();

    const storeDisplayed = (id: SnackbarKey) => {
        displayed = [...displayed, id];
    };

    const removeDisplayed = (id: SnackbarKey) => {
        displayed = [...displayed.filter(key => id !== key)];
    };

    React.useEffect(() => {
        notifications.forEach(({ key, message, dismissed = false, ...options }) => {
            if (dismissed) {
                // dismiss snackbar using notistack
                closeSnackbar(key);
                return;
            }

            // do nothing if snackbar is already displayed
            if (displayed.includes(key)) return;

            // display snackbar using notistack
            enqueueSnackbar(message, {
                key,
                ...options,
                onClose: (event, reason, myKey) => {
                    if ((options as any).onClose) {
                        (options as any).onClose(event, reason, myKey);
                    }
                },
                onExited: (event, myKey) => {
                    // remove this snackbar from redux store
                    dispatch(removeSnackbar(myKey));
                    removeDisplayed(myKey);
                },
            });

            // keep track of snackbars that we've displayed
            storeDisplayed(key);
        });

    }, [notifications, closeSnackbar, enqueueSnackbar, dispatch]);
}
Example #25
Source File: ApproveRejectButtons.tsx    From frontend with Apache License 2.0 5 votes vote down vote up
ApproveRejectButtons: React.FunctionComponent<{
  testRun: TestRun;
}> = ({ testRun }) => {
  const { enqueueSnackbar } = useSnackbar();

  const approve = () => {
    testRunService
      .approveBulk([testRun.id], testRun.merge)
      .then(() =>
        enqueueSnackbar("Approved", {
          variant: "success",
        })
      )
      .catch((err) =>
        enqueueSnackbar(err, {
          variant: "error",
        })
      );
  };

  const reject = () => {
    testRunService
      .rejectBulk([testRun.id])
      .then(() =>
        enqueueSnackbar("Rejected", {
          variant: "success",
        })
      )
      .catch((err) =>
        enqueueSnackbar(err, {
          variant: "error",
        })
      );
  };

  useHotkeys("a", approve, [testRun]);
  useHotkeys("x", reject, [testRun]);

  return (
    <Grid container spacing={2} alignItems="center">
      {testRun.merge && (
        <Grid item>
          <Tooltip title="Will replace target branch baseline if accepted">
            <Chip
              label={`merge into: ${testRun.baselineBranchName}`}
              color="secondary"
              size="small"
            />
          </Tooltip>
        </Grid>
      )}
      <Grid item>
        <Tooltip title={"Hotkey: A"}>
          <Button color="inherit" onClick={approve}>
            Approve
          </Button>
        </Tooltip>
      </Grid>
      <Grid item>
        <Tooltip title={"Hotkey: X"}>
          <Button color="secondary" onClick={reject}>
            Reject
          </Button>
        </Tooltip>
      </Grid>
    </Grid>
  );
}
Example #26
Source File: NotificationProvider.tsx    From Teyvat.moe with GNU General Public License v3.0 5 votes vote down vote up
NotificationHandler: FunctionComponent = () => {
  const notifications = useSelector(selectNotifications);
  const dispatch = useDispatch();

  /**
   * The functions which link with the NotificationProvider
   * to enqueue and dequeue the notifications.
   */
  const { enqueueSnackbar, closeSnackbar } = useSnackbar();

  /**
   * The keys of the notifications which have already been enqueued for display.
   */
  const [currentlyDisplayed, setCurrentlyDisplayed] = useState<SnackbarKey[]>([]);

  useEffect(() => {
    const addDisplayed = (key: SnackbarKey) => {
      setCurrentlyDisplayed((previous) => [...previous, key]);
    };
    const removeDisplayed = (key: SnackbarKey) => {
      setCurrentlyDisplayed((previous) =>
        _.filter(previous, (value: SnackbarKey) => value !== key)
      );
    };

    _.forEach(notifications, (notification) => {
      // If this snackbar has been flagged for dismissal, close it.
      if (notification.dismissed) {
        closeSnackbar(notification.options.key);
        return;
      }

      // This notification is invalid.
      if (notification.options.key == null) return;

      // Skip if we've already displayed this snackbar.
      if (_.includes(currentlyDisplayed, notification.options.key)) return;

      const notificationOptions: OptionsObject = {
        ...notification.options,
        onClose: (event, reason, myKey) => {
          if (notification.options.onClose) {
            notification.options.onClose(event, reason, myKey);
          }
        },
        onExited: () => {
          // The notification has left. We can now remove it from the store.
          if (notification.options.key != null) {
            dispatch(removeNotification(notification.options.key));
            removeDisplayed(notification.options.key);
          }
        },
      };

      // Else, we need to enqueue this snackbar.
      enqueueSnackbar(notification.message, notificationOptions);
      addDisplayed(notification.options.key);
    });
  }, [
    notifications,
    currentlyDisplayed,
    setCurrentlyDisplayed,
    enqueueSnackbar,
    closeSnackbar,
    removeNotification,
  ]);

  // Has no actual render presence.
  return null;
}
Example #27
Source File: CreateNewFeed.tsx    From bee-dashboard with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
export default function CreateNewFeed(): ReactElement {
  const { beeApi, beeDebugApi } = useContext(SettingsContext)
  const { identities, setIdentities } = useContext(FeedsContext)
  const [loading, setLoading] = useState(false)
  const { enqueueSnackbar } = useSnackbar()

  const navigate = useNavigate()

  async function onSubmit(values: FormValues) {
    setLoading(true)

    if (!beeApi) {
      enqueueSnackbar(<span>Bee API unavailabe</span>, { variant: 'error' })
      setLoading(false)

      return
    }
    const wallet = generateWallet()
    const stamps = await beeDebugApi?.getAllPostageBatch()

    if (!stamps || !stamps.length) {
      enqueueSnackbar(<span>No stamp available</span>, { variant: 'error' })
      setLoading(false)

      return
    }

    if (!values.identityName || !values.type) {
      enqueueSnackbar(<span>Form is unfinished</span>, { variant: 'error' })
      setLoading(false)

      return
    }

    const identity = await convertWalletToIdentity(wallet, values.type, values.identityName, values.password)
    persistIdentity(identities, identity)
    setIdentities(identities)
    navigate(ROUTES.FEEDS)
    setLoading(false)
  }

  function cancel() {
    navigate(-1)
  }

  return (
    <div>
      <HistoryHeader>Create new feed</HistoryHeader>
      <Box mb={4}>
        <DocumentationText>
          To create a feed you will need to create an identity. Please refer to the{' '}
          <a
            href="https://docs.ethswarm.org/api/#tag/Feed/paths/~1feeds~1{owner}~1{topic}/post"
            target="_blank"
            rel="noreferrer"
          >
            official Bee documentation
          </a>{' '}
          to understand how feeds work.
        </DocumentationText>
      </Box>
      <Formik initialValues={initialValues} onSubmit={onSubmit}>
        {({ submitForm, values }) => (
          <Form>
            <Box mb={0.25}>
              <SwarmTextInput name="identityName" label="Identity name" formik />
            </Box>
            <Box mb={0.25}>
              <SwarmSelect
                formik
                name="type"
                options={[
                  { label: 'Keypair Only', value: 'PRIVATE_KEY' },
                  { label: 'Password Protected', value: 'V3' },
                ]}
              />
            </Box>
            {values.type === 'V3' && <SwarmTextInput name="password" label="Password" password formik />}
            <Box mt={2}>
              <ExpandableListItemKey label="Topic" value={'00'.repeat(32)} />
            </Box>
            <Box mt={2} sx={{ bgcolor: '#fcf2e8' }} p={2}>
              <Grid container justifyContent="space-between">
                <Typography>Feeds name</Typography>
                <Typography>{values.identityName} Website</Typography>
              </Grid>
            </Box>
            <Box mt={1.25}>
              <ExpandableListItemActions>
                <SwarmButton onClick={submitForm} iconType={Check} disabled={loading} loading={loading}>
                  Create Feed
                </SwarmButton>
                <SwarmButton onClick={cancel} iconType={X} disabled={loading} cancel>
                  Cancel
                </SwarmButton>
              </ExpandableListItemActions>
            </Box>
          </Form>
        )}
      </Formik>
    </div>
  )
}
Example #28
Source File: index.tsx    From Search-Next with GNU General Public License v3.0 4 votes vote down vote up
Sites: React.FC = (props) => {
  const { enqueueSnackbar } = useSnackbar();
  const [open, setOpen] = React.useState<boolean>(false);
  const [type, setType] = React.useState<SiteDialogType>('add');
  const [editValue, setEditValue] = React.useState({} as Site);
  const [confirmOpen, setConfirmOpen] = React.useState<boolean>(false);
  const [delId, setDelId] = React.useState<string>('');
  const [siteList, setSiteList] = React.useState<Site[]>([]);

  const getSiteList = () => {
    const result = findSite();
    setSiteList(result);
  };

  const itemClick = (val: Site) => {
    addCount(val._id);
    window.open(replaceUrlNotHaveHttpsOrHttpToHttps(val.url));
    getSiteList();
  };

  const onAdd = () => {
    setType('add');
    setOpen(true);
  };

  const onEdit = (value: Site) => {
    setType('edit');
    setEditValue(value);
    setOpen(true);
  };

  const onRemove = (id: string) => {
    setDelId(id);
    setConfirmOpen(true);
  };

  const remove = () => {
    const result = delSite(delId);
    if (result) {
      setConfirmOpen(false);
      getSiteList();
      enqueueSnackbar('删除成功', {
        variant: 'info',
        action: () => (
          <Button
            style={{ color: '#fff' }}
            onClick={() => {
              const result = repeal();
              if (result) {
                enqueueSnackbar('撤销成功', { variant: 'success' });
                getSiteList();
              }
            }}
          >
            撤销
          </Button>
        ),
      });
    } else {
      enqueueSnackbar('删除失败', { variant: 'warning' });
    }
  };

  const dialogClose = () => {
    setOpen(false);
    getSiteList();
    setEditValue({ _id: '', name: '', url: '', count: 0 });
  };

  const dialogSubmit = (val: FormTypes) => {
    if (type === 'add') {
      const result = addSite(val);
      if (result) {
        enqueueSnackbar('添加成功', { variant: 'success' });
        dialogClose();
      } else {
        enqueueSnackbar('保存失败', { variant: 'warning' });
      }
    }
    if (type === 'edit') {
      const result = editSite(editValue._id, val);
      if (result) {
        enqueueSnackbar('修改成功', { variant: 'success' });
        dialogClose();
      } else {
        enqueueSnackbar('保存失败', { variant: 'warning' });
      }
    }
  };

  React.useEffect(() => {
    getSiteList();
  }, []);

  return (
    <>
      <div className="flex justify-center items-end gap-2 h-full py-12">
        {siteList.map((i) => (
          <SiteCard
            item={i}
            key={i._id}
            onClick={() => itemClick(i)}
            onEdit={onEdit}
            onRemove={onRemove}
          />
        ))}
        <SiteCard type="add" onAdd={onAdd} />
      </div>
      <SiteDialog
        open={open}
        type={type}
        value={editValue}
        onSubmit={dialogSubmit}
        onClose={dialogClose}
      />
      <DialogConfirm
        title="删除"
        type="warning"
        content="是否删除此网址"
        open={confirmOpen}
        onOk={remove}
        onCancel={() => setConfirmOpen(false)}
      />
    </>
  );
}
Example #29
Source File: Footer.tsx    From akashlytics with GNU General Public License v3.0 4 votes vote down vote up
Footer: React.FunctionComponent<IFooterProps> = ({}) => {
  const { enqueueSnackbar, closeSnackbar } = useSnackbar();
  const classes = useStyles();

  const onDonationClick = () => {
    copyTextToClipboard(donationAddress);

    const action = (key) => (
      <React.Fragment>
        <IconButton
          onClick={() => {
            closeSnackbar(key);
          }}
        >
          <CloseIcon />
        </IconButton>
      </React.Fragment>
    );

    enqueueSnackbar("Address copied!", {
      anchorOrigin: { vertical: "bottom", horizontal: "right" },
      variant: "success",
      action,
      autoHideDuration: 3000
    });
  };

  return (
    <div className={classes.root}>
      <footer className="container">
        <Grid container spacing={2}>
          <Grid item xs={12} sm={6} lg={4}>
            <Typography variant="h3" className={classes.title}>
              akashlytics
            </Typography>
            <Typography variant="h5" className={classes.subSitle}>
              We make tools to boost and enhance <strong>web3</strong> adoption.
            </Typography>
            <img src="/images/powered-by-akash.png" className={clsx("img-fluid", classes.poweredAkash)} alt="Powered by Akash logo" />
          </Grid>
          <Grid item xs={12} sm={6} lg={8}>
            <Grid container>
              <Grid item xs={12} lg={6}>
                <Typography variant="body2" className={classes.sectionTitle}>
                  <strong>Support</strong>
                </Typography>
                <Chip
                  label={donationAddress}
                  size="small"
                  deleteIcon={<FileCopyIcon fontSize="small" />}
                  onDelete={onDonationClick}
                  onClick={onDonationClick}
                  classes={{label: classes.donationLabel}}
                />
              </Grid>
              <Grid item xs={12} lg={6}>
                <Typography variant="body2" className={classes.sectionTitle}>
                  Follow
                </Typography>
                <ul className={classes.socialLinks}>
                  <li>
                    <a href="https://discord.gg/rXDFNYnFwv" target="_blank" className={classes.socialLink}>
                      <DiscordIcon className={classes.socialIcon} />
                    </a>
                  </li>
                  <li>
                    <a href="https://www.youtube.com/channel/UC1rgl1y8mtcQoa9R_RWO0UA?sub_confirmation=1" target="_blank" className={classes.socialLink}>
                      <YouTubeIcon className={classes.socialIcon} />
                    </a>
                  </li>
                  <li>
                    <a href="https://twitter.com/akashlytics" target="_blank" className={classes.socialLink}>
                      <TwitterIcon className={classes.socialIcon} />
                    </a>
                  </li>
                  <li>
                    <a href="https://github.com/Akashlytics/akashlytics" target="_blank" className={classes.socialLink}>
                      <GitHubIcon className={classes.socialIcon} />
                    </a>
                  </li>
                </ul>
              </Grid>
            </Grid>

            <Grid item sm={12}>
              <Typography variant="body2" className={classes.sectionTitle}>
                Ideas
              </Typography>
              <Typography variant="caption">
                We are ready for the challenge{" "}
                <a className={classes.link} href="mailto:[email protected]">
                  [email protected]
                </a>
              </Typography>
            </Grid>
          </Grid>
        </Grid>

        <Box className={classes.meta}>
          <Box>
            <small>Version: {process.env.PACKAGE_VERSION}</small>
          </Box>
          <Box>
            <CopyrightIcon /> Akashlytics
          </Box>
        </Box>
      </footer>
    </div>
  );
}