{lang === 'ka'
? 'ჩვენმა SMS ოპერატორმა გაშვების გამო ყველა გაგზავნა ანტი-სპამის შემოწმებაში გადაიტანა. ვამუშავებთ. სცადე ხვალ დილით ან მომწერე პირადში Facebook-ზე — დაგეხმარები ხელით.'
: 'Notre opérateur SMS a temporairement bloqué les envois (vérification anti-spam suite au lancement). On rétablit ça dans la nuit. Réessaie demain matin, ou écris-moi en privé sur Facebook — je te connecte à la main 💛'}
) : (
{t('sms_disclaimer')}
)}
{t('no_account')} {t('register_link')}
);
}
function errorMessage(err, lang) {
const msgs = {
invalid_phone: { fr: 'Numéro invalide', ka: 'არასწორი ნომერი' },
rate_limited: { fr: 'Trop de demandes, réessayez plus tard', ka: 'ძალიან ბევრი მოთხოვნა, სცადეთ მოგვიანებით' },
too_many_requests_phone: { fr: 'Trop de demandes pour ce numéro', ka: 'ძალიან ბევრი მოთხოვნა ამ ნომრისთვის' },
too_many_requests_ip: { fr: 'Trop de demandes depuis votre IP', ka: 'ძალიან ბევრი მოთხოვნა' },
phone_not_verified_trial:{ fr: 'Numéro non vérifié (compte Twilio trial)', ka: 'ნომერი არ არის გადამოწმებული' },
invalid_code: { fr: 'Code incorrect ou expiré', ka: 'არასწორი ან ვადაგასული კოდი' },
network_error: { fr: 'Pas de connexion internet', ka: 'ინტერნეტის გარეშე' },
sms_failed: { fr: 'Échec envoi SMS, réessayez', ka: 'SMS-ის გაგზავნა ვერ მოხერხდა' },
};
const code = err?.code;
if (code && msgs[code]) return msgs[code][lang] || msgs[code].fr;
// Pas de mapping connu → on affiche le vrai message backend (utile pour debug)
if (err?.message) return err.message;
return msgs.sms_failed[lang] || msgs.sms_failed.fr;
}
window.errorMessage = errorMessage;
function OtpScreen({ onNext, onBack, t, lang, phone }) {
const [code, setCode] = React.useState(['', '', '', '', '', '']);
const [loading, setLoading] = React.useState(false);
const [error, setError] = React.useState(null);
const refs = React.useRef([]);
// Garde-fou : si on arrive sur cet écran sans phone, retour à PhoneScreen
React.useEffect(() => {
if (!phone && onBack) {
console.warn('[OtpScreen] No phone provided, going back to PhoneScreen');
onBack();
}
}, [phone]);
const verify = async (digits) => {
if (loading) return;
setError(null);
if (!window.API_AVAILABLE) {
// Mode dev/preview : pas de vérification, on passe direct
setTimeout(() => onNext({ isNewUser: true }), 350);
return;
}
setLoading(true);
try {
const res = await window.TrustaAPI.verifyOtp(phone, digits);
onNext({ isNewUser: res.is_new_user, user: res.user });
} catch (err) {
setError(window.errorMessage(err, lang));
setCode(['', '', '', '', '', '']);
refs.current[0]?.focus();
setLoading(false);
}
};
const setDigit = (i, v) => {
if (!/^\d?$/.test(v)) return;
const nc = [...code]; nc[i] = v; setCode(nc);
if (v && i < 5) refs.current[i + 1]?.focus();
if (nc.every(d => d) && nc.join('').length === 6) {
verify(nc.join(''));
}
};
return (