diff --git a/src/components/dashboard/RoleWizard.tsx b/src/components/dashboard/RoleWizard.tsx
index 4911612..58eea28 100644
--- a/src/components/dashboard/RoleWizard.tsx
+++ b/src/components/dashboard/RoleWizard.tsx
@@ -171,7 +171,10 @@ export default function RoleWizard(props: Props) {
{/* ── basic ─────────────────────────────────────────────── */}
-
+
+ This step has no fields configured yet.
+
+ 0}>
{(field) => (
@@ -212,7 +215,10 @@ export default function RoleWizard(props: Props) {
{/* ── documents ─────────────────────────────────────────── */}
-
+
+ This step has no documents configured yet.
+
+ 0}>
{(field) => (
@@ -260,7 +266,10 @@ export default function RoleWizard(props: Props) {
{/* ── portfolio ─────────────────────────────────────────── */}
-
+
+ This step has no fields configured yet.
+
+ 0}>
{(field) => (
diff --git a/src/components/dashboard/widgets/ProfileCompletionWidget.tsx b/src/components/dashboard/widgets/ProfileCompletionWidget.tsx
index fa58625..d322d67 100644
--- a/src/components/dashboard/widgets/ProfileCompletionWidget.tsx
+++ b/src/components/dashboard/widgets/ProfileCompletionWidget.tsx
@@ -2,69 +2,43 @@ import { createResource, Show } from 'solid-js';
import { User } from 'lucide-solid';
import DashboardWidget from './DashboardWidget';
import type { RoleKey } from '../RoleDashboardShared';
-import { PROFESSIONAL_ROLE_SET, ROLE_PREFIXES } from '../RoleDashboardShared';
-import { fetchProfile } from '~/lib/api';
-
-const API = '';
-
-async function apiFetch(path: string, opts?: RequestInit) {
- const token =
- typeof window !== 'undefined'
- ? window.sessionStorage.getItem('nxtgauge_access_token') || ''
- : '';
- return fetch(`${API}${path}`, {
- ...opts,
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- ...(token ? { Authorization: `Bearer ${token}` } : {}),
- ...(opts?.headers ?? {}),
- },
- });
-}
+import { apiFetch } from '~/lib/api';
+import { fetchOnboardingSchemaForRole } from '~/lib/runtime/storage';
type Props = {
roleKey: RoleKey;
};
-async function fetchProfileData(roleKey: RoleKey) {
- if (PROFESSIONAL_ROLE_SET.has(roleKey) || roleKey === 'COMPANY' || roleKey === 'CUSTOMER') {
- const prefix = ROLE_PREFIXES[roleKey];
- if (!prefix) return null;
- try {
- return await fetchProfile(prefix);
- } catch {
- return null;
- }
- }
- if (roleKey === 'JOB_SEEKER') {
- const res = await apiFetch('/api/jobseeker/profile/me');
- if (!res.ok) return null;
- return await res.json();
- }
- return null;
+// Same source of truth the wizard itself uses (fetchOnboardingSchemaForRole)
+// and the same storage the wizard writes to (/api/profile?roleKey=...) — so
+// this can never drift from what fields actually exist / get saved for a role,
+// unlike a hardcoded per-role field list.
+async function fetchCompletionInputs(roleKey: RoleKey) {
+ const [schema, profileRes] = await Promise.all([
+ fetchOnboardingSchemaForRole(roleKey),
+ apiFetch(`/api/profile?roleKey=${roleKey}`).catch(() => null),
+ ]);
+ const requiredFieldIds = (schema?.steps ?? [])
+ .filter((step) => step.type !== 'review')
+ .flatMap((step) => step.fields)
+ .filter((field) => field.required)
+ .map((field) => field.id);
+ const profileData = profileRes?.profile_data ?? {};
+ return { requiredFieldIds, profileData };
}
-const PROFILE_FIELDS: Record = {
- COMPANY: ['company_name', 'industry', 'description', 'website', 'contact_email'],
- CUSTOMER: ['full_name', 'location', 'phone', 'email'],
- JOB_SEEKER: ['full_name', 'location', 'summary', 'skills', 'experience_years'],
- PROFESSIONAL: ['full_name', 'headline', 'bio', 'location', 'skills'],
-};
-
export default function ProfileCompletionWidget(props: Props) {
- const [profile] = createResource(() => props.roleKey, fetchProfileData);
+ const [data] = createResource(() => props.roleKey, fetchCompletionInputs);
const completion = () => {
- const p = profile();
- if (!p) return { filled: 0, total: 5, pct: 0 };
- const fields = PROFILE_FIELDS[props.roleKey] || PROFILE_FIELDS['PROFESSIONAL'];
+ const d = data();
+ if (!d || d.requiredFieldIds.length === 0) return { filled: 0, total: 0, pct: 0 };
let filled = 0;
- for (const field of fields) {
- const val = (p as any)[field];
+ for (const id of d.requiredFieldIds) {
+ const val = (d.profileData as any)[id];
if (val !== null && val !== undefined && String(val).trim() !== '') filled++;
}
- const total = fields.length;
+ const total = d.requiredFieldIds.length;
const pct = total > 0 ? Math.round((filled / total) * 100) : 0;
return { filled, total, pct };
};
@@ -79,11 +53,11 @@ export default function ProfileCompletionWidget(props: Props) {
return (
}
>
-
+