diff --git a/apps/backoffice/src/app/providers/AppProviders.tsx b/apps/backoffice/src/app/providers/AppProviders.tsx
index 8782892f6..2be88a654 100644
--- a/apps/backoffice/src/app/providers/AppProviders.tsx
+++ b/apps/backoffice/src/app/providers/AppProviders.tsx
@@ -1,7 +1,6 @@
import { I18nextProvider } from 'react-i18next';
import { Provider } from 'react-redux';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import { AuthConfigProvider } from '@ema-platform/auth';
import type { ReactNode } from 'react';
import { store } from '../store';
import { i18n } from '../i18n/config';
@@ -17,19 +16,9 @@ export function AppProviders({ children }: { children: ReactNode }) {
return (
-
-
- {children}
-
-
+
+ {children}
+
);
diff --git a/apps/backoffice/src/app/router/index.tsx b/apps/backoffice/src/app/router/index.tsx
index 73a324d40..06bf91cd4 100644
--- a/apps/backoffice/src/app/router/index.tsx
+++ b/apps/backoffice/src/app/router/index.tsx
@@ -41,8 +41,8 @@ const router = createBrowserRouter([
{
element: ,
children: [
- { path: '/login', element: },
- { path: '/forgot-password', element: },
+ { path: '/login', element: },
+ { path: '/forgot-password', element: },
{ path: '/otp-verify', element: },
],
},
diff --git a/apps/portal/src/app/components/ProfileGuard.tsx b/apps/portal/src/app/components/ProfileGuard.tsx
index 5a564b142..1e64a8c49 100644
--- a/apps/portal/src/app/components/ProfileGuard.tsx
+++ b/apps/portal/src/app/components/ProfileGuard.tsx
@@ -4,8 +4,8 @@ import type { ReactNode } from 'react';
import { authStorage } from '@ema-platform/auth';
const ROUTE_ACCESS: Record = {
- SEAFARER: ['/dashboard', '/seafarer-', '/seaman-book', '/documents', '/certificates', '/endorsements', '/notifications', '/basic-safety-training'],
- VESSEL_OWNER: ['/vessel-owner', '/vessel-registration'],
+ SEAFARER: ['/','/dashboard', '/seafarer-', '/seaman-book', '/documents', '/certificates', '/endorsements', '/notifications', '/basic-safety-training'],
+ VESSEL_OWNER: ['/','/dashboard', '/vessel-owner', '/vessel-registration'],
};
const SHARED = ['/profile', '/support'];
diff --git a/apps/portal/src/app/components/SmartDashboard.tsx b/apps/portal/src/app/components/SmartDashboard.tsx
new file mode 100644
index 000000000..004b4ea04
--- /dev/null
+++ b/apps/portal/src/app/components/SmartDashboard.tsx
@@ -0,0 +1,11 @@
+import { Navigate } from 'react-router-dom';
+import { authStorage } from '@ema-platform/auth';
+import { DashboardPage } from '../features/dashboard/pages/DashboardPage';
+
+export function SmartDashboard() {
+ const profile = authStorage.getProfile<{ type: string }>();
+ if (profile?.type === 'VESSEL_OWNER') {
+ return ;
+ }
+ return ;
+}
diff --git a/apps/portal/src/app/features/profile-setup/pages/ProfileSetupPage.tsx b/apps/portal/src/app/features/profile-setup/pages/ProfileSetupPage.tsx
index 570a9c868..c7f05262b 100644
--- a/apps/portal/src/app/features/profile-setup/pages/ProfileSetupPage.tsx
+++ b/apps/portal/src/app/features/profile-setup/pages/ProfileSetupPage.tsx
@@ -116,7 +116,7 @@ export function ProfileSetupPage() {
const [active, setActive] = useState(0);
const [completed, setCompleted] = useState([]);
const [submitting, setSubmitting] = useState(false);
- const [professions, setProfessions] = useState>([]);
+ const [professions, setProfessions] = useState>([]);
const [professionsLoading, setProfessionsLoading] = useState(true);
const [profileTrigger] = useApiMutation<{ id: string }>();
const [addressTrigger] = useApiMutation();
@@ -147,6 +147,14 @@ export function ProfileSetupPage() {
return map;
}, [professions]);
+ const professionTypeMap = useMemo(() => {
+ const map: Record = {};
+ professions.forEach((p) => {
+ if (p.type) map[p.id] = p.type;
+ });
+ return map;
+ }, [professions]);
+
const nameParts = useMemo(() => (user?.name?.en || '').trim().split(/\s+/), [user]);
const profileDefaults: ProfileValues = useMemo(() => ({
professionId: '',
@@ -218,13 +226,14 @@ export function ProfileSetupPage() {
const pv = profileWatch();
const av = addressWatch();
const selectedProfessionName = professionNameMap[pv.professionId] ?? '';
+ const selectedType = professionTypeMap[pv.professionId] || 'SEAFARER';
const profileResult = await profileTrigger({
url: '/profiles',
method: 'POST',
body: {
userId: user?.id,
- type: 'SEAFARER',
+ type: selectedType,
professionId: pv.professionId,
firstName: pv.firstName,
middleName: pv.middleName,
@@ -261,8 +270,7 @@ export function ProfileSetupPage() {
}).unwrap();
notify.success('Profile setup complete!');
- //TODO: update the comparision
- navigate('SEAFARER' === 'VESSEL_OWNER' ? '/vessel-owner/dashboard' : '/dashboard');
+ navigate('/dashboard');
} catch {
notify.error('Failed to save profile. Please try again.');
} finally {
diff --git a/apps/portal/src/app/providers/AppProviders.tsx b/apps/portal/src/app/providers/AppProviders.tsx
index 15ec0c1d2..b907bae8d 100644
--- a/apps/portal/src/app/providers/AppProviders.tsx
+++ b/apps/portal/src/app/providers/AppProviders.tsx
@@ -1,6 +1,5 @@
import { Provider } from 'react-redux';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import { AuthConfigProvider } from '@ema-platform/auth';
import type { ReactNode } from 'react';
import { store } from '../store';
import { MantineThemeProvider } from './MantineThemeProvider';
@@ -15,17 +14,7 @@ export function AppProviders({ children }: { children: ReactNode }) {
-
- {children}
-
+ {children}
diff --git a/apps/portal/src/app/router.tsx b/apps/portal/src/app/router.tsx
index eb7c6d09e..95a4b7be3 100644
--- a/apps/portal/src/app/router.tsx
+++ b/apps/portal/src/app/router.tsx
@@ -4,6 +4,7 @@ import { i18n } from './i18n/config';
import { PortalLayout } from './layouts/PortalLayout';
import { ProtectedRoute } from './components/ProtectedRoute';
import { ProfileGuard } from './components/ProfileGuard';
+import { SmartDashboard } from './components/SmartDashboard';
// Auth (standalone pages, no portal chrome)
import { LoginPage, SignupPage, OTPVerificationPage, ForgotPasswordPage } from '@ema-platform/auth';
@@ -12,7 +13,6 @@ import { LoginPage, SignupPage, OTPVerificationPage, ForgotPasswordPage } from '
import { ProfileSetupPage } from './features/profile-setup/pages/ProfileSetupPage';
// Portal feature pages
-import { DashboardPage } from './features/dashboard/pages/DashboardPage';
import { ProfilePage } from './features/profile/pages/ProfilePage';
import { SupportPage } from './features/support/pages/SupportPage';
import { SeafarerRegistrationPage } from './features/seafarer/pages/SeafarerRegistrationPage';
@@ -45,11 +45,11 @@ import { VesselOwnerDashboardPage } from './features/vessel-owner/pages/VesselOw
export const router = createBrowserRouter([
// Public auth pages
- { path: '/login', element: },
- { path: '/signup', element: },
+ { path: '/login', element: },
+ { path: '/signup', element: },
// Public auth pages
- { path: '/forgot-password', element: },
+ { path: '/forgot-password', element: },
// Protected auth pages
{
@@ -73,8 +73,8 @@ export const router = createBrowserRouter([
),
children: [
- { path: '/', element: },
- { path: '/dashboard', element: },
+ { path: '/', element: },
+ { path: '/dashboard', element: },
// Seafarer
{ path: '/seafarer-registration', element: },
diff --git a/libs/auth/src/index.ts b/libs/auth/src/index.ts
index 7c178a615..1b729dbd7 100644
--- a/libs/auth/src/index.ts
+++ b/libs/auth/src/index.ts
@@ -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';
diff --git a/libs/auth/src/lib/AuthConfig.tsx b/libs/auth/src/lib/AuthConfig.tsx
deleted file mode 100644
index bbc446adb..000000000
--- a/libs/auth/src/lib/AuthConfig.tsx
+++ /dev/null
@@ -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(defaultConfig);
-
-export function AuthConfigProvider({
- children,
- value,
-}: {
- children: ReactNode;
- value: Partial;
-}) {
- const merged = { ...defaultConfig, ...value };
- return (
-
- {children}
-
- );
-}
-
-export function useAuthConfig() {
- return useContext(AuthConfigContext);
-}
diff --git a/libs/auth/src/lib/components/AuthShell.tsx b/libs/auth/src/lib/components/AuthShell.tsx
index f3e75ba54..6696cea3a 100644
--- a/libs/auth/src/lib/components/AuthShell.tsx
+++ b/libs/auth/src/lib/components/AuthShell.tsx
@@ -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 (
diff --git a/libs/auth/src/lib/pages/ForgotPasswordPage.tsx b/libs/auth/src/lib/pages/ForgotPasswordPage.tsx
index 98552e2b8..39e3e2216 100644
--- a/libs/auth/src/lib/pages/ForgotPasswordPage.tsx
+++ b/libs/auth/src/lib/pages/ForgotPasswordPage.tsx
@@ -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;
-export function ForgotPasswordPage() {
- const { appName } = useAuthConfig();
+interface ForgotPasswordPageProps {
+ appName?: string;
+}
+
+export function ForgotPasswordPage({ appName = 'Portal' }: ForgotPasswordPageProps) {
const [forgotTrigger, { isLoading }] = useApiMutation();
const [sentTo, setSentTo] = useState(null);
const [serverError, setServerError] = useState(null);
diff --git a/libs/auth/src/lib/pages/LoginPage.tsx b/libs/auth/src/lib/pages/LoginPage.tsx
index 54be7d675..063738a9e 100644
--- a/libs/auth/src/lib/pages/LoginPage.tsx
+++ b/libs/auth/src/lib/pages/LoginPage.tsx
@@ -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;
-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(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 ??
diff --git a/libs/auth/src/lib/pages/OTPVerificationPage.tsx b/libs/auth/src/lib/pages/OTPVerificationPage.tsx
index 17f25762e..e59593f88 100644
--- a/libs/auth/src/lib/pages/OTPVerificationPage.tsx
+++ b/libs/auth/src/lib/pages/OTPVerificationPage.tsx
@@ -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;
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
diff --git a/libs/auth/src/lib/pages/SignupPage.tsx b/libs/auth/src/lib/pages/SignupPage.tsx
index 76a875ef2..970c285ea 100644
--- a/libs/auth/src/lib/pages/SignupPage.tsx
+++ b/libs/auth/src/lib/pages/SignupPage.tsx
@@ -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(null);
const [signupTrigger, { isLoading: loading }] = useApiMutation<{