feat: add react-hot-toast for toast notifs

This commit is contained in:
Aaron William Po
2023-05-19 23:14:49 -04:00
parent 39c310f296
commit 56af72a471
24 changed files with 140 additions and 30 deletions

View File

@@ -4,6 +4,7 @@ import { FC, useState } from 'react';
import { useInView } from 'react-intersection-observer';
import { z } from 'zod';
import CreateCommentValidationSchema from '@/services/types/CommentSchema/CreateCommentValidationSchema';
import CommentContentBody from './CommentContentBody';
import EditCommentBody from './EditCommentBody';

View File

@@ -1,4 +1,4 @@
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import { Dispatch, SetStateAction, FC, useContext } from 'react';
import { FaEllipsisH } from 'react-icons/fa';
import CommentQueryResult from '@/services/types/CommentSchema/CommentQueryResult';

View File

@@ -1,4 +1,4 @@
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import useTimeDistance from '@/hooks/utilities/useTimeDistance';
import { format } from 'date-fns';
import { Dispatch, FC, SetStateAction, useContext } from 'react';

View File

@@ -1,5 +1,5 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { FC, useState, Dispatch, SetStateAction } from 'react';
import { FC, useState, Dispatch, SetStateAction, useContext } from 'react';
import { Rating } from 'react-daisyui';
import { useForm, SubmitHandler } from 'react-hook-form';
import { z } from 'zod';
@@ -7,6 +7,7 @@ import useBeerPostComments from '@/hooks/data-fetching/beer-comments/useBeerPost
import CommentQueryResult from '@/services/types/CommentSchema/CommentQueryResult';
import CreateCommentValidationSchema from '@/services/types/CommentSchema/CreateCommentValidationSchema';
import useBreweryPostComments from '@/hooks/data-fetching/brewery-comments/useBreweryPostComments';
import ToastContext from '@/contexts/ToastContext';
import FormError from '../ui/forms/FormError';
import FormInfo from '../ui/forms/FormInfo';
import FormLabel from '../ui/forms/FormLabel';
@@ -42,6 +43,7 @@ const EditCommentBody: FC<EditCommentBodyProps> = ({
resolver: zodResolver(CreateCommentValidationSchema),
});
const { toast } = useContext(ToastContext);
const { errors } = formState;
const [isDeleting, setIsDeleting] = useState(false);
@@ -58,6 +60,7 @@ const EditCommentBody: FC<EditCommentBodyProps> = ({
setInEditMode(true);
await handleEditRequest(comment.id, data);
await mutate();
toast.success('Submitted edits');
setInEditMode(false);
};

View File

@@ -2,7 +2,7 @@ import Link from 'next/link';
import format from 'date-fns/format';
import { FC, useContext } from 'react';
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import { FaRegEdit } from 'react-icons/fa';
import beerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult';
import { z } from 'zod';

View File

@@ -1,4 +1,4 @@
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import beerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult';

View File

@@ -3,7 +3,7 @@ import { FC, useContext } from 'react';
import Image from 'next/image';
import beerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult';
import { z } from 'zod';
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import useGetBeerPostLikeCount from '@/hooks/data-fetching/beer-likes/useBeerPostLikeCount';
import BeerPostLikeButton from '../BeerById/BeerPostLikeButton';

View File

@@ -5,7 +5,7 @@ import { FC, MutableRefObject, useContext, useRef } from 'react';
import { useInView } from 'react-intersection-observer';
import { z } from 'zod';
import { FaPlus } from 'react-icons/fa';
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import BeerRecommendationLoadingComponent from '../BeerById/BeerRecommendationLoadingComponent';
interface BreweryCommentsSectionProps {

View File

@@ -1,4 +1,4 @@
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import BreweryPostQueryResult from '@/services/BreweryPost/types/BreweryPostQueryResult';
import { FC, MutableRefObject, useContext, useRef } from 'react';
import { z } from 'zod';
@@ -9,6 +9,7 @@ import APIResponseValidationSchema from '@/validation/APIResponseValidationSchem
import CommentQueryResult from '@/services/types/CommentSchema/CommentQueryResult';
import useBreweryPostComments from '@/hooks/data-fetching/brewery-comments/useBreweryPostComments';
import ToastContext from '@/contexts/ToastContext';
import LoadingComponent from '../BeerById/LoadingComponent';
import CommentsComponent from '../ui/CommentsComponent';
import CommentForm from '../ui/CommentForm';
@@ -63,6 +64,7 @@ const BreweryCommentForm: FC<BreweryCommentFormProps> = ({ breweryPost, mutate }
resolver: zodResolver(CreateCommentValidationSchema),
});
const { toast } = useContext(ToastContext);
const onSubmit: SubmitHandler<z.infer<typeof CreateCommentValidationSchema>> = async (
data,
) => {
@@ -72,6 +74,7 @@ const BreweryCommentForm: FC<BreweryCommentFormProps> = ({ breweryPost, mutate }
breweryPostId: breweryPost.id,
});
await mutate();
toast.loading('Created new comment.');
reset();
};

View File

