/* Pages: Survey (single page), Clinic checklist (stepper + draft), Thank You */ const { useState: useSt, useEffect: useEf, useRef: useRf } = React; function SurveyPage() { return (
window.navigate('/')}>← Về trang webinar
); } const DRAFT_KEY = 'vtc_clinic_draft_v1'; function ClinicPage() { const schema = window.VTC.clinicSchema; const sections = schema.sections; const [step, setStep] = useSt(0); const [values, setValues] = useSt(() => { try { return JSON.parse(localStorage.getItem(DRAFT_KEY)) || {}; } catch { return {}; } }); const [errors, setErrors] = useSt({}); const [busy, setBusy] = useSt(false); const [savedAt, setSavedAt] = useSt(null); const top = useRf(null); // persist draft useEf(() => { const id = setTimeout(() => { try { localStorage.setItem(DRAFT_KEY, JSON.stringify(values)); setSavedAt(Date.now()); } catch {} }, 400); return () => clearTimeout(id); }, [values]); const onChange = (id, v) => { setValues((p) => ({ ...p, [id]: v })); setErrors((p) => (p[id] ? { ...p, [id]: '' } : p)); }; const cur = sections[step]; const pct = Math.round(((step + 1) / sections.length) * 100); const validateStep = () => { const { errors: er, firstBad } = validateSections([cur], values); setErrors(er); if (firstBad) { window.toast({ kind: 'err', title: 'Còn mục chưa hoàn tất', sub: 'Vui lòng kiểm tra các ô tô đỏ.' }); const el = document.getElementById('f_' + firstBad); if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 150, behavior: 'smooth' }); return false; } return true; }; const goTop = () => { if (top.current) window.scrollTo({ top: top.current.getBoundingClientRect().top + window.scrollY - 90, behavior: 'smooth' }); }; const next = () => { if (validateStep()) { setStep((s) => Math.min(s + 1, sections.length - 1)); goTop(); } }; const back = () => { setStep((s) => Math.max(s - 1, 0)); goTop(); }; const jump = (i) => { if (i <= step || validateStep()) { setStep(i); goTop(); } }; async function submit() { const { errors: er, firstBad } = validateSections(sections, values); setErrors(er); if (firstBad) { // jump to the section containing the first bad field const idx = sections.findIndex((s) => s.fields.some((f) => f.id === firstBad)); setStep(idx >= 0 ? idx : step); window.toast({ kind: 'err', title: 'Còn mục chưa hoàn tất', sub: 'Đã chuyển tới phần cần bổ sung.' }); return; } setBusy(true); try { await submitForm(schema.formName, { ...values, __type: 'bangkiem' }); localStorage.removeItem(DRAFT_KEY); window.navigate('/cam-on?type=bangkiem'); } catch { setBusy(false); window.toast({ kind: 'err', title: 'Gửi chưa thành công', sub: 'Dữ liệu của bạn vẫn được lưu nháp.' }); } } const last = step === sections.length - 1; return (
window.navigate('/')}>← Về trang webinar
Lead-gen · ~5–7 phút

{schema.title}

{schema.description}

{sections.map((s, i) => ( ))}
Phần {cur.letter} / {sections[sections.length - 1].letter} — {cur.title} {savedAt ? 'Đã lưu nháp' : 'Tự lưu nháp'}
{last ? : }

Bản nháp được lưu trên trình duyệt của bạn — có thể đóng và quay lại sau.

); } function TrialPage() { const feats = ['Hồ sơ bệnh án điện tử cho bệnh nhân cận thị', 'Biểu đồ tiến triển trục nhãn cầu & khúc xạ', 'Quản lý liệu trình Ortho-K / Atropine', 'Báo cáo phụ huynh mang thương hiệu phòng khám']; return (
window.navigate('/')}>← Về trang webinar
[ Ảnh app — màn hình
hồ sơ & biểu đồ AL ]

Bạn nhận được gì?

    {feats.map((f) =>
  • {f}
  • )}

Công cụ hỗ trợ quyết định lâm sàng, không thay thế chẩn đoán của bác sĩ.

); } function ThankYou({ query }) { const type = query.get('type') || 'dangky'; const W = window.VTC.WEBINAR; const MAP = { dangky: { title: 'Đăng ký thành công!', sub: 'Hẹn gặp bạn tại Webinar Kiểm soát cận thị. Chúng tôi đã gửi xác nhận và sẽ nhắc lịch trước giờ diễn ra.', next: { h: 'Bước tiếp theo', items: [ ['video', 'Link tham dự Zoom', CẦN LINK ZOOM], ['calendar', 'Thêm vào lịch (.ics)', CẦN FILE .ICS], ['doc', 'Điền trước Bảng kiểm nhu cầu để nhận tư vấn lộ trình riêng', window.navigate('/bang-kiem-phong-kham')}>Mở bảng kiểm], ]}, }, khaosat: { title: 'Cảm ơn bạn đã hoàn tất khảo sát!', sub: 'Quà tặng đang trên đường tới bạn. VietCanThi sẽ gửi bộ tài liệu trong vòng 48h làm việc.', next: { h: 'Nhận quà của bạn', items: [ ['download', 'Trọn bộ quy trình setup KSCT (PDF)', CẦN LINK PDF], ['key', 'Kích hoạt tài khoản dùng thử phần mềm', window.navigate('/trai-nghiem-phan-mem')}>Đăng ký trải nghiệm], ]}, }, bangkiem: { title: 'Đã nhận bảng kiểm của bạn!', sub: 'Đội ngũ VietCanThi sẽ phân tích hiện trạng và liên hệ đề xuất lộ trình setup/nâng cấp phù hợp với đơn vị của bạn.', next: { h: 'Trong lúc chờ', items: [ ['key', 'Trải nghiệm ngay phần mềm quản lý cận thị', window.navigate('/trai-nghiem-phan-mem')}>Đăng ký trải nghiệm], ['phone', 'Cần trao đổi gấp? Liên hệ hotline', CẦN HOTLINE THẬT], ]}, }, dungthu: { title: 'Tài khoản trải nghiệm đã sẵn sàng!', sub: 'Bạn có thể mở phần mềm VietCanThi để bắt đầu số hóa hồ sơ và theo dõi tiến triển cận thị.', next: { h: 'Bắt đầu ngay', items: [ ['monitor', 'Mở phần mềm VietCanThi', Mở ngay], ['doc', 'Xem hướng dẫn sử dụng nhanh', SẮP RA MẮT], ]}, }, }; const c = MAP[type] || MAP.dangky; return (
VietCanThi · {W.dateText}

{c.title}

{c.sub}

{c.next.h}

{c.next.items.map((it, i) => (
{it[1]} {it[2]}
))}
); } Object.assign(window, { SurveyPage, ClinicPage, TrialPage, ThankYou });