components | index

This commit is contained in:
Didier Palma
2026-05-22 19:53:15 -06:00
parent 1dadefb5d1
commit 7ea28a78c2
7 changed files with 389 additions and 2 deletions

View File

@@ -1,4 +1,4 @@
import { View, Text } from "react-native";
/*import { View, Text, ScrollView } from "react-native";
export default function HomeScreen() {
return (
@@ -12,4 +12,91 @@ export default function HomeScreen() {
<Text>Inicio</Text>
</View>
);
}*/
import { View, ScrollView } from 'react-native';
import EtaCard from '../components/EtaCard';
import QuickAction from '../components/QuickAction';
import SectionTitle from '../components/SectionTitle';
import AlertItem from '../components/Alertltem';
export default function Home() {
return (
<ScrollView
style={{ flex: 1, backgroundColor: '#ffffff' }}
showsVerticalScrollIndicator={false}
>
{/*ETA*/}
<EtaCard
minutes={12}
status="Camión en ruta 🚛"
/>
{/*ACCIONES RÁPIDAS*/}
<SectionTitle title="Acciones rápidas" />
<View
style={{
flexDirection: 'row',
justifyContent: 'space-around',
paddingHorizontal: 10,
marginTop: 10,
}}
>
<QuickAction title="Mapa" icon="🗺️" />
<QuickAction title="Reportar" icon="🚨" />
<QuickAction title="Horarios" icon="🕒" />
</View>
{/*IMPACTO SEMANAL*/}
<SectionTitle title="Impacto semanal" />
<View
style={{
marginHorizontal: 15,
backgroundColor: '#F0F0F3',
padding: 20,
borderRadius: 16,
}}
>
<AlertItem
message="🚛 5 recolecciones completadas"
type="success"
/>
<AlertItem
message="⏱ Sin retrasos esta semana"
type="success"
/>
<AlertItem
message="📍 Cobertura completa en tu zona"
type="success"
/>
</View>
{/* 🔔 ALERTAS RECIENTES */}
<SectionTitle title="Alertas recientes" />
<View style={{ marginBottom: 40 }}>
<AlertItem
message="🚛 Ruta iniciada"
type="success"
/>
<AlertItem
message="📍 Camión cerca de tu zona"
type="warning"
/>
<AlertItem
message="⏳ Retraso detectado"
type="danger"
/>
</View>
</ScrollView>
);
}

View File

@@ -0,0 +1,59 @@
import { View, Text, StyleSheet } from 'react-native';
import { Colors, Spacing } from '../constants/theme';
type AlertItemProps = {
message: string;
type?: 'success' | 'warning' | 'danger';
};
export default function AlertItem({
message,
type = 'success',
}: AlertItemProps) {
const theme = Colors.light;
const getColor = () => {
switch (type) {
case 'success':
return '#22C55E';
case 'warning':
return '#FACC15';
case 'danger':
return '#EF4444';
default:
return theme.textSecondary;
}
};
return (
<View style={styles.container}>
<View style={[styles.bar, { backgroundColor: getColor() }]} />
<Text style={[styles.text, { color: theme.text }]}>
{message}
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
padding: Spacing.three,
marginHorizontal: Spacing.three,
marginVertical: Spacing.one,
borderRadius: 12,
backgroundColor: '#F0F0F3',
alignItems: 'center',
},
bar: {
width: 6,
height: '100%',
borderRadius: 4,
marginRight: Spacing.two,
},
text: {
fontSize: 14,
flex: 1,
},
});

View File

