fix: fix redirect based on profile bug

This commit is contained in:
mengstabketemaw
2026-07-09 11:34:41 +03:00
parent 1471c797d9
commit db6a485374
14 changed files with 65 additions and 104 deletions

View File

@@ -1,5 +1,3 @@
export { AuthConfigProvider, useAuthConfig } from './lib/AuthConfig';
export type { AuthConfigValue } from './lib/AuthConfig';
export { AuthShell, BrandMark } from './lib/components/AuthShell';
export { ProtectedRoute } from './lib/components/ProtectedRoute';
export { LoginPage } from './lib/pages/LoginPage';

View File

@@ -1,40 +0,0 @@
import { createContext, useContext, type ReactNode } from 'react';
export interface AuthConfigValue {
appName: string;
storagePrefix: string;
loginRedirectPath: string;
enableSignup: boolean;
enableForgotPassword: boolean;
logoUrl: string;
}
const defaultConfig: AuthConfigValue = {
appName: 'Portal',
storagePrefix: 'ema-auth',
loginRedirectPath: '/dashboard',
enableSignup: true,
enableForgotPassword: true,
logoUrl: '/brand/ema-white.png',
};
const AuthConfigContext = createContext<AuthConfigValue>(defaultConfig);
export function AuthConfigProvider({
children,
value,
}: {
children: ReactNode;
value: Partial<AuthConfigValue>;
}) {
const merged = { ...defaultConfig, ...value };
return (
<AuthConfigContext.Provider value={merged}>
{children}
</AuthConfigContext.Provider>
);
}
export function useAuthConfig() {
return useContext(AuthConfigContext);
}

View File

