bugfix: the flow for trial and accept invitation (org + staff)is now unified. all navigate to dshboard if succesfull.
This commit is contained in:
@@ -15,3 +15,20 @@ export function consumeAuthRedirect(): string | null {
|
||||
if (path) sessionStorage.removeItem(AUTH_REDIRECT_KEY);
|
||||
return path;
|
||||
}
|
||||
|
||||
/** Dashboard (or a stored share-link / post-auth path). Consume once — never inside useAuth.login() or registerTrial. */
|
||||
export function appPathAfterAuth(): string {
|
||||
return consumeAuthRedirect() ?? '/today';
|
||||
}
|
||||
|
||||
/**
|
||||
* After login() on invite pages only. Multi-org already went to /select-organization.
|
||||
* Do not use useEnterAppWhenAuthenticated on invite pages.
|
||||
*/
|
||||
export function navigateIntoAppIfOrgSelected(
|
||||
replace: (href: string) => void,
|
||||
organizationCount: number,
|
||||
) {
|
||||
if (organizationCount > 1) return;
|
||||
replace(appPathAfterAuth());
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
} from '@/lib/auth/proactiveRefresh';
|
||||
import { notifyAccessTokenRefreshed } from '@/lib/auth/accessTokenEvents';
|
||||
import { asApiError, legacyStatusCode, type ApiError } from '@/types/api';
|
||||
import { consumeAuthRedirect } from '@/lib/auth/postAuthRedirect';
|
||||
import { appPathAfterAuth } from '@/lib/auth/postAuthRedirect';
|
||||
|
||||
function toApiError(err: unknown): ApiError {
|
||||
return (
|
||||
@@ -50,7 +50,11 @@ interface AuthContextType {
|
||||
organizationEmail: string,
|
||||
organizationType: 'CLINIC' | 'LAB'
|
||||
) => Promise<void>;
|
||||
login: (email: string, password: string, rememberMe?: boolean) => Promise<void>;
|
||||
login: (
|
||||
email: string,
|
||||
password: string,
|
||||
rememberMe?: boolean,
|
||||
) => Promise<{ organizations: Organization[] }>;
|
||||
logout: () => Promise<void>;
|
||||
selectOrganization: (orgId: string) => Promise<void>;
|
||||
createOrganization: (
|
||||
@@ -337,6 +341,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
router.push('/select-organization');
|
||||
}
|
||||
|
||||
return { organizations: orgs };
|
||||
} catch (err: any) {
|
||||
setApiError(toApiError(err));
|
||||
throw err;
|
||||
@@ -388,12 +393,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
plan: (organization as { plan?: Organization['plan'] }).plan,
|
||||
});
|
||||
|
||||
const redirectPath = consumeAuthRedirect();
|
||||
if (redirectPath) {
|
||||
router.push(redirectPath);
|
||||
} else {
|
||||
router.push('/today');
|
||||
}
|
||||
router.push(appPathAfterAuth());
|
||||
|
||||
} catch (err: any) {
|
||||
setApiError(toApiError(err));
|
||||
|
||||
23
frontend/src/lib/hooks/useEnterAppWhenAuthenticated.ts
Normal file
23
frontend/src/lib/hooks/useEnterAppWhenAuthenticated.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { useRouter } from '@/i18n/navigation';
|
||||
import { appPathAfterAuth } from '@/lib/auth/postAuthRedirect';
|
||||
import { useAuth } from '@/lib/hooks/useAuth';
|
||||
|
||||
/**
|
||||
* When a session already exists (or was just created on this page), enter the app.
|
||||
* Use on /login and /register only — not on invite pages, where a logged-in visitor
|
||||
* must still be able to finish accept before navigating.
|
||||
*/
|
||||
export function useEnterAppWhenAuthenticated() {
|
||||
const { user, isAuthReady, isLoading, organizations, currentOrganization } = useAuth();
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAuthReady || !user || isLoading) return;
|
||||
const orgReady = organizations.length <= 1 || currentOrganization;
|
||||
if (!orgReady) return;
|
||||
router.push(appPathAfterAuth());
|
||||
}, [isAuthReady, user, isLoading, organizations, currentOrganization, router]);
|
||||
}
|
||||
Reference in New Issue
Block a user