// onboarding.jsx — Merchant QRIS onboarding wizard (hibank DS)
function MerchantOnboarding({ onBack, onComplete, primary, secondary }) {
const TEAL = primary || '#0056D2',ORANGE = secondary || '#cf5a27',DARK = '#001F5B';
const [step, setStep] = React.useState(0);
const [data, setData] = React.useState({
merchantName: '', mcc: '', mccCode: '', businessType: '', legalName: '',
npwp: '', monthlyOmset: '',
mAddress: '', mPostal: '', mKelurahan: '', mKecamatan: '', mKabupaten: '', mProvinsi: '',
picName: '', picPhone: '', nik: '', email: '',
picAddress: '', picPostal: '', picKelurahan: '', picKecamatan: '', picKabupaten: '', picProvinsi: '',
bankName: 'Bank Hibank (Member of BNI)', accountNumber: '', accountHolder: '', branchCode: ''
});
const [verify, setVerify] = React.useState({ status: 'idle' }); // idle | loading | success | error
// Simulate Cek Rekening lookup
const checkAccount = () => {
if (!data.accountNumber || data.accountNumber.length < 6) {
setVerify({ status: 'error' });
return;
}
setVerify({ status: 'loading' });
setTimeout(() => {
// Pull holder name from PIC if available, else mock
const holder = data.picName ? data.picName.toUpperCase() : 'BUDI SANTOSO';
setData((d) => ({ ...d, accountHolder: holder }));
setVerify({ status: 'success' });
}, 1100);
};
const set = (k) => (e) => setData((d) => ({ ...d, [k]: e.target.value }));
const steps = [
{ id: 'merchant', title: 'Informasi Merchant', sub: 'Data dasar bisnis Anda', icon: 'bx-store-alt' },
{ id: 'address', title: 'Alamat Merchant', sub: 'Lokasi tempat usaha', icon: 'bx-map-alt' },
{ id: 'pic', title: 'Penanggung Jawab', sub: 'Identitas PIC merchant', icon: 'bx-user' },
{ id: 'bank', title: 'Rekening Settlement', sub: 'Tujuan dana settlement', icon: 'bx-credit-card-alt' }];
const mccOptions = [
{ code: '5411', name: 'Grocery / Supermarket' },
{ code: '5812', name: 'Eating Places / Restoran' },
{ code: '5651', name: 'Family Clothing Stores' },
{ code: '7230', name: 'Beauty / Barber Shop' },
{ code: '5499', name: 'Misc. Food Stores' },
{ code: '5814', name: 'Fast Food / F&B' },
{ code: '5999', name: 'Misc. Retail Store' },
{ code: '4121', name: 'Transportation / Logistics' }];
const businessTypes = ['Perorangan / UMKM Mikro', 'CV (Persekutuan Komanditer)', 'PT (Perseroan Terbatas)', 'Firma', 'Koperasi', 'Yayasan'];
const banks = ['Bank Hibank (Member of BNI)', 'BNI', 'BCA', 'Mandiri', 'BRI', 'CIMB Niaga', 'Permata', 'Mayora'];
// ── FIELD ──
const Field = ({ label, name, type = 'text', placeholder, required, hint, options, span = 6, prefix, maxLength, disabled, readOnly }) =>
{label}{required && * }
{options ?
Pilih {label.toLowerCase()}
{options.map((o) => {o.code ? `${o.code} — ${o.name}` : o} )}
{disabled ?
:
}
:
{prefix && {prefix} }
{if (!disabled && !readOnly) {e.target.style.borderColor = TEAL;e.target.style.boxShadow = '0 0 0 4px rgba(0,86,210,0.12)';}}}
onBlur={(e) => {e.target.style.borderColor = '#efefef';e.target.style.boxShadow = 'none';}} />
}
{hint &&
{hint}
}
;
const fieldBase = () => ({
width: '100%', padding: '11px 14px', border: '1.5px solid #efefef',
borderRadius: 8, fontSize: 14, outline: 'none', background: '#fff',
color: '#171919', fontFamily: "'Open Sans', sans-serif",
transition: 'all 200ms', appearance: 'none'
});
const SectionTitle = ({ icon, title, sub }) =>
;
// ── STEP CONTENT ──
const renderStep = () => {
if (step === 0) return (
<>
>);
if (step === 1) return (
<>
>);
if (step === 2) return (
<>
>);
if (step === 3) return (
<>
{/* Account number + Cek Rekening */}
Nomor Rekening*
{setData((d) => ({ ...d, accountNumber: e.target.value, accountHolder: '' }));setVerify({ status: 'idle' });}}
placeholder="1234567890" maxLength={16}
style={{ ...fieldBase(), flex: 1 }}
onFocus={(e) => {e.target.style.borderColor = TEAL;e.target.style.boxShadow = '0 0 0 4px rgba(0,86,210,0.12)';}}
onBlur={(e) => {e.target.style.borderColor = '#efefef';e.target.style.boxShadow = 'none';}} />
{if (data.accountNumber && verify.status !== 'loading') e.currentTarget.style.background = '#3A7EE0';}}
onMouseLeave={(e) => {if (data.accountNumber && verify.status !== 'loading') e.currentTarget.style.background = TEAL;}}>
{verify.status === 'loading' ?
<> Mengecek...> :
verify.status === 'success' ?
<> Tervalidasi> :
<> Cek Rekening>
}
{verify.status === 'error' &&
Nomor rekening tidak ditemukan. Periksa kembali.
}
{/* Summary card */}
Sebelum mengirim pendaftaran
Pastikan semua data sudah benar. Tim akan melakukan verifikasi dalam 1–3 hari kerja . Anda akan menerima notifikasi melalui email {data.email || 'PIC'} setelah merchant aktif.
>);
};
const next = () => step < 3 ? setStep(step + 1) : onComplete && onComplete(data);
const prev = () => step > 0 ? setStep(step - 1) : onBack && onBack();
return (
{/* ── HEADER BAR ── */}
Kembali ke Dashboard
Onboarding Merchant
Registrasi Merchant QRIS Baru
Disimpan otomatis · {new Date().toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit' })}
Simpan Draft
{/* ── CONTENT ── */}
{/* Stepper sidebar */}
Langkah Pendaftaran
{/* connector line */}
{steps.map((s, i) => {
const done = i < step,active = i === step;
return (
i <= step && setStep(i)}
style={{ display: 'flex', alignItems: 'flex-start', gap: 12, padding: '10px 8px', border: 'none', background: 'transparent',
textAlign: 'left', cursor: i <= step ? 'pointer' : 'default', borderRadius: 8,
position: 'relative', zIndex: 1 }}>
{done ?
:
{i + 1}
}
);
})}
{/* Helper card */}
Butuh bantuan?
Hubungi tim kami untuk panduan pengisian.
1112344
{/* Form card */}
{renderStep()}
{/* Bottom action bar */}
Sebelumnya
Langkah {step + 1} dari {steps.length}
e.currentTarget.style.background = step === 3 ? '#e87a4d' : '#3A7EE0'}
onMouseLeave={(e) => e.currentTarget.style.background = step === 3 ? ORANGE : TEAL}>
{step === 3 ? 'Kirim Pendaftaran' : 'Lanjut'}
);
}
Object.assign(window, { MerchantOnboarding });