diff --git a/MobileApp/app/(tabs)/_layout.tsx b/MobileApp/app/(tabs)/_layout.tsx index 54e11d0..9973455 100644 --- a/MobileApp/app/(tabs)/_layout.tsx +++ b/MobileApp/app/(tabs)/_layout.tsx @@ -1,5 +1,6 @@ import { Tabs } from 'expo-router'; import React from 'react'; +import { Platform } from 'react-native'; import { HapticTab } from '@/components/haptic-tab'; import { IconSymbol } from '@/components/ui/icon-symbol'; @@ -13,8 +14,18 @@ export default function TabLayout() { , + title: 'Alerts', + tabBarIcon: ({ color }) => , + }} + /> + , + }} + /> + , }} /> diff --git a/MobileApp/app/(tabs)/alerts.tsx b/MobileApp/app/(tabs)/alerts.tsx new file mode 100644 index 0000000..da850bc --- /dev/null +++ b/MobileApp/app/(tabs)/alerts.tsx @@ -0,0 +1,65 @@ +import { StyleSheet } from 'react-native'; + +import { ThemedText } from '@/components/themed-text'; +import { ThemedView } from '@/components/themed-view'; +import { IconSymbol } from '@/components/ui/icon-symbol'; +import { Colors } from '@/constants/theme'; +import { useColorScheme } from '@/hooks/use-color-scheme'; + +export default function AlertsScreen() { + const colorScheme = useColorScheme(); + const theme = colorScheme ?? 'light'; + + return ( + + + Alerts + Recent security activity + + + + + No Alerts + + You have no new security alerts. + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + padding: 20, + paddingTop: 80, + }, + header: { + marginBottom: 32, + }, + card: { + padding: 32, + borderRadius: 16, + alignItems: 'center', + justifyContent: 'center', + borderWidth: 1, + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.1, + shadowRadius: 12, + elevation: 2, + }, + cardTitle: { + marginTop: 16, + marginBottom: 8, + }, + cardDescription: { + textAlign: 'center', + maxWidth: 240, + }, +}); diff --git a/MobileApp/app/(tabs)/clips.tsx b/MobileApp/app/(tabs)/clips.tsx new file mode 100644 index 0000000..e22d85b --- /dev/null +++ b/MobileApp/app/(tabs)/clips.tsx @@ -0,0 +1,65 @@ +import { StyleSheet } from 'react-native'; + +import { ThemedText } from '@/components/themed-text'; +import { ThemedView } from '@/components/themed-view'; +import { IconSymbol } from '@/components/ui/icon-symbol'; +import { Colors } from '@/constants/theme'; +import { useColorScheme } from '@/hooks/use-color-scheme'; + +export default function ClipsScreen() { + const colorScheme = useColorScheme(); + const theme = colorScheme ?? 'light'; + + return ( + + + Clips + Recorded footage + + + + + No Clips Available + + Recorded clips will appear here. + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + padding: 20, + paddingTop: 80, + }, + header: { + marginBottom: 32, + }, + card: { + padding: 32, + borderRadius: 16, + alignItems: 'center', + justifyContent: 'center', + borderWidth: 1, + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.1, + shadowRadius: 12, + elevation: 2, + }, + cardTitle: { + marginTop: 16, + marginBottom: 8, + }, + cardDescription: { + textAlign: 'center', + maxWidth: 240, + }, +}); diff --git a/MobileApp/app/(tabs)/explore.tsx b/MobileApp/app/(tabs)/explore.tsx deleted file mode 100644 index 71518f9..0000000 --- a/MobileApp/app/(tabs)/explore.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { Image } from 'expo-image'; -import { Platform, StyleSheet } from 'react-native'; - -import { Collapsible } from '@/components/ui/collapsible'; -import { ExternalLink } from '@/components/external-link'; -import ParallaxScrollView from '@/components/parallax-scroll-view'; -import { ThemedText } from '@/components/themed-text'; -import { ThemedView } from '@/components/themed-view'; -import { IconSymbol } from '@/components/ui/icon-symbol'; -import { Fonts } from '@/constants/theme'; - -export default function TabTwoScreen() { - return ( - - }> - - - Explore - - - This app includes example code to help you get started. - - - This app has two screens:{' '} - app/(tabs)/index.tsx and{' '} - app/(tabs)/explore.tsx - - - The layout file in app/(tabs)/_layout.tsx{' '} - sets up the tab navigator. - - - Learn more - - - - - You can open this project on Android, iOS, and the web. To open the web version, press{' '} - w in the terminal running this project. - - - - - For static images, you can use the @2x and{' '} - @3x suffixes to provide files for - different screen densities - - - - Learn more - - - - - This template has light and dark mode support. The{' '} - useColorScheme() hook lets you inspect - what the user's current color scheme is, and so you can adjust UI colors accordingly. - - - Learn more - - - - - This template includes an example of an animated component. The{' '} - components/HelloWave.tsx component uses - the powerful{' '} - - react-native-reanimated - {' '} - library to create a waving hand animation. - - {Platform.select({ - ios: ( - - The components/ParallaxScrollView.tsx{' '} - component provides a parallax effect for the header image. - - ), - })} - - - ); -} - -const styles = StyleSheet.create({ - headerImage: { - color: '#808080', - bottom: -90, - left: -35, - position: 'absolute', - }, - titleContainer: { - flexDirection: 'row', - gap: 8, - }, -}); diff --git a/MobileApp/app/(tabs)/index.tsx b/MobileApp/app/(tabs)/index.tsx index 786b736..37a5a49 100644 --- a/MobileApp/app/(tabs)/index.tsx +++ b/MobileApp/app/(tabs)/index.tsx @@ -1,98 +1,67 @@ -import { Image } from 'expo-image'; -import { Platform, StyleSheet } from 'react-native'; +import { StyleSheet } from 'react-native'; -import { HelloWave } from '@/components/hello-wave'; -import ParallaxScrollView from '@/components/parallax-scroll-view'; import { ThemedText } from '@/components/themed-text'; import { ThemedView } from '@/components/themed-view'; -import { Link } from 'expo-router'; +import { IconSymbol } from '@/components/ui/icon-symbol'; +import { Colors } from '@/constants/theme'; +import { useColorScheme } from '@/hooks/use-color-scheme'; export default function HomeScreen() { - return ( - - }> - - Welcome! - - - - Step 1: Try it - - Edit app/(tabs)/index.tsx to see changes. - Press{' '} - - {Platform.select({ - ios: 'cmd + d', - android: 'cmd + m', - web: 'F12', - })} - {' '} - to open developer tools. - - - - - - Step 2: Explore - - - - alert('Action pressed')} /> - alert('Share pressed')} - /> - - alert('Delete pressed')} - /> - - - + const colorScheme = useColorScheme(); + const theme = colorScheme ?? 'light'; - - {`Tap the Explore tab to learn more about what's included in this starter app.`} + return ( + + + Your Cameras + Manage your indoor security devices + + + + + No Cameras Added + + Add a camera to start monitoring your home. - - Step 3: Get a fresh start - - {`When you're ready, run `} - npm run reset-project to get a fresh{' '} - app directory. This will move the current{' '} - app to{' '} - app-example. - - - + ); } const styles = StyleSheet.create({ - titleContainer: { - flexDirection: 'row', - alignItems: 'center', - gap: 8, + container: { + flex: 1, + padding: 20, + paddingTop: 80, }, - stepContainer: { - gap: 8, + header: { + marginBottom: 32, + }, + card: { + padding: 32, + borderRadius: 16, + alignItems: 'center', + justifyContent: 'center', + borderWidth: 1, + // iOS Shadow + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.1, + shadowRadius: 12, + // Android Shadow + elevation: 2, + }, + cardTitle: { + marginTop: 16, marginBottom: 8, }, - reactLogo: { - height: 178, - width: 290, - bottom: 0, - left: 0, - position: 'absolute', + cardDescription: { + textAlign: 'center', + maxWidth: 240, }, }); diff --git a/MobileApp/app/(tabs)/settings.tsx b/MobileApp/app/(tabs)/settings.tsx new file mode 100644 index 0000000..8697cae --- /dev/null +++ b/MobileApp/app/(tabs)/settings.tsx @@ -0,0 +1,78 @@ +import { StyleSheet } from 'react-native'; + +import { ThemedText } from '@/components/themed-text'; +import { ThemedView } from '@/components/themed-view'; +import { Colors } from '@/constants/theme'; +import { useColorScheme } from '@/hooks/use-color-scheme'; + +export default function SettingsScreen() { + const colorScheme = useColorScheme(); + const theme = colorScheme ?? 'light'; + + const cardStyle = [ + styles.card, + { + shadowColor: Colors[theme].border, + borderColor: Colors[theme].border + } + ]; + + return ( + + + Settings + App preferences + + + + Account + + + Profile + Notifications + Privacy + + + + General + + + About + Help & Support + Sign Out + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + padding: 20, + paddingTop: 80, + }, + header: { + marginBottom: 32, + }, + sectionHeader: { + marginBottom: 12, + marginTop: 24, + }, + card: { + borderRadius: 16, + borderWidth: 1, + shadowOffset: { width: 0, height: 2 }, + shadowOpacity: 0.05, + shadowRadius: 8, + elevation: 2, + overflow: 'hidden', + }, + item: { + padding: 16, + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: 'rgba(0,0,0,0.05)', + }, + lastItem: { + borderBottomWidth: 0, + }, +}); diff --git a/MobileApp/components/themed-text.tsx b/MobileApp/components/themed-text.tsx index d79d0a1..05bc38e 100644 --- a/MobileApp/components/themed-text.tsx +++ b/MobileApp/components/themed-text.tsx @@ -5,7 +5,7 @@ import { useThemeColor } from '@/hooks/use-theme-color'; export type ThemedTextProps = TextProps & { lightColor?: string; darkColor?: string; - type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link'; + type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link' | 'secondary'; }; export function ThemedText({ @@ -15,7 +15,10 @@ export function ThemedText({ type = 'default', ...rest }: ThemedTextProps) { - const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text'); + const color = useThemeColor( + { light: lightColor, dark: darkColor }, + type === 'secondary' ? 'textSecondary' : 'text' + ); return ( ; } diff --git a/MobileApp/components/ui/icon-symbol.tsx b/MobileApp/components/ui/icon-symbol.tsx index b7ece6b..53e6750 100644 --- a/MobileApp/components/ui/icon-symbol.tsx +++ b/MobileApp/components/ui/icon-symbol.tsx @@ -1,7 +1,7 @@ // Fallback for using MaterialIcons on Android and web. import MaterialIcons from '@expo/vector-icons/MaterialIcons'; -import { SymbolWeight, SymbolViewProps } from 'expo-symbols'; +import { SymbolViewProps, SymbolWeight } from 'expo-symbols'; import { ComponentProps } from 'react'; import { OpaqueColorValue, type StyleProp, type TextStyle } from 'react-native'; @@ -18,6 +18,9 @@ const MAPPING = { 'paperplane.fill': 'send', 'chevron.left.forwardslash.chevron.right': 'code', 'chevron.right': 'chevron-right', + 'bell.fill': 'notifications', + 'film.fill': 'video-library', + 'gearshape.fill': 'settings', } as IconMapping; /** diff --git a/MobileApp/constants/theme.ts b/MobileApp/constants/theme.ts index f06facd..4e25250 100644 --- a/MobileApp/constants/theme.ts +++ b/MobileApp/constants/theme.ts @@ -5,25 +5,31 @@ import { Platform } from 'react-native'; -const tintColorLight = '#0a7ea4'; +const tintColorLight = '#635bff'; const tintColorDark = '#fff'; export const Colors = { light: { - text: '#11181C', - background: '#fff', + text: '#0a2540', + textSecondary: '#425466', + background: '#f6f9fc', tint: tintColorLight, - icon: '#687076', - tabIconDefault: '#687076', + icon: '#8898aa', + tabIconDefault: '#8898aa', tabIconSelected: tintColorLight, + card: '#ffffff', + border: '#e6ebf1', }, dark: { text: '#ECEDEE', + textSecondary: '#9BA1A6', background: '#151718', tint: tintColorDark, icon: '#9BA1A6', tabIconDefault: '#9BA1A6', tabIconSelected: tintColorDark, + card: '#232526', // Fallback for dark mode + border: '#333333', }, };