@@ -1,4 +1,4 @@
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import useGetBreweryPostLikeCount from '@/hooks/data-fetching/brewery-likes/useGetBreweryPostLikeCount';
import useTimeDistance from '@/hooks/utilities/useTimeDistance';
import BreweryPostQueryResult from '@/services/BreweryPost/types/BreweryPostQueryResult';

View File

@@ -1,4 +1,4 @@
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import useGetBreweryPostLikeCount from '@/hooks/data-fetching/brewery-likes/useGetBreweryPostLikeCount';
import BreweryPostQueryResult from '@/services/BreweryPost/types/BreweryPostQueryResult';
import { FC, useContext } from 'react';

View File

@@ -5,7 +5,8 @@ import { useRouter } from 'next/router';
import { useContext, useState } from 'react';
import { useForm, SubmitHandler } from 'react-hook-form';
import { z } from 'zod';
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import ToastContext from '@/contexts/ToastContext';
import ErrorAlert from '../ui/alerts/ErrorAlert';
import FormError from '../ui/forms/FormError';
import FormInfo from '../ui/forms/FormInfo';
@@ -30,12 +31,15 @@ const LoginForm = () => {
const [responseError, setResponseError] = useState<string>('');
const { mutate } = useContext(UserContext);
const { toast } = useContext(ToastContext);
const onSubmit: SubmitHandler<LoginT> = async (data) => {
try {
const id = toast.loading('Logging in.');
await sendLoginUserRequest(data);
await mutate!();
await router.push(`/user/current`);
toast.remove(id);
} catch (error) {
if (error instanceof Error) {
setResponseError(error.message);

View File

@@ -0,0 +1,50 @@
import ToastContext from '@/contexts/ToastContext';
import { FC, ReactNode } from 'react';
import toast, { Toast, Toaster, resolveValue } from 'react-hot-toast';
import { FaTimes } from 'react-icons/fa';
const toastToClassName = (toastType: Toast['type']) => {
let className: 'alert-success' | 'alert-error' | 'alert-info';
switch (toastType) {
case 'success':
className = 'alert-success';
break;
case 'error':
className = 'alert-error';
break;
default:
className = 'alert-info';
}
return className;
};
const CustomToast: FC<{ children: ReactNode }> = ({ children }) => {
return (
<ToastContext.Provider value={{ toast }}>
<Toaster>
{(t) => {
const alertType = toastToClassName(t.type);
return (
<div className="flex w-full items-center justify-center">
<div
className={`alert ${alertType} w-11/12 flex-row items-center py-[0.5rem] shadow-lg animate-in fade-in duration-200 lg:w-6/12`}
>
<div>{resolveValue(t.message, t)}</div>
<button
className="btn-ghost btn-circle btn"
onClick={() => toast.dismiss(t.id)}
>
<FaTimes />
</button>
</div>
</div>
);
}}
</Toaster>
{children}
</ToastContext.Provider>
);
};
export default CustomToast;

View File

@@ -0,0 +1,8 @@
import { createContext } from 'react';
import toast from 'react-hot-toast';
const ToastContext = createContext<{
toast: typeof toast;
}>({ toast });
export default ToastContext;

View File

@@ -1,4 +1,4 @@
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import { useRouter } from 'next/router';
import { useContext } from 'react';

View File

@@ -1,4 +1,4 @@
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
import { useContext } from 'react';
import useSWR from 'swr';

View File

@@ -1,4 +1,4 @@
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
import { useContext } from 'react';
import useSWR from 'swr';

View File

@@ -1,4 +1,4 @@
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import { useRouter } from 'next/router';
import { useState, useEffect, useContext } from 'react';

View File

@@ -1,4 +1,4 @@
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import '@/styles/globals.css';
import type { AppProps } from 'next/app';
@@ -11,6 +11,7 @@ import { Space_Grotesk } from 'next/font/google';
import Head from 'next/head';
import Layout from '@/components/ui/Layout';
import useUser from '@/hooks/auth/useUser';
import CustomToast from '@/components/ui/CustomToast';
const spaceGrotesk = Space_Grotesk({
subsets: ['latin'],
@@ -39,9 +40,12 @@ export default function App({ Component, pageProps }: AppProps) {
</Head>
<UserContext.Provider value={{ user, isLoading, error, mutate }}>
<Layout>
<Component {...pageProps} />
<CustomToast>
<Component {...pageProps} />
</CustomToast>
</Layout>
</UserContext.Provider>
<Analytics />
</>
);

View File

@@ -1,7 +1,7 @@
import BreweryCard from '@/components/BreweryIndex/BreweryCard';
import LoadingCard from '@/components/ui/LoadingCard';
import Spinner from '@/components/ui/Spinner';
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import useBreweryPosts from '@/hooks/data-fetching/brewery-posts/useBreweryPosts';
import BreweryPostQueryResult from '@/services/BreweryPost/types/BreweryPostQueryResult';
import { NextPage } from 'next';

View File

@@ -1,6 +1,6 @@
import Spinner from '@/components/ui/Spinner';
import withPageAuthRequired from '@/util/withPageAuthRequired';
import UserContext from '@/contexts/userContext';
import UserContext from '@/contexts/UserContext';
import { GetServerSideProps, NextPage } from 'next';
import { useContext } from 'react';