kopia lustrzana https://github.com/bugout-dev/moonstream
Merge pull request #261 from bugout-dev/fix-login-error
improve login/signup/logout and appLoading viewpull/265/head
commit
b2b27ef6e5
|
@ -40,7 +40,6 @@ const LandingNavbar = () => {
|
|||
py={1}
|
||||
flexBasis="200px"
|
||||
flexGrow={1}
|
||||
flexShirnk={1}
|
||||
id="Logo Container"
|
||||
>
|
||||
<RouterLink href="/" passHref>
|
||||
|
|
|
@ -6,7 +6,7 @@ import CustomIcon from "../CustomIcon";
|
|||
import styles from "./styles";
|
||||
|
||||
const Modal = ({ children, onClose }) => (
|
||||
<Flex onClick={onClose} css={styles.modal}>
|
||||
<Flex onClick={onClose} css={styles.modal} zIndex={100002}>
|
||||
<Flex onClick={(e) => e.stopPropagation()} css={styles.flex}>
|
||||
<Image
|
||||
color="primary.900"
|
||||
|
|
|
@ -8,7 +8,6 @@ const styles = {
|
|||
display: flex;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import React, { Fragment, useEffect, useState } from "react";
|
||||
import {
|
||||
Text,
|
||||
Stack,
|
||||
|
@ -175,9 +175,9 @@ const EthereumWhalewatchCard_ = ({
|
|||
>
|
||||
Value
|
||||
</Text>
|
||||
{Object.keys(whales).map((whaleType) => {
|
||||
{Object.keys(whales).map((whaleType, idx) => {
|
||||
return (
|
||||
<>
|
||||
<Fragment key={`whale-whatch-${idx}`}>
|
||||
<Box gridColumn="1 / 3">
|
||||
<Text
|
||||
h="100%"
|
||||
|
@ -238,7 +238,7 @@ const EthereumWhalewatchCard_ = ({
|
|||
>
|
||||
{whales[whaleType].statistic}
|
||||
</Box>
|
||||
</>
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</SimpleGrid>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { useContext } from "react";
|
||||
import { useMutation } from "react-query";
|
||||
import { useToast, useUser, useInviteAccept } from ".";
|
||||
import UIContext from "../providers/UIProvider/context";
|
||||
import { AuthService } from "../services";
|
||||
|
||||
const LOGIN_TYPES = {
|
||||
|
@ -7,6 +9,7 @@ const LOGIN_TYPES = {
|
|||
TOKEN: true,
|
||||
};
|
||||
const useLogin = (loginType) => {
|
||||
const { setLoggingIn } = useContext(UIContext);
|
||||
const { getUser } = useUser();
|
||||
const toast = useToast();
|
||||
const { inviteAccept } = useInviteAccept();
|
||||
|
@ -16,6 +19,9 @@ const useLogin = (loginType) => {
|
|||
error,
|
||||
data,
|
||||
} = useMutation(AuthService.login, {
|
||||
onMutate: () => {
|
||||
setLoggingIn(true);
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
// Default value for loginType is LOGIN_TYPES.MANUAL
|
||||
if (!loginType) {
|
||||
|
@ -37,6 +43,9 @@ const useLogin = (loginType) => {
|
|||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
onSettled: () => {
|
||||
setLoggingIn(false);
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useCallback, useContext } from "react";
|
||||
import { useContext } from "react";
|
||||
import { useMutation, useQueryClient } from "react-query";
|
||||
import { useUser, useRouter } from ".";
|
||||
import UIContext from "../providers/UIProvider/context";
|
||||
|
@ -7,21 +7,19 @@ import { AuthService } from "../services";
|
|||
const useLogout = () => {
|
||||
const { setLoggingOut } = useContext(UIContext);
|
||||
const router = useRouter();
|
||||
const { mutate: revoke } = useMutation(AuthService.revoke, {
|
||||
const cache = useQueryClient();
|
||||
const { mutate: logout } = useMutation(AuthService.revoke, {
|
||||
onMutate: () => {
|
||||
setLoggingOut(true);
|
||||
},
|
||||
onSuccess: () => {
|
||||
router.push("/");
|
||||
setUser(null);
|
||||
localStorage.removeItem("MOONSTREAM_ACCESS_TOKEN");
|
||||
cache.clear();
|
||||
setUser(null);
|
||||
router.push("/");
|
||||
},
|
||||
});
|
||||
const { setUser } = useUser();
|
||||
const cache = useQueryClient();
|
||||
|
||||
const logout = useCallback(() => {
|
||||
setLoggingOut(true);
|
||||
revoke();
|
||||
}, [revoke, setLoggingOut]);
|
||||
|
||||
return {
|
||||
logout,
|
||||
|
|
|
@ -21,6 +21,9 @@ const useSignUp = (source) => {
|
|||
data,
|
||||
isSuccess,
|
||||
} = useMutation(AuthService.register(), {
|
||||
onMutate: () => {
|
||||
ui.setLoggingIn(true);
|
||||
},
|
||||
onSuccess: (response) => {
|
||||
localStorage.setItem("MOONSTREAM_ACCESS_TOKEN", response.data.id);
|
||||
const invite_code = window.sessionStorage.getItem("invite_code");
|
||||
|
@ -35,13 +38,15 @@ const useSignUp = (source) => {
|
|||
});
|
||||
}
|
||||
getUser();
|
||||
ui.setisOnboardingComplete(false);
|
||||
ui.setOnboardingState({ welcome: 0, subscriptions: 0, stream: 0 });
|
||||
ui.setOnboardingComplete(false);
|
||||
router.push("/welcome", undefined, { shallow: false });
|
||||
},
|
||||
onError: (error) => {
|
||||
toast(error, "error");
|
||||
},
|
||||
onSettled: () => {
|
||||
ui.setLoggingIn(false);
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import React, { useState, useContext, useEffect, useCallback } from "react";
|
||||
import React, {
|
||||
useState,
|
||||
useContext,
|
||||
useEffect,
|
||||
useCallback,
|
||||
useLayoutEffect,
|
||||
} from "react";
|
||||
import { useBreakpointValue } from "@chakra-ui/react";
|
||||
import { useStorage, useQuery, useRouter } from "../../hooks";
|
||||
import UIContext from "./context";
|
||||
|
@ -47,21 +53,25 @@ const UIProvider = ({ children }) => {
|
|||
// ******* APP state ********
|
||||
const [isLoggedIn, setLoggedIn] = useState(user && user.username);
|
||||
const [isLoggingOut, setLoggingOut] = useState(false);
|
||||
const [isLoggingIn, setLoggingIn] = useState(false);
|
||||
const [isAppReady, setAppReady] = useState(false);
|
||||
const [isAppView, setAppView] = useState(
|
||||
router.nextRouter.asPath.includes("/stream") ||
|
||||
router.nextRouter.asPath.includes("/account") ||
|
||||
router.nextRouter.asPath.includes("/subscriptions") ||
|
||||
router.nextRouter.asPath.includes("/analytics") ||
|
||||
router.nextRouter.asPath.includes("/welcome")
|
||||
);
|
||||
const [isAppView, setAppView] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isAppView && isAppReady && !user?.username && !isLoggingOut) {
|
||||
// toggleModal("login");
|
||||
useLayoutEffect(() => {
|
||||
if (
|
||||
isAppView &&
|
||||
isInit &&
|
||||
!user?.username &&
|
||||
!isLoggingOut &&
|
||||
!isLoggingIn &&
|
||||
!modal
|
||||
) {
|
||||
toggleModal("login");
|
||||
} else if (user || isLoggingOut) {
|
||||
toggleModal(false);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isAppView, isAppReady, user, isLoggingOut]);
|
||||
}, [isAppView, isAppReady, user, isLoggingOut, modal]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoggingOut && !isAppView && user) {
|
||||
|
@ -77,15 +87,16 @@ const UIProvider = ({ children }) => {
|
|||
}
|
||||
}, [user]);
|
||||
|
||||
useEffect(() => {
|
||||
setAppView(
|
||||
router.nextRouter.asPath.includes("/stream") ||
|
||||
router.nextRouter.asPath.includes("/account") ||
|
||||
router.nextRouter.asPath.includes("/subscriptions") ||
|
||||
router.nextRouter.asPath.includes("/analytics") ||
|
||||
router.nextRouter.asPath.includes("/welcome")
|
||||
);
|
||||
}, [router.nextRouter.asPath, user]);
|
||||
useLayoutEffect(() => {
|
||||
if (
|
||||
isLoggingOut &&
|
||||
router.nextRouter.pathname === "/" &&
|
||||
!user &&
|
||||
!localStorage.getItem("MOONSTREAM_ACCESS_TOKEN")
|
||||
) {
|
||||
setLoggingOut(false);
|
||||
}
|
||||
}, [isLoggingOut, router.nextRouter.pathname, user]);
|
||||
|
||||
// *********** Sidebar states **********************
|
||||
|
||||
|
@ -166,6 +177,8 @@ const UIProvider = ({ children }) => {
|
|||
const [onboardingState, setOnboardingState] = useState(false);
|
||||
const [onboardingStep, setOnboardingStep] = useState();
|
||||
const [onboardingStateInit, setOnboardingStateInit] = useState(false);
|
||||
const [onboardingRedirectCheckPassed, setOnboardingRedirectCheckPassed] =
|
||||
useState(false);
|
||||
|
||||
const setOnboardingComplete = useCallback(
|
||||
(newState) => {
|
||||
|
@ -178,7 +191,7 @@ const UIProvider = ({ children }) => {
|
|||
//If onboarding state not exists - fetch it from backend
|
||||
//If it exists but init is not set - set init true
|
||||
//If it exists and is init -> post update to backend
|
||||
if (!onboardingState && user) {
|
||||
if (!onboardingState && user && !isLoggingOut) {
|
||||
const currentOnboardingState = async () =>
|
||||
PreferencesService.getOnboardingState().then((response) => {
|
||||
return response.data;
|
||||
|
@ -189,7 +202,7 @@ const UIProvider = ({ children }) => {
|
|||
});
|
||||
} else if (user && onboardingState && !onboardingStateInit) {
|
||||
setOnboardingStateInit(true);
|
||||
} else if (onboardingStateInit) {
|
||||
} else if (user && onboardingStateInit) {
|
||||
PreferencesService.setOnboardingState(onboardingState);
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
|
@ -211,16 +224,16 @@ const UIProvider = ({ children }) => {
|
|||
|
||||
useEffect(() => {
|
||||
//redirect to welcome page if yet not completed onboarding
|
||||
if (
|
||||
isLoggedIn &&
|
||||
isAppReady &&
|
||||
onboardingState &&
|
||||
!onboardingState?.is_complete
|
||||
) {
|
||||
router.replace("/welcome");
|
||||
if (isLoggedIn && onboardingState && !onboardingState?.is_complete) {
|
||||
router.replace("/welcome", undefined, { shallow: true });
|
||||
}
|
||||
if (isLoggedIn) {
|
||||
setOnboardingRedirectCheckPassed(true);
|
||||
} else {
|
||||
setOnboardingRedirectCheckPassed(false);
|
||||
}
|
||||
// eslint-disable-next-line
|
||||
}, [isLoggedIn, onboardingState?.is_complete, isAppReady]);
|
||||
}, [isLoggedIn, onboardingState?.is_complete]);
|
||||
|
||||
useEffect(() => {
|
||||
//This will set up onboarding complete once user finishes each view at least once
|
||||
|
@ -242,7 +255,7 @@ const UIProvider = ({ children }) => {
|
|||
isAppReady &&
|
||||
user &&
|
||||
Number.isInteger(onboardingStep) &&
|
||||
onboardingState
|
||||
onboardingState?.steps
|
||||
) {
|
||||
setOnboardingState({
|
||||
...onboardingState,
|
||||
|
@ -259,12 +272,26 @@ const UIProvider = ({ children }) => {
|
|||
// ********************************************************
|
||||
|
||||
useEffect(() => {
|
||||
if (isInit && router.nextRouter.isReady && onboardingState) {
|
||||
if (
|
||||
isInit &&
|
||||
router.nextRouter.isReady &&
|
||||
onboardingState &&
|
||||
!isLoggingOut &&
|
||||
!isLoggingIn &&
|
||||
onboardingRedirectCheckPassed
|
||||
) {
|
||||
setAppReady(true);
|
||||
} else {
|
||||
setAppReady(false);
|
||||
}
|
||||
}, [isInit, router, onboardingState]);
|
||||
}, [
|
||||
isInit,
|
||||
router,
|
||||
onboardingState,
|
||||
isLoggingOut,
|
||||
isLoggingIn,
|
||||
onboardingRedirectCheckPassed,
|
||||
]);
|
||||
|
||||
return (
|
||||
<UIContext.Provider
|
||||
|
@ -300,6 +327,8 @@ const UIProvider = ({ children }) => {
|
|||
setOnboardingState,
|
||||
onboardingState,
|
||||
isLoggingOut,
|
||||
isLoggingIn,
|
||||
setLoggingIn,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
import { Flex } from "@chakra-ui/react";
|
||||
import { Flex, Spinner, Box } from "@chakra-ui/react";
|
||||
import { getLayout as getSiteLayout } from "./RootLayout";
|
||||
import React, { useContext } from "react";
|
||||
import React, { useContext, useEffect } from "react";
|
||||
import UIContext from "../core/providers/UIProvider/context";
|
||||
|
||||
const AppLayout = ({ children }) => {
|
||||
const ui = useContext(UIContext);
|
||||
|
||||
useEffect(() => {
|
||||
ui.setAppView(true);
|
||||
return () => {
|
||||
ui.setAppView(false);
|
||||
};
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
direction="row"
|
||||
|
@ -15,6 +23,28 @@ const AppLayout = ({ children }) => {
|
|||
w="100%"
|
||||
overflow="hidden"
|
||||
>
|
||||
{(!ui.isAppReady || !ui.isLoggedIn) && (
|
||||
<Spinner
|
||||
position="absolute"
|
||||
top="50%"
|
||||
left="50%"
|
||||
size="xl"
|
||||
speed="1s"
|
||||
zIndex={100001}
|
||||
/>
|
||||
)}
|
||||
{(!ui.isAppReady || !ui.isLoggedIn) && (
|
||||
<Box
|
||||
position="absolute"
|
||||
top="0"
|
||||
bottom={0}
|
||||
left={0}
|
||||
right={0}
|
||||
bg="rgba(0,0,0,0.7)"
|
||||
zIndex={100000}
|
||||
/>
|
||||
)}
|
||||
|
||||
{ui.isAppReady && ui.isLoggedIn && children}
|
||||
</Flex>
|
||||
);
|
||||
|
|
|
@ -1,32 +1,14 @@
|
|||
import { CloseIcon } from "@chakra-ui/icons";
|
||||
import {
|
||||
Flex,
|
||||
Spinner,
|
||||
Center,
|
||||
Text,
|
||||
Link,
|
||||
IconButton,
|
||||
} from "@chakra-ui/react";
|
||||
import React, { Suspense, useContext, useState, useEffect } from "react";
|
||||
import { Flex, Center, Text, Link, IconButton } from "@chakra-ui/react";
|
||||
import React, { Suspense, useContext, useState } from "react";
|
||||
import UIContext from "../core/providers/UIProvider/context";
|
||||
const Sidebar = React.lazy(() => import("../components/Sidebar"));
|
||||
const Navbar = React.lazy(() => import("../components/Navbar"));
|
||||
import UIContext from "../core/providers/UIProvider/context";
|
||||
|
||||
const RootLayout = (props) => {
|
||||
const ui = useContext(UIContext);
|
||||
const [showSpinner, setSpinner] = useState(true);
|
||||
const [showBanner, setShowBanner] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (ui.isAppView && ui.isAppReady) {
|
||||
setSpinner(false);
|
||||
} else if (!ui.isAppView) {
|
||||
setSpinner(false);
|
||||
} else {
|
||||
setSpinner(true);
|
||||
}
|
||||
}, [ui, setSpinner]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
direction="row"
|
||||
|
@ -98,8 +80,7 @@ const RootLayout = (props) => {
|
|||
</Flex>
|
||||
</Flex>
|
||||
)}
|
||||
{!showSpinner && props.children}
|
||||
{showSpinner && <Spinner />}
|
||||
{props.children}
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
|
|
Ładowanie…
Reference in New Issue