diff --git a/.gitignore b/.gitignore index ec8a36a..6623142 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,9 @@ web-build/ # macOS .DS_Store + +# @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb +# The following patterns were generated by expo-cli + +expo-env.d.ts +# @end expo-cli \ No newline at end of file diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index 22a49b6..2284b65 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -17,18 +17,27 @@ export default function TabLayout() { ( - + ), }} /> ( - + + ), + }} + /> + ( + ), }} /> diff --git a/app/(tabs)/countdown.tsx b/app/(tabs)/countdown.tsx new file mode 100644 index 0000000..34c2528 --- /dev/null +++ b/app/(tabs)/countdown.tsx @@ -0,0 +1,92 @@ +import React, { useState, useEffect } from 'react'; +import { StyleSheet } from 'react-native'; +import { ThemedText } from '@/components/ThemedText'; +import { ThemedView } from '@/components/ThemedView'; + + +export default function TabTwoScreen() { + const [countdown, setCountdown] = useState({ + days: 0, + hours: 0, + minutes: 0, + seconds: 0, + }); + + const targetDate = new Date('2024-09-20T10:10:00').getTime(); + + useEffect(() => { + const interval = setInterval(() => { + const now = new Date().getTime(); + const distance = targetDate - now; + + const days = Math.floor(distance / (1000 * 60 * 60 * 24)); + const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); + const seconds = Math.floor((distance % (1000 * 60)) / 1000); + + setCountdown({ days, hours, minutes, seconds }); + + if (distance < 0) { + clearInterval(interval); + setCountdown({ days: 0, hours: 0, minutes: 0, seconds: 0 }); + } + }, 1000); + + return () => clearInterval(interval); + }, [targetDate]); + + return ( + + Countdown to Next Visit + + + + + + + + ); +} + +function CountdownItem({ value, label }) { + return ( + + {value} + {label} + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, + title: { + fontSize: 56, + lineHeight: 64, + fontWeight: 'bold', + marginBottom: 20, + textAlign: 'center', + paddingHorizontal: 20, + }, + countdownContainer: { + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + }, + countdownItem: { + margin: 10, + lineHeight: 32, + alignItems: 'center', + }, + countdownValue: { + fontSize: 32, + lineHeight: 32, + fontWeight: 'bold', + }, + countdownLabel: { + fontSize: 24, + }, +}); diff --git a/app/(tabs)/explore.tsx b/app/(tabs)/explore.tsx deleted file mode 100644 index e480218..0000000 --- a/app/(tabs)/explore.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import Ionicons from '@expo/vector-icons/Ionicons'; -import { StyleSheet, Image, Platform } from 'react-native'; - -import { Collapsible } from '@/components/Collapsible'; -import { ExternalLink } from '@/components/ExternalLink'; -import ParallaxScrollView from '@/components/ParallaxScrollView'; -import { ThemedText } from '@/components/ThemedText'; -import { ThemedView } from '@/components/ThemedView'; - -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 - - - - - Open app/_layout.tsx to see how to load{' '} - - custom fonts such as this one. - - - - 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/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 324aeb7..e56c0d1 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -1,70 +1,29 @@ import { Image, StyleSheet, Platform } from 'react-native'; -import { HelloWave } from '@/components/HelloWave'; -import ParallaxScrollView from '@/components/ParallaxScrollView'; import { ThemedText } from '@/components/ThemedText'; import { ThemedView } from '@/components/ThemedView'; export default function HomeScreen() { + const message = "This is the message"; return ( - - }> - - Welcome! - - - - Step 1: Try it - - Edit app/(tabs)/index.tsx to see changes. - Press{' '} - - {Platform.select({ ios: 'cmd + d', android: 'cmd + m' })} - {' '} - to open developer tools. - - - - Step 2: Explore - - Tap the Explore tab to learn more about what's included in this starter app. - - - - 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. - - - - ); + + {message} + + ); } const styles = StyleSheet.create({ - titleContainer: { - flexDirection: 'row', + container: { + flex: 1, alignItems: 'center', - gap: 8, + justifyContent: 'center', }, - stepContainer: { - gap: 8, - marginBottom: 8, + title: { + fontSize: 56, + lineHeight: 64, + fontWeight: 'bold', + marginBottom: 20, + textAlign: 'center', + paddingHorizontal: 20, }, - reactLogo: { - height: 178, - width: 290, - bottom: 0, - left: 0, - position: 'absolute', - }, -}); + }); diff --git a/app/(tabs)/sendmessage.tsx b/app/(tabs)/sendmessage.tsx new file mode 100644 index 0000000..671c71e --- /dev/null +++ b/app/(tabs)/sendmessage.tsx @@ -0,0 +1,27 @@ +import { Image, StyleSheet, Platform } from 'react-native'; + +import { ThemedText } from '@/components/ThemedText'; +import { ThemedView } from '@/components/ThemedView'; + +export default function HomeScreen() { + return ( + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, + title: { + fontSize: 56, + lineHeight: 64, + fontWeight: 'bold', + marginBottom: 20, + textAlign: 'center', + paddingHorizontal: 20, + }, + }); diff --git a/assets/fonts/SpaceMono-Regular.ttf b/assets/fonts/SpaceMono-Regular.ttf old mode 100755 new mode 100644 diff --git a/package-lock.json b/package-lock.json index 916cb3b..fa88307 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "dependencies": { "@expo/vector-icons": "^14.0.2", + "@react-native-async-storage/async-storage": "^2.0.0", "@react-navigation/native": "^6.0.2", "expo": "~51.0.28", "expo-constants": "~16.0.2", @@ -4599,6 +4600,18 @@ "react": "^16.8 || ^17.0 || ^18.0" } }, + "node_modules/@react-native-async-storage/async-storage": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.0.0.tgz", + "integrity": "sha512-af6H9JjfL6G/PktBfUivvexoiFKQTJGQCtSWxMdivLzNIY94mu9DdiY0JqCSg/LyPCLGKhHPUlRQhNvpu3/KVA==", + "license": "MIT", + "dependencies": { + "merge-options": "^3.0.4" + }, + "peerDependencies": { + "react-native": "^0.0.0-0 || >=0.65 <1.0" + } + }, "node_modules/@react-native-community/cli": { "version": "13.6.9", "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-13.6.9.tgz", @@ -11684,6 +11697,15 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -14935,6 +14957,18 @@ "integrity": "sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==", "license": "BSD-2-Clause" }, + "node_modules/merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "license": "MIT", + "dependencies": { + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", diff --git a/package.json b/package.json index 9619b9b..e50e165 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@expo/vector-icons": "^14.0.2", + "@react-native-async-storage/async-storage": "^2.0.0", "@react-navigation/native": "^6.0.2", "expo": "~51.0.28", "expo-constants": "~16.0.2", diff --git a/scripts/reset-project.js b/scripts/reset-project.js old mode 100755 new mode 100644