import { A, useNavigate } from '@solidjs/router'; import { createMemo, createSignal, onMount } from 'solid-js'; import AdminShell from '~/components/AdminShell'; import OnboardingManagementTabs from '~/components/admin/OnboardingManagementTabs'; import OnboardingFlowBuilder, { buildStepsFromFields, createDefaultFields, type OnboardingField, } from '~/components/admin/OnboardingFlowBuilder'; const API = '/api/gateway'; const FRONTEND_PREVIEW_BASE = String(import.meta.env.VITE_FRONTEND_PREVIEW_URL || 'http://localhost:3001').replace(/\/+$/, ''); function normalizeRoleKey(value: string): string { return String(value || '').trim().toUpperCase().replace(/[-\s]+/g, '_'); } export default function NewOnboardingSchemaPage() { const navigate = useNavigate(); const [roleMap, setRoleMap] = createSignal>({}); const [title, setTitle] = createSignal(''); const [roleKey, setRoleKey] = createSignal('company'); const [description, setDescription] = createSignal(''); const [finalSubmissionMessage, setFinalSubmissionMessage] = createSignal('Your onboarding has been submitted for review. We will notify you once it is approved.'); const [stepCount, setStepCount] = createSignal(2); const [selectedFields, setSelectedFields] = createSignal(createDefaultFields('company')); const [saving, setSaving] = createSignal(false); const [error, setError] = createSignal(''); onMount(async () => { try { const res = await fetch(`${API}/api/admin/roles?audience=EXTERNAL`); if (!res.ok) return; const payload = await res.json(); const rows = Array.isArray(payload) ? payload : (payload.roles || []); const map: Record = {}; rows .filter((item: any) => String(item?.audience || '').toUpperCase() === 'EXTERNAL') .forEach((item: any) => { const key = String(item?.key || '').trim().toUpperCase(); if (!key) return; map[key] = String(item?.id || ''); }); setRoleMap(map); } catch { setRoleMap({}); } }); const payload = createMemo(() => ({ title: title(), roleKey: roleKey(), description: description(), finalSubmissionMessage: finalSubmissionMessage(), steps: buildStepsFromFields(selectedFields(), stepCount()), })); const livePreviewUrl = createMemo(() => { const role = normalizeRoleKey(roleKey()); if (!role) return ''; return `${FRONTEND_PREVIEW_BASE}/onboarding?${new URLSearchParams({ roleKey: role }).toString()}`; }); const handleChange = (next: { title?: string; roleKey?: string; description?: string; finalSubmissionMessage?: string; stepCount?: number; selectedFields?: OnboardingField[]; }) => { if (typeof next.title === 'string') setTitle(next.title); if (typeof next.description === 'string') setDescription(next.description); if (typeof next.finalSubmissionMessage === 'string') setFinalSubmissionMessage(next.finalSubmissionMessage); if (typeof next.stepCount === 'number') setStepCount(next.stepCount); if (Array.isArray(next.selectedFields)) setSelectedFields(next.selectedFields); if (typeof next.roleKey === 'string') { setRoleKey(next.roleKey); setSelectedFields(createDefaultFields(next.roleKey)); } }; const handleSubmit = async () => { try { setSaving(true); setError(''); const normalizedRole = normalizeRoleKey(roleKey()); const roleId = roleMap()[normalizedRole]; if (!roleId) { throw new Error('Please choose a valid role before creating this flow.'); } const response = await fetch(`${API}/api/admin/onboarding-config`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ role_id: roleId, schema_json: payload() }), }); const body = await response.json(); if (!response.ok) throw new Error(body?.message || 'Failed to create onboarding flow'); navigate(`/admin/onboarding-schemas/${body.role_id || roleId}`); } catch (nextError: any) { setError(nextError?.message || 'Failed to create onboarding flow'); } finally { setSaving(false); } }; return (

Create Onboarding Flow

Create one onboarding form at a time. Pick the role, choose the questions, set the steps, and write the final success message.

Back to Onboarding Management

Role

{roleKey().replace(/_/g, ' ').toUpperCase()}

Steps

{stepCount()}

Questions

{selectedFields().length}

); }