import React, { useState, useEffect, useMemo } from 'react'; import { X, ChevronLeft, ChevronRight, Check } from 'lucide-react'; import { useAppConfig } from '../contexts/AppConfigContext'; const buildSteps = (config) => { const knowledgeLevels = (config?.login?.knowledge_levels || config?.login?.academic_stages || []) .filter((o) => o.value) .map((o) => ({ value: o.value, label: o.label })); const timezones = (config?.login?.timezones || []) .filter((o) => o.value) .map((o) => ({ value: o.value, label: o.label })); return [ { title: 'Background', fields: [ { key: 'knowledge_level', label: 'Learner stage', type: 'select', options: knowledgeLevels.length ? knowledgeLevels : [ { value: 'hs_senior', label: 'High school senior' }, { value: 'transfer', label: 'Community college / transfer' }, { value: 'returning_adult', label: 'Returning adult / mid-career' }, ], }, { key: 'timezone', label: 'Time zone', type: 'select', options: timezones.length ? timezones : [{ value: 'UTC', label: 'UTC' }], }, ], }, { title: 'Path & modality', fields: [ { key: 'cyber_role', label: 'Your college search path', type: 'select', options: [ 'High school / traditional', 'Returning adult / online', 'Both / exploring', 'Transfer pathway', 'Graduate / professional school later', 'Other', ], }, { key: 'organization_type', label: 'Preferred learning modality', type: 'select', options: [ 'On-campus residential', 'Commuter campus', 'Fully online', 'Hybrid / evening', 'Community college first', 'Undecided / comparing', ], }, ], }, { title: 'Goals & majors', fields: [ { key: 'primary_domains', label: 'Interests / majors / programs (comma-separated)', type: 'text', placeholder: 'e.g. Nursing, business, CS, education, undecided STEM', }, { key: 'certifications', label: 'Credentials or prior learning to count (comma-separated)', type: 'text', placeholder: 'e.g. AA degree, military training, certificates, AP/IB, CLEP', }, { key: 'tools_stack', label: 'Tools you use for the search (comma-separated)', type: 'text', placeholder: 'e.g. Common App, College Scorecard, Notion, Google Sheets', }, ], }, { title: 'Budget, access & story', fields: [ { key: 'compliance_focus', label: 'Budget, location & accommodations', type: 'text', placeholder: 'e.g. Net price under $15k/yr; Colorado or online; ADHD accommodations; no meal plan needed', }, { key: 'current_goals', label: 'Current college goals', type: 'textarea', placeholder: 'Build a shortlist, estimate aid, check Disability Services, finish applications by...', }, { key: 'learning_preferences', label: 'How you like to work the search', type: 'text', placeholder: 'Weekend research blocks, counselor meetings, family decision nights...', }, { key: 'advisor_notes', label: 'About you / college narrative', type: 'textarea', placeholder: 'Who you are, what you want schools to know, work/family context, and any essay themes. Advisors will not invent achievements.', }, ], }, ]; }; const initFormFromProfile = (steps, profile) => { const init = {}; steps.forEach((s) => s.fields.forEach((f) => { const val = profile[f.key]; if (Array.isArray(val)) init[f.key] = val.join(', '); else if (val) init[f.key] = val; })); return init; }; const ProfileWalkthrough = ({ authToken, onClose, existingProfile }) => { const { config } = useAppConfig(); const steps = useMemo(() => buildSteps(config), [config]); const [step, setStep] = useState(0); const [formData, setFormData] = useState({}); const [saving, setSaving] = useState(false); const [loading, setLoading] = useState(true); useEffect(() => { let cancelled = false; const fetchProfile = async () => { try { const resp = await fetch(`${process.env.REACT_APP_API_URL}/api/users/me/profile`, { headers: { 'Authorization': `Bearer ${authToken}` }, }); if (resp.ok && !cancelled) { const profile = await resp.json(); setFormData(initFormFromProfile(steps, profile)); } } catch (e) { if (!cancelled && existingProfile) { setFormData(initFormFromProfile(steps, existingProfile)); } } finally { if (!cancelled) setLoading(false); } }; fetchProfile(); return () => { cancelled = true; }; }, [authToken, existingProfile, steps]); const handleChange = (key, value) => setFormData((prev) => ({ ...prev, [key]: value })); const saveProfile = async () => { const payload = { ...formData }; ['primary_domains', 'certifications', 'tools_stack'].forEach((k) => { if (typeof payload[k] === 'string') { payload[k] = payload[k].split(',').map((s) => s.trim()).filter(Boolean); } }); const hasData = Object.values(payload).some((v) => (Array.isArray(v) ? v.length > 0 : Boolean(v)) ); if (!hasData) return; try { await fetch(`${process.env.REACT_APP_API_URL}/api/users/me/profile`, { method: 'PUT', headers: { 'Authorization': `Bearer ${authToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }); } catch (e) { console.error('Failed to save profile:', e); } }; const handleSave = async () => { setSaving(true); await saveProfile(); setSaving(false); onClose(); }; const handleClose = async () => { await saveProfile(); onClose(); }; const currentStep = steps[step]; const isLast = step === steps.length - 1; const renderSelectOptions = (options) => options.map((o) => { if (o && typeof o === 'object' && o.value != null) { return ; } return ; }); return (