DEV Community

Cover image for 23- React File Manager Chapter XXIII: Let's Make Some Toasts 🍞
Hasan Zohdy
Hasan Zohdy

Posted on

23- React File Manager Chapter XXIII: Let's Make Some Toasts 🍞

Now our requests are ready and successful, but we need to display a loading indicator while the request is being sent and also display a success or error message once the request is done.

Let's create a Toast directory to be located in design-system/components/Toast and create a Toast.tsx file inside it.

We'll be using Mantine Notifications, we already installed it so we don't need to install it again.

First off, let's import the notification provider in our Root component.

// src/design-system/components/layouts/Root.tsx
import { AppShell, MantineProvider } from "@mantine/core";
import { NotificationsProvider } from "@mantine/notifications";
import { BasicComponentProps } from "../../utils/types";

/**
 * The root should be used with react-router's configuration for rootComponent.
 * So it will wrap the entire app.
 * It can be useful for single operations as this component will only render once in the entire application life cycle.
 * You may for instance fetch settings from the server before loading the app or a Bearer token to work with the API.
 */
export default function Root({ children }: BasicComponentProps) {
  return (
    <>
      <MantineProvider withGlobalStyles withNormalizeCSS>
        <NotificationsProvider position="top-right">
          <AppShell>{children}</AppShell>
        </NotificationsProvider>
      </MantineProvider>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Now let's make our toast.

Our Toast concept

The toast we're making is as simple as this:

We'll create a loading toast that will be always displayed until some point (i.e success/error response) then we'll display a message as an update of that loading toast.

So we need to make a toast to return as an object with error and success methods.

As mentioned in the docs, we'll use showNotification method to display the toast.

So we need to get the loading title and message and make a unique id for that loading toast.

Then we'll return an object with two methods error and success that will be used to display the error and success messages.

// src/design-system/components/Toast/index.tsx
import {
  NotificationProps,
  showNotification,
  updateNotification,
} from "@mantine/notifications";
import { Random } from "@mongez/reinforcements";
import { IconCheck, IconX } from "@tabler/icons";
import React from "react";

export function toastLoading(title: React.ReactNode, message: React.ReactNode) {
  // πŸ‘‡πŸ» generate a unique id for the loading toast
  const id = Random.id();

showNotification({
    id,
    loading: true,
    title,
    message,
    autoClose: false,
    disallowClose: true,
  });

// πŸ‘‡πŸ» return an object with two methods to display success and error messages
  return {
    // πŸ‘‡πŸ» success method
    success: (
      title: React.ReactNode,
      message: React.ReactNode,
      notificationProps: Partial<NotificationProps> = {
        color: "green",
        autoClose: 5000,
      },
    ) => {
      updateNotification({
        id,
        title,
        message,
        icon: <IconCheck size={16} />,
        ...notificationProps,
      });
    },
    // πŸ‘‡πŸ» error method
    error: (
      title: React.ReactNode,
      message: React.ReactNode,
      notificationProps: Partial<NotificationProps> = {
        color: "red",
        autoClose: 5000,
      },
    ) => {
      updateNotification({
        id,
        title,
        message,
        icon: <IconX size={16} />,
        ...notificationProps,
      });
    },
  };
}
Enter fullscreen mode Exit fullscreen mode

Now let's give it a try, go to our HomePage component and let's try it.

// HomePage.tsx
import Helmet from "@mongez/react-helmet";
import FileManager from "app/file-manager";
import { toastLoading } from "design-system/components/Toast";
import { useEffect } from "react";

export default function HomePage() {
  useEffect(() => {
    const loader = toastLoading(
      "Loading",
      "Please wait while we are loading your files",
    );

    setTimeout(() => {
      loader.success("Success", "Your files are loaded successfully");
    }, 2000);
  }, []);
  return (
    <>
      <Helmet title="home" appendAppName={false} />

      <FileManager />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Now you should see something like this

Loading

And after two seconds

Success

And that's it❗️

Next Chapter

In the next chapter we'll use the toaster and try our created directory.

Article Repository

You can see chapter files in Github Repository

Don't forget the main branch has the latest updated code.

Tell me where you are now

If you're following up with me this series, tell me where are you now and what you're struggling with, i'll try to help you as much as i can.

Salam.

Oldest comments (0)