feat: scaffold ShieldAI React Native mobile app MVP (FRE-4572)
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>
This commit is contained in:
51
packages/mobile/src/components/Input.tsx
Normal file
51
packages/mobile/src/components/Input.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
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,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user