All job seeker pages are already connected to real APIs:
- Jobs: /api/jobseeker/jobs (real company job postings)
- Applications: /api/jobseeker/applications (my applied jobs)
- Saved Jobs: Custom data storage for bookmarked jobs
- Apply: POST /api/jobseeker/jobs/{id}/apply
Dashboard shows real data from backend, not mock preview.
736 lines
22 KiB
TypeScript
736 lines
22 KiB
TypeScript
import {
|
|
Match,
|
|
Show,
|
|
Switch,
|
|
createEffect,
|
|
createMemo,
|
|
createResource,
|
|
createSignal,
|
|
onMount,
|
|
} from "solid-js";
|
|
import { useNavigate } from "@solidjs/router";
|
|
import { useAuth, RequireAuth } from "~/lib/auth";
|
|
import DashboardDesignPreview from "~/components/admin/DashboardDesignPreview";
|
|
import DashboardShell from "~/components/DashboardShell";
|
|
import ProfilePage from "~/components/dashboard/ProfilePage";
|
|
import PortfolioPage from "~/components/dashboard/PortfolioPage";
|
|
import VerificationStatusPage from "~/components/dashboard/VerificationStatusPage";
|
|
import CompanyJobsPage from "~/components/dashboard/CompanyJobsPage";
|
|
import CompanyApplicationsPage from "~/components/dashboard/CompanyApplicationsPage";
|
|
import SettingsPage from "~/components/dashboard/SettingsPage";
|
|
import MyDashboardPage from "~/components/dashboard/MyDashboardPage";
|
|
import CustomerRequirementsPage from "~/components/dashboard/CustomerRequirementsPage";
|
|
import CustomerResponsesPage from "~/components/dashboard/CustomerResponsesPage";
|
|
import CompanyShortlistedCandidatesPage from "~/components/dashboard/CompanyShortlistedCandidatesPage";
|
|
import JobSeekerApplicationsPage from "~/components/dashboard/JobSeekerApplicationsPage";
|
|
import JobSeekerSavedJobsPage from "~/components/dashboard/JobSeekerSavedJobsPage";
|
|
import JobSeekerJobsPage from "~/components/dashboard/JobSeekerJobsPage";
|
|
import ProfessionalLeadsPage from "~/components/dashboard/ProfessionalLeadsPage";
|
|
import ProfessionalResponsesPage from "~/components/dashboard/ProfessionalResponsesPage";
|
|
import CreditsPage from "~/components/dashboard/CreditsPage";
|
|
import ExploreServicesPage from "~/components/dashboard/ExploreServicesPage";
|
|
import HelpCenterDashboardPage from "~/components/dashboard/HelpCenterDashboardPage";
|
|
import SwitchServicesPage from "~/components/dashboard/SwitchServicesPage";
|
|
import LogoutPage from "~/components/dashboard/LogoutPage";
|
|
import { PROFESSIONAL_ROLE_SET } from "~/components/dashboard/RoleDashboardShared";
|
|
|
|
// Sidebar items that have real data implementations (wired to backend APIs)
|
|
// These show real components instead of DashboardDesignPreview mock
|
|
const BASE_REAL_PAGES = ["my dashboard", "my profile", "my portfolio", "verification", "settings"];
|
|
const COMMON_REAL_PAGES = [
|
|
"credits",
|
|
"explore nxtgauge",
|
|
"help center",
|
|
"switch services",
|
|
"logout",
|
|
];
|
|
const COMPANY_REAL_PAGES = ["jobs", "applications", "shortlisted candidates"];
|
|
const CUSTOMER_REAL_PAGES = ["my requirements", "received responses", "shortlisted responses"];
|
|
const JOB_SEEKER_REAL_PAGES = ["jobs", "my applications", "saved jobs", "my portfolio"];
|
|
const PROFESSIONAL_REAL_PAGES = ["leads", "my responses"];
|
|
|
|
type RoleKey =
|
|
| "COMPANY"
|
|
| "CUSTOMER"
|
|
| "JOB_SEEKER"
|
|
| "PHOTOGRAPHER"
|
|
| "MAKEUP_ARTIST"
|
|
| "TUTOR"
|
|
| "DEVELOPER"
|
|
| "VIDEO_EDITOR"
|
|
| "UGC_CONTENT_CREATOR"
|
|
| "GRAPHIC_DESIGNER"
|
|
| "SOCIAL_MEDIA_MANAGER"
|
|
| "FITNESS_TRAINER"
|
|
| "CATERING_SERVICES";
|
|
|
|
type RuntimeBundle = {
|
|
role: RoleKey;
|
|
status: "ACTIVE" | "INACTIVE";
|
|
sidebarItems: string[];
|
|
tabs: string[];
|
|
widgets: string[];
|
|
fields: string[];
|
|
verificationStatus?: string;
|
|
source: "dashboard-config";
|
|
};
|
|
|
|
const API_GATEWAY = "/api/gateway";
|
|
const SERVER_API_BASE = (process.env.PUBLIC_API_URL || "http://localhost:8080/api").replace(
|
|
/\/+$/,
|
|
""
|
|
);
|
|
|
|
const ROLE_OPTIONS: RoleKey[] = [
|
|
"COMPANY",
|
|
"CUSTOMER",
|
|
"JOB_SEEKER",
|
|
"PHOTOGRAPHER",
|
|
"MAKEUP_ARTIST",
|
|
"TUTOR",
|
|
"DEVELOPER",
|
|
"VIDEO_EDITOR",
|
|
"UGC_CONTENT_CREATOR",
|
|
"GRAPHIC_DESIGNER",
|
|
"SOCIAL_MEDIA_MANAGER",
|
|
"FITNESS_TRAINER",
|
|
"CATERING_SERVICES",
|
|
];
|
|
|
|
const ROLE_BASED_SIDEBAR: Record<RoleKey, string[]> = {
|
|
PHOTOGRAPHER: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Portfolio",
|
|
"Leads",
|
|
"My Responses",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
MAKEUP_ARTIST: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Portfolio",
|
|
"Leads",
|
|
"My Responses",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
TUTOR: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Portfolio",
|
|
"Leads",
|
|
"My Responses",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
DEVELOPER: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Portfolio",
|
|
"Leads",
|
|
"My Responses",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
VIDEO_EDITOR: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Portfolio",
|
|
"Leads",
|
|
"My Responses",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
UGC_CONTENT_CREATOR: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Portfolio",
|
|
"Leads",
|
|
"My Responses",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
GRAPHIC_DESIGNER: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Portfolio",
|
|
"Leads",
|
|
"My Responses",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
SOCIAL_MEDIA_MANAGER: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Portfolio",
|
|
"Leads",
|
|
"My Responses",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
FITNESS_TRAINER: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Portfolio",
|
|
"Leads",
|
|
"My Responses",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
CATERING_SERVICES: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Portfolio",
|
|
"Leads",
|
|
"My Responses",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
COMPANY: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"Jobs",
|
|
"Applications",
|
|
"Shortlisted Candidates",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
JOB_SEEKER: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Portfolio",
|
|
"Jobs",
|
|
"My Applications",
|
|
"Saved Jobs",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
CUSTOMER: [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"My Requirements",
|
|
"Received Responses",
|
|
"Shortlisted Responses",
|
|
"Credits",
|
|
"Explore Nxtgauge",
|
|
"Verification",
|
|
"Help Center",
|
|
"Settings",
|
|
"Switch Services",
|
|
"Logout",
|
|
],
|
|
};
|
|
|
|
const ROLE_PREFIXES: Record<string, string> = {
|
|
PHOTOGRAPHER: "photographers",
|
|
MAKEUP_ARTIST: "makeup-artists",
|
|
TUTOR: "tutors",
|
|
DEVELOPER: "developers",
|
|
VIDEO_EDITOR: "video-editors",
|
|
GRAPHIC_DESIGNER: "graphic-designers",
|
|
SOCIAL_MEDIA_MANAGER: "social-media-managers",
|
|
FITNESS_TRAINER: "fitness-trainers",
|
|
CATERING_SERVICES: "catering-services",
|
|
UGC_CONTENT_CREATOR: "ugc-content-creators",
|
|
CUSTOMER: "customers",
|
|
COMPANY: "companies",
|
|
JOB_SEEKER: "jobseeker",
|
|
};
|
|
|
|
function getNameFromStorage(): string {
|
|
if (typeof window === "undefined") return "User";
|
|
const keys = ["nxtgauge_signup_profile_v1", "nxtgauge_auth_user", "nxtgauge_user"];
|
|
for (const key of keys) {
|
|
try {
|
|
const raw = window.localStorage.getItem(key) || window.sessionStorage.getItem(key);
|
|
if (!raw) continue;
|
|
const parsed = JSON.parse(raw);
|
|
const name =
|
|
parsed?.name || parsed?.first_name || parsed?.user?.name || parsed?.user?.first_name;
|
|
if (name) return String(name);
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}
|
|
return "User";
|
|
}
|
|
|
|
const EXPLORE_ROLES = [
|
|
{ key: "PHOTOGRAPHER", name: "Photographer" },
|
|
{ key: "MAKEUP_ARTIST", name: "Makeup Artist" },
|
|
{ key: "TUTOR", name: "Tutor" },
|
|
{ key: "DEVELOPER", name: "Developer" },
|
|
{ key: "VIDEO_EDITOR", name: "Video Editor" },
|
|
{ key: "UGC_CONTENT_CREATOR", name: "UGC Content Creator" },
|
|
{ key: "GRAPHIC_DESIGNER", name: "Graphic Designer" },
|
|
{ key: "SOCIAL_MEDIA_MANAGER", name: "Social Media Manager" },
|
|
{ key: "FITNESS_TRAINER", name: "Fitness Trainer" },
|
|
{ key: "CATERING_SERVICES", name: "Catering Services" },
|
|
];
|
|
|
|
function normalizeRole(value: string): RoleKey {
|
|
const up = String(value || "")
|
|
.trim()
|
|
.toUpperCase()
|
|
.replace(/\s+/g, "_");
|
|
return (ROLE_OPTIONS.find((r) => r === up) || "JOB_SEEKER") as RoleKey;
|
|
}
|
|
|
|
function asStringArray(value: unknown): string[] {
|
|
if (!Array.isArray(value)) return [];
|
|
return value.map((item) => String(item || "").trim()).filter(Boolean);
|
|
}
|
|
|
|
function getInitialRoleFromStorage(): RoleKey {
|
|
if (typeof window === "undefined") return "JOB_SEEKER";
|
|
const keys = ["nxtgauge_signup_profile_v1", "nxtgauge_auth_user", "nxtgauge_user"];
|
|
for (const key of keys) {
|
|
try {
|
|
const raw = window.localStorage.getItem(key) || window.sessionStorage.getItem(key);
|
|
if (!raw) continue;
|
|
const parsed = JSON.parse(raw);
|
|
const found = normalizeRole(
|
|
String(
|
|
parsed?.roleKey ||
|
|
parsed?.role ||
|
|
parsed?.active_role ||
|
|
parsed?.user?.active_role ||
|
|
parsed?.user?.roles?.[0] ||
|
|
""
|
|
)
|
|
);
|
|
if (ROLE_OPTIONS.includes(found)) return found;
|
|
} catch {
|
|
// ignore invalid payload
|
|
}
|
|
}
|
|
return "JOB_SEEKER";
|
|
}
|
|
|
|
async function fetchJson(path: string): Promise<any | null> {
|
|
try {
|
|
const isServer = typeof window === "undefined";
|
|
const target = isServer ? `${SERVER_API_BASE}${path}` : `${API_GATEWAY}${path}`;
|
|
const res = await fetch(target, { credentials: "include" });
|
|
if (!res.ok) return null;
|
|
return await res.json();
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function loadRoleBundle(role: RoleKey): Promise<RuntimeBundle | null> {
|
|
if (typeof window === "undefined") {
|
|
return null;
|
|
}
|
|
const runtime = await fetchJson("/api/runtime-config");
|
|
if (runtime) {
|
|
const runtimeRole = normalizeRole(String(runtime?.role || runtime?.user?.active_role || role));
|
|
const runtimeSidebar = asStringArray(
|
|
runtime?.dashboard_config?.sidebar_items ??
|
|
runtime?.dashboard_config?.sidebarItems ??
|
|
runtime?.sidebar_items ??
|
|
runtime?.sidebarItems
|
|
);
|
|
const runtimeTabs = asStringArray(runtime?.dashboard_config?.tabs ?? runtime?.tabs);
|
|
const runtimeWidgetsRaw = Array.isArray(runtime?.dashboard_config?.widgets)
|
|
? runtime.dashboard_config.widgets
|
|
: Array.isArray(runtime?.widgets)
|
|
? runtime.widgets
|
|
: [];
|
|
const runtimeWidgets = runtimeWidgetsRaw
|
|
.map((item: any) =>
|
|
String(typeof item === "string" ? item : item?.key || item?.id || "").trim()
|
|
)
|
|
.filter(Boolean);
|
|
const runtimeFields = asStringArray(runtime?.dashboard_config?.fields ?? runtime?.fields);
|
|
|
|
return {
|
|
role: runtimeRole,
|
|
status: "ACTIVE",
|
|
sidebarItems: runtimeSidebar,
|
|
tabs: runtimeTabs,
|
|
widgets: runtimeWidgets,
|
|
fields: runtimeFields,
|
|
verificationStatus:
|
|
String(
|
|
runtime?.verification_status || runtime?.user?.verification_status || ""
|
|
).toUpperCase() || undefined,
|
|
source: "dashboard-config",
|
|
};
|
|
}
|
|
|
|
let payload = await fetchJson(
|
|
`/api/config/dashboard/by-key/${encodeURIComponent(role)}?audience=EXTERNAL`
|
|
);
|
|
if (!payload) {
|
|
const listPayload = await fetchJson("/api/admin/dashboard-config?audience=EXTERNAL");
|
|
const rows = Array.isArray(listPayload)
|
|
? listPayload
|
|
: Array.isArray(listPayload?.items)
|
|
? listPayload.items
|
|
: [];
|
|
const matched = rows.find(
|
|
(row: any) => String(row?.role_key || row?.config_json?.role_key || "").toUpperCase() === role
|
|
);
|
|
if (matched) payload = matched;
|
|
}
|
|
const config = (payload?.config_json || payload || null) as Record<string, unknown> | null;
|
|
if (!config) return null;
|
|
const sidebarItems = asStringArray(
|
|
(config as any)?.sidebar_items ?? (config as any)?.sidebarItems
|
|
);
|
|
const tabs = asStringArray((config as any)?.tabs);
|
|
const widgetsRaw = Array.isArray((config as any)?.widgets) ? (config as any).widgets : [];
|
|
const widgets = widgetsRaw
|
|
.map((item: any) =>
|
|
String(typeof item === "string" ? item : item?.key || item?.id || "").trim()
|
|
)
|
|
.filter(Boolean);
|
|
const fields = asStringArray((config as any)?.fields);
|
|
return {
|
|
role,
|
|
status: payload?.is_active === false ? "INACTIVE" : "ACTIVE",
|
|
sidebarItems,
|
|
tabs,
|
|
widgets,
|
|
fields,
|
|
source: "dashboard-config",
|
|
};
|
|
}
|
|
|
|
function mergeSidebar(
|
|
role: RoleKey,
|
|
runtimeSidebar: string[],
|
|
verificationStatus?: string
|
|
): string[] {
|
|
const base = ROLE_BASED_SIDEBAR[role] || [
|
|
"My Dashboard",
|
|
"My Profile",
|
|
"Switch Services",
|
|
"Logout",
|
|
];
|
|
const fromRuntime = runtimeSidebar.filter(Boolean);
|
|
const source = fromRuntime.length > 0 ? fromRuntime : base;
|
|
const map = new Map<string, string>();
|
|
for (const item of source) {
|
|
const key = item.trim().toLowerCase();
|
|
if (!map.has(key)) map.set(key, item);
|
|
}
|
|
let merged = Array.from(map.values());
|
|
const status = String(verificationStatus || "").toUpperCase();
|
|
const approved = status === "APPROVED";
|
|
if (!approved && status) {
|
|
const restricted = new Set([
|
|
"my profile",
|
|
"help center",
|
|
"settings",
|
|
"verification",
|
|
"logout",
|
|
...(PROFESSIONAL_ROLE_SET.has(role) || role === "JOB_SEEKER"
|
|
? ["my portfolio", "credits"]
|
|
: []),
|
|
]);
|
|
merged = merged.filter((item) => restricted.has(item.trim().toLowerCase()));
|
|
}
|
|
return merged;
|
|
}
|
|
|
|
export default function RuntimeDashboardPage() {
|
|
const navigate = useNavigate();
|
|
const auth = useAuth();
|
|
const [hydrated, setHydrated] = createSignal(false);
|
|
const [role, setRole] = createSignal<RoleKey>("JOB_SEEKER");
|
|
const [activeSidebar, setActiveSidebar] = createSignal("My Dashboard");
|
|
const [activeTab, setActiveTab] = createSignal("overview");
|
|
const [userName, setUserName] = createSignal("User");
|
|
const [userId, setUserId] = createSignal("");
|
|
|
|
onMount(() => {
|
|
setHydrated(true);
|
|
const storedRole = getInitialRoleFromStorage();
|
|
setRole(storedRole);
|
|
setUserName(getNameFromStorage());
|
|
if (auth.user()) {
|
|
const u = auth.user()!;
|
|
if (u.full_name) setUserName(u.full_name);
|
|
if (u.id) setUserId(u.id);
|
|
if (u.active_role) setRole(normalizeRole(u.active_role));
|
|
}
|
|
});
|
|
|
|
createEffect(() => {
|
|
const u = auth.user();
|
|
if (u) {
|
|
if (u.full_name && userName() === "User") setUserName(u.full_name);
|
|
if (u.id && !userId()) setUserId(u.id);
|
|
if (u.active_role) setRole(normalizeRole(u.active_role));
|
|
}
|
|
});
|
|
|
|
const [bundle] = createResource(() => role(), loadRoleBundle);
|
|
|
|
const sidebarItems = createMemo(() =>
|
|
mergeSidebar(role(), bundle()?.sidebarItems || [], bundle()?.verificationStatus)
|
|
);
|
|
|
|
createEffect(() => {
|
|
const runtimeRole = bundle()?.role;
|
|
if (runtimeRole && runtimeRole !== role()) setRole(runtimeRole);
|
|
});
|
|
|
|
createEffect(() => {
|
|
const first = sidebarItems()[0] || "My Dashboard";
|
|
const current = activeSidebar();
|
|
const exists = sidebarItems().some((item) => item.toLowerCase() === current.toLowerCase());
|
|
if (!exists) setActiveSidebar(first);
|
|
});
|
|
|
|
const tabs = createMemo(() => {
|
|
const fromRuntime = bundle()?.tabs || [];
|
|
return fromRuntime.length > 0 ? fromRuntime : ["overview"];
|
|
});
|
|
|
|
createEffect(() => {
|
|
role();
|
|
const firstTab = tabs()[0] || "overview";
|
|
setActiveTab((prev) => (prev ? prev : firstTab));
|
|
});
|
|
|
|
const loading = createMemo(() => !hydrated() || bundle.loading);
|
|
const ready = createMemo(() => hydrated() && !bundle.loading);
|
|
|
|
const liveData = createMemo(() => {
|
|
const prefix = ROLE_PREFIXES[role()];
|
|
if (!prefix) return undefined;
|
|
return { userName: userName(), userId: userId(), rolePrefix: prefix };
|
|
});
|
|
|
|
const isRealPage = createMemo(() => {
|
|
const key = activeSidebar().toLowerCase();
|
|
if (BASE_REAL_PAGES.includes(key)) return true;
|
|
if (COMMON_REAL_PAGES.includes(key)) return true;
|
|
if (role() === "COMPANY" && COMPANY_REAL_PAGES.includes(key)) return true;
|
|
if (role() === "CUSTOMER" && CUSTOMER_REAL_PAGES.includes(key)) return true;
|
|
if (role() === "JOB_SEEKER" && JOB_SEEKER_REAL_PAGES.includes(key)) return true;
|
|
if (PROFESSIONAL_ROLE_SET.has(role()) && PROFESSIONAL_REAL_PAGES.includes(key)) return true;
|
|
return false;
|
|
});
|
|
|
|
return (
|
|
<RequireAuth>
|
|
<main style={{ "min-height": "100vh", background: "#F3F4F6" }}>
|
|
<Show when={loading()}>
|
|
<div style={cardStyle}>Loading dashboard…</div>
|
|
</Show>
|
|
|
|
<Show when={ready()}>
|
|
{/* ── Real pages: DashboardShell + actual components ── */}
|
|
<Show when={isRealPage()}>
|
|
<DashboardShell
|
|
sidebarItems={sidebarItems()}
|
|
activeSidebar={activeSidebar()}
|
|
onSidebarSelect={setActiveSidebar}
|
|
roleKey={role()}
|
|
userName={userName()}
|
|
>
|
|
<Switch>
|
|
<Match when={activeSidebar().toLowerCase() === "my dashboard"}>
|
|
<MyDashboardPage roleKey={role()} userName={userName()} />
|
|
</Match>
|
|
<Match when={activeSidebar().toLowerCase() === "my profile"}>
|
|
<ProfilePage roleKey={role()} />
|
|
</Match>
|
|
<Match when={activeSidebar().toLowerCase() === "my portfolio"}>
|
|
<PortfolioPage
|
|
roleKey={role()}
|
|
runtimeTabs={bundle()?.tabs || []}
|
|
runtimeFields={bundle()?.fields || []}
|
|
/>
|
|
</Match>
|
|
<Match when={activeSidebar().toLowerCase() === "verification"}>
|
|
<VerificationStatusPage roleKey={role()} onNavigate={setActiveSidebar} />
|
|
</Match>
|
|
<Match when={activeSidebar().toLowerCase() === "settings"}>
|
|
<SettingsPage />
|
|
</Match>
|
|
<Match when={activeSidebar().toLowerCase() === "credits"}>
|
|
<CreditsPage roleKey={role()} />
|
|
</Match>
|
|
<Match when={activeSidebar().toLowerCase() === "explore nxtgauge"}>
|
|
<ExploreServicesPage />
|
|
</Match>
|
|
<Match when={activeSidebar().toLowerCase() === "help center"}>
|
|
<HelpCenterDashboardPage roleKey={role()} />
|
|
</Match>
|
|
<Match when={activeSidebar().toLowerCase() === "switch services"}>
|
|
<SwitchServicesPage />
|
|
</Match>
|
|
<Match when={activeSidebar().toLowerCase() === "logout"}>
|
|
<LogoutPage />
|
|
</Match>
|
|
<Match when={role() === "COMPANY" && activeSidebar().toLowerCase() === "jobs"}>
|
|
<CompanyJobsPage />
|
|
</Match>
|
|
<Match
|
|
when={role() === "COMPANY" && activeSidebar().toLowerCase() === "applications"}
|
|
>
|
|
<CompanyApplicationsPage />
|
|
</Match>
|
|
<Match
|
|
when={
|
|
role() === "COMPANY" &&
|
|
activeSidebar().toLowerCase() === "shortlisted candidates"
|
|
}
|
|
>
|
|
<CompanyShortlistedCandidatesPage />
|
|
</Match>
|
|
<Match
|
|
when={
|
|
role() === "CUSTOMER" && activeSidebar().toLowerCase() === "my requirements"
|
|
}
|
|
>
|
|
<CustomerRequirementsPage />
|
|
</Match>
|
|
<Match
|
|
when={
|
|
role() === "CUSTOMER" && activeSidebar().toLowerCase() === "received responses"
|
|
}
|
|
>
|
|
<CustomerResponsesPage mode="received" />
|
|
</Match>
|
|
<Match
|
|
when={
|
|
role() === "CUSTOMER" &&
|
|
activeSidebar().toLowerCase() === "shortlisted responses"
|
|
}
|
|
>
|
|
<CustomerResponsesPage mode="shortlisted" />
|
|
</Match>
|
|
<Match
|
|
when={
|
|
role() === "JOB_SEEKER" && activeSidebar().toLowerCase() === "my applications"
|
|
}
|
|
>
|
|
<JobSeekerApplicationsPage />
|
|
</Match>
|
|
<Match when={role() === "JOB_SEEKER" && activeSidebar().toLowerCase() === "jobs"}>
|
|
<JobSeekerJobsPage />
|
|
</Match>
|
|
<Match
|
|
when={role() === "JOB_SEEKER" && activeSidebar().toLowerCase() === "saved jobs"}
|
|
>
|
|
<JobSeekerSavedJobsPage />
|
|
</Match>
|
|
<Match
|
|
when={
|
|
PROFESSIONAL_ROLE_SET.has(role()) && activeSidebar().toLowerCase() === "leads"
|
|
}
|
|
>
|
|
<ProfessionalLeadsPage roleKey={role()} />
|
|
</Match>
|
|
<Match
|
|
when={
|
|
PROFESSIONAL_ROLE_SET.has(role()) &&
|
|
activeSidebar().toLowerCase() === "my responses"
|
|
}
|
|
>
|
|
<ProfessionalResponsesPage roleKey={role()} />
|
|
</Match>
|
|
</Switch>
|
|
</DashboardShell>
|
|
</Show>
|
|
|
|
{/* ── All other views: DashboardDesignPreview mock ── */}
|
|
<Show when={!isRealPage()}>
|
|
<DashboardDesignPreview
|
|
status={bundle()?.status ?? "ACTIVE"}
|
|
sidebarItems={sidebarItems()}
|
|
activeSidebar={activeSidebar()}
|
|
onSidebarSelect={setActiveSidebar}
|
|
tabs={tabs()}
|
|
activeTab={activeTab()}
|
|
onTabSelect={setActiveTab}
|
|
widgets={bundle()?.widgets || []}
|
|
fields={bundle()?.fields || []}
|
|
mode="customer_external"
|
|
roleKey={role()}
|
|
exploreRoles={EXPLORE_ROLES}
|
|
hidePreviewHeader
|
|
liveData={liveData()}
|
|
/>
|
|
</Show>
|
|
</Show>
|
|
</main>
|
|
</RequireAuth>
|
|
);
|
|
}
|
|
|
|
const cardStyle = {
|
|
border: "1px solid #E5E7EB",
|
|
"border-radius": "12px",
|
|
padding: "16px",
|
|
background: "#fff",
|
|
color: "#111827",
|
|
} as const;
|