import { useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, ScrollView, Alert, ActivityIndicator } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { router } from 'expo-router'; import { useQueryClient } from '@tanstack/react-query'; import { api } from '../../../services/api'; const ROLES = [ { value: 'TECHNICIAN', label: 'Technician', desc: 'Field work & installations', color: '#059669', bg: '#F0FDF4' }, { value: 'COLLECTOR', label: 'Collector', desc: 'Payments & remittances', color: '#D97706', bg: '#FFFBEB' }, { value: 'STAFF', label: 'Staff', desc: 'General access', color: '#0891B2', bg: '#ECFEFF' }, { value: 'ADMIN', label: 'Admin', desc: 'Full access + user mgmt', color: '#7C3AED', bg: '#F5F3FF' }, ]; export default function NewUserScreen() { const qc = useQueryClient(); const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); const [email, setEmail] = useState(''); const [phone, setPhone] = useState(''); const [password, setPassword] = useState(''); const [showPass, setShowPass] = useState(false); const [role, setRole] = useState('TECHNICIAN'); const [loading, setLoading] = useState(false); const isValid = firstName.trim() && lastName.trim() && email.trim() && password.length >= 8; const submit = async () => { if (!isValid) return Alert.alert('Required', 'Please fill all required fields. Password must be at least 8 characters.'); setLoading(true); try { await api.post('/api/v1/users', { firstName: firstName.trim(), lastName: lastName.trim(), email: email.trim().toLowerCase(), phone: phone.trim() || undefined, password, role, }); qc.invalidateQueries({ queryKey: ['users'] }); Alert.alert('User Created!', `${firstName} ${lastName} can now log in with ${email.trim().toLowerCase()}`, [ { text: 'Add Another', onPress: () => { setFirstName(''); setLastName(''); setEmail(''); setPhone(''); setPassword(''); } }, { text: 'Done', onPress: () => router.back() }, ]); } catch (e: any) { const msg = e?.response?.data?.message; Alert.alert('Error', Array.isArray(msg) ? msg.join('\n') : msg ?? 'Could not create user.'); } finally { setLoading(false); } }; return ( {/* Header */} router.back()} style={{ marginBottom: 12 }} activeOpacity={0.7}> ← Back Add User Create a new team member {/* Name row */} First Name * Last Name * {/* Email */} Email * {/* Phone */} Phone (optional) {/* Password */} Password * setShowPass(!showPass)} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}> {showPass ? 'Hide' : 'Show'} They can change this after first login. {/* Role */} Role * {ROLES.map(r => ( setRole(r.value)} style={{ flexDirection: 'row', alignItems: 'center', backgroundColor: role === r.value ? r.bg : '#FFF', borderRadius: 16, padding: 18, marginBottom: 10, borderWidth: 2, borderColor: role === r.value ? r.color : '#E2E8F0' }} activeOpacity={0.7} > {r.value.slice(0,4)} {r.label} {r.desc} {role === r.value && } ))} {/* Submit */} {loading ? : Create User } ); }