Skip to content

Commit

Permalink
Merge pull request #82 from asharonbaltazar/feat-error-notifs
Browse files Browse the repository at this point in the history
Add Error Notifications
  • Loading branch information
vmatsiiako authored Dec 7, 2022
2 parents baacc31 + d46bf54 commit ccf1010
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 121 deletions.
38 changes: 38 additions & 0 deletions frontend/components/context/Notifications/Notification.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { faXmarkCircle } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import classnames from "classnames";

import { Notification as NotificationType } from "./NotificationProvider";

interface NotificationProps {
notification: NotificationType;
clearNotification: (text?: string) => void;
}

const Notification = ({
notification,
clearNotification,
}: NotificationProps) => {
return (
<div
className={classnames(
"w-full flex items-center justify-between px-4 py-3 rounded pointer-events-auto",
{
"bg-green-600": notification.type === "success",
"bg-red-500": notification.type === "error",
}
)}
role="alert"
>
<p className="text-white text-sm font-bold">{notification.text}</p>
<button
className="bg-white/5 rounded-lg p-3"
onClick={() => clearNotification(notification.text)}
>
<FontAwesomeIcon className="text-white" icon={faXmarkCircle} />
</button>
</div>
);
};

export default Notification;
64 changes: 64 additions & 0 deletions frontend/components/context/Notifications/NotificationProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { createContext, ReactNode, useContext, useState } from "react";

import Notifications from "./Notifications";

type NotificationType = "success" | "error";

export type Notification = {
text: string;
type: NotificationType;
};

type NotificationContextState = {
createNotification: ({ text, type }: Notification) => void;
};

const NotificationContext = createContext<NotificationContextState>({
createNotification: () => console.log("createNotification not set!"),
});

export const useNotificationContext = () => useContext(NotificationContext);

interface NotificationProviderProps {
children: ReactNode;
}

const NotificationProvider = ({ children }: NotificationProviderProps) => {
const [notifications, setNotifications] = useState<Notification[]>([]);

const clearNotification = (text?: string) => {
if (text) {
return setNotifications((state) =>
state.filter((notif) => notif.text !== text)
);
}

return setNotifications([]);
};

const createNotification = ({ text, type = "success" }: Notification) => {
const doesNotifExist = notifications.some((notif) => notif.text === text);

if (doesNotifExist) {
return;
}

return setNotifications((state) => [...state, { text, type }]);
};

return (
<NotificationContext.Provider
value={{
createNotification,
}}
>
<Notifications
notifications={notifications}
clearNotification={clearNotification}
/>
{children}
</NotificationContext.Provider>
);
};

export default NotificationProvider;
28 changes: 28 additions & 0 deletions frontend/components/context/Notifications/Notifications.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Notification from "./Notification";
import { Notification as NotificationType } from "./NotificationProvider";

interface NoticationsProps {
notifications: NotificationType[];
clearNotification: (text?: string) => void;
}

const Notifications = ({
notifications,
clearNotification,
}: NoticationsProps) => {
return (
<div className="hidden fixed z-50 top-1 w-full inset-x-0 pointer-events-none md:flex justify-center">
<div className="flex flex-col gap-y-2 w-96">
{notifications.map((notif) => (
<Notification
key={notif.text}
notification={notif}
clearNotification={clearNotification}
/>
))}
</div>
</div>
);
};

export default Notifications;
107 changes: 27 additions & 80 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"devDependencies": {
"@tailwindcss/typography": "^0.5.4",
"@types/node": "18.11.9",
"@types/react": "^18.0.26",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"autoprefixer": "^10.4.7",
Expand Down
Loading

0 comments on commit ccf1010

Please sign in to comment.