Build complete Expo/React Native mobile app with: - Auth flow: email/password login, registration, biometric auth - Dashboard: exposure summary, spam stats, voice protection status - DarkWatch: watch list management, exposure feed, alert toggles - SpamShield: call/text history, whitelist/blacklist management - VoicePrint: family member enrollment, voice analysis - Settings: tier management, notification preferences, security - Push notification integration via FCM/APNs - Offline-first state management with Zustand + AsyncStorage - Integration with @shieldai/mobile-api-client for API services - React Navigation with auth-aware routing (stack + bottom tabs) - Dark theme with consistent design system (colors, spacing, typography) - Network status monitoring and offline request queuing Co-Authored-By: Paperclip <noreply@paperclip.ing>
52 lines
1.3 KiB
TypeScript
52 lines
1.3 KiB
TypeScript
import React from 'react';
|
|
import { StyleSheet, TextInput, TextInputProps, Text, View } from 'react-native';
|
|
import { COLORS, BORDER_RADIUS, FONT_SIZES } from '@/constants/theme';
|
|
|
|
interface InputProps extends Omit<TextInputProps, 'style'> {
|
|
label?: string;
|
|
error?: string;
|
|
containerStyle?: object;
|
|
}
|
|
|
|
export function Input({ label, error, containerStyle, ...props }: InputProps) {
|
|
return (
|
|
<View style={[styles.container, containerStyle]}>
|
|
{label && <Text style={styles.label}>{label}</Text>}
|
|
<TextInput
|
|
style={[
|
|
styles.input,
|
|
error ? { borderColor: COLORS.danger } : null,
|
|
]}
|
|
placeholderTextColor={COLORS.textMuted}
|
|
{...props}
|
|
/>
|
|
{error && <Text style={styles.error}>{error}</Text>}
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
marginBottom: 16,
|
|
},
|
|
label: {
|
|
color: COLORS.textSecondary,
|
|
fontSize: FONT_SIZES.sm,
|
|
marginBottom: 6,
|
|
},
|
|
input: {
|
|
backgroundColor: COLORS.backgroundLight,
|
|
borderColor: COLORS.border,
|
|
borderWidth: 1,
|
|
borderRadius: BORDER_RADIUS.md,
|
|
padding: 12,
|
|
color: COLORS.text,
|
|
fontSize: FONT_SIZES.md,
|
|
},
|
|
error: {
|
|
color: COLORS.danger,
|
|
fontSize: FONT_SIZES.xs,
|
|
marginTop: 4,
|
|
},
|
|
});
|