mirror of
https://github.com/aljazceru/landscape-template.git
synced 2026-01-06 07:54:21 +01:00
feat: add toasts to the profile updating page
This commit is contained in:
25
package-lock.json
generated
25
package-lock.json
generated
@@ -82,6 +82,7 @@
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-select": "^5.3.2",
|
||||
"react-toastify": "^9.0.8",
|
||||
"react-tooltip": "^4.2.21",
|
||||
"react-topbar-progress-indicator": "^4.1.1",
|
||||
"remirror": "^1.0.77",
|
||||
@@ -19587,7 +19588,6 @@
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
|
||||
"integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@@ -60696,6 +60696,18 @@
|
||||
"react": "^16.8.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-toastify": {
|
||||
"version": "9.0.8",
|
||||
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.8.tgz",
|
||||
"integrity": "sha512-EwM+teWt49HSHx+67qI08yLAW1zAsBxCXLCsUfxHYv1W7/R3ZLhrqKalh7j+kjgPna1h5LQMSMwns4tB4ww2yQ==",
|
||||
"dependencies": {
|
||||
"clsx": "^1.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16",
|
||||
"react-dom": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/react-tooltip": {
|
||||
"version": "4.2.21",
|
||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-4.2.21.tgz",
|
||||
@@ -83039,8 +83051,7 @@
|
||||
"clsx": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
|
||||
"integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA=="
|
||||
},
|
||||
"co": {
|
||||
"version": "4.6.0",
|
||||
@@ -114215,6 +114226,14 @@
|
||||
"use-latest": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"react-toastify": {
|
||||
"version": "9.0.8",
|
||||
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.8.tgz",
|
||||
"integrity": "sha512-EwM+teWt49HSHx+67qI08yLAW1zAsBxCXLCsUfxHYv1W7/R3ZLhrqKalh7j+kjgPna1h5LQMSMwns4tB4ww2yQ==",
|
||||
"requires": {
|
||||
"clsx": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"react-tooltip": {
|
||||
"version": "4.2.21",
|
||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-4.2.21.tgz",
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-select": "^5.3.2",
|
||||
"react-toastify": "^9.0.8",
|
||||
"react-tooltip": "^4.2.21",
|
||||
"react-topbar-progress-indicator": "^4.1.1",
|
||||
"remirror": "^1.0.77",
|
||||
|
||||
@@ -55,7 +55,7 @@ type BtnState = 'ready' | 'voting' | 'loading' | "success" | "fail";
|
||||
export default function VoteButton({
|
||||
votes,
|
||||
onVote = () => { },
|
||||
fillType = 'leftRight',
|
||||
fillType = 'background',
|
||||
direction = 'horizontal',
|
||||
disableCounter = false,
|
||||
disableShake = true,
|
||||
|
||||
@@ -26,6 +26,12 @@ export default function SaveChangesCard(props: Props) {
|
||||
if (!profileQuery.data?.profile)
|
||||
return <></>
|
||||
|
||||
|
||||
const clickCancel = () => {
|
||||
if (window.confirm('You might lose some unsaved changes. Are you sure you want to continue?'))
|
||||
props.onCancel?.()
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="md:p-24 rounded-16 bg-white md:border-2 border-gray-200 flex flex-col gap-24">
|
||||
<div className='hidden md:flex gap-8'>
|
||||
@@ -45,14 +51,13 @@ export default function SaveChangesCard(props: Props) {
|
||||
<Button
|
||||
color="primary"
|
||||
onClick={props.onSubmit}
|
||||
isLoading={props.isLoading}
|
||||
disabled={!props.isDirty || props.isLoading}
|
||||
>
|
||||
Save Changes
|
||||
</Button>
|
||||
<Button
|
||||
color="gray"
|
||||
onClick={props.onCancel}
|
||||
onClick={clickCancel}
|
||||
disabled={!props.isDirty || props.isLoading}
|
||||
>
|
||||
Cancel
|
||||
|
||||
@@ -7,6 +7,7 @@ import { yupResolver } from "@hookform/resolvers/yup";
|
||||
import Avatar from "src/features/Profiles/Components/Avatar/Avatar";
|
||||
import { usePrompt } from "src/utils/hooks";
|
||||
import SaveChangesCard from "../SaveChangesCard/SaveChangesCard";
|
||||
import { toast } from "react-toastify";
|
||||
|
||||
interface Props {
|
||||
data: Pick<User,
|
||||
@@ -69,11 +70,7 @@ export default function UpdateMyProfileCard({ data, onClose }: Props) {
|
||||
mode: 'onBlur',
|
||||
});
|
||||
|
||||
const [mutate, mutationStatus] = useUpdateProfileAboutMutation({
|
||||
onCompleted: () => {
|
||||
onClose?.()
|
||||
}
|
||||
});
|
||||
const [mutate, mutationStatus] = useUpdateProfileAboutMutation();
|
||||
|
||||
|
||||
|
||||
@@ -81,6 +78,9 @@ export default function UpdateMyProfileCard({ data, onClose }: Props) {
|
||||
|
||||
|
||||
const onSubmit: SubmitHandler<IFormInputs> = data => {
|
||||
|
||||
const toastId = toast.loading("Saving changes...", NotificationsService.defaultOptions)
|
||||
|
||||
mutate({
|
||||
variables: {
|
||||
data: {
|
||||
@@ -99,11 +99,13 @@ export default function UpdateMyProfileCard({ data, onClose }: Props) {
|
||||
},
|
||||
onCompleted: () => {
|
||||
reset(data);
|
||||
toast.update(toastId, { render: "Saved changes successfully", type: "success", ...NotificationsService.defaultOptions, isLoading: false });
|
||||
}
|
||||
}).catch(() => {
|
||||
NotificationsService.error('A network error happened');
|
||||
mutationStatus.reset()
|
||||
})
|
||||
.catch(() => {
|
||||
toast.update(toastId, { render: "A network error happened", type: "error", ...NotificationsService.defaultOptions, isLoading: false });
|
||||
mutationStatus.reset()
|
||||
})
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,9 +1,47 @@
|
||||
import { toast, ToastOptions } from "react-toastify"
|
||||
|
||||
const DEBUG = process.env.NODE_ENV === 'development'
|
||||
|
||||
interface AlertOptions {
|
||||
onComplete?: () => void
|
||||
autoClose?: number
|
||||
}
|
||||
|
||||
export class NotificationsService {
|
||||
static error(msg: string, options?: Partial<{ error: any }>) {
|
||||
if (options?.error && DEBUG) console.log(options?.error)
|
||||
alert(msg)
|
||||
|
||||
static defaultOptions: ToastOptions = {
|
||||
position: "bottom-center",
|
||||
autoClose: 4000,
|
||||
hideProgressBar: false,
|
||||
closeOnClick: true,
|
||||
rtl: false,
|
||||
pauseOnFocusLoss: true,
|
||||
draggable: true,
|
||||
pauseOnHover: true,
|
||||
theme: 'light',
|
||||
}
|
||||
|
||||
static success(msg: string, options?: AlertOptions) {
|
||||
toast.success(msg, {
|
||||
onClose: options?.onComplete,
|
||||
autoClose: options?.autoClose ?? 2500,
|
||||
icon: "✅"
|
||||
})
|
||||
}
|
||||
|
||||
static info(msg: string, options?: AlertOptions) {
|
||||
toast.info(msg, {
|
||||
onClose: options?.onComplete,
|
||||
autoClose: options?.autoClose ?? 2500,
|
||||
})
|
||||
}
|
||||
|
||||
static error(msg: string, options?: AlertOptions & Partial<{ error: any }>) {
|
||||
if (options?.error && DEBUG) console.log(options?.error)
|
||||
toast.error(msg, {
|
||||
onClose: options?.onComplete,
|
||||
autoClose: options?.autoClose ?? 2500,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,10 +8,13 @@ import { useCallback, useLayoutEffect } from 'react';
|
||||
import { setIsMobileScreen } from 'src/redux/features/ui.slice';
|
||||
import { isMobileScreen } from './helperFunctions';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
import { ToastContainer } from 'react-toastify';
|
||||
|
||||
import 'react-toastify/dist/ReactToastify.css';
|
||||
import 'react-loading-skeleton/dist/skeleton.css'
|
||||
import THEME from './theme';
|
||||
import ErrorBoundary from 'src/Components/ErrorBoundary/ErrorBoundary';
|
||||
import { NotificationsService } from 'src/services';
|
||||
THEME.injectStyles();
|
||||
|
||||
let basename = '/';
|
||||
@@ -55,6 +58,11 @@ export default function Wrapper(props: any) {
|
||||
effect='solid'
|
||||
delayShow={1000}
|
||||
/>
|
||||
<ToastContainer
|
||||
{...NotificationsService.defaultOptions}
|
||||
newestOnTop={false}
|
||||
limit={2}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { gql } from '@apollo/client';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useConfirmVoteMutation, useVoteMutation, Vote_Item_Type } from 'src/graphql';
|
||||
import { Wallet_Service } from 'src/services';
|
||||
import { NotificationsService, Wallet_Service } from 'src/services';
|
||||
|
||||
export enum PaymentStatus {
|
||||
DEFAULT,
|
||||
@@ -105,14 +105,14 @@ export const useVote = (params: Params) => {
|
||||
setPaymentStatus(PaymentStatus.NETWORK_ERROR);
|
||||
onError?.(error);
|
||||
onSetteled?.();
|
||||
alert("A network error happened while confirming the payment...")
|
||||
NotificationsService.error("A network error happened while confirming the payment...")
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
setPaymentStatus(PaymentStatus.CANCELED);
|
||||
onError?.(error);
|
||||
onSetteled?.();
|
||||
alert("Payment rejected by user")
|
||||
NotificationsService.error("Payment rejected by user")
|
||||
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ export const useVote = (params: Params) => {
|
||||
setPaymentStatus(PaymentStatus.NETWORK_ERROR);
|
||||
onError?.(error);
|
||||
onSetteled?.();
|
||||
alert("A network error happened...")
|
||||
NotificationsService.error("A network error happened...")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user