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: 'Academic standing', type: 'select', options: knowledgeLevels.length ? knowledgeLevels : [ { value: 'sophomore', label: 'Sophomore (2nd year)' }, { value: 'junior', label: 'Junior (3rd year — internships)' }, { value: 'senior', label: 'Senior (4th year — FT / entry-level)' }, { value: 'grad', label: 'Graduate / recent grad' }, ], }, { key: 'timezone', label: 'Time zone', type: 'select', options: timezones.length ? timezones : [{ value: 'UTC', label: 'UTC' }], }, ], }, { title: 'Career focus & setup', fields: [ { key: 'cyber_role', label: 'Your career focus', type: 'select', options: ['Internship search', 'Full-time / entry-level', 'Both internship and FT', 'Career exploration', 'Return offer conversion', 'Industry switch / pivot', 'Graduate school path', 'Other'] }, { key: 'organization_type', label: 'Primary search channel', type: 'select', options: ['Handshake', 'LinkedIn', 'Company career pages', 'Career fairs / campus recruiting', 'Referrals / alumni', 'Hybrid (multiple channels)'] }, ], }, { title: 'Targets & tools', fields: [ { key: 'primary_domains', label: 'Major + target industries / roles (comma-separated)', type: 'text', placeholder: 'e.g. Business Analytics; marketing analytics, finance internship, consulting' }, { key: 'certifications', label: 'Skills & tools to highlight (comma-separated)', type: 'text', placeholder: 'e.g. Excel, SQL, Python, Canva, Tableau' }, { key: 'tools_stack', label: 'Apps you use for the search (comma-separated)', type: 'text', placeholder: 'e.g. Handshake, LinkedIn, Notion, Google Sheets' }, ], }, { title: 'Goals & preferences', fields: [ { key: 'compliance_focus', label: 'Target term + constraints', type: 'text', placeholder: 'e.g. Summer 2027; Denver/remote; paid only; 6 hrs/week for applications' }, { key: 'current_goals', label: 'Current goals', type: 'textarea', placeholder: 'Land a summer internship, improve resume, prep for interviews...' }, { key: 'learning_preferences', label: 'How you like to work the search', type: 'text', placeholder: 'Daily apply blocks, weekend deep work, career-fair focused...' }, { key: 'advisor_notes', label: 'About Me / career narrative', type: 'textarea', placeholder: 'Who you are, what you want employers to know, and any LinkedIn About draft. Advisors can expand this into employer-readable LinkedIn copy.', }, ], }, ]; }; 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 (