From ff5868df1fe53ee2686f4f41cc6e8cd33e0325ca Mon Sep 17 00:00:00 2001 From: justice chimobi Date: Fri, 11 Oct 2024 20:11:55 +0100 Subject: [PATCH] Added: Modal for users to login when click to participate or interact when not logged In --- src/components/LoginForm/index.tsx | 67 ++++++ src/components/Popover/index.tsx | 45 ---- src/components/RegisterForm/index.tsx | 83 +++++++ src/components/ShowLoginModal/index.tsx | 58 +++++ .../components/ThreadCardInteractions.tsx | 131 ++++++----- src/components/ThreadCard/index.tsx | 6 - src/components/index.tsx | 8 +- src/hooks/auth/useSignin.ts | 13 +- src/main.tsx | 8 +- .../components/ArticleActionButtons.tsx | 8 +- .../Articles/components/CommentDrawer.tsx | 215 +++++++++--------- src/pages/Auth/Login/index.tsx | 107 +++------ src/pages/Auth/Register/index.tsx | 122 +++------- src/pages/Users/SavedArticles/index.tsx | 9 +- src/pages/Users/Settings/index.tsx | 13 +- src/types/auth/index.ts | 9 + 16 files changed, 484 insertions(+), 418 deletions(-) create mode 100644 src/components/LoginForm/index.tsx delete mode 100644 src/components/Popover/index.tsx create mode 100644 src/components/RegisterForm/index.tsx create mode 100644 src/components/ShowLoginModal/index.tsx diff --git a/src/components/LoginForm/index.tsx b/src/components/LoginForm/index.tsx new file mode 100644 index 0000000..4a37a56 --- /dev/null +++ b/src/components/LoginForm/index.tsx @@ -0,0 +1,67 @@ +import { FunctionComponent } from 'react' +import { Box, FormControl, FormErrorMessage, FormLabel } from '@chakra-ui/react' +import { Field } from 'formik' + +import { Button, Input } from '@components/index' +import { AuthFormProps } from 'src/types' + +const LoginForm: FunctionComponent = ({ + handleSubmit, + errors, + touched, + isSubmitting +}) => { + return ( +
+ + + Email address + + {errors.email} + + + + + + Password + + {errors.password} + + + + + + +
+ ) +} + +export default LoginForm; \ No newline at end of file diff --git a/src/components/Popover/index.tsx b/src/components/Popover/index.tsx deleted file mode 100644 index 5b90eff..0000000 --- a/src/components/Popover/index.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { FunctionComponent } from 'react' -import { Link } from 'react-router-dom' -import { - Popover as ChakraPopover, - PopoverArrow, - PopoverBody, - PopoverCloseButton, - PopoverContent, - PopoverHeader, - PopoverTrigger, - Text -} from '@chakra-ui/react' - -import { colors } from '../../colors' - -interface PopoverProps { - isOpen: boolean; - onClose: () => void; -} - -const Popover: FunctionComponent = ({ isOpen, onClose }) => { - return ( - - - - - - Sign in to participate - - - - Sign in to participate to keep the conversation going! Sign in here - - - - ) -} - -export default Popover; \ No newline at end of file diff --git a/src/components/RegisterForm/index.tsx b/src/components/RegisterForm/index.tsx new file mode 100644 index 0000000..9471846 --- /dev/null +++ b/src/components/RegisterForm/index.tsx @@ -0,0 +1,83 @@ +import { FunctionComponent } from 'react' +import { Box, FormControl, FormErrorMessage, FormLabel } from '@chakra-ui/react' +import { Field } from 'formik' + +import { Button, Input } from '@components/index' +import { AuthFormProps } from 'src/types' + +const RegisterForm: FunctionComponent = ({ + handleSubmit, + errors, + touched, + isSubmitting +}) => { + return ( +
+ + + Fullname + + {errors.fullname} + + + + + Enter Email + + {errors.email} + + + + + + Password + + {errors.password} + + + + + + +
+ ) +} + +export default RegisterForm; \ No newline at end of file diff --git a/src/components/ShowLoginModal/index.tsx b/src/components/ShowLoginModal/index.tsx new file mode 100644 index 0000000..22c6ab8 --- /dev/null +++ b/src/components/ShowLoginModal/index.tsx @@ -0,0 +1,58 @@ +import { FunctionComponent } from 'react' +import { Modal, ModalBody, ModalContent, ModalHeader, ModalOverlay } from '@chakra-ui/react' +import { Formik } from 'formik' + +import { LoginForm } from '@components/index' +import { signInValidataionSchema } from '@validations/signin' +import { useSignin } from '@hooks/auth/useSignin' +import { ISignin } from 'src/types' + +interface IProps { + isOpen: boolean; + onClose: () => void; +} + +const ShowLoginModal: FunctionComponent = ({ isOpen, onClose }) => { + const { signinMutation } = useSignin(); + + const handleSignin = (values: ISignin) => { + signinMutation.mutate(values); + }; + + const initialValues: ISignin = { + email: "", + password: "" + } + + return ( + + + + + Sign in to paticipate + + + {({ handleSubmit, errors, touched }) => ( + + )} + + + + + ) +} + +export default ShowLoginModal; \ No newline at end of file diff --git a/src/components/ThreadCard/components/ThreadCardInteractions.tsx b/src/components/ThreadCard/components/ThreadCardInteractions.tsx index c05f3f4..3167785 100644 --- a/src/components/ThreadCard/components/ThreadCardInteractions.tsx +++ b/src/components/ThreadCard/components/ThreadCardInteractions.tsx @@ -1,6 +1,7 @@ import { FunctionComponent } from 'react' -import { HStack, Text } from '@chakra-ui/react' +import { HStack, Text, useDisclosure } from '@chakra-ui/react' import { MdOutlineQuickreply, MdOutlineThumbUp, MdOutlineThumbDown } from 'react-icons/md' +import ShowLoginModal from '@components/ShowLoginModal' interface ThreadCardInteractionsProps { userLikedThread: boolean; @@ -20,67 +21,81 @@ const ThreadCardInteractions: FunctionComponent = ( handleThreadLike, handleThreadDisLike, user -}) => ( - - {user ? ( - <> - - - {threadCommentCounts} - +}) => { + const { isOpen, onClose, onOpen } = useDisclosure(); - - {!userLikedThread && ( - + + {user ? ( + <> + + - )} + {threadCommentCounts} + + + + {!userLikedThread && ( + + )} - {userLikedThread && ( - + )} + {threadLikeCounts} + + + ) : ( + <> + + - )} - {threadLikeCounts} - - - ) : ( - <> - - - {threadCommentCounts} - + {threadCommentCounts} + - - - {threadLikeCounts} - - - )} - -); + + + {threadLikeCounts} + + + )} + + + + + + ) +} export default ThreadCardInteractions; diff --git a/src/components/ThreadCard/index.tsx b/src/components/ThreadCard/index.tsx index a706fd6..8bca8f2 100644 --- a/src/components/ThreadCard/index.tsx +++ b/src/components/ThreadCard/index.tsx @@ -9,7 +9,6 @@ import { DeleteConfirmation, ThreadCommentForm } from '@components/ThreadCard/components' -import { errorNotification } from '@helpers/notification' import { useUser } from '@context/userContext' import { useCreateThreadComment } from '@hooks/thread/useCreateThreadComment' import { useCreateThreadLike } from '@hooks/thread/useCreateThreadLike' @@ -44,11 +43,6 @@ const ThreadCard: FunctionComponent = ({ thread, isSingleView = const handleCommentSubmit = (event: FormEvent) => { event.preventDefault(); - if (!comment) { - errorNotification('The comment field is Required*'); - return; - } - const commmentValue = { comment } createThreadCommentMutation.mutate({ data: commmentValue, id: thread?.id }) setComment(""); diff --git a/src/components/index.tsx b/src/components/index.tsx index 178f8cc..779a415 100644 --- a/src/components/index.tsx +++ b/src/components/index.tsx @@ -16,8 +16,10 @@ import EmptyState from '@components/EmptyState' import Editor from '@components/Editor' import ContentBlockContent from '@components/CodeBlockContent' import ThreadCard from '@components/ThreadCard' -import Popover from '@components/Popover' import Loading from '@components/Loading' +import LoginForm from '@components/LoginForm' +import RegisterForm from '@components/RegisterForm' +import ShowLoginModal from '@components/ShowLoginModal' export { Alert, @@ -38,6 +40,8 @@ export { Editor, ContentBlockContent, ThreadCard, - Popover, Loading, + LoginForm, + RegisterForm, + ShowLoginModal, } \ No newline at end of file diff --git a/src/hooks/auth/useSignin.ts b/src/hooks/auth/useSignin.ts index 967fbe0..994f610 100644 --- a/src/hooks/auth/useSignin.ts +++ b/src/hooks/auth/useSignin.ts @@ -1,4 +1,4 @@ -import { useNavigate } from 'react-router-dom' +import { useLocation, useNavigate } from 'react-router-dom' import { useMutation, useQueryClient } from '@tanstack/react-query' import { signinUser } from '@services/auth' @@ -6,19 +6,22 @@ import { errorNotification, successNotification } from '@helpers/notification' export const useSignin = () => { const navigate = useNavigate(); + const location = useLocation(); const queryClient = useQueryClient(); const signinMutation = useMutation({ mutationFn: signinUser, onSuccess: (data) => { successNotification(data.message); - queryClient.invalidateQueries({ - queryKey: ['user'] - }) + queryClient.invalidateQueries({ queryKey: ['user'] }) localStorage.setItem('ucType_', data?.access_token); - navigate('/'); + if (location.pathname === '/auth/login') { + navigate('/'); + } else { + window.location.reload(); + } }, onError: (error: any) => { errorNotification(error?.response?.data?.message) diff --git a/src/main.tsx b/src/main.tsx index d8aca07..6e11009 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -22,11 +22,11 @@ ReactDOM.createRoot(document.getElementById('root')!).render( - - + + - - + + diff --git a/src/pages/Articles/components/ArticleActionButtons.tsx b/src/pages/Articles/components/ArticleActionButtons.tsx index c6d0a96..adaa99b 100644 --- a/src/pages/Articles/components/ArticleActionButtons.tsx +++ b/src/pages/Articles/components/ArticleActionButtons.tsx @@ -3,7 +3,7 @@ import { Stack, Text, useDisclosure } from '@chakra-ui/react' import { MdOutlineQuickreply, MdOutlineThumbDown, MdOutlineThumbUp } from 'react-icons/md' import { useUser } from '@context/userContext' -import { Popover } from '@components/index' +import { ShowLoginModal } from '@components/index' import { ArticleActionButtonsProps } from 'src/types' const ArticleActionButtons: FunctionComponent = ({ @@ -13,7 +13,7 @@ const ArticleActionButtons: FunctionComponent = ({ onShowComment }) => { const { user } = useUser(); - const { onClose, onToggle, isOpen} = useDisclosure(); + const { onClose, onOpen, isOpen} = useDisclosure(); return ( <> @@ -78,7 +78,7 @@ const ArticleActionButtons: FunctionComponent = ({ {article?.article_like_counts} @@ -86,7 +86,7 @@ const ArticleActionButtons: FunctionComponent = ({ )} - diff --git a/src/pages/Articles/components/CommentDrawer.tsx b/src/pages/Articles/components/CommentDrawer.tsx index a1b8f6c..bfbf608 100644 --- a/src/pages/Articles/components/CommentDrawer.tsx +++ b/src/pages/Articles/components/CommentDrawer.tsx @@ -11,10 +11,11 @@ import { DrawerHeader, DrawerOverlay, Stack, - Text + Text, + useDisclosure } from '@chakra-ui/react' -import { Button, ContentBlockContent, Editor } from '@components/index' +import { Button, ContentBlockContent, Editor, ShowLoginModal } from '@components/index' import { useUser } from '@context/userContext' import { colors } from '../../../colors' import { CommentDrawerProps } from 'src/types' @@ -30,121 +31,131 @@ const CommentDrawer: FunctionComponent = ({ isSubmitting }) => { const { user } = useUser(); + const { onClose: onCloseShowLoginModal, onOpen: onOpenShowLoginModal, isOpen: isOpenShowLoginModal } = useDisclosure(); return ( - - - - - - Responses ({commentCounts}) - + <> + + + + + + Responses ({commentCounts}) + - - - - {user && ( -
- - - - - - - -
- )} - - {!user && ( - - - Sign in to participate! - - Sign in here - - - - )} -
- - + + + + {user && ( +
+ + + - {comments?.map((comment: any, index: number) => ( - - - - - - - + + + + )} - + {!user && ( + + + Sign in to participate! + Sign in here + + + + )} + + + + + {comments?.map((comment: any, index: number) => ( + + + + - {comment?.user?.fullname} + - - - about {comment?.created_at?.human} - + + + + + + {comment?.user?.fullname} + + + + about {comment?.created_at?.human} + + + + - - + +
+ ))} +
+
+
+
- - - ))} - - -
-
+ + ) } diff --git a/src/pages/Auth/Login/index.tsx b/src/pages/Auth/Login/index.tsx index d45e06d..0644339 100644 --- a/src/pages/Auth/Login/index.tsx +++ b/src/pages/Auth/Login/index.tsx @@ -1,20 +1,10 @@ import { FunctionComponent } from 'react' import { Link } from 'react-router-dom' -import { - Box, - FormControl, - FormLabel, - Card, - CardBody, - CardHeader, - Heading, - Text, - FormErrorMessage -} from '@chakra-ui/react' -import { Formik, Field } from 'formik' +import { Box, Card, CardBody, CardHeader, Heading, Text } from '@chakra-ui/react' +import { Formik } from 'formik' import { Helmet } from 'react-helmet-async' -import { Button, Input } from '@components/index' +import { LoginForm } from '@components/index' import { colors } from '../../../colors' import { useSignin } from '@hooks/auth/useSignin' import { signInValidataionSchema } from '@validations/signin' @@ -53,75 +43,32 @@ const Login: FunctionComponent = () => { validationSchema={signInValidataionSchema} > {({ handleSubmit, errors, touched }) => ( -
- - - Email address - - {errors.email} - - - - - - Password - - {errors.password} - - - - - - - - - Don't have an account? {" "} - - - Sign Up - - - -
+ )} + + + Don't have an account? {" "} + + + Sign Up + + + diff --git a/src/pages/Auth/Register/index.tsx b/src/pages/Auth/Register/index.tsx index ea318b6..458d559 100644 --- a/src/pages/Auth/Register/index.tsx +++ b/src/pages/Auth/Register/index.tsx @@ -1,20 +1,10 @@ import { FunctionComponent } from 'react' import { Link } from 'react-router-dom' -import { - Box, - FormControl, - FormLabel, - Card, - CardBody, - CardHeader, - Heading, - Text, - FormErrorMessage, -} from '@chakra-ui/react' -import { Formik, Field } from 'formik' +import { Box, Card, CardBody, CardHeader, Heading, Text } from '@chakra-ui/react' +import { Formik } from 'formik' import { Helmet } from 'react-helmet-async' -import { Button, Input } from '@components/index' +import { RegisterForm } from '@components/index' import { colors } from '../../../colors' import { useSignup } from '@hooks/auth/useSignup' import { signUpValidataionSchema } from '@validations/signup' @@ -54,90 +44,32 @@ const Register: FunctionComponent = () => { validationSchema={signUpValidataionSchema} > {({ handleSubmit, errors, touched }) => ( -
- - - Fullname - - {errors.fullname} - - - - - Enter Email - - {errors.email} - - - - - - Password - - {errors.password} - - - - - - - - Already have an account? {" "} - - - Sign In - - - -
+ )} + + + Already have an account? {" "} + + + Sign In + + + diff --git a/src/pages/Users/SavedArticles/index.tsx b/src/pages/Users/SavedArticles/index.tsx index c81b079..253e9b0 100644 --- a/src/pages/Users/SavedArticles/index.tsx +++ b/src/pages/Users/SavedArticles/index.tsx @@ -2,7 +2,7 @@ import { Link } from 'react-router-dom' import { Avatar, Box, Container, Flex, Heading, Text } from '@chakra-ui/react' import { Helmet } from 'react-helmet-async' -import { ArticlesCard } from '@components/index' +import { ArticlesCard, Skeleton } from '@components/index' import { useUser } from '@context/userContext' import { useSavedArticles } from '@hooks/article/useGetSavedArticles' import { colors } from '../../../colors' @@ -10,7 +10,7 @@ import { useDeleteSaveArticle } from '@hooks/article/useDeleteSavaArticles' const SavedArticles = () => { const { user } = useUser(); - const { data: savedArticles } = useSavedArticles(); + const { data: savedArticles, isLoading } = useSavedArticles(); const { deleteSaveArticleMutation} = useDeleteSaveArticle() const handleUnSaveArticle = (articleId: string) => { @@ -45,6 +45,8 @@ const SavedArticles = () => { + {isLoading && } + {savedArticles && savedArticles?.map((article: any, index: number) => ( { /> {user?.data?.fullname} - {/* 0 Follower */} - {user?.data?.bio} - { m={"3rem auto"} width={"90%"} > - - - Back - - - - profile \ Settings + profile \ Settings ) => void; +} + export interface AuthFields { email: string; password: string;