Files
info-target-mobile/screens/auth/register/RegisterForm.tsx
Samandar Turgunboyev 124798419b fitst commit
2026-01-28 18:26:50 +05:00

207 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { formatPhone, normalizeDigits } from '@/constants/formatPhone';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'expo-router';
import { Hash } from 'lucide-react-native';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
ActivityIndicator,
KeyboardAvoidingView,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
import { auth_api } from '../login/lib/api';
import PhonePrefix from '../login/ui/PhonePrefix';
import { UseLoginForm } from '../login/ui/UseLoginForm';
export default function RegisterForm() {
const router = useRouter();
const { t } = useTranslation();
const { phone, setPhone } = UseLoginForm();
const [stir, setStir] = useState('');
const [info, setInfo] = useState<any>(null);
const [loading, setLoading] = useState(false);
const [directorTinInput, setDirectorTinInput] = useState('');
const { mutate } = useMutation({
mutationFn: (stir: string) => auth_api.get_info(stir),
onSuccess: (res) => {
setInfo(res.data);
setLoading(false);
},
onError: () => {
setInfo(null);
setLoading(false);
},
});
const hasDirectorTin = info?.directorTin && String(info.directorTin).length > 0;
const isDirectorTinValid = !hasDirectorTin || directorTinInput === String(info.directorTin);
const hasValidName = Boolean(info?.name || info?.fullName);
const valid =
phone.length === 9 &&
(stir.length === 9 || stir.length === 14) &&
info &&
hasValidName &&
isDirectorTinValid;
return (
<KeyboardAvoidingView behavior="position">
<View style={{ gap: 16 }}>
{/* STIR */}
<View>
<Text style={styles.label}>{t('STIR')}</Text>
<View style={styles.input}>
<Hash size={18} color="#94a3b8" />
<TextInput
value={stir}
keyboardType="numeric"
placeholder={t('STIR')}
placeholderTextColor="#94a3b8"
style={{ flex: 1 }}
onChangeText={(text) => {
const v = normalizeDigits(text).slice(0, 14);
setStir(v);
if (v.length === 9 || v.length === 14) {
setLoading(true);
mutate(v);
}
}}
/>
{loading && <ActivityIndicator size="small" />}
</View>
</View>
{/* PHONE */}
<View>
<Text style={styles.label}>{t('Telefon raqami')}</Text>
<View style={styles.input}>
<PhonePrefix focused={false} />
<TextInput
value={formatPhone(phone)}
placeholder="90 123 45 67"
placeholderTextColor="#94a3b8"
keyboardType="phone-pad"
style={{ flex: 1 }}
onChangeText={(t) => setPhone(normalizeDigits(t))}
/>
</View>
</View>
{/* DIRECTOR TIN */}
{hasDirectorTin && (
<View>
<Text style={styles.label}>{t('Direktor STIR')}</Text>
<View style={styles.input}>
<Hash size={18} color="#94a3b8" />
<TextInput
value={directorTinInput}
keyboardType="numeric"
placeholder={t('Direktor STIR')}
placeholderTextColor="#94a3b8"
style={{ flex: 1 }}
onChangeText={(t) => setDirectorTinInput(normalizeDigits(t))}
/>
</View>
{directorTinInput.length > 0 && !isDirectorTinValid && (
<Text style={styles.error}>{t('Direktor STIR notogri')}</Text>
)}
</View>
)}
{/* INFO */}
{info &&
(hasValidName ? (
<Text style={styles.info}>{info.fullName || info.name}</Text>
) : (
<Text style={styles.notFound}>{t('Foydalanuvchi topilmadi')}</Text>
))}
{/* BUTTON */}
<TouchableOpacity
disabled={!valid}
style={[styles.btn, !valid && styles.disabled]}
onPress={() =>
router.push({
pathname: '/(auth)/select-category',
params: {
phone,
company_name: info?.fullname,
address: info?.fullAddress,
director_full_name: info?.director,
stir,
person_type: stir.length === 9 ? 'legal_entity' : info?.company ? 'ytt' : 'band',
},
})
}
>
<Text style={styles.btnText}>{t('Davom etish')}</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
}
const styles = StyleSheet.create({
label: {
fontWeight: '700',
color: '#475569',
},
notFound: {
backgroundColor: '#fef2f2',
padding: 12,
borderRadius: 12,
fontWeight: '700',
color: '#dc2626',
borderWidth: 1,
borderColor: '#fecaca',
},
input: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#f8fafc',
borderRadius: 12,
paddingHorizontal: 12,
height: 50,
borderWidth: 1,
borderColor: '#e2e8f0',
gap: 8,
},
info: {
backgroundColor: '#f1f5f9',
padding: 12,
borderRadius: 12,
fontWeight: '700',
},
btn: {
height: 52,
backgroundColor: '#2563eb',
borderRadius: 16,
alignItems: 'center',
justifyContent: 'center',
},
disabled: {
opacity: 0.5,
},
btnText: {
color: '#fff',
fontWeight: '800',
fontSize: 16,
},
error: {
color: '#dc2626',
fontSize: 12,
marginTop: 4,
fontWeight: '600',
},
});