diff options
Diffstat (limited to 'src')
23 files changed, 534 insertions, 65 deletions
@@ -16,7 +16,9 @@ */ import { BrowserRouter, Route, Routes } from "react-router-dom"; -import './App.scss'; +import { ReactNotifications } from "react-notifications-component"; +import "./notifications_styles/notification.scss" + import Navbar from './components/navbar/navbar'; import HomePage from './views/homepage'; import RegisterPage from './views/login/register'; @@ -27,11 +29,13 @@ import ManageItemsPage from './views/manage/items'; import ManageClientsPage from './views/manage/clients'; import ManageBrandsPage from './views/manage/brands'; import ManageInvoicesPage from './views/manage/invoices'; +import './App.scss'; const App = () => { return ( <BrowserRouter> <Navbar/> + <ReactNotifications /> <main> <Routes> <Route exact path="/" element={<HomePage/>}/> diff --git a/src/App.scss b/src/App.scss index 1b37ffe..f7fdf46 100644 --- a/src/App.scss +++ b/src/App.scss @@ -86,3 +86,22 @@ $selectionColor: rgba($primaryAccentColor, 0.9) } } +.floating-wrapper { + height: 100vh; + width: 100vw; + box-sizing: border-box; + position: fixed; + top: 0; + left: 0; + background-color: rgba($backgroundColor, 0.3); + z-index: 5; + display: flex; + justify-content: center; + align-items: center; + backdrop-filter: blur(2px); + .floating-window { + width: 90%; + max-width: 1200px; + z-index: 6; + } +} diff --git a/src/_colors.scss b/src/_colors.scss index 08a700c..0b73ab9 100644 --- a/src/_colors.scss +++ b/src/_colors.scss @@ -30,6 +30,8 @@ $darkgray: #232627; $black: black; $warningColor: #ed4683; +$infoColor: #e8b454; +$successColor: #0ec685; $fgColor: $white; $darkFgColor: $black; diff --git a/src/classes/item.js b/src/classes/item.js index 63f65ca..53f4bcd 100644 --- a/src/classes/item.js +++ b/src/classes/item.js @@ -54,25 +54,25 @@ export class InvoiceItem extends Item { export const saveItem = (item, ok, fail) => { axios.post("/item/new", item) .then(res => ok()) - .catch((err) => fail()) + .catch(err => fail(err)) } export const deleteItem = (id, ok, fail) => { axios.delete(`/item/${id}`) .then(res => ok()) - .catch((err) => fail()) + .catch(err => fail(err)) } export const getAllItems = (ok, fail) => { axios.get("/item/all") .then(res => ok(res.data)) - .catch(err => fail()) + .catch(err => fail(err)) } export const editItem = (item, ok, fail) => { axios.put(`/item/${item.Id}`, item) .then(res => ok()) - .catch(err => fail()); + .catch(err => fail(err)); } export const getDiscountValue = (item) => diff --git a/src/_styles.scss b/src/classes/notifications.js index 064b9c6..5ffdec8 100644 --- a/src/_styles.scss +++ b/src/classes/notifications.js @@ -15,26 +15,17 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -@import "colors"; - -@mixin floating-window { - .floating-wrapper { - height: 100vh; - width: 100vw; - box-sizing: border-box; - position: fixed; - top: 0; - left: 0; - background-color: rgba($backgroundColor, 0.3); - z-index: 5; - display: flex; - justify-content: center; - align-items: center; - backdrop-filter: blur(2px); - .floating-window { - width: 90%; - max-width: 1200px; - z-index: 6; - } +// TODO: load defaults from config +export function notificationConfig(type, duration=3000) { + return { + type: type, + insert: "top", + container: "top-right", + animationIn: ["animate__animated", "animate__fadeIn"], + animationOut: ["animate__animated", "animate__fadeOut"], + dismiss: { + duration: duration, + onScreen: true } + }; } diff --git a/src/components/editors/brand-editor.js b/src/components/editors/brand-editor.js index 7796c68..2b7806e 100644 --- a/src/components/editors/brand-editor.js +++ b/src/components/editors/brand-editor.js @@ -16,8 +16,10 @@ */ import { Brand, saveBrand, editBrand } from './../../classes/brand' +import { notificationConfig } from "./../../classes/notifications"; import './scss/brand-editor.scss' +import { Store } from "react-notifications-component"; import { useState } from 'react'; const BrandEditor = (props) => { @@ -36,13 +38,22 @@ const BrandEditor = (props) => { } const handleSuccess = () => { + Store.addNotification({ + title: `Successfully ${props.editing ? "edited" : "added"} brand!`, + message: `${name} has successfully been ${props.editing ? "edited" : "saved"}.`, + ...notificationConfig("success") + }); clearAll(); props.callback(); props.editing && props.hide(); } - const handleFail = () => { - alert("fail"); + const handleFail = err => { + Store.addNotification({ + title: "An error occoured", + message: `Failed to ${props.editing ? "edit" : "add"} brand '${name}'. ${err.message}`, + ...notificationConfig("danger") + }); } const clearAll = () => { diff --git a/src/components/editors/client-editor.js b/src/components/editors/client-editor.js index 9a752c7..96ab639 100644 --- a/src/components/editors/client-editor.js +++ b/src/components/editors/client-editor.js @@ -16,11 +16,13 @@ */ import { Client, saveClient, editClient, Contact, Address } from './../../classes/client'; +import { notificationConfig } from "./../../classes/notifications"; import MultiAddressEditor from './multi-address-editor'; import AddressEditor from './address-editor'; import ContactEditor from './contact-editor'; import './scss/client-editor.scss'; +import { Store } from "react-notifications-component"; import { useState, useEffect } from 'react'; const ClientEditor = (props) => { @@ -37,8 +39,8 @@ const ClientEditor = (props) => { // will delete existing shipping addresses if false useEffect(() => - setShippingAddresses(shipToBillingAddress ? [] : (shippingAddresses.length > 0 ? shippingAddresses : [new Address()])) - , [shipToBillingAddress, shippingAddresses]); + setShippingAddresses(i => shipToBillingAddress ? [] : (i.length > 0 ? i : [new Address()])) + , [shipToBillingAddress]); const handleSubmit = (e) => { e.preventDefault(); @@ -63,15 +65,23 @@ const ClientEditor = (props) => { } const handleSuccess = (res) => { - console.log("Successfully saved client", res) + Store.addNotification({ + title: `Successfully ${props.editing ? "edited" : "added"} client!`, + message: `${name} has successfully been ${props.editing ? "edited" : "saved"}.`, + ...notificationConfig("success") + }); clearAll(); - props.successCallback(); + props.successCallback && props.successCallback(); props.editing && props.hide(); } - const handleFail = (err) => { - alert("error while saving client. please check logs"); - console.log(err); + const handleFail = err => { + Store.addNotification({ + title: "An error occoured", + message: `Failed to edit client ${name}. ${err.message}`, + ...notificationConfig("danger") + }); + console.log(err) } const clearAll = () => { diff --git a/src/components/editors/item-editor.js b/src/components/editors/item-editor.js index be0ac4f..c1d260d 100644 --- a/src/components/editors/item-editor.js +++ b/src/components/editors/item-editor.js @@ -17,9 +17,11 @@ import { Item, saveItem, editItem } from './../../classes/item'; import { Brand, getAllBrands } from './../../classes/brand'; +import { notificationConfig } from "./../../classes/notifications"; import './scss/item-editor.scss'; import { useState, useEffect } from 'react'; +import { Store } from "react-notifications-component"; const ItemEditor = (props) => { const [name, setName] = useState(props.item.Name); @@ -37,8 +39,13 @@ const ItemEditor = (props) => { // get saved brands from API // needed by the brands dropdown menu useEffect(() => { - // TODO: handle error - getAllBrands(setSavedBrands, () => {}); + getAllBrands(setSavedBrands, err => { + Store.addNotification({ + title: "Error while getting Brands list.", + message: err.message, + ...notificationConfig("danger") + }); + }); }, []) const handleSubmit = (e) => { @@ -76,13 +83,22 @@ const ItemEditor = (props) => { } const handleSuccess = () => { + Store.addNotification({ + title: `Successfully ${props.editing ? "edited" : "added"} item!`, + message: `${name} has successfully been ${props.editing ? "edited" : "saved"}.`, + ...notificationConfig("success") + }); clearAll(); props.callback(); props.editing && props.hide(); } - const handleFail = () => { - alert("fail"); + const handleFail = err => { + Store.addNotification({ + title: "An error occoured", + message: `Failed to ${props.editing ? "edit" : "add"} item ${name}. ${err.message}`, + ...notificationConfig("danger") + }); } const handleBrandSelect = (e) => { diff --git a/src/components/editors/multi-address-editor.js b/src/components/editors/multi-address-editor.js index 1159fab..1ea58b7 100644 --- a/src/components/editors/multi-address-editor.js +++ b/src/components/editors/multi-address-editor.js @@ -18,7 +18,6 @@ import AddressEditor from './address-editor'; const MultiAddressEditor = ({addresses, setAddresses, setShipToBillingAddress}) => { - console.log(addresses) const handleChange = (id, data) => { const newAddresses = [...addresses]; newAddresses[id] = { diff --git a/src/components/navbar/navbar.js b/src/components/navbar/navbar.js index bf909e7..1254952 100644 --- a/src/components/navbar/navbar.js +++ b/src/components/navbar/navbar.js @@ -58,7 +58,7 @@ const Navbar = () => { <div className={"navbar"}> <span className={"logo"}> <Link to="/"> - <img src="/logo.png" alt="App Logo"/> + <img src="/waifu_logo.png" alt="App Logo"/> </Link> </span> diff --git a/src/components/navbar/navbar.scss b/src/components/navbar/navbar.scss index 8173249..a7f560e 100644 --- a/src/components/navbar/navbar.scss +++ b/src/components/navbar/navbar.scss @@ -52,8 +52,9 @@ .logo { flex: 1; + height: 3.5rem; img { - height: 4rem; + height: 3.5rem; } } } diff --git a/src/components/tables/brand-table.js b/src/components/tables/brand-table.js index db8272c..3b38a5c 100644 --- a/src/components/tables/brand-table.js +++ b/src/components/tables/brand-table.js @@ -17,6 +17,9 @@ import './scss/brand-table.scss'; import { deleteBrand } from './../../classes/brand'; +import { notificationConfig } from "./../../classes/notifications"; + +import { Store } from "react-notifications-component"; const BrandTable = (props) => { const handleEdit = (b) => { @@ -25,15 +28,24 @@ const BrandTable = (props) => { const handleDelete = (b) => { // TODO: add confirmation prompt - deleteBrand(b.Id, handleDelSuccess, handleDelFail); + deleteBrand(b.Id, () => handleDelSuccess(b), err => handleDelFail(b, err)); } - const handleDelSuccess = () => { + const handleDelSuccess = b => { + Store.addNotification({ + title: "Successfully deleted brand!", + message: `Brand '${b.Name}' has successfully been deleted.`, + ...notificationConfig("success") + }); props.refresh(); } - const handleDelFail = () => { - alert("fail") + const handleDelFail = (b, err) => { + Store.addNotification({ + title: "An error occoured", + message: `Failed to delete brand '${b.Name}'. ${err.message}`, + ...notificationConfig("danger") + }); } return ( diff --git a/src/components/tables/client-table.js b/src/components/tables/client-table.js index cea612d..1f51c88 100644 --- a/src/components/tables/client-table.js +++ b/src/components/tables/client-table.js @@ -17,23 +17,35 @@ import './scss/client-table.scss'; import { deleteClient } from './../../classes/client'; +import { notificationConfig } from "./../../classes/notifications"; + +import { Store } from "react-notifications-component"; const ClientTable = (props) => { - const handleEdit = (c) => { + const handleEdit = c => { props.setClientToEdit(c) } - const handleDelete = (c) => { + const handleDelete = c => { // TODO: add confirmation prompt - deleteClient(c.Id, handleDelSuccess, handleDelFail); + deleteClient(c.Id, () => handleDelSuccess(c), err => handleDelFail(c, err)); } - const handleDelSuccess = () => { + const handleDelSuccess = c => { + Store.addNotification({ + title: "Successfully deleted client!", + message: `Client '${c.Name}' has successfully been deleted.`, + ...notificationConfig("success") + }); props.refresh(); } - const handleDelFail = () => { - alert("fail") + const handleDelFail = (c, err) => { + Store.addNotification({ + title: "An error occoured", + message: `Failed to delete client '${c.Name}'. ${err.message}`, + ...notificationConfig("danger") + }); } return ( diff --git a/src/components/tables/item-table.js b/src/components/tables/item-table.js index 2fb7210..1b47f6f 100644 --- a/src/components/tables/item-table.js +++ b/src/components/tables/item-table.js @@ -17,6 +17,9 @@ import './scss/table.scss'; import { deleteItem } from './../../classes/item'; +import { notificationConfig } from "./../../classes/notifications"; + +import { Store } from "react-notifications-component"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faPencil, faTrashCan } from '@fortawesome/free-solid-svg-icons' @@ -27,15 +30,24 @@ const ItemTable = (props) => { const handleDelete = (i) => { // TODO: add confirmation prompt - deleteItem(i.Id, handleDelSuccess, handleDelFail); + deleteItem(i.Id, () => handleDelSuccess(i), err => handleDelFail(i, err)); } - const handleDelSuccess = () => { + const handleDelSuccess = i => { + Store.addNotification({ + title: "Successfully deleted item!", + message: `Item '${i.Name}' has successfully been deleted.`, + ...notificationConfig("success") + }); props.refresh(); } - const handleDelFail = () => { - alert("fail") + const handleDelFail = (i, err) => { + Store.addNotification({ + title: "An error occoured", + message: `Failed to delete item '${i.Name}'. ${err.message}`, + ...notificationConfig("danger") + }); } return ( diff --git a/src/notifications_styles/_containers.scss b/src/notifications_styles/_containers.scss new file mode 100644 index 0000000..b0f00a4 --- /dev/null +++ b/src/notifications_styles/_containers.scss @@ -0,0 +1,100 @@ +.rnc__notification-container--top-center,
+.rnc__notification-container--top-left,
+.rnc__notification-container--top-right,
+.rnc__notification-container--bottom-center,
+.rnc__notification-container--bottom-left,
+.rnc__notification-container--bottom-right,
+.rnc__notification-container--center,
+.rnc__notification-container--top-full,
+.rnc__notification-container--bottom-full {
+ min-width: 325px;
+ position: absolute;
+ pointer-events: all;
+}
+
+.rnc__notification-container--center,
+.rnc__notification-container--top-center,
+.rnc__notification-container--bottom-center {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ left: calc(50% - 175px);
+}
+
+.rnc__notification-container--center,
+.rnc__notification-container--top-center,
+.rnc__notification-container--bottom-center {
+ max-width: 350px;
+}
+
+.rnc__notification-container--center {
+ top: 20px;
+ height: 100%;
+ pointer-events: none;
+}
+
+.rnc__notification-container--top-full,
+.rnc__notification-container--bottom-full {
+ width: 100%;
+ min-width: 100%;
+}
+
+.rnc__notification-container--bottom-full {
+ bottom: 0;
+}
+
+.rnc__util--flex-center {
+ min-width: 325px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ pointer-events: all;
+}
+
+.rnc__notification-container--top-center {
+ top: 20px;
+}
+.rnc__notification-container--bottom-center {
+ bottom: 20px;
+}
+
+.rnc__notification-container--top-left {
+ left: 20px;
+ top: 20px;
+}
+
+.rnc__notification-container--top-right {
+ right: 20px;
+ top: 20px;
+}
+
+.rnc__notification-container--bottom-left {
+ left: 20px;
+ bottom: 20px;
+}
+
+.rnc__notification-container--bottom-right {
+ bottom: 20px;
+ right: 20px;
+}
+
+.rnc__notification-container--mobile-top,
+.rnc__notification-container--mobile-bottom {
+ pointer-events: all;
+ position: absolute;
+}
+
+.rnc__notification-container--mobile-top {
+ right: 20px;
+ left: 20px;
+ top: 20px;
+}
+
+.rnc__notification-container--mobile-bottom {
+ right: 20px;
+ left: 20px;
+ bottom: 20px;
+ margin-bottom: -15px;
+}
diff --git a/src/notifications_styles/_types.scss b/src/notifications_styles/_types.scss new file mode 100644 index 0000000..ccfbee2 --- /dev/null +++ b/src/notifications_styles/_types.scss @@ -0,0 +1,91 @@ +@import "_variables.scss";
+
+.rnc__notification-item--default {
+ background-color: $default;
+ border-left: 8px solid $default_dark;
+
+ .rnc__notification-timer {
+ background-color: $default_timer;
+ }
+ .rnc__notification-timer-filler {
+ background-color: $default_timer_filler;
+ }
+ .rnc__notification-close-mark {
+ background-color: $default;
+ }
+}
+
+.rnc__notification-item--success {
+ background-color: $success;
+ border-left: 8px solid $success_dark;
+
+ .rnc__notification-timer {
+ background-color: $success_timer;
+ }
+ .rnc__notification-timer-filler {
+ background-color: $success_timer_filler;
+ }
+ .rnc__notification-close-mark {
+ background-color: $success;
+ }
+}
+
+.rnc__notification-item--danger {
+ background-color: $danger;
+ border-left: 8px solid $danger_dark;
+
+ .rnc__notification-timer {
+ background-color: $danger_timer;
+ }
+ .rnc__notification-timer-filler {
+ background-color: $danger_timer_filler;
+ }
+ .rnc__notification-close-mark {
+ background-color: $danger;
+ }
+}
+
+.rnc__notification-item--info {
+ background-color: $info;
+ border-left: 8px solid $info_dark;
+
+ .rnc__notification-timer {
+ background-color: $info_timer;
+ }
+ .rnc__notification-timer-filler {
+ background-color: $info_timer_filler;
+ }
+ .rnc__notification-close-mark {
+ background-color: $info;
+ }
+}
+
+.rnc__notification-item--warning {
+ background-color: $warning;
+ border-left: 8px solid $warning_dark;
+
+ .rnc__notification-timer {
+ background-color: $warning_timer;
+ }
+ .rnc__notification-timer-filler {
+ background-color: $warning_timer_filler;
+ }
+ .rnc__notification-close-mark {
+ background-color: $warning;
+ }
+}
+
+.rnc__notification-item--awesome {
+ background-color: $awesome;
+ border-left: 8px solid $awesome_dark;
+
+ .rnc__notification-timer {
+ background-color: $awesome_timer;
+ }
+ .rnc__notification-timer-filler {
+ background-color: $awesome_timer_filler;
+ }
+ .rnc__notification-close-mark {
+ background-color: $awesome;
+ }
+}
\ No newline at end of file diff --git a/src/notifications_styles/_variables.scss b/src/notifications_styles/_variables.scss new file mode 100644 index 0000000..a65c811 --- /dev/null +++ b/src/notifications_styles/_variables.scss @@ -0,0 +1,31 @@ +@import "../colors";
+
+$default: $altBackgroundColor !default;
+$default_dark: $primaryAccentColor !default;
+$default_timer: $backgroundColor !default;
+$default_timer_filler: $primaryAccentColor !default;
+
+$success: $altBackgroundColor !default;
+$success_dark: $successColor !default;
+$success_timer: $backgroundColor !default;
+$success_timer_filler: $successColor !default;
+
+$danger: $altBackgroundColor !default;
+$danger_dark: $warningColor !default;
+$danger_timer: $backgroundColor !default;
+$danger_timer_filler: $warningColor !default;
+
+$warning: $altBackgroundColor !default;
+$warning_dark: $infoColor !default;
+$warning_timer: $backgroundColor !default;
+$warning_timer_filler: $infoColor !default;
+
+$info: $default;
+$info_dark: $default_dark;
+$info_timer: $default_timer;
+$info_timer_filler: $default_timer_filler;
+
+$awesome: $success;
+$awesome_dark: $success_dark;
+$awesome_timer: $success_timer;
+$awesome_timer_filler: $success_timer_filler;
diff --git a/src/notifications_styles/notification.scss b/src/notifications_styles/notification.scss new file mode 100644 index 0000000..33d8efb --- /dev/null +++ b/src/notifications_styles/notification.scss @@ -0,0 +1,110 @@ +@import "./_containers.scss";
+@import "./_types.scss";
+
+@keyframes timer {
+ 0% { width: 100%; }
+ 100% { width: 0%; }
+}
+
+.rnc__base {
+ position: fixed;
+ z-index: 9000;
+ pointer-events: none;
+ width: 100%;
+ height: 100%;
+}
+
+.rnc__notification-item {
+ display: flex;
+ position: relative;
+ border-radius: 3px;
+ margin-bottom: 15px;
+ box-shadow: 1px 3px 4px rgba(0, 0, 0, 0.2);
+ cursor: pointer;
+}
+
+.rnc__notification-container--top-full .rnc__notification-item,
+.rnc__notification-container--bottom-full .rnc__notification-item {
+ margin-bottom: 0;
+ border-radius: 0;
+}
+
+.rnc__notification-container--top-full .rnc__notification,
+.rnc__notification-container--bottom-full .rnc__notification {
+ width: 100% !important;
+}
+
+.rnc__notification-timer {
+ width: 100%;
+ height: 3px;
+ margin-top: 10px;
+ border-radius: 5px;
+}
+.rnc__notification-timer-filler {
+ height: 3px;
+ border-radius: 5px;
+}
+.rnc__notification-title {
+ color: #fff;
+ font-weight: 700;
+ font-size: 14px;
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+.rnc__notification-message {
+ color: #fff;
+ max-width: calc(100% - 15px);
+ font-size: 14px;
+ line-height: 150%;
+ word-wrap: break-word;
+ margin-bottom: 0;
+ margin-top: 0;
+}
+.rnc__notification-content {
+ padding: 8px 15px;
+ display: inline-block;
+ width: 100%;
+}
+.rnc__notification-close-mark {
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ display: inline-block;
+ position: absolute;
+ right: 10px;
+ top: 10px;
+
+ &::after {
+ content: '\D7';
+ position: absolute;
+ transform: translate(-50%, -50%);
+ color: #fff;
+ font-size: 12px;
+ left: 50%;
+ top: 50%;
+ }
+}
+
+.rnc__notification-container--mobile-top .rnc__notification-item,
+.rnc__notification-container--mobile-bottom .rnc__notification-item,
+.rnc__notification-container--mobile-top .notification,
+.rnc__notification-container--mobile-bottom .notification {
+ max-width: 100%;
+ width: 100%;
+}
+
+.rnc__notification-container--top-right .notification,
+.rnc__notification-container--bottom-right .notification {
+ margin-left: auto;
+}
+
+.rnc__notification-container--top-left .notification,
+.rnc__notification-container--bottom-left .notification {
+ margin-right: auto;
+}
+
+.rnc__notification-container--mobile-top .notification,
+.rnc__notification-container--mobile-bottom .notification {
+ margin-left: auto;
+ margin-right: auto;
+}
\ No newline at end of file diff --git a/src/views/homepage.js b/src/views/homepage.js index a9cdb50..92f9544 100644 --- a/src/views/homepage.js +++ b/src/views/homepage.js @@ -15,9 +15,22 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -import { Link } from 'react-router-dom'; +import { Link, useNavigate } from 'react-router-dom'; +import { notificationConfig } from "../classes/notifications"; +import { Store } from "react-notifications-component"; const HomePage = () => { + // this is temporary, just for testing + // TODO: find better way to do this + const navigate = useNavigate(); + if (!localStorage.getItem("accessToken")) { + Store.addNotification({ + title: "You are not logged in", + message: "You need to log in before accessing this page.", + ...notificationConfig("default") + }); + navigate("/login") + } return ( <> <h1>Welcome to OpenBills</h1> diff --git a/src/views/login/register.js b/src/views/login/register.js index c747f59..1b1755b 100644 --- a/src/views/login/register.js +++ b/src/views/login/register.js @@ -17,12 +17,15 @@ import './scss/login.scss'; import { User, validateEmail, validateUsername, validatePassword, saveUser } from '../../classes/user'; +import { notificationConfig } from "./../../classes/notifications"; +import { Store } from "react-notifications-component"; import { Link } from 'react-router-dom'; import { useState } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faEye } from '@fortawesome/free-solid-svg-icons' + const RegisterPage = () => { const [user, setUser] = useState(new User()); const [showPassword, setShowPassword] = useState(false); @@ -41,11 +44,19 @@ const RegisterPage = () => { } const handleSuccess = () => { - alert("yay") + Store.addNotification({ + title: "Created new account", + message: `Welcome to OpenBills, ${user.UserName}!`, + ...notificationConfig("default") + }); } - const handleError = () => { - alert("fail") + const handleError = err => { + Store.addNotification({ + title: "An error occoured", + message: `Failed to create new account. ${err.message}`, + ...notificationConfig("danger") + }); } return ( diff --git a/src/views/manage/brands.js b/src/views/manage/brands.js index dad21e2..4ab3924 100644 --- a/src/views/manage/brands.js +++ b/src/views/manage/brands.js @@ -16,18 +16,26 @@ */ import { useState, useEffect } from 'react'; +import { Store } from "react-notifications-component"; import './scss/management-page.scss' import { Brand, getAllBrands } from '../../classes/brand'; import BrandEditor from './../../components/editors/brand-editor'; import BrandTable from './../../components/tables/brand-table'; +import { notificationConfig } from "./../../classes/notifications"; const ManageBrandsPage = () => { const [brandToEdit, setBrandToEdit] = useState(new Brand()); const [allBrands, setAllBrands] = useState([]); - // TODO: handle error + const updateList = () => - getAllBrands(setAllBrands, () => {}); + getAllBrands(setAllBrands, err => { + Store.addNotification({ + title: "Error while getting Brands list.", + message: err.message, + ...notificationConfig("danger") + }); + }); useEffect(() => { updateList(); diff --git a/src/views/manage/clients.js b/src/views/manage/clients.js index 8445d80..89e5ade 100644 --- a/src/views/manage/clients.js +++ b/src/views/manage/clients.js @@ -20,18 +20,26 @@ */ import { useState, useEffect } from 'react'; +import { Store } from "react-notifications-component"; import './scss/management-page.scss'; import { Client, getAllClients } from '../../classes/client'; import ClientEditor from './../../components/editors/client-editor'; import ClientTable from './../../components/tables/client-table'; +import { notificationConfig } from "./../../classes/notifications"; const ManageClientsPage = () => { const [clientToEdit, setClientToEdit] = useState(new Client()); const [allClients, setAllClients] = useState([]); // TODO: handle error const updateList = () => - getAllClients(setAllClients, () => {}); + getAllClients(setAllClients, err => { + Store.addNotification({ + title: "Error while getting Clients list.", + message: err.message, + ...notificationConfig("danger") + }); + }); useEffect(() => { updateList(); diff --git a/src/views/manage/items.js b/src/views/manage/items.js index 567be7c..2a862bc 100644 --- a/src/views/manage/items.js +++ b/src/views/manage/items.js @@ -20,18 +20,26 @@ */ import { useState, useEffect } from 'react'; +import { Store } from "react-notifications-component"; import './scss/management-page.scss' import { Item, getAllItems } from '../../classes/item'; import ItemEditor from './../../components/editors/item-editor'; import ItemTable from './../../components/tables/item-table'; +import { notificationConfig } from "./../../classes/notifications"; const ManageItemsPage = () => { const [itemToEdit, setItemToEdit] = useState(new Item()); const [allItems, setAllItems] = useState([]); - // TODO: handle error + const updateList = () => - getAllItems(setAllItems, () => {}); + getAllItems(setAllItems, err => { + Store.addNotification({ + title: "Error while getting Items list.", + message: err.message, + ...notificationConfig("danger") + }); + }); useEffect(() => { updateList(); |