components | index
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
});
|
||||
@@ -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,
|
||||
},
|
||||
});
|
||||
@@ -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',
|
||||
},
|
||||
});
|
||||
@@ -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',
|
||||
},
|
||||
});
|
||||
@@ -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,
|
||||
},
|
||||
});
|
||||
@@ -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',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user