Untitled
Anonymous
plain_text
02/24/2026 11:10 AM
91.9 KB
12
Indexable
const ComponentFunction = function() {
// @section:imports @depends:[]
const React = require('react');
const { useState, useEffect, useContext, useMemo, useCallback } = React;
const { View, Text, StyleSheet, ScrollView, TouchableOpacity, TextInput, Modal, Alert, Platform, StatusBar, ActivityIndicator, KeyboardAvoidingView, FlatList, Image } = require('react-native');
const { MaterialIcons } = require('@expo/vector-icons');
const { createBottomTabNavigator } = require('@react-navigation/bottom-tabs');
// @end:imports
// @section:theme @depends:[]
const storageStrategy = 'all-local';
const primaryColor = '#2E5266';
const accentColor = '#4A90A4';
const backgroundColor = '#F8FAFB';
const cardColor = '#FFFFFF';
const textPrimary = '#1F2937';
const textSecondary = '#6B7280';
const designStyle = 'modern';
// @end:theme
// @section:navigation-setup @depends:[]
const Tab = createBottomTabNavigator();
const { useQuery, useMutation } = require('platform-hooks');
// @end:navigation-setup
// @section:ThemeContext @depends:[theme]
const ThemeContext = React.createContext();
const ThemeProvider = function(props) {
const darkModeState = useState(false);
const darkMode = darkModeState[0];
const setDarkMode = darkModeState[1];
const lightTheme = useMemo(function() {
return {
colors: {
primary: primaryColor,
accent: accentColor,
background: backgroundColor,
card: cardColor,
textPrimary: textPrimary,
textSecondary: textSecondary,
border: '#E5E7EB',
success: '#10B981',
error: '#EF4444',
warning: '#F59E0B'
}
};
}, []);
const darkTheme = useMemo(function() {
return {
colors: {
primary: primaryColor,
accent: accentColor,
background: '#1F2937',
card: '#374151',
textPrimary: '#F9FAFB',
textSecondary: '#D1D5DB',
border: '#4B5563',
success: '#10B981',
error: '#EF4444',
warning: '#F59E0B'
}
};
}, []);
const theme = darkMode ? darkTheme : lightTheme;
const toggleDarkMode = useCallback(function() {
setDarkMode(function(prev) { return !prev; });
}, []);
const value = useMemo(function() {
return { theme: theme, darkMode: darkMode, toggleDarkMode: toggleDarkMode, designStyle: designStyle };
}, [theme, darkMode, toggleDarkMode]);
return React.createElement(ThemeContext.Provider, { value: value }, props.children);
};
const useTheme = function() { return useContext(ThemeContext); };
// @end:ThemeContext
// @section:HomeScreen-state @depends:[ThemeContext]
const useHomeScreenState = function() {
const themeContext = useTheme();
const theme = themeContext.theme;
const offlineModeState = useState(false);
const offlineMode = offlineModeState[0];
const setOfflineMode = offlineModeState[1];
const showSyncModalState = useState(false);
const showSyncModal = showSyncModalState[0];
const setShowSyncModal = showSyncModalState[1];
const { data: currentTrip } = useQuery('user_activity', { status: 'active' });
const { data: recentTrails } = useQuery('trails', {}, { column: 'created_at', ascending: false });
return {
theme: theme,
offlineMode: offlineMode,
setOfflineMode: setOfflineMode,
showSyncModal: showSyncModal,
setShowSyncModal: setShowSyncModal,
currentTrip: currentTrip && currentTrip.length > 0 ? currentTrip[0] : null,
recentTrails: recentTrails || []
};
};
// @end:HomeScreen-state
// @section:HomeScreen-handlers @depends:[HomeScreen-state]
const homeScreenHandlers = {
toggleOfflineMode: function(state) {
if (!state.offlineMode) {
state.setShowSyncModal(true);
} else {
state.setOfflineMode(false);
Platform.OS === 'web' ? window.alert('Back online! Data will sync automatically.') : Alert.alert('Online Mode', 'Back online! Data will sync automatically.');
}
},
startOfflineSync: function(state) {
state.setShowSyncModal(false);
state.setOfflineMode(true);
Platform.OS === 'web' ? window.alert('Offline sync complete! You can now hike without signal.') : Alert.alert('Ready for Adventure', 'Offline sync complete! You can now hike without signal.');
}
};
// @end:HomeScreen-handlers
// @section:HomeScreen-OfflineModal @depends:[styles]
const renderOfflineSyncModal = function(visible, onClose, onConfirm, theme) {
return React.createElement(Modal, {
visible: visible,
animationType: 'slide',
presentationStyle: 'pageSheet',
transparent: true,
onRequestClose: onClose
},
React.createElement(View, {
style: { flex: 1, justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.5)' },
componentId: 'offline-modal-overlay'
},
React.createElement(View, {
style: {
flex: 1,
maxHeight: '80%',
marginHorizontal: 20,
backgroundColor: theme.colors.card,
borderRadius: 16,
padding: 24
},
componentId: 'offline-modal-content'
},
React.createElement(ScrollView, { style: { flex: 1 } },
React.createElement(View, { style: styles.modalHeader, componentId: 'offline-modal-header' },
React.createElement(MaterialIcons, { name: 'cloud-download', size: 32, color: theme.colors.primary }),
React.createElement(Text, { style: [styles.modalTitle, { color: theme.colors.textPrimary }], componentId: 'offline-modal-title' }, 'Go Offline')
),
React.createElement(Text, { style: [styles.modalDescription, { color: theme.colors.textSecondary }], componentId: 'offline-modal-desc' }, 'Download maps, vouchers, and safety protocols for offline use. This ensures you have everything needed for your hike even without cell service.'),
React.createElement(View, { style: styles.syncItems, componentId: 'sync-items' },
React.createElement(View, { style: styles.syncItem, componentId: 'sync-item-maps' },
React.createElement(MaterialIcons, { name: 'map', size: 24, color: theme.colors.success }),
React.createElement(Text, { style: [styles.syncItemText, { color: theme.colors.textPrimary }] }, 'Trail maps & GPS data')
),
React.createElement(View, { style: styles.syncItem, componentId: 'sync-item-vouchers' },
React.createElement(MaterialIcons, { name: 'receipt', size: 24, color: theme.colors.success }),
React.createElement(Text, { style: [styles.syncItemText, { color: theme.colors.textPrimary }] }, 'Food & lodge vouchers')
),
React.createElement(View, { style: styles.syncItem, componentId: 'sync-item-safety' },
React.createElement(MaterialIcons, { name: 'security', size: 24, color: theme.colors.success }),
React.createElement(Text, { style: [styles.syncItemText, { color: theme.colors.textPrimary }] }, 'Safety protocols & emergency info')
)
),
React.createElement(View, { style: styles.modalActions, componentId: 'offline-modal-actions' },
React.createElement(TouchableOpacity, {
style: [styles.modalButton, styles.cancelButton, { borderColor: theme.colors.border }],
onPress: onClose,
componentId: 'offline-cancel-button'
},
React.createElement(Text, { style: [styles.buttonText, { color: theme.colors.textSecondary }] }, 'Cancel')
),
React.createElement(TouchableOpacity, {
style: [styles.modalButton, styles.confirmButton, { backgroundColor: theme.colors.primary }],
onPress: onConfirm,
componentId: 'offline-confirm-button'
},
React.createElement(Text, { style: [styles.buttonText, { color: '#FFFFFF' }] }, 'Download & Go Offline')
)
)
)
)
)
);
};
// @end:HomeScreen-OfflineModal
// @section:HomeScreen-StatusCard @depends:[styles]
const renderStatusCard = function(theme, offlineMode, currentTrip) {
return React.createElement(View, {
style: [styles.statusCard, { backgroundColor: theme.colors.card, borderColor: theme.colors.border }],
componentId: 'home-status-card'
},
React.createElement(View, { style: styles.statusHeader, componentId: 'status-header' },
React.createElement(View, { style: styles.statusInfo, componentId: 'status-info' },
React.createElement(Text, { style: [styles.statusTitle, { color: theme.colors.textPrimary }], componentId: 'status-title' }, offlineMode ? 'Offline Mode Active' : 'Connected'),
React.createElement(Text, { style: [styles.statusSubtitle, { color: theme.colors.textSecondary }], componentId: 'status-subtitle' },
offlineMode ? 'Ready for adventure without signal' : 'Prepare for your next hike'
)
),
React.createElement(View, {
style: [styles.statusIndicator, { backgroundColor: offlineMode ? theme.colors.warning : theme.colors.success }],
componentId: 'status-indicator'
})
),
currentTrip ? React.createElement(View, { style: styles.currentTrip, componentId: 'current-trip' },
React.createElement(Text, { style: [styles.tripTitle, { color: theme.colors.textPrimary }], componentId: 'trip-title' }, 'Current Adventure'),
React.createElement(Text, { style: [styles.tripName, { color: theme.colors.accent }], componentId: 'trip-name' }, currentTrip.trail_name || 'Hidden Ridge Trail'),
React.createElement(Text, { style: [styles.tripDetail, { color: theme.colors.textSecondary }], componentId: 'trip-detail' },
'Guide: ' + (currentTrip.guide_name || 'Lukas') + ' • 1:00 PM at The Stone Lodge'
)
) : null
);
};
// @end:HomeScreen-StatusCard
// @section:HomeScreen-QuickActions @depends:[styles]
const renderQuickActions = function(theme, onGoOffline) {
const actions = [
{ id: 'navigate', icon: 'explore', title: 'AR Navigation', subtitle: 'Trail finder' },
{ id: 'marketplace', icon: 'store', title: 'Marketplace', subtitle: 'Guides & lodges' },
{ id: 'offline', icon: 'cloud-download', title: 'Go Offline', subtitle: 'Download for hike', onPress: onGoOffline },
{ id: 'reports', icon: 'report', title: 'Trail Reports', subtitle: 'Share conditions' }
];
return React.createElement(View, { style: styles.quickActions, componentId: 'home-quick-actions' },
React.createElement(Text, { style: [styles.sectionTitle, { color: theme.colors.textPrimary }], componentId: 'quick-actions-title' }, 'Quick Actions'),
React.createElement(View, { style: styles.actionsGrid, componentId: 'actions-grid' },
actions.map(function(action) {
return React.createElement(TouchableOpacity, {
key: action.id,
style: [styles.actionButton, { backgroundColor: theme.colors.card, borderColor: theme.colors.border }],
onPress: action.onPress || function() {},
componentId: 'action-' + action.id
},
React.createElement(MaterialIcons, { name: action.icon, size: 28, color: theme.colors.primary }),
React.createElement(Text, { style: [styles.actionTitle, { color: theme.colors.textPrimary }] }, action.title),
React.createElement(Text, { style: [styles.actionSubtitle, { color: theme.colors.textSecondary }] }, action.subtitle)
);
})
)
);
};
// @end:HomeScreen-QuickActions
// @section:HomeScreen-RecentTrails @depends:[styles]
const renderRecentTrails = function(theme, trails) {
if (!trails || trails.length === 0) return null;
return React.createElement(View, { style: styles.recentSection, componentId: 'recent-trails-section' },
React.createElement(Text, { style: [styles.sectionTitle, { color: theme.colors.textPrimary }], componentId: 'recent-trails-title' }, 'Recent Trails'),
React.createElement(ScrollView, {
horizontal: true,
showsHorizontalScrollIndicator: false,
style: { flexGrow: 'initial' },
contentContainerStyle: { paddingHorizontal: 20 },
componentId: 'recent-trails-scroll'
},
trails.slice(0, 3).map(function(trail, index) {
return React.createElement(View, {
key: trail.id || index,
style: [styles.trailCard, { backgroundColor: theme.colors.card, borderColor: theme.colors.border }],
componentId: 'trail-card-' + index
},
React.createElement(Image, {
source: { uri: 'IMAGE:mountain-hiking-trail-scenic' },
style: styles.trailImage,
componentId: 'trail-image-' + index
}),
React.createElement(View, { style: styles.trailInfo, componentId: 'trail-info-' + index },
React.createElement(Text, { style: [styles.trailName, { color: theme.colors.textPrimary }] }, trail.name || 'Hidden Ridge Trail'),
React.createElement(Text, { style: [styles.trailDifficulty, { color: theme.colors.textSecondary }] }, trail.difficulty || 'Moderate'),
React.createElement(View, { style: styles.trailMeta, componentId: 'trail-meta-' + index },
React.createElement(MaterialIcons, { name: 'terrain', size: 16, color: theme.colors.accent }),
React.createElement(Text, { style: [styles.trailDistance, { color: theme.colors.accent }] }, (trail.distance || '8.5') + ' km')
)
)
);
})
)
);
};
// @end:HomeScreen-RecentTrails
// @section:HomeScreen @depends:[HomeScreen-state,HomeScreen-handlers,HomeScreen-OfflineModal,HomeScreen-StatusCard,HomeScreen-QuickActions,HomeScreen-RecentTrails,styles]
const HomeScreen = function() {
const state = useHomeScreenState();
const handlers = homeScreenHandlers;
return React.createElement(View, {
style: [styles.container, { backgroundColor: state.theme.colors.background }],
componentId: 'home-screen'
},
React.createElement(ScrollView, {
style: { flex: 1 },
contentContainerStyle: { paddingBottom: Platform.OS === 'web' ? 90 : 100 },
showsVerticalScrollIndicator: false,
componentId: 'home-scroll'
},
React.createElement(View, { style: styles.header, componentId: 'home-header' },
React.createElement(Text, { style: [styles.greeting, { color: state.theme.colors.textSecondary }], componentId: 'home-greeting' }, 'Welcome back, Maya'),
React.createElement(Text, { style: [styles.title, { color: state.theme.colors.textPrimary }], componentId: 'home-title' }, 'Ready for Adventure'),
React.createElement(TouchableOpacity, {
style: [styles.profileButton, { backgroundColor: state.theme.colors.card, borderColor: state.theme.colors.border }],
componentId: 'home-profile-button'
},
React.createElement(MaterialIcons, { name: 'account-circle', size: 24, color: state.theme.colors.primary })
)
),
renderStatusCard(state.theme, state.offlineMode, state.currentTrip),
renderQuickActions(state.theme, function() { handlers.toggleOfflineMode(state); }),
renderRecentTrails(state.theme, state.recentTrails)
),
renderOfflineSyncModal(
state.showSyncModal,
function() { state.setShowSyncModal(false); },
function() { handlers.startOfflineSync(state); },
state.theme
)
);
};
// @end:HomeScreen
// @section:MarketplaceScreen-state @depends:[ThemeContext]
const useMarketplaceState = function() {
const themeContext = useTheme();
const theme = themeContext.theme;
const activeTabState = useState('guides');
const activeTab = activeTabState[0];
const setActiveTab = activeTabState[1];
const searchQueryState = useState('');
const searchQuery = searchQueryState[0];
const setSearchQuery = searchQueryState[1];
const showBookingModalState = useState(false);
const showBookingModal = showBookingModalState[0];
const setShowBookingModal = showBookingModalState[1];
const selectedServiceState = useState(null);
const selectedService = selectedServiceState[0];
const setSelectedService = selectedServiceState[1];
const { data: localServices } = useQuery('local_services');
return {
theme: theme,
activeTab: activeTab,
setActiveTab: setActiveTab,
searchQuery: searchQuery,
setSearchQuery: setSearchQuery,
showBookingModal: showBookingModal,
setShowBookingModal: setShowBookingModal,
selectedService: selectedService,
setSelectedService: setSelectedService,
localServices: localServices || []
};
};
// @end:MarketplaceScreen-state
// @section:MarketplaceScreen-handlers @depends:[MarketplaceScreen-state]
const marketplaceHandlers = {
selectService: function(state, service) {
state.setSelectedService(service);
state.setShowBookingModal(true);
},
bookService: function(state) {
const { mutate: insertBooking } = useMutation('user_activity', 'insert');
const bookingData = {
service_type: state.selectedService.type,
service_name: state.selectedService.name,
provider_name: state.selectedService.provider,
booking_time: new Date().toISOString(),
status: 'confirmed'
};
insertBooking(bookingData)
.then(function() {
state.setShowBookingModal(false);
state.setSelectedService(null);
Platform.OS === 'web' ? window.alert('Booking confirmed! Check your itinerary.') : Alert.alert('Success', 'Booking confirmed! Check your itinerary.');
})
.catch(function(error) {
Platform.OS === 'web' ? window.alert(error.message) : Alert.alert('Error', error.message);
});
}
};
// @end:MarketplaceScreen-handlers
// @section:MarketplaceScreen-TabSelector @depends:[styles]
const renderTabSelector = function(theme, activeTab, setActiveTab) {
const tabs = [
{ id: 'guides', title: 'Local Guides', icon: 'person' },
{ id: 'lodges', title: 'Mountain Lodges', icon: 'cabin' },
{ id: 'meals', title: 'Pre-Order Meals', icon: 'restaurant' }
];
return React.createElement(View, { style: styles.tabSelector, componentId: 'marketplace-tabs' },
tabs.map(function(tab) {
const isActive = activeTab === tab.id;
return React.createElement(TouchableOpacity, {
key: tab.id,
style: [
styles.tab,
isActive ? { backgroundColor: theme.colors.primary } : { backgroundColor: theme.colors.card, borderColor: theme.colors.border }
],
onPress: function() { setActiveTab(tab.id); },
componentId: 'tab-' + tab.id
},
React.createElement(MaterialIcons, {
name: tab.icon,
size: 20,
color: isActive ? '#FFFFFF' : theme.colors.textSecondary
}),
React.createElement(Text, {
style: [styles.tabText, { color: isActive ? '#FFFFFF' : theme.colors.textSecondary }]
}, tab.title)
);
})
);
};
// @end:MarketplaceScreen-TabSelector
// @section:MarketplaceScreen-ServiceCard @depends:[styles]
const renderServiceCard = function(service, theme, onPress) {
const getServiceImage = function(type) {
if (type === 'guide') return 'IMAGE:mountain-guide-hiking-trail';
if (type === 'lodge') return 'IMAGE:mountain-lodge-cabin-wooden';
return 'IMAGE:mountain-food-warm-meal';
};
return React.createElement(TouchableOpacity, {
style: [styles.serviceCard, { backgroundColor: theme.colors.card, borderColor: theme.colors.border }],
onPress: onPress,
componentId: 'service-card-' + service.id
},
React.createElement(Image, {
source: { uri: getServiceImage(service.type) },
style: styles.serviceImage,
componentId: 'service-image-' + service.id
}),
React.createElement(View, { style: styles.serviceContent, componentId: 'service-content-' + service.id },
React.createElement(Text, { style: [styles.serviceName, { color: theme.colors.textPrimary }] }, service.name),
React.createElement(Text, { style: [styles.serviceProvider, { color: theme.colors.accent }] }, service.provider),
React.createElement(Text, { style: [styles.serviceDescription, { color: theme.colors.textSecondary }] }, service.description),
React.createElement(View, { style: styles.serviceFooter, componentId: 'service-footer-' + service.id },
React.createElement(View, { style: styles.serviceRating, componentId: 'service-rating-' + service.id },
React.createElement(MaterialIcons, { name: 'star', size: 16, color: '#FFB800' }),
React.createElement(Text, { style: [styles.ratingText, { color: theme.colors.textSecondary }] }, service.rating || '4.8')
),
React.createElement(Text, { style: [styles.servicePrice, { color: theme.colors.primary }] }, service.price)
)
)
);
};
// @end:MarketplaceScreen-ServiceCard
// @section:MarketplaceScreen-BookingModal @depends:[styles]
const renderBookingModal = function(visible, service, onClose, onConfirm, theme) {
if (!service) return null;
return React.createElement(Modal, {
visible: visible,
animationType: 'slide',
presentationStyle: 'pageSheet',
transparent: true,
onRequestClose: onClose
},
React.createElement(View, {
style: { flex: 1, justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.5)' },
componentId: 'booking-modal-overlay'
},
React.createElement(View, {
style: {
flex: 1,
maxHeight: '85%',
marginHorizontal: 20,
backgroundColor: theme.colors.card,
borderRadius: 16,
padding: 24
},
componentId: 'booking-modal-content'
},
React.createElement(ScrollView, { style: { flex: 1 } },
React.createElement(View, { style: styles.modalHeader, componentId: 'booking-modal-header' },
React.createElement(TouchableOpacity, {
style: styles.closeButton,
onPress: onClose,
componentId: 'booking-close-button'
},
React.createElement(MaterialIcons, { name: 'close', size: 24, color: theme.colors.textSecondary })
)
),
React.createElement(Image, {
source: { uri: service.type === 'guide' ? 'IMAGE:mountain-guide-hiking-trail' : service.type === 'lodge' ? 'IMAGE:mountain-lodge-cabin-wooden' : 'IMAGE:mountain-food-warm-meal' },
style: styles.modalServiceImage,
componentId: 'booking-modal-service-image'
}),
React.createElement(Text, { style: [styles.modalServiceName, { color: theme.colors.textPrimary }], componentId: 'booking-modal-service-name' }, service.name),
React.createElement(Text, { style: [styles.modalServiceProvider, { color: theme.colors.accent }], componentId: 'booking-modal-service-provider' }, service.provider),
React.createElement(Text, { style: [styles.modalServiceDescription, { color: theme.colors.textSecondary }], componentId: 'booking-modal-service-description' }, service.description),
React.createElement(View, { style: styles.bookingDetails, componentId: 'booking-details' },
React.createElement(Text, { style: [styles.detailsTitle, { color: theme.colors.textPrimary }], componentId: 'booking-details-title' }, 'Booking Details'),
React.createElement(View, { style: styles.detailRow, componentId: 'detail-price' },
React.createElement(Text, { style: [styles.detailLabel, { color: theme.colors.textSecondary }] }, 'Price:'),
React.createElement(Text, { style: [styles.detailValue, { color: theme.colors.primary }] }, service.price)
),
React.createElement(View, { style: styles.detailRow, componentId: 'detail-time' },
React.createElement(Text, { style: [styles.detailLabel, { color: theme.colors.textSecondary }] }, 'Time:'),
React.createElement(Text, { style: [styles.detailValue, { color: theme.colors.textPrimary }] }, service.type === 'meal' ? '1:00 PM' : 'Full day')
)
),
React.createElement(View, { style: styles.modalActions, componentId: 'booking-modal-actions' },
React.createElement(TouchableOpacity, {
style: [styles.modalButton, styles.cancelButton, { borderColor: theme.colors.border }],
onPress: onClose,
componentId: 'booking-cancel-button'
},
React.createElement(Text, { style: [styles.buttonText, { color: theme.colors.textSecondary }] }, 'Cancel')
),
React.createElement(TouchableOpacity, {
style: [styles.modalButton, styles.confirmButton, { backgroundColor: theme.colors.primary }],
onPress: onConfirm,
componentId: 'booking-confirm-button'
},
React.createElement(Text, { style: [styles.buttonText, { color: '#FFFFFF' }] }, 'Confirm Booking')
)
)
)
)
)
);
};
// @end:MarketplaceScreen-BookingModal
// @section:MarketplaceScreen @depends:[MarketplaceScreen-state,MarketplaceScreen-handlers,MarketplaceScreen-TabSelector,MarketplaceScreen-ServiceCard,MarketplaceScreen-BookingModal,styles]
const MarketplaceScreen = function() {
const state = useMarketplaceState();
const handlers = marketplaceHandlers;
const getFilteredServices = function() {
const typeMap = {
'guides': 'guide',
'lodges': 'lodge',
'meals': 'meal'
};
return state.localServices.filter(function(service) {
return service.type === typeMap[state.activeTab];
});
};
const mockServices = [
{ id: '1', type: 'guide', name: 'Heritage Hike with Lukas', provider: 'Mountain Guide Lukas', description: '4-hour guided hike through historical mining trails', price: '$85', rating: '4.9' },
{ id: '2', type: 'guide', name: 'Sunrise Peak Adventure', provider: 'Alpine Guides Co.', description: 'Early morning ascent to catch the sunrise', price: '$120', rating: '4.8' },
{ id: '3', type: 'lodge', name: 'The Stone Lodge', provider: 'Mountain Hospitality', description: 'Traditional stone lodge with panoramic views', price: '$45/night', rating: '4.7' },
{ id: '4', type: 'lodge', name: 'Eagle\'s Nest Cabin', provider: 'Highland Retreats', description: 'Cozy cabin perfect for solo travelers', price: '$65/night', rating: '4.6' },
{ id: '5', type: 'meal', name: 'Wild Herb Polenta Bowl', provider: 'The Stone Lodge', description: 'Locally foraged herbs with creamy polenta', price: '$28', rating: '4.8' },
{ id: '6', type: 'meal', name: 'Mountain Stew & Bread', provider: 'Eagle\'s Nest Cabin', description: 'Hearty stew with freshly baked bread', price: '$22', rating: '4.7' }
];
const typeMap = {
'guides': 'guide',
'lodges': 'lodge',
'meals': 'meal'
};
const filteredServices = mockServices.filter(function(service) {
return service.type === typeMap[state.activeTab];
});
return React.createElement(View, {
style: [styles.container, { backgroundColor: state.theme.colors.background }],
componentId: 'marketplace-screen'
},
React.createElement(View, { style: styles.header, componentId: 'marketplace-header' },
React.createElement(Text, { style: [styles.title, { color: state.theme.colors.textPrimary }], componentId: 'marketplace-title' }, 'Basecamp Marketplace'),
React.createElement(Text, { style: [styles.subtitle, { color: state.theme.colors.textSecondary }], componentId: 'marketplace-subtitle' }, 'Support local mountain communities')
),
renderTabSelector(state.theme, state.activeTab, state.setActiveTab),
React.createElement(ScrollView, {
style: { flex: 1 },
contentContainerStyle: { paddingBottom: Platform.OS === 'web' ? 90 : 100, paddingHorizontal: 20 },
showsVerticalScrollIndicator: false,
componentId: 'marketplace-scroll'
},
filteredServices.map(function(service) {
return renderServiceCard(service, state.theme, function() {
handlers.selectService(state, service);
});
})
),
renderBookingModal(
state.showBookingModal,
state.selectedService,
function() { state.setShowBookingModal(false); },
function() { handlers.bookService(state); },
state.theme
)
);
};
// @end:MarketplaceScreen
// @section:NavigationScreen-state @depends:[ThemeContext]
const useNavigationState = function() {
const themeContext = useTheme();
const theme = themeContext.theme;
const arModeState = useState(false);
const arMode = arModeState[0];
const setArMode = arModeState[1];
const showSafetyAlertState = useState(false);
const showSafetyAlert = showSafetyAlertState[0];
const setShowSafetyAlert = showSafetyAlertState[1];
const { data: currentTrail } = useQuery('trails', { status: 'active' });
return {
theme: theme,
arMode: arMode,
setArMode: setArMode,
showSafetyAlert: showSafetyAlert,
setShowSafetyAlert: setShowSafetyAlert,
currentTrail: currentTrail && currentTrail.length > 0 ? currentTrail[0] : null
};
};
// @end:NavigationScreen-state
// @section:NavigationScreen-handlers @depends:[NavigationScreen-state]
const navigationHandlers = {
toggleAR: function(state) {
state.setArMode(function(prev) { return !prev; });
if (!state.arMode) {
Platform.OS === 'web' ? window.alert('AR Trail-Finder activated! Point your camera at the trail ahead.') : Alert.alert('AR Active', 'AR Trail-Finder activated! Point your camera at the trail ahead.');
}
},
dismissSafetyAlert: function(state) {
state.setShowSafetyAlert(false);
}
};
// @end:NavigationScreen-handlers
// @section:NavigationScreen-ARView @depends:[styles]
const renderARView = function(theme, arMode) {
return React.createElement(View, {
style: [styles.arContainer, { backgroundColor: arMode ? '#000000' : theme.colors.card }],
componentId: 'ar-view-container'
},
arMode ? React.createElement(View, { style: styles.arOverlay, componentId: 'ar-overlay' },
React.createElement(Image, {
source: { uri: 'IMAGE:hiking-trail-path-forest' },
style: styles.arCameraView,
componentId: 'ar-camera-view'
}),
React.createElement(View, { style: styles.arTrailLine, componentId: 'ar-trail-line' }),
React.createElement(View, { style: styles.arWaypoint, componentId: 'ar-waypoint' },
React.createElement(MaterialIcons, { name: 'place', size: 32, color: '#00FF88' }),
React.createElement(Text, { style: styles.waypointText }, '50m ahead')
)
) : React.createElement(View, { style: styles.arPlaceholder, componentId: 'ar-placeholder' },
React.createElement(MaterialIcons, { name: 'camera-alt', size: 48, color: theme.colors.textSecondary }),
React.createElement(Text, { style: [styles.arPlaceholderText, { color: theme.colors.textSecondary }] }, 'Tap to activate AR Trail-Finder'),
React.createElement(Text, { style: [styles.arPlaceholderSubtext, { color: theme.colors.textSecondary }] }, 'Point camera at trail for navigation overlay')
)
);
};
// @end:NavigationScreen-ARView
// @section:NavigationScreen-TrailInfo @depends:[styles]
const renderTrailInfo = function(theme) {
return React.createElement(View, {
style: [styles.trailInfoCard, { backgroundColor: theme.colors.card, borderColor: theme.colors.border }],
componentId: 'navigation-trail-info'
},
React.createElement(View, { style: styles.trailHeader, componentId: 'trail-header' },
React.createElement(Text, { style: [styles.trailName, { color: theme.colors.textPrimary }], componentId: 'nav-trail-name' }, 'Hidden Ridge Trail'),
React.createElement(View, { style: [styles.difficultyBadge, { backgroundColor: '#FFF3CD', borderColor: '#FFEAA7' }], componentId: 'difficulty-badge' },
React.createElement(Text, { style: [styles.difficultyText, { color: '#856404' }] }, 'Moderate')
)
),
React.createElement(View, { style: styles.trailStats, componentId: 'trail-stats' },
React.createElement(View, { style: styles.statItem, componentId: 'stat-distance' },
React.createElement(MaterialIcons, { name: 'straighten', size: 20, color: theme.colors.accent }),
React.createElement(Text, { style: [styles.statLabel, { color: theme.colors.textSecondary }] }, 'Distance'),
React.createElement(Text, { style: [styles.statValue, { color: theme.colors.textPrimary }] }, '8.5 km')
),
React.createElement(View, { style: styles.statItem, componentId: 'stat-elevation' },
React.createElement(MaterialIcons, { name: 'terrain', size: 20, color: theme.colors.accent }),
React.createElement(Text, { style: [styles.statLabel, { color: theme.colors.textSecondary }] }, 'Elevation'),
React.createElement(Text, { style: [styles.statValue, { color: theme.colors.textPrimary }] }, '2,150m')
),
React.createElement(View, { style: styles.statItem, componentId: 'stat-progress' },
React.createElement(MaterialIcons, { name: 'timeline', size: 20, color: theme.colors.accent }),
React.createElement(Text, { style: [styles.statLabel, { color: theme.colors.textSecondary }] }, 'Progress'),
React.createElement(Text, { style: [styles.statValue, { color: theme.colors.textPrimary }] }, '3.2 km')
)
)
);
};
// @end:NavigationScreen-TrailInfo
// @section:NavigationScreen-SafetyAlert @depends:[styles]
const renderSafetyAlert = function(visible, onDismiss, theme) {
if (!visible) return null;
return React.createElement(View, {
style: [styles.safetyAlert, { backgroundColor: theme.colors.warning, borderColor: '#F59E0B' }],
componentId: 'safety-alert'
},
React.createElement(MaterialIcons, { name: 'warning', size: 24, color: '#FFFFFF' }),
React.createElement(View, { style: styles.alertContent, componentId: 'alert-content' },
React.createElement(Text, { style: styles.alertTitle }, 'Cold Weather Detected'),
React.createElement(Text, { style: styles.alertMessage }, 'Temperature dropped to -5°C. Keep phone in inner pocket to preserve battery.')
),
React.createElement(TouchableOpacity, {
style: styles.alertDismiss,
onPress: onDismiss,
componentId: 'alert-dismiss-button'
},
React.createElement(MaterialIcons, { name: 'close', size: 20, color: '#FFFFFF' })
)
);
};
// @end:NavigationScreen-SafetyAlert
// @section:NavigationScreen @depends:[NavigationScreen-state,NavigationScreen-handlers,NavigationScreen-ARView,NavigationScreen-TrailInfo,NavigationScreen-SafetyAlert,styles]
const NavigationScreen = function() {
const state = useNavigationState();
const handlers = navigationHandlers;
useEffect(function() {
const timer = setTimeout(function() {
state.setShowSafetyAlert(true);
}, 3000);
return function() { clearTimeout(timer); };
}, []);
return React.createElement(View, {
style: [styles.container, { backgroundColor: state.theme.colors.background }],
componentId: 'navigation-screen'
},
React.createElement(View, { style: styles.header, componentId: 'navigation-header' },
React.createElement(Text, { style: [styles.title, { color: state.theme.colors.textPrimary }], componentId: 'navigation-title' }, 'Trail Navigation'),
React.createElement(TouchableOpacity, {
style: [styles.offlineIndicator, { backgroundColor: state.theme.colors.warning }],
componentId: 'offline-indicator'
},
React.createElement(MaterialIcons, { name: 'cloud-off', size: 16, color: '#FFFFFF' }),
React.createElement(Text, { style: styles.offlineText }, 'Offline')
)
),
renderSafetyAlert(state.showSafetyAlert, function() { handlers.dismissSafetyAlert(state); }, state.theme),
React.createElement(TouchableOpacity, {
style: styles.arViewContainer,
onPress: function() { handlers.toggleAR(state); },
componentId: 'ar-view-touchable'
},
renderARView(state.theme, state.arMode)
),
renderTrailInfo(state.theme),
React.createElement(View, { style: styles.navigationControls, componentId: 'navigation-controls' },
React.createElement(TouchableOpacity, {
style: [styles.controlButton, { backgroundColor: state.theme.colors.card, borderColor: state.theme.colors.border }],
componentId: 'waypoint-button'
},
React.createElement(MaterialIcons, { name: 'place', size: 24, color: state.theme.colors.primary }),
React.createElement(Text, { style: [styles.controlButtonText, { color: state.theme.colors.textPrimary }] }, 'Waypoints')
),
React.createElement(TouchableOpacity, {
style: [styles.controlButton, { backgroundColor: state.arMode ? state.theme.colors.primary : state.theme.colors.card, borderColor: state.theme.colors.border }],
onPress: function() { handlers.toggleAR(state); },
componentId: 'ar-toggle-button'
},
React.createElement(MaterialIcons, { name: 'camera-alt', size: 24, color: state.arMode ? '#FFFFFF' : state.theme.colors.primary }),
React.createElement(Text, { style: [styles.controlButtonText, { color: state.arMode ? '#FFFFFF' : state.theme.colors.textPrimary }] }, state.arMode ? 'AR On' : 'AR Off')
),
React.createElement(TouchableOpacity, {
style: [styles.controlButton, { backgroundColor: state.theme.colors.card, borderColor: state.theme.colors.border }],
componentId: 'location-button'
},
React.createElement(MaterialIcons, { name: 'my-location', size: 24, color: state.theme.colors.primary }),
React.createElement(Text, { style: [styles.controlButtonText, { color: state.theme.colors.textPrimary }] }, 'Location')
)
)
);
};
// @end:NavigationScreen
// @section:ActivityScreen-state @depends:[ThemeContext]
const useActivityState = function() {
const themeContext = useTheme();
const theme = themeContext.theme;
const activeTabState = useState('history');
const activeTab = activeTabState[0];
const setActiveTab = activeTabState[1];
const showReportModalState = useState(false);
const showReportModal = showReportModalState[0];
const setShowReportModal = showReportModalState[1];
const reportDescriptionState = useState('');
const reportDescription = reportDescriptionState[0];
const setReportDescription = reportDescriptionState[1];
const { data: userActivity } = useQuery('user_activity');
return {
theme: theme,
activeTab: activeTab,
setActiveTab: setActiveTab,
showReportModal: showReportModal,
setShowReportModal: setShowReportModal,
reportDescription: reportDescription,
setReportDescription: setReportDescription,
userActivity: userActivity || []
};
};
// @end:ActivityScreen-state
// @section:ActivityScreen-handlers @depends:[ActivityScreen-state]
const activityHandlers = {
submitReport: function(state) {
const { mutate: insertReport } = useMutation('user_activity', 'insert');
const reportData = {
type: 'trail_report',
description: state.reportDescription,
location: 'Hidden Ridge Trail - Mile 3.2',
created_at: new Date().toISOString(),
credits_earned: 50,
status: 'pending'
};
insertReport(reportData)
.then(function() {
state.setShowReportModal(false);
state.setReportDescription('');
Platform.OS === 'web' ? window.alert('Trail report submitted! You earned 50 Summit Credits.') : Alert.alert('Report Submitted', 'Trail report submitted! You earned 50 Summit Credits.');
})
.catch(function(error) {
Platform.OS === 'web' ? window.alert(error.message) : Alert.alert('Error', error.message);
});
}
};
// @end:ActivityScreen-handlers
// @section:ActivityScreen-SummaryCards @depends:[styles]
const renderSummaryCards = function(theme) {
const summaryData = [
{ title: 'Trails Completed', value: '12', icon: 'terrain', color: theme.colors.success },
{ title: 'Summit Credits', value: '340', icon: 'star', color: '#FFB800' },
{ title: 'Local Bookings', value: '8', icon: 'store', color: theme.colors.accent },
{ title: 'Trail Reports', value: '5', icon: 'report', color: theme.colors.primary }
];
return React.createElement(View, { style: styles.summaryContainer, componentId: 'activity-summary' },
React.createElement(Text, { style: [styles.sectionTitle, { color: theme.colors.textPrimary }], componentId: 'summary-title' }, 'Your Impact'),
React.createElement(View, { style: styles.summaryGrid, componentId: 'summary-grid' },
summaryData.map(function(item) {
return React.createElement(View, {
key: item.title,
style: [styles.summaryCard, { backgroundColor: theme.colors.card, borderColor: theme.colors.border }],
componentId: 'summary-card-' + item.title.toLowerCase().replace(' ', '-')
},
React.createElement(View, {
style: [styles.summaryIcon, { backgroundColor: item.color + '20' }],
componentId: 'summary-icon-' + item.title.toLowerCase().replace(' ', '-')
},
React.createElement(MaterialIcons, { name: item.icon, size: 24, color: item.color })
),
React.createElement(Text, { style: [styles.summaryValue, { color: theme.colors.textPrimary }] }, item.value),
React.createElement(Text, { style: [styles.summaryLabel, { color: theme.colors.textSecondary }] }, item.title)
);
})
)
);
};
// @end:ActivityScreen-SummaryCards
// @section:ActivityScreen-TabContent @depends:[styles]
const renderTabContent = function(theme, activeTab, onAddReport) {
if (activeTab === 'history') {
const historyItems = [
{ id: '1', type: 'trail', title: 'Hidden Ridge Trail', date: 'Oct 28, 2024', status: 'Completed', credits: 25 },
{ id: '2', type: 'booking', title: 'Heritage Hike with Lukas', date: 'Oct 27, 2024', status: 'Confirmed', credits: 0 },
{ id: '3', type: 'meal', title: 'Wild Herb Polenta Bowl', date: 'Oct 27, 2024', status: 'Redeemed', credits: 0 },
{ id: '4', type: 'report', title: 'Damaged trail marker reported', date: 'Oct 26, 2024', status: 'Verified', credits: 50 }
];
return React.createElement(View, { style: styles.tabContent, componentId: 'history-tab-content' },
historyItems.map(function(item) {
const getIcon = function(type) {
if (type === 'trail') return 'terrain';
if (type === 'booking') return 'person';
if (type === 'meal') return 'restaurant';
return 'report';
};
return React.createElement(View, {
key: item.id,
style: [styles.historyItem, { backgroundColor: theme.colors.card, borderColor: theme.colors.border }],
componentId: 'history-item-' + item.id
},
React.createElement(View, {
style: [styles.historyIcon, { backgroundColor: theme.colors.primary + '20' }],
componentId: 'history-icon-' + item.id
},
React.createElement(MaterialIcons, { name: getIcon(item.type), size: 20, color: theme.colors.primary })
),
React.createElement(View, { style: styles.historyContent, componentId: 'history-content-' + item.id },
React.createElement(Text, { style: [styles.historyTitle, { color: theme.colors.textPrimary }] }, item.title),
React.createElement(Text, { style: [styles.historyDate, { color: theme.colors.textSecondary }] }, item.date),
React.createElement(View, { style: styles.historyFooter, componentId: 'history-footer-' + item.id },
React.createElement(Text, { style: [styles.historyStatus, { color: theme.colors.success }] }, item.status),
item.credits > 0 ? React.createElement(Text, { style: [styles.historyCredits, { color: '#FFB800' }] }, '+' + item.credits + ' credits') : null
)
)
);
})
);
} else if (activeTab === 'reports') {
return React.createElement(View, { style: styles.tabContent, componentId: 'reports-tab-content' },
React.createElement(TouchableOpacity, {
style: [styles.addReportButton, { backgroundColor: theme.colors.primary }],
onPress: onAddReport,
componentId: 'add-report-button'
},
React.createElement(MaterialIcons, { name: 'add', size: 24, color: '#FFFFFF' }),
React.createElement(Text, { style: styles.addReportText }, 'Report Trail Issue')
),
React.createElement(Text, { style: [styles.reportsDescription, { color: theme.colors.textSecondary }], componentId: 'reports-description' },
'Help keep trails safe by reporting hazards, damaged markers, or maintenance needs. Earn Summit Credits for verified reports.')
);
}
return null;
};
// @end:ActivityScreen-TabContent
// @section:ActivityScreen-ReportModal @depends:[styles]
const renderReportModal = function(visible, description, setDescription, onClose, onSubmit, theme) {
return React.createElement(Modal, {
visible: visible,
animationType: 'slide',
presentationStyle: 'pageSheet',
transparent: true,
onRequestClose: onClose
},
React.createElement(KeyboardAvoidingView, {
style: { flex: 1 },
behavior: Platform.OS === 'ios' ? 'padding' : (Platform.OS === 'web' ? undefined : 'height'),
componentId: 'report-modal-keyboard'
},
React.createElement(View, {
style: { flex: 1, justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.5)' },
componentId: 'report-modal-overlay'
},
React.createElement(View, {
style: {
flex: 1,
maxHeight: '80%',
marginHorizontal: 20,
backgroundColor: theme.colors.card,
borderRadius: 16,
padding: 24
},
componentId: 'report-modal-content'
},
React.createElement(ScrollView, { style: { flex: 1 } },
React.createElement(View, { style: styles.modalHeader, componentId: 'report-modal-header' },
React.createElement(MaterialIcons, { name: 'report', size: 32, color: theme.colors.primary }),
React.createElement(Text, { style: [styles.modalTitle, { color: theme.colors.textPrimary }], componentId: 'report-modal-title' }, 'Report Trail Issue')
),
React.createElement(Text, { style: [styles.modalDescription, { color: theme.colors.textSecondary }], componentId: 'report-modal-desc' }, 'Describe any hazards, damaged infrastructure, or maintenance needs you observed on the trail.'),
React.createElement(TextInput, {
style: [styles.reportInput, { backgroundColor: theme.colors.background, borderColor: theme.colors.border, color: theme.colors.textPrimary }],
placeholder: 'Describe the issue (e.g., damaged trail marker, fallen tree, unsafe conditions)...',
placeholderTextColor: theme.colors.textSecondary,
value: description,
onChangeText: setDescription,
multiline: true,
numberOfLines: 6,
textAlignVertical: 'top',
componentId: 'report-input'
}),
React.createElement(View, { style: styles.locationInfo, componentId: 'report-location-info' },
React.createElement(MaterialIcons, { name: 'location-on', size: 16, color: theme.colors.accent }),
React.createElement(Text, { style: [styles.locationText, { color: theme.colors.textSecondary }] }, 'Location will be automatically tagged with GPS coordinates')
),
React.createElement(View, { style: styles.modalActions, componentId: 'report-modal-actions' },
React.createElement(TouchableOpacity, {
style: [styles.modalButton, styles.cancelButton, { borderColor: theme.colors.border }],
onPress: onClose,
componentId: 'report-cancel-button'
},
React.createElement(Text, { style: [styles.buttonText, { color: theme.colors.textSecondary }] }, 'Cancel')
),
React.createElement(TouchableOpacity, {
style: [styles.modalButton, styles.confirmButton, { backgroundColor: theme.colors.primary }],
onPress: onSubmit,
componentId: 'report-submit-button'
},
React.createElement(Text, { style: [styles.buttonText, { color: '#FFFFFF' }] }, 'Submit Report')
)
)
)
)
)
)
);
};
// @end:ActivityScreen-ReportModal
// @section:ActivityScreen @depends:[ActivityScreen-state,ActivityScreen-handlers,ActivityScreen-SummaryCards,ActivityScreen-TabContent,ActivityScreen-ReportModal,styles]
const ActivityScreen = function() {
const state = useActivityState();
const handlers = activityHandlers;
const tabs = [
{ id: 'history', title: 'History', icon: 'history' },
{ id: 'reports', title: 'Reports', icon: 'report' }
];
return React.createElement(View, {
style: [styles.container, { backgroundColor: state.theme.colors.background }],
componentId: 'activity-screen'
},
React.createElement(ScrollView, {
style: { flex: 1 },
contentContainerStyle: { paddingBottom: Platform.OS === 'web' ? 90 : 100 },
showsVerticalScrollIndicator: false,
componentId: 'activity-scroll'
},
React.createElement(View, { style: styles.header, componentId: 'activity-header' },
React.createElement(Text, { style: [styles.title, { color: state.theme.colors.textPrimary }], componentId: 'activity-title' }, 'My Activity'),
React.createElement(Text, { style: [styles.subtitle, { color: state.theme.colors.textSecondary }], componentId: 'activity-subtitle' }, 'Track your adventures and contributions')
),
renderSummaryCards(state.theme),
React.createElement(View, { style: styles.tabSelector, componentId: 'activity-tabs' },
tabs.map(function(tab) {
const isActive = state.activeTab === tab.id;
return React.createElement(TouchableOpacity, {
key: tab.id,
style: [
styles.tab,
isActive ? { backgroundColor: state.theme.colors.primary } : { backgroundColor: state.theme.colors.card, borderColor: state.theme.colors.border }
],
onPress: function() { state.setActiveTab(tab.id); },
componentId: 'activity-tab-' + tab.id
},
React.createElement(MaterialIcons, {
name: tab.icon,
size: 20,
color: isActive ? '#FFFFFF' : state.theme.colors.textSecondary
}),
React.createElement(Text, {
style: [styles.tabText, { color: isActive ? '#FFFFFF' : state.theme.colors.textSecondary }]
}, tab.title)
);
})
),
renderTabContent(state.theme, state.activeTab, function() { state.setShowReportModal(true); })
),
renderReportModal(
state.showReportModal,
state.reportDescription,
state.setReportDescription,
function() { state.setShowReportModal(false); },
function() { handlers.submitReport(state); },
state.theme
)
);
};
// @end:ActivityScreen
// @section:TabNavigator @depends:[HomeScreen,MarketplaceScreen,NavigationScreen,ActivityScreen,navigation-setup]
const TabNavigator = function() {
const themeContext = useTheme();
const theme = themeContext.theme;
return React.createElement(Tab.Navigator, {
screenOptions: function(props) {
const route = props.route;
return {
headerShown: false,
tabBarStyle: {
position: 'absolute',
bottom: 0,
backgroundColor: theme.colors.card,
borderTopColor: theme.colors.border,
borderTopWidth: 1,
paddingBottom: Platform.OS === 'ios' ? 20 : 10,
paddingTop: 10,
height: Platform.OS === 'ios' ? 80 : 70
},
tabBarActiveTintColor: theme.colors.primary,
tabBarInactiveTintColor: theme.colors.textSecondary,
tabBarLabelStyle: {
fontSize: 12,
fontWeight: '600'
},
tabBarIcon: function(iconProps) {
const focused = iconProps.focused;
const color = iconProps.color;
const size = iconProps.size;
if (route.name === 'Home') {
return React.createElement(MaterialIcons, { name: 'home', size: size, color: color });
} else if (route.name === 'Marketplace') {
return React.createElement(MaterialIcons, { name: 'store', size: size, color: color });
} else if (route.name === 'Navigation') {
return React.createElement(MaterialIcons, { name: 'explore', size: size, color: color });
} else if (route.name === 'Activity') {
return React.createElement(MaterialIcons, { name: 'timeline', size: size, color: color });
}
}
};
}
},
React.createElement(Tab.Screen, { name: 'Home', component: HomeScreen }),
React.createElement(Tab.Screen, { name: 'Marketplace', component: MarketplaceScreen }),
React.createElement(Tab.Screen, { name: 'Navigation', component: NavigationScreen }),
React.createElement(Tab.Screen, { name: 'Activity', component: ActivityScreen })
);
};
// @end:TabNavigator
// @section:styles @depends:[theme]
const styles = StyleSheet.create({
container: {
flex: 1
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 20,
paddingTop: Platform.OS === 'ios' ? 60 : 40,
paddingBottom: 20
},
greeting: {
fontSize: 14,
marginBottom: 4
},
title: {
fontSize: 28,
fontWeight: 'bold',
flex: 1
},
subtitle: {
fontSize: 16,
marginTop: 4
},
profileButton: {
width: 40,
height: 40,
borderRadius: 20,
borderWidth: 1,
alignItems: 'center',
justifyContent: 'center'
},
statusCard: {
marginHorizontal: 20,
marginBottom: 24,
padding: 20,
borderRadius: 16,
borderWidth: 1,
shadowColor: '#000000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 8,
elevation: 4
},
statusHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 16
},
statusInfo: {
flex: 1
},
statusTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 4
},
statusSubtitle: {
fontSize: 14
},
statusIndicator: {
width: 12,
height: 12,
borderRadius: 6
},
currentTrip: {
paddingTop: 16,
borderTopWidth: 1,
borderTopColor: '#E5E7EB'
},
tripTitle: {
fontSize: 12,
fontWeight: '600',
textTransform: 'uppercase',
marginBottom: 8
},
tripName: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 4
},
tripDetail: {
fontSize: 14
},
quickActions: {
marginBottom: 24
},
sectionTitle: {
fontSize: 20,
fontWeight: 'bold',
marginHorizontal: 20,
marginBottom: 16
},
actionsGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
paddingHorizontal: 20,
justifyContent: 'space-between'
},
actionButton: {
width: '48%',
padding: 16,
borderRadius: 16,
borderWidth: 1,
alignItems: 'center',
marginBottom: 12,
shadowColor: '#000000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.05,
shadowRadius: 4,
elevation: 2
},
actionTitle: {
fontSize: 14,
fontWeight: '600',
marginTop: 8,
textAlign: 'center'
},
actionSubtitle: {
fontSize: 12,
marginTop: 2,
textAlign: 'center'
},
recentSection: {
marginBottom: 24
},
trailCard: {
width: 200,
marginRight: 16,
borderRadius: 16,
borderWidth: 1,
overflow: 'hidden',
shadowColor: '#000000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 8,
elevation: 4
},
trailImage: {
width: '100%',
height: 120
},
trailInfo: {
padding: 16
},
trailName: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 4
},
trailDifficulty: {
fontSize: 12,
marginBottom: 8
},
trailMeta: {
flexDirection: 'row',
alignItems: 'center'
},
trailDistance: {
fontSize: 12,
fontWeight: '600',
marginLeft: 4
},
modalHeader: {
alignItems: 'center',
marginBottom: 24
},
modalTitle: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginTop: 12
},
modalDescription: {
fontSize: 16,
lineHeight: 24,
textAlign: 'center',
marginBottom: 24
},
syncItems: {
marginBottom: 32
},
syncItem: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 12
},
syncItemText: {
fontSize: 16,
marginLeft: 12
},
modalActions: {
flexDirection: 'row',
justifyContent: 'space-between',
gap: 12
},
modalButton: {
flex: 1,
paddingVertical: 16,
borderRadius: 12,
alignItems: 'center'
},
cancelButton: {
borderWidth: 1
},
confirmButton: {
shadowColor: '#000000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 2
},
buttonText: {
fontSize: 16,
fontWeight: '600'
},
tabSelector: {
flexDirection: 'row',
paddingHorizontal: 20,
marginBottom: 24,
gap: 8
},
tab: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 12,
paddingHorizontal: 16,
borderRadius: 12,
borderWidth: 1
},
tabText: {
fontSize: 14,
fontWeight: '600',
marginLeft: 8
},
serviceCard: {
marginBottom: 16,
borderRadius: 16,
borderWidth: 1,
overflow: 'hidden',
shadowColor: '#000000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 8,
elevation: 4
},
serviceImage: {
width: '100%',
height: 200
},
serviceContent: {
padding: 20
},
serviceName: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 4
},
serviceProvider: {
fontSize: 14,
fontWeight: '600',
marginBottom: 8
},
serviceDescription: {
fontSize: 14,
lineHeight: 20,
marginBottom: 16
},
serviceFooter: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center'
},
serviceRating: {
flexDirection: 'row',
alignItems: 'center'
},
ratingText: {
fontSize: 14,
marginLeft: 4
},
servicePrice: {
fontSize: 18,
fontWeight: 'bold'
},
closeButton: {
position: 'absolute',
top: 0,
right: 0,
width: 32,
height: 32,
alignItems: 'center',
justifyContent: 'center'
},
modalServiceImage: {
width: '100%',
height: 200,
borderRadius: 12,
marginBottom: 20
},
modalServiceName: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 8
},
modalServiceProvider: {
fontSize: 16,
fontWeight: '600',
textAlign: 'center',
marginBottom: 16
},
modalServiceDescription: {
fontSize: 16,
lineHeight: 24,
textAlign: 'center',
marginBottom: 24
},
bookingDetails: {
marginBottom: 32
},
detailsTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 16
},
detailRow: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 12
},
detailLabel: {
fontSize: 16
},
detailValue: {
fontSize: 16,
fontWeight: '600'
},
arContainer: {
marginHorizontal: 20,
marginBottom: 24,
borderRadius: 16,
overflow: 'hidden',
height: 300
},
arOverlay: {
position: 'relative',
width: '100%',
height: '100%'
},
arCameraView: {
width: '100%',
height: '100%'
},
arTrailLine: {
position: 'absolute',
left: '50%',
top: '60%',
width: 4,
height: 100,
backgroundColor: '#00FF88',
borderRadius: 2,
transform: [{ translateX: -2 }]
},
arWaypoint: {
position: 'absolute',
top: 40,
left: '50%',
transform: [{ translateX: -16 }],
alignItems: 'center'
},
waypointText: {
color: '#FFFFFF',
fontSize: 12,
fontWeight: 'bold',
marginTop: 4,
backgroundColor: 'rgba(0,0,0,0.7)',
paddingHorizontal: 8,
paddingVertical: 4,
borderRadius: 8
},
arPlaceholder: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
arPlaceholderText: {
fontSize: 18,
fontWeight: 'bold',
marginTop: 16,
textAlign: 'center'
},
arPlaceholderSubtext: {
fontSize: 14,
marginTop: 8,
textAlign: 'center'
},
arViewContainer: {
marginHorizontal: 20,
marginBottom: 24
},
trailInfoCard: {
marginHorizontal: 20,
marginBottom: 24,
padding: 20,
borderRadius: 16,
borderWidth: 1,
shadowColor: '#000000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 8,
elevation: 4
},
trailHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 16
},
difficultyBadge: {
paddingHorizontal: 12,
paddingVertical: 4,
borderRadius: 12,
borderWidth: 1
},
difficultyText: {
fontSize: 12,
fontWeight: '600'
},
trailStats: {
flexDirection: 'row',
justifyContent: 'space-between'
},
statItem: {
alignItems: 'center',
flex: 1
},
statLabel: {
fontSize: 12,
marginTop: 8
},
statValue: {
fontSize: 16,
fontWeight: 'bold',
marginTop: 4
},
navigationControls: {
flexDirection: 'row',
paddingHorizontal: 20,
justifyContent: 'space-between',
gap: 12
},
controlButton: {
flex: 1,
flexDirection: 'column',
alignItems: 'center',
paddingVertical: 16,
borderRadius: 12,
borderWidth: 1
},
controlButtonText: {
fontSize: 12,
fontWeight: '600',
marginTop: 8
},
safetyAlert: {
flexDirection: 'row',
alignItems: 'center',
marginHorizontal: 20,
marginBottom: 16,
padding: 16,
borderRadius: 12,
borderWidth: 1
},
alertContent: {
flex: 1,
marginLeft: 12
},
alertTitle: {
color: '#FFFFFF',
fontSize: 16,
fontWeight: 'bold',
marginBottom: 4
},
alertMessage: {
color: '#FFFFFF',
fontSize: 14
},
alertDismiss: {
padding: 4
},
offlineIndicator: {
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 12,
paddingVertical: 6,
borderRadius: 16
},
offlineText: {
color: '#FFFFFF',
fontSize: 12,
fontWeight: '600',
marginLeft: 4
},
summaryContainer: {
marginBottom: 24
},
summaryGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
paddingHorizontal: 20,
justifyContent: 'space-between'
},
summaryCard: {
width: '48%',
padding: 16,
borderRadius: 16,
borderWidth: 1,
alignItems: 'center',
marginBottom: 12,
shadowColor: '#000000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.05,
shadowRadius: 4,
elevation: 2
},
summaryIcon: {
width: 48,
height: 48,
borderRadius: 24,
alignItems: 'center',
justifyContent: 'center',
marginBottom: 12
},
summaryValue: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 4
},
summaryLabel: {
fontSize: 12,
textAlign: 'center'
},
tabContent: {
paddingHorizontal: 20
},
historyItem: {
flexDirection: 'row',
padding: 16,
borderRadius: 12,
borderWidth: 1,
marginBottom: 12,
shadowColor: '#000000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.05,
shadowRadius: 4,
elevation: 2
},
historyIcon: {
width: 40,
height: 40,
borderRadius: 20,
alignItems: 'center',
justifyContent: 'center',
marginRight: 12
},
historyContent: {
flex: 1
},
historyTitle: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 4
},
historyDate: {
fontSize: 14,
marginBottom: 8
},
historyFooter: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center'
},
historyStatus: {
fontSize: 12,
fontWeight: '600'
},
historyCredits: {
fontSize: 12,
fontWeight: 'bold'
},
addReportButton: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
padding: 20,
borderRadius: 16,
marginBottom: 16
},
addReportText: {
color: '#FFFFFF',
fontSize: 16,
fontWeight: 'bold',
marginLeft: 8
},
reportsDescription: {
fontSize: 14,
lineHeight: 20,
textAlign: 'center'
},
reportInput: {
borderWidth: 1,
borderRadius: 12,
padding: 16,
fontSize: 16,
height: 120,
marginBottom: 16
},
locationInfo: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 24
},
locationText: {
fontSize: 12,
marginLeft: 8
}
});
// @end:styles
// @section:return @depends:[ThemeProvider,TabNavigator]
return React.createElement(ThemeProvider, null,
React.createElement(View, { style: { flex: 1, width: '100%', height: '100%', overflow: 'hidden' } },
React.createElement(StatusBar, { barStyle: 'dark-content' }),
React.createElement(TabNavigator)
)
);
// @end:return
};
return ComponentFunctioEditor is loading...
Leave a Comment