@@ -15,14 +15,14 @@ import {
type BoxProps,
} from '@mantine/core';
import { IconCheck, IconMoon, IconSun } from '@tabler/icons-react';
import { useAuthConfig } from '../AuthConfig';
const LOGO_URL = '/brand/ema-white.png';
export function BrandMark({ size = 44, ...boxProps }: BoxProps & { size?: number }) {
const { logoUrl } = useAuthConfig();
return (
<Box
component="img"
src={logoUrl}
src={LOGO_URL}
alt="EMA"
w={size}
h={size}
@@ -78,7 +78,6 @@ export function AuthShell({
brandSubtitle = 'Apply for vessel and seafarer licenses, upload documents, and track every application in one secure portal.',
}: AuthShellProps) {
const theme = useMantineTheme();
const { logoUrl } = useAuthConfig();
const heroGradient = theme.other.heroGradient as string;
const computed = useComputedColorScheme('light');
const isDark = computed === 'dark';
@@ -167,7 +166,7 @@ export function AuthShell({
<Center>
<Box
component="img"
src={logoUrl}
src={LOGO_URL}
alt="EMA Portal"
style={{ display: 'block', maxWidth: '60%', height: 'auto' }}
/>

View File

@@ -24,7 +24,6 @@ import { Link } from 'react-router-dom';
import { useApiMutation } from '@ema-platform/api';
import { notify } from '@ema-platform/ui';
import { AuthShell } from '../components/AuthShell';
import { useAuthConfig } from '../AuthConfig';
const schema = z.object({
email: z.string().email({ message: 'Enter a valid email' }),
@@ -32,8 +31,11 @@ const schema = z.object({
type FormValues = z.infer<typeof schema>;
export function ForgotPasswordPage() {
const { appName } = useAuthConfig();
interface ForgotPasswordPageProps {
appName?: string;
}
export function ForgotPasswordPage({ appName = 'Portal' }: ForgotPasswordPageProps) {
const [forgotTrigger, { isLoading }] = useApiMutation();
const [sentTo, setSentTo] = useState<string | null>(null);
const [serverError, setServerError] = useState<string | null>(null);

View File

@@ -28,7 +28,6 @@ import { notify } from '@ema-platform/ui';
import { AuthShell } from '../components/AuthShell';
import { loginSuccess, setUser, setCurrentProfile } from '../store/auth.slice';
import type { LoginPayload, AuthUser, CurrentProfile } from '../types/auth.types';
import { useAuthConfig } from '../AuthConfig';
import { authStorage } from '../utils/auth-storage';
const schema = z.object({
@@ -38,11 +37,19 @@ const schema = z.object({
type FormValues = z.infer<typeof schema>;
export function LoginPage() {
interface LoginPageProps {
appName?: string;
enableSignup?: boolean;
enableForgotPassword?: boolean;
}
export function LoginPage({
appName = 'Portal',
enableSignup = true,
enableForgotPassword = true,
}: LoginPageProps) {
const navigate = useNavigate();
const dispatch = useDispatch();
const { appName, loginRedirectPath, enableSignup, enableForgotPassword } =
useAuthConfig();
const [isLoading, setIsLoading] = useState(false);
const [rememberMe, setRememberMe] = useState(true);
const [serverError, setServerError] = useState<string | null>(null);
@@ -75,7 +82,6 @@ export function LoginPage() {
dispatch(setUser(me));
let hasProfile = false;
let profileType: string | undefined;
try {
const q = `w=user_id:=:${me.id}&i=user,address,profession`;
const result = await profileCheckTrigger({
@@ -84,7 +90,6 @@ export function LoginPage() {
}).unwrap();
if (result.total > 0 && result.items.length > 0) {
const profile = result.items[0];
profileType = 'VESSEL_OWNER';
authStorage.setProfileId(profile.id);
dispatch(setCurrentProfile(profile));
hasProfile = true;
@@ -109,7 +114,7 @@ export function LoginPage() {
return;
}
navigate(profileType === 'VESSEL_OWNER' ? '/vessel-owner/dashboard' : loginRedirectPath);
navigate('/dashboard');
} catch (err: unknown) {
const msg =
(err as { data?: { message?: string } })?.data?.message ??

View File

@@ -20,7 +20,6 @@ import { useNavigate, useLocation } from 'react-router-dom';
import { useApiMutation } from '@ema-platform/api';
import { notify } from '@ema-platform/ui';
import { AuthShell } from '../components/AuthShell';
import { useAuthConfig } from '../AuthConfig';
const CODE_LENGTH = 6;
const RESEND_SECONDS = 30;
@@ -36,7 +35,6 @@ type FormValues = z.infer<typeof schema>;
export function OTPVerificationPage() {
const navigate = useNavigate();
const location = useLocation();
const { loginRedirectPath } = useAuthConfig();
const state = location.state as
| { email?: string; phoneNumber?: string; needsProfile?: boolean }
| null;
@@ -73,7 +71,7 @@ export function OTPVerificationPage() {
}).unwrap();
notify.success('Phone number verified successfully');
navigate(needsProfile ? '/profile-setup' : loginRedirectPath);
navigate(needsProfile ? '/profile-setup' : '/dashboard');
} catch (err: unknown) {
const msg =
(err as { data?: { message?: string } })?.data?.message ??
@@ -182,7 +180,7 @@ export function OTPVerificationPage() {
variant="light"
fullWidth
size="md"
onClick={() => navigate(loginRedirectPath)}
onClick={() => navigate('/dashboard')}
>
Skip verification for now
</Button>

View File

@@ -30,7 +30,6 @@ import { notify } from '@ema-platform/ui';
import { AuthShell } from '../components/AuthShell';
import { loginSuccess, setUser } from '../store/auth.slice';
import type { AuthUser } from '../types/auth.types';
import { useAuthConfig } from '../AuthConfig';
const schema = z
.object({
@@ -63,10 +62,13 @@ interface SignupPayload {
confirmPassword: string;
}
export function SignupPage() {
interface SignupPageProps {
appName?: string;
}
export function SignupPage({ appName = 'Portal' }: SignupPageProps) {
const navigate = useNavigate();
const dispatch = useDispatch();
const { appName, loginRedirectPath } = useAuthConfig();
const [agreed, setAgreed] = useState(false);
const [serverError, setServerError] = useState<string | null>(null);
const [signupTrigger, { isLoading: loading }] = useApiMutation<{