/* Me2You - Trust & Verification: Verified badge, ID verify, proof of ownership, safe meet-ups, report/block, 2FA */ /* global React, Icon, panelStyle, btnPrimary, btnGhost, btnSmall, btnDanger, LeafletMap, CITY_COORDS */ const { useState } = React; /* --- Verified Badge --- */ function VerifiedBadge({ level = 'verified', size = 14 }) { const map = { verified: { color:'var(--info)', label:'ID verified', icon:'shield-check' }, trusted: { color:'var(--success)', label:'Trusted seller', icon:'check-circle' }, pro: { color:'var(--brand-orange)', label:'Pro seller', icon:'star' }, }; const c = map[level] || map.verified; return ( {c.label} ); } /* --- ID Verification Wizard (FICA-style) --- */ function IDVerifyWizard({ onComplete, onBack }) { const [step, setStep] = useState(1); const [idType, setIdType] = useState('za_id'); const [idNumber, setIdNumber] = useState(''); const [docFront, setDocFront] = useState(null); const [selfie, setSelfie] = useState(null); const frontRef = React.useRef(null); const selfieRef = React.useRef(null); const readFile = (file, set) => { const r = new FileReader(); r.onload = () => set(r.result); r.readAsDataURL(file); }; return (

Verify your identity

Verified sellers get a badge, list vehicles and property, and earn buyer trust. Takes about 3 minutes.

{['Document','Photos','Selfie','Done'].map((s,i) => (
{i+1}
{s}
))}
{step === 1 && (

What document will you use?

{[ {key:'za_id', label:'South African ID book / smart card', desc:'13-digit ID number'}, {key:'passport', label:'Passport', desc:'For SA residents and visitors'}, {key:'drivers', label:"Driver's licence", desc:'Card with photo and 13-digit ID'}, ].map(opt => (
setIdType(opt.key)} style={{ padding:14,borderRadius:'var(--radius-md)',cursor:'pointer',marginBottom:8, border: idType===opt.key ? '2px solid var(--brand-orange)' : '1.5px solid var(--ink-200)', background: idType===opt.key ? 'var(--brand-orange-50)' : 'transparent', }}>
{opt.label}
{opt.desc}
))}
setIdNumber(e.target.value)} placeholder="9001011234086" maxLength={13} style={{width:'100%',padding:'13px 14px',border:'1.5px solid var(--ink-200)',borderRadius:'var(--radius-sm)', fontFamily:'var(--font-mono)',fontSize:15,boxSizing:'border-box'}}/>
)} {step === 2 && (

Photo of your document

e.target.files[0] && readFile(e.target.files[0], setDocFront)} style={{display:'none'}}/>
frontRef.current?.click()} style={{ border: docFront ? '2px solid var(--success)' : '2px dashed var(--brand-orange)', borderRadius:'var(--radius-lg)',padding: docFront ? 0 : 40,minHeight:200,cursor:'pointer', background: docFront ? 'transparent' : 'var(--brand-orange-50)', display:'flex',alignItems:'center',justifyContent:'center',position:'relative',overflow:'hidden' }}> {docFront ? ( ) : (
Tap to scan document
Make sure all 4 corners are visible
)}
)} {step === 3 && (

Selfie holding your document

We use this to match your face to your ID. Used once for verification, never shared.

e.target.files[0] && readFile(e.target.files[0], setSelfie)} style={{display:'none'}}/>
selfieRef.current?.click()} style={{ border: selfie ? '2px solid var(--success)' : '2px dashed var(--brand-orange)', borderRadius:'var(--radius-lg)',padding: selfie ? 0 : 40,minHeight:200,cursor:'pointer', background: selfie ? 'transparent' : 'var(--brand-orange-50)', display:'flex',alignItems:'center',justifyContent:'center',position:'relative',overflow:'hidden' }}> {selfie ? ( ) : (
Tap to take selfie
Hold your ID next to your face
)}
)} {step === 4 && (

Submitted for review

Your documents are encrypted and being reviewed. You'll get a notification within 24 hours. Most verifications complete in under 4 hours.

)}
); } /* --- Proof of Ownership uploader (for vehicles/property) --- */ function ProofOfOwnership({ kind = 'vehicle' }) { const map = { vehicle: { docs: ['Vehicle registration certificate (NaTIS)','Most recent licence disc','Proof of insurance (optional)'], title:'Prove you own this vehicle' }, property: { docs: ['Title deed or rental agreement','Latest municipal rates account','Proof of address (Eskom / water bill)'], title:'Prove you own this property' }, }; const c = map[kind]; const [uploaded, setUploaded] = useState({}); return (

{c.title}

Required to publish {kind} listings. Documents are reviewed by Me2You admins, encrypted, and never shown to buyers.

{c.docs.map((d,i) => (
{d}
{uploaded[i] ? 'Uploaded - pending review' : 'JPG, PNG or PDF - max 5 MB'}
))}
); } /* --- Safe Meet-up Locations Map --- */ const SAFE_LOCATIONS = [ { name:'Sandton SAPS', type:'Police station', lat:-26.1051, lng:28.0532, hours:'24/7' }, { name:'Soweto Police Station', type:'Police station', lat:-26.2683, lng:27.8543, hours:'24/7' }, { name:'Maponya Mall', type:'Shopping mall', lat:-26.2734, lng:27.8941, hours:'9am-7pm' }, { name:'Sandton City', type:'Shopping mall', lat:-26.1085, lng:28.0568, hours:'9am-9pm' }, { name:'Cresta Mall', type:'Shopping mall', lat:-26.1334, lng:27.9744, hours:'9am-7pm' }, { name:'Hatfield SAPS', type:'Police station', lat:-25.7491, lng:28.2389, hours:'24/7' }, { name:'Menlyn Park', type:'Shopping mall', lat:-25.7838, lng:28.2774, hours:'9am-9pm' }, ]; function SafeMeetupMap({ buyerCoords = [-26.2041, 28.0473], onPick }) { const [chosen, setChosen] = useState(null); const markers = SAFE_LOCATIONS.map(l => ({ lat:l.lat, lng:l.lng, label: l.type === 'Police station' ? 'P' : 'M', color: l.type === 'Police station' ? '#2D7AC7' : '#2F9E5A', popup: `${l.name}
${l.type}
${l.hours}`, })); return (
For self-collect orders we recommend meeting at a police station or busy shopping mall during daylight hours. Never meet at a private residence.
{SAFE_LOCATIONS.slice(0,4).map((l,i) => ( ))}
); } /* --- Report / Block User Modal --- */ function ReportUserModal({ userName, onClose, onSubmit }) { const [reason, setReason] = useState(''); const [details, setDetails] = useState(''); const [block, setBlock] = useState(true); return (

Report {userName || 'this user'}

Reports are anonymous and reviewed by Me2You admins.

{['Scam or fake listing','Harassment or threats','Counterfeit goods','Stolen item','Inappropriate behaviour','Other'].map(r => ( ))}