@@ -0,0 +1,49 @@
import { View, TextInput, StyleSheet } from 'react-native';
import { Colors, Spacing } from '../constants/theme';
type InputFieldProps = {
placeholder?: string;
value?: string;
onChangeText?: (text: string) => void;
secureTextEntry?: boolean;
};
export default function InputField({
placeholder,
value,
onChangeText,
secureTextEntry,
}: InputFieldProps) {
const theme = Colors.light;
return (
<View
style={[
styles.container,
{ backgroundColor: theme.backgroundElement },
]}
>
<TextInput
placeholder={placeholder}
placeholderTextColor={theme.textSecondary}
value={value}
onChangeText={onChangeText}
secureTextEntry={secureTextEntry}
style={[styles.input, { color: theme.text }]}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
paddingHorizontal: Spacing.three,
paddingVertical: Spacing.two,
borderRadius: 12,
marginVertical: 8,
},
input: {
fontSize: 16,
},
});

View File

@@ -0,0 +1,39 @@
import { Pressable, Text, StyleSheet } from 'react-native';
import { Colors, Spacing } from '../constants/theme';
type PrimaryButtonProps = {
title: string;
onPress?: () => void;
};
export default function PrimaryButton({
title,
onPress,
}: PrimaryButtonProps) {
const theme = Colors.light;
return (
<Pressable
style={[styles.button, { backgroundColor: theme.backgroundElement }]}
onPress={onPress}
>
<Text style={[styles.text, { color: theme.text }]}>
{title}
</Text>
</Pressable>
);
}
const styles = StyleSheet.create({
button: {
padding: Spacing.three,
borderRadius: 12,
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 16,
fontWeight: '600',
},
});

View File

@@ -0,0 +1,76 @@
import {
Pressable,
Text,
StyleSheet,
View,
} from 'react-native';
import { Colors, Spacing } from '../constants/theme';
type QuickActionProps = {
title: string;
icon: string;
onPress?: () => void;
};
export default function QuickAction({
title,
icon,
onPress,
}: QuickActionProps) {
const theme = Colors.light;
return (
<Pressable
style={[
styles.container,
{
backgroundColor: theme.backgroundElement,
},
]}
onPress={onPress}
>
<View style={styles.iconContainer}>
<Text style={styles.icon}>
{icon}
</Text>
</View>
<Text
style={[
styles.title,
{
color: theme.text,
},
]}
>
{title}
</Text>
</Pressable>
);
}
const styles = StyleSheet.create({
container: {
width: 100,
padding: Spacing.three,
borderRadius: 16,
alignItems: 'center',
justifyContent: 'center',
},
iconContainer: {
marginBottom: Spacing.two,
},
icon: {
fontSize: 28,
},
title: {
fontSize: 14,
fontWeight: '600',
textAlign: 'center',
},
});

View File

@@ -0,0 +1,27 @@
import { Text, StyleSheet } from 'react-native';
import { Colors, Spacing } from '../constants/theme';
type SectionTitleProps = {
title: string;
};
export default function SectionTitle({ title }: SectionTitleProps) {
const theme = Colors.light;
return (
<Text style={[styles.title, { color: theme.text }]}>
{title}
</Text>
);
}
const styles = StyleSheet.create({
title: {
fontSize: 18,
fontWeight: '700',
marginTop: Spacing.four,
marginBottom: Spacing.two,
marginLeft: Spacing.three,
},
});

View File

@@ -0,0 +1,50 @@
import { View, Text, StyleSheet } from 'react-native';
import { Colors, Spacing } from '../constants/theme';
type StatusType = 'success' | 'warning' | 'danger';
type StatusBadgeProps = {
label: string;
type?: StatusType;
};
export default function StatusBadge({
label,
type = 'success',
}: StatusBadgeProps) {
const theme = Colors.light;
const getColor = () => {
switch (type) {
case 'success':
return '#22C55E';
case 'warning':
return '#FACC15';
case 'danger':
return '#EF4444';
default:
return theme.textSecondary;
}
};
return (
<View style={[styles.badge, { backgroundColor: getColor() }]}>
<Text style={styles.text}>{label}</Text>
</View>
);
}
const styles = StyleSheet.create({
badge: {
paddingHorizontal: Spacing.two,
paddingVertical: 4,
borderRadius: 20,
alignSelf: 'flex-start',
},
text: {
color: '#fff',
fontSize: 12,
fontWeight: '600',
},
});