const { useState } = React;
const CONTACT_EMAIL = 'hello@developerark.com';
const getSteps = () => [S.step1, S.step2, S.step3, S.step4];
const OrderFormPage = ({ navigate }) => {
const STEPS = getSteps();
const [step, setStep] = useState(0);
const [form, setForm] = useState({
package: '',
projectName: '', projectUrl: '', projectType: '',
stage: '', techStack: '', teamSize: '',
hasCI: '', hasBackup: '', hasSecurity: '',
contactEmail: '', notes: '',
});
const buildFitCheckEmailHref = () => {
const pkg = (window.PACKAGES || []).find(p => p.id === form.package);
const subject = `Launch Ark fit check request — ${form.projectName || 'Unnamed project'}`;
const lines = [
'Launch Ark fit check',
'',
`Package: ${pkg ? pkg.name : form.package || '(not selected)'}`,
`Project name: ${form.projectName || '(not provided)'}`,
`Project URL: ${form.projectUrl || '(not provided)'}`,
`Project type: ${form.projectType || '(not provided)'}`,
`Stage: ${form.stage || '(not provided)'}`,
`Tech stack: ${form.techStack || '(not provided)'}`,
`Team size: ${form.teamSize || '(not provided)'}`,
`CI/CD: ${form.hasCI || '(not provided)'}`,
`Backup plan: ${form.hasBackup || '(not provided)'}`,
`Security baseline: ${form.hasSecurity || '(not provided)'}`,
`Contact email: ${form.contactEmail || '(not provided)'}`,
`Notes: ${form.notes || '(none)'}`,
'',
'Fit check only. No payment is requested here.',
'Do not send secrets, API keys, credentials, or private repository access.',
'Scope and price should be confirmed by email before any work starts.',
];
return `mailto:${CONTACT_EMAIL}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(lines.join('\n'))}`;
};
const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
const canNext = [
() => form.package !== '',
() => form.projectName && form.projectType && form.stage,
() => form.contactEmail && form.contactEmail.includes('@'),
() => true,
][step];
return (
{/* Header */}
{S.order_label}
{S.order_h1}
{S.order_sub}
{S.order_no_secrets_label}
{S.order_no_secrets_body}
FIT CHECK ONLY В· NO PAYMENT AT THIS STAGE В· EMAIL CONFIRMATION REQUIRED
{/* Step indicator */}
{STEPS.map((s, i) => (
{i < step ? 'вњ“' : i + 1}
{s}
{i < STEPS.length - 1 && (
)}
))}
{/* Step content */}
{step === 0 && }
{step === 1 && }
{step === 2 && }
{step === 3 && }
{/* Navigation */}
{step > 0 && (
setStep(s => s - 1)}>{S.back}
)}
{step < STEPS.length - 1 ? (
setStep(s => s + 1)}>{S.continue}
) : (
{S.submit}
)}
{step === 3 && (
Fit check only. No payment is requested here. Use the email draft to contact {CONTACT_EMAIL}. Do not submit secrets, API keys, credentials, or private repository access.
)}
);
};
const FormField = ({ label, hint, children, required }) => (
{label} {required && * }
{hint &&
{hint}
}
{children}
);
const Input = ({ value, onChange, placeholder, type = 'text' }) => (
onChange(e.target.value)}
placeholder={placeholder}
style={{
width: '100%', background: T.surface, border: `1px solid ${T.border}`,
borderRadius: 6, padding: '9px 14px', color: T.text,
fontFamily: T.sans, fontSize: 14, outline: 'none', boxSizing: 'border-box',
}}
/>
);
const Select = ({ value, onChange, options, placeholder }) => (
onChange(e.target.value)}
style={{
width: '100%', background: T.surface, border: `1px solid ${T.border}`,
borderRadius: 6, padding: '9px 14px', color: value ? T.text : T.muted,
fontFamily: T.sans, fontSize: 14, outline: 'none', appearance: 'none',
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8L1 3h10z'/%3E%3C/svg%3E")`,
backgroundRepeat: 'no-repeat', backgroundPosition: 'right 14px center',
}}
>
{placeholder}
{options.map(o => {o.label || o} )}
);
const RadioGroup = ({ value, onChange, options }) => (
{options.map(o => (
onChange(o.value)}
style={{
padding: '7px 16px', borderRadius: 6, cursor: 'pointer',
fontFamily: T.sans, fontSize: 13.5, fontWeight: value === o.value ? 600 : 400,
background: value === o.value ? T.accentSubtle : T.surface,
border: `1px solid ${value === o.value ? T.accentDim : T.border}`,
color: value === o.value ? T.accent : T.muted,
transition: 'all 0.12s',
}}>
{o.label}
))}
);
const Step0 = ({ form, set, navigate }) => (
{S.order_choose_pkg}
{S.order_not_sure} navigate('pricing')} style={{ background: 'none', border: 'none', color: T.accent, cursor: 'pointer', fontFamily: T.sans, fontSize: 14, padding: 0 }}>{S.order_compare}
{(window.PACKAGES || []).map(pkg => (
set('package', pkg.id)} style={{
display: 'flex', justifyContent: 'space-between', alignItems: 'center',
background: form.package === pkg.id ? T.accentSubtle : T.surface,
border: `1px solid ${form.package === pkg.id ? T.accentDim : T.border}`,
borderRadius: 8, padding: '16px 20px', cursor: 'pointer', transition: 'all 0.12s',
textAlign: 'left',
}}>
{pkg.name}
{pkg.tagline} {pkg.forWho}
{pkg.price}
))}
);
const Step1 = ({ form, set }) => (
{S.order_project_title}
set('projectName', v)} placeholder={S.f_pkg_ph} />
set('projectUrl', v)} placeholder={S.f_url_ph} />
set('projectType', v)} placeholder={S.f_select_type}
options={[S.f_web_app, S.f_mobile, S.f_api, S.f_cli, S.f_data, S.f_internal, S.f_other]} />
set('stage', v)} options={[
{ value: 'pre-launch', label: S.f_pre },
{ value: 'launched', label: S.f_launched },
{ value: 'production', label: S.f_prod },
{ value: 'legacy', label: S.f_legacy },
]} />
set('techStack', v)} placeholder="e.g. Node.js, PostgreSQL" />
set('teamSize', v)} options={[
{ value: '1', label: S.f_solo },
{ value: '2-5', label: '2–5' },
{ value: '6-15',label: '6–15' },
{ value: '16+', label: '16+' },
]} />
set('hasCI', v)} options={[{ value: 'yes', label: S.f_yes }, { value: 'no', label: S.f_no }, { value: 'partial', label: S.f_partial }]} />
set('hasBackup', v)} options={[{ value: 'yes', label: S.f_yes }, { value: 'no', label: S.f_no }, { value: 'partial', label: S.f_partial }]} />
set('hasSecurity', v)} options={[{ value: 'yes', label: S.f_yes }, { value: 'no', label: S.f_no }, { value: 'partial', label: S.f_partial }]} />
);
const Step2 = ({ form, set }) => (
);
const Step3 = ({ form }) => {
const pkg = (window.PACKAGES || []).find(p => p.id === form.package);
const rows = [
[S.review_package, pkg ? pkg.name : '—'],
[S.review_project, form.projectName || '—'],
[S.review_type, form.projectType || '—'],
[S.review_stage, form.stage || '—'],
[S.review_stack, form.techStack || '—'],
[S.review_team, form.teamSize || '—'],
[S.review_email, form.contactEmail || '—'],
];
return (
{S.order_review_title}
{S.order_review_sub}
{rows.map(([k, v], i) => (
{k}
{v}
))}
{S.order_confirm_no_secrets} {S.order_confirm_keys} .
);
};
window.OrderFormPage = OrderFormPage;