added signup callback page that runs an api call to finish signup
This commit is contained in:
parent
e654aa002b
commit
24d27121d1
5 changed files with 142 additions and 21 deletions
|
|
@ -19,7 +19,7 @@ if ('serviceWorker' in navigator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
createRoot(document.getElementById('root')!).render(
|
createRoot(document.getElementById('root')!).render(
|
||||||
<StrictMode>
|
// <StrictMode>
|
||||||
<App />
|
<App />
|
||||||
</StrictMode>,
|
// </StrictMode>,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { getWhitelabel } from "services/whiteLabel";
|
||||||
import Ventilation from "pages/VentEditor";
|
import Ventilation from "pages/VentEditor";
|
||||||
import { useGlobalState } from "providers";
|
import { useGlobalState } from "providers";
|
||||||
import DeviceSupport from "pages/DeviceSupport";
|
import DeviceSupport from "pages/DeviceSupport";
|
||||||
|
import SignupCallback from "pages/SignupCallback";
|
||||||
|
|
||||||
const DeviceHistory = lazy(() => import("pages/DeviceHistory"));
|
const DeviceHistory = lazy(() => import("pages/DeviceHistory"));
|
||||||
const DevicePage = lazy(() => import("pages/Device"));
|
const DevicePage = lazy(() => import("pages/Device"));
|
||||||
|
|
@ -302,6 +303,8 @@ export default function Router() {
|
||||||
|
|
||||||
{/* Redirects */}
|
{/* Redirects */}
|
||||||
<Route path="/callback" element={<Navigate to="/" />} />
|
<Route path="/callback" element={<Navigate to="/" />} />
|
||||||
|
{/* <Route path="/signupCallback" element={<Navigate to="/" />} /> */}
|
||||||
|
<Route path="/signupCallback" element={<SignupCallback />} />
|
||||||
{/* <Route path="/login" element={<Login />} /> */}
|
{/* <Route path="/login" element={<Login />} /> */}
|
||||||
{/* <Route path="/team/:teamID" element={<Navigate to="/teams/:teamID" />} /> */}
|
{/* <Route path="/team/:teamID" element={<Navigate to="/teams/:teamID" />} /> */}
|
||||||
{/* <Route path="/device/:deviceID" element={<Navigate to="/devices/:devicesID" />} /> */}
|
{/* <Route path="/device/:deviceID" element={<Navigate to="/devices/:devicesID" />} /> */}
|
||||||
|
|
|
||||||
87
src/pages/SignupCallback.tsx
Normal file
87
src/pages/SignupCallback.tsx
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
import { useDeviceAPI, useUserAPI } from "hooks";
|
||||||
|
import PageContainer from "./PageContainer";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Divider } from "@mui/material";
|
||||||
|
import { useBinAPI, useTeamAPI } from "providers";
|
||||||
|
import { CheckCircleOutline } from "@mui/icons-material";
|
||||||
|
import { green } from "@mui/material/colors";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SignupCallback (props: Props) {
|
||||||
|
const userAPI = useUserAPI();
|
||||||
|
const teamAPI = useTeamAPI()
|
||||||
|
const deviceAPI = useDeviceAPI();
|
||||||
|
const binAPI = useBinAPI();
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [signupDialogOpen, setSignupDialogOpen] = useState(true)
|
||||||
|
const [hasTeams, setHasTeams] = useState(false)
|
||||||
|
const [hasDevices, setHasDevices] = useState(false)
|
||||||
|
const [hasBins, setHasBins] = useState(false)
|
||||||
|
|
||||||
|
const [doneBins, setDoneBins] = useState(false)
|
||||||
|
const [doneTeams, setDoneTeams] = useState(false)
|
||||||
|
const [doneDevices, setDoneDevices] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(hasTeams)
|
||||||
|
}, [hasTeams])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setLoading(true)
|
||||||
|
userAPI.completeSignup().then(resp => {
|
||||||
|
console.log(resp)
|
||||||
|
teamAPI.listTeams(1, 0).then(resp => {
|
||||||
|
setHasTeams(resp.data.teams.length > 0)
|
||||||
|
}).finally(() => setDoneTeams(true))
|
||||||
|
deviceAPI.list(1, 0).then(resp => {
|
||||||
|
setHasDevices(resp.data.devices.length > 0)
|
||||||
|
}).finally(() => setDoneDevices(true))
|
||||||
|
binAPI.listBins(1, 0).then(resp => {
|
||||||
|
setHasBins(resp.data.bins.length > 0)
|
||||||
|
}).finally(() => setDoneBins(true))
|
||||||
|
}).finally(() => setLoading(false))
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const loadingComplete = () => {
|
||||||
|
return loading === false && doneBins && doneTeams && doneDevices
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = () => {
|
||||||
|
return (
|
||||||
|
<DialogContent sx={{ margin: "auto", textAlign: "center" }}>
|
||||||
|
{ loadingComplete() ?
|
||||||
|
<CheckCircleOutline sx={{ fontSize: 64, color: green[500] }}/>
|
||||||
|
:
|
||||||
|
<CircularProgress size={64}/>
|
||||||
|
}
|
||||||
|
<DialogContentText sx={{marginTop: 2}}>
|
||||||
|
{hasTeams && "Teams found!"}
|
||||||
|
{hasDevices && "Devices found!"}
|
||||||
|
{hasBins && "Bins found!"}
|
||||||
|
</DialogContentText>
|
||||||
|
</DialogContent>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer spacing={1}>
|
||||||
|
<Dialog open={signupDialogOpen} >
|
||||||
|
<DialogTitle>
|
||||||
|
Finishing Signup
|
||||||
|
</DialogTitle>
|
||||||
|
<Divider sx={{ marginBottom: 2 }}/>
|
||||||
|
{ content() }
|
||||||
|
<DialogActions>
|
||||||
|
{loadingComplete() &&
|
||||||
|
<Button onClick={() => setSignupDialogOpen(false)}>
|
||||||
|
Done
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</PageContainer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -9,28 +9,30 @@ interface Props extends PropsWithChildren<any>{
|
||||||
|
|
||||||
export default function AuthWrapper(props: Props) {
|
export default function AuthWrapper(props: Props) {
|
||||||
const { children, setToken } = props;
|
const { children, setToken } = props;
|
||||||
const { isLoading, loginWithRedirect, isAuthenticated, getAccessTokenSilently } = useAuth0();
|
const { isLoading, loginWithRedirect, isAuthenticated, getAccessTokenSilently, getIdTokenClaims } = useAuth0();
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
|
|
||||||
const isManualLoginPage = url.pathname.includes("/login");
|
const isManualLoginPage = url.pathname.includes("/login");
|
||||||
|
const options: RedirectLoginOptions = {
|
||||||
|
authorizationParams: {} // Initialize here
|
||||||
|
};
|
||||||
|
|
||||||
if (isManualLoginPage) {
|
if (isManualLoginPage && options.authorizationParams) {
|
||||||
const options: RedirectLoginOptions = {
|
|
||||||
authorizationParams: {} // Initialize here
|
|
||||||
};
|
|
||||||
|
|
||||||
let parsed = queryString.parse(url.search);
|
let parsed = queryString.parse(url.search);
|
||||||
if (parsed.signup === "true") {
|
if (parsed.signup === "true") {
|
||||||
options.authorizationParams!.screen_hint = "signup";
|
options.authorizationParams.screen_hint = "signUp";
|
||||||
options.authorizationParams!.prompt = "login";
|
// options.authorizationParams.m
|
||||||
|
// options.authorizationParams.prompt = "login";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parsed.email && parsed.email !== "") {
|
if (parsed.email && parsed.email !== "") {
|
||||||
options.authorizationParams!.login_hint = parsed.email.toString(); // prefill email
|
options.authorizationParams.login_hint = parsed.email.toString(); // prefill email
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.authorizationParams.redirect_uri = "http://localhost:5173/signupCallback"
|
||||||
|
|
||||||
loginWithRedirect(options)
|
loginWithRedirect(options)
|
||||||
|
|
||||||
|
|
@ -40,15 +42,28 @@ export default function AuthWrapper(props: Props) {
|
||||||
}, [isAuthenticated, loginWithRedirect, isLoading]);
|
}, [isAuthenticated, loginWithRedirect, isLoading]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isAuthenticated) getAccessTokenSilently().then(t => {
|
const url = new URL(window.location.href);
|
||||||
if (t.length < 1) {
|
const isSignupCallback = url.pathname.includes("/signupCallback");
|
||||||
|
if (isAuthenticated) {
|
||||||
|
getAccessTokenSilently().then(t => {
|
||||||
|
if (t.length < 1) {
|
||||||
|
loginWithRedirect()
|
||||||
|
}
|
||||||
|
setToken(t)
|
||||||
|
}).catch(() => {
|
||||||
|
// No token, go back to login
|
||||||
loginWithRedirect()
|
loginWithRedirect()
|
||||||
|
})
|
||||||
|
if (isSignupCallback) {
|
||||||
|
console.log("IS SIGNUP")
|
||||||
|
getIdTokenClaims().then(id_claims => {
|
||||||
|
console.log(id_claims)
|
||||||
|
console.log(id_claims?.nickname)
|
||||||
|
if (id_claims) console.log(Object.keys(id_claims))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
setToken(t)
|
|
||||||
}).catch(() => {
|
}
|
||||||
// No token, go back to login
|
|
||||||
loginWithRedirect()
|
|
||||||
})
|
|
||||||
}, [setToken, isAuthenticated])
|
}, [setToken, isAuthenticated])
|
||||||
|
|
||||||
return children;
|
return children;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ export interface IUserAPIContext {
|
||||||
prefixSearch?: string,
|
prefixSearch?: string,
|
||||||
) => Promise<ListUsersResponse>;
|
) => Promise<ListUsersResponse>;
|
||||||
listProfiles: () => Promise<pond.UserProfile[]>;
|
listProfiles: () => Promise<pond.UserProfile[]>;
|
||||||
|
completeSignup: () => Promise<pond.CompleteSignupUserResponse>;
|
||||||
listObjectUsers: (scope: Scope) => Promise<any>;
|
listObjectUsers: (scope: Scope) => Promise<any>;
|
||||||
updateObjectUsers: (scope: Scope, users: pond.IUser[]) => Promise<any>;
|
updateObjectUsers: (scope: Scope, users: pond.IUser[]) => Promise<any>;
|
||||||
getUser: (id: string, scope?: Scope) => Promise<User>;
|
getUser: (id: string, scope?: Scope) => Promise<User>;
|
||||||
|
|
@ -55,8 +56,22 @@ export const UserAPIContext = createContext<IUserAPIContext>({} as IUserAPIConte
|
||||||
|
|
||||||
export default function UserProvider(props: PropsWithChildren<any>) {
|
export default function UserProvider(props: PropsWithChildren<any>) {
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
const { get, put } = useHTTP();
|
const { get, put, post } = useHTTP();
|
||||||
const [{ as }] = useGlobalState();
|
const [{ as, user }] = useGlobalState();
|
||||||
|
|
||||||
|
const completeSignup = (): Promise<pond.CompleteSignupUserResponse> => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let request = pond.CompleteSignupUserRequest.create();
|
||||||
|
request.avatar = user.settings.avatar
|
||||||
|
request.email = user.settings.email
|
||||||
|
request.id = user.id()
|
||||||
|
request.name = user.name()
|
||||||
|
post(pondURL("/signups"), request).then(res => {
|
||||||
|
console.log(res)
|
||||||
|
resolve(pond.CompleteSignupUserResponse.create())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const listUsers = (
|
const listUsers = (
|
||||||
limit: number,
|
limit: number,
|
||||||
|
|
@ -234,6 +249,7 @@ export default function UserProvider(props: PropsWithChildren<any>) {
|
||||||
return (
|
return (
|
||||||
<UserAPIContext.Provider
|
<UserAPIContext.Provider
|
||||||
value={{
|
value={{
|
||||||
|
completeSignup,
|
||||||
listUsers,
|
listUsers,
|
||||||
listProfiles,
|
listProfiles,
|
||||||
listObjectUsers,
|
listObjectUsers,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue