nxtgauge-admin-solid/src/routes/admin/onboarding-schemas/new.tsx

104 lines
4 KiB
TypeScript
Raw Normal View History

import { A, useNavigate } from '@solidjs/router';
import { createMemo, createSignal } 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';
export default function NewOnboardingSchemaPage() {
const navigate = useNavigate();
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<OnboardingField[]>(createDefaultFields('company'));
const [saving, setSaving] = createSignal(false);
const [error, setError] = createSignal('');
const payload = createMemo(() => ({
title: title(),
roleKey: roleKey(),
description: description(),
finalSubmissionMessage: finalSubmissionMessage(),
steps: buildStepsFromFields(selectedFields(), stepCount()),
}));
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 response = await fetch(`${API}/api/admin/onboarding-config`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ schema_json: payload(), is_active: false }),
});
const body = await response.json();
if (!response.ok) throw new Error(body?.message || 'Failed to create onboarding flow');
navigate(`/admin/onboarding-schemas/${body.id || body.schema?.id}`);
} catch (nextError: any) {
setError(nextError?.message || 'Failed to create onboarding flow');
} finally {
setSaving(false);
}
};
return (
<AdminShell>
<OnboardingManagementTabs />
<div class="page-hero-card page-actions">
<div>
<h1 class="page-title">Create Onboarding Flow</h1>
<p class="page-subtitle">Build one onboarding flow at a time. Start with role, questions, and final submission message.</p>
</div>
<A class="btn" href="/admin/onboarding-schemas">Back to Onboarding Management</A>
</div>
<div class="field-grid-2" style="margin-bottom:16px">
<div class="card"><p class="kv-label">Role</p><p class="kv-value">{roleKey().replace(/_/g, ' ').toUpperCase()}</p></div>
<div class="card"><p class="kv-label">Steps</p><p class="kv-value">{stepCount()}</p></div>
<div class="card" style="grid-column:1 / -1"><p class="kv-label">Questions</p><p class="kv-value">{selectedFields().length}</p></div>
</div>
<OnboardingFlowBuilder
title={title()}
roleKey={roleKey()}
description={description()}
finalSubmissionMessage={finalSubmissionMessage()}
stepCount={stepCount()}
selectedFields={selectedFields()}
saving={saving()}
error={error()}
primaryLabel="Create Onboarding Flow"
onChange={handleChange}
onSubmit={handleSubmit}
/>
</AdminShell>
);
}