Compare commits
1 Commits
luggage-li
...
luggage-li
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ec877362f |
@@ -727,6 +727,14 @@ export default function AppRoot() {
|
|||||||
}, 80);
|
}, 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openQuickAddItemFromNav() {
|
||||||
|
if (!selectedTripId) {
|
||||||
|
showAlert('No trip selected', 'Please select or create a trip first.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
openAddItemModal();
|
||||||
|
}
|
||||||
|
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={[styles.safe, { paddingTop: topInset }]}>
|
<SafeAreaView style={[styles.safe, { paddingTop: topInset }]}>
|
||||||
@@ -817,7 +825,7 @@ export default function AppRoot() {
|
|||||||
</ScrollView>
|
</ScrollView>
|
||||||
</KeyboardAvoidingView>
|
</KeyboardAvoidingView>
|
||||||
|
|
||||||
<BottomTab current={tab} onChange={setTab} />
|
<BottomTab current={tab} onChange={setTab} onAddItem={openQuickAddItemFromNav} canAddItem={!!selectedTripId} />
|
||||||
|
|
||||||
<DatePickerModal
|
<DatePickerModal
|
||||||
visible={datePicker.visible}
|
visible={datePicker.visible}
|
||||||
|
|||||||
@@ -3,10 +3,23 @@ import { Pressable, Text, View } from 'react-native';
|
|||||||
import Ionicons from '@expo/vector-icons/Ionicons';
|
import Ionicons from '@expo/vector-icons/Ionicons';
|
||||||
import { styles } from '../styles';
|
import { styles } from '../styles';
|
||||||
|
|
||||||
export default function BottomTab({ current, onChange }) {
|
function TabBtn({ tab, current, onChange }) {
|
||||||
const tabs = [
|
const active = current === tab.key;
|
||||||
|
return (
|
||||||
|
<Pressable onPress={() => onChange(tab.key)} style={styles.tabItem}>
|
||||||
|
<Ionicons name={active ? tab.iconActive : tab.icon} size={18} color={active ? '#dbeafe' : '#94a3b8'} />
|
||||||
|
<Text style={[styles.tabLabel, active && styles.tabLabelActive]}>{tab.label}</Text>
|
||||||
|
</Pressable>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function BottomTab({ current, onChange, onAddItem, canAddItem }) {
|
||||||
|
const leftTabs = [
|
||||||
{ key: 'trips', label: 'Trips', icon: 'airplane-outline', iconActive: 'airplane' },
|
{ key: 'trips', label: 'Trips', icon: 'airplane-outline', iconActive: 'airplane' },
|
||||||
{ key: 'items', label: 'Items', icon: 'briefcase-outline', iconActive: 'briefcase' },
|
{ key: 'items', label: 'Items', icon: 'briefcase-outline', iconActive: 'briefcase' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const rightTabs = [
|
||||||
{ key: 'checkup', label: 'Check-Up', icon: 'checkmark-circle-outline', iconActive: 'checkmark-circle' },
|
{ key: 'checkup', label: 'Check-Up', icon: 'checkmark-circle-outline', iconActive: 'checkmark-circle' },
|
||||||
{ key: 'history', label: 'History', icon: 'time-outline', iconActive: 'time' },
|
{ key: 'history', label: 'History', icon: 'time-outline', iconActive: 'time' },
|
||||||
];
|
];
|
||||||
@@ -14,19 +27,25 @@ export default function BottomTab({ current, onChange }) {
|
|||||||
return (
|
return (
|
||||||
<View style={styles.tabBarWrap}>
|
<View style={styles.tabBarWrap}>
|
||||||
<View style={styles.tabBar}>
|
<View style={styles.tabBar}>
|
||||||
{tabs.map((tab) => {
|
<View style={styles.tabGroupSide}>
|
||||||
const active = current === tab.key;
|
{leftTabs.map((tab) => (
|
||||||
return (
|
<TabBtn key={tab.key} tab={tab} current={current} onChange={onChange} />
|
||||||
<Pressable key={tab.key} onPress={() => onChange(tab.key)} style={styles.tabItem}>
|
))}
|
||||||
<Ionicons
|
</View>
|
||||||
name={active ? tab.iconActive : tab.icon}
|
|
||||||
size={18}
|
<Pressable
|
||||||
color={active ? '#dbeafe' : '#94a3b8'}
|
style={[styles.tabAddBtn, !canAddItem && styles.tabAddBtnDisabled]}
|
||||||
/>
|
onPress={onAddItem}
|
||||||
<Text style={[styles.tabLabel, active && styles.tabLabelActive]}>{tab.label}</Text>
|
disabled={!canAddItem}
|
||||||
|
>
|
||||||
|
<Ionicons name="add" size={26} color="#fff" />
|
||||||
</Pressable>
|
</Pressable>
|
||||||
);
|
|
||||||
})}
|
<View style={styles.tabGroupSide}>
|
||||||
|
{rightTabs.map((tab) => (
|
||||||
|
<TabBtn key={tab.key} tab={tab} current={current} onChange={onChange} />
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -462,13 +462,34 @@ export const styles = StyleSheet.create({
|
|||||||
borderColor: '#1f2937',
|
borderColor: '#1f2937',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
paddingHorizontal: 8,
|
||||||
|
},
|
||||||
|
tabGroupSide: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
width: '42%',
|
||||||
justifyContent: 'space-around',
|
justifyContent: 'space-around',
|
||||||
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
tabItem: {
|
tabItem: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
gap: 4,
|
gap: 4,
|
||||||
minWidth: 62,
|
minWidth: 58,
|
||||||
|
},
|
||||||
|
tabAddBtn: {
|
||||||
|
width: 54,
|
||||||
|
height: 54,
|
||||||
|
borderRadius: 999,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
backgroundColor: '#2563eb',
|
||||||
|
marginTop: -24,
|
||||||
|
borderWidth: 2,
|
||||||
|
borderColor: '#0b1220',
|
||||||
|
},
|
||||||
|
tabAddBtnDisabled: {
|
||||||
|
opacity: 0.45,
|
||||||
},
|
},
|
||||||
tabLabel: {
|
tabLabel: {
|
||||||
color: '#94a3b8',
|
color: '#94a3b8',
|
||||||
|
|||||||
Reference in New Issue
Block a user