├── assets
├── images
│ ├── icon.png
│ ├── favicon.png
│ ├── iconify.png
│ ├── splash.png
│ ├── weather.png
│ ├── adaptive-icon.png
│ └── map-background.png
└── fonts
│ └── SpaceMono-Regular.ttf
├── tsconfig.json
├── babel.config.js
├── components
├── StyledText.tsx
├── __tests__
│ └── StyledText-test.js
├── Icon
│ └── index.tsx
├── Back.tsx
├── Themed.tsx
├── SearchBox
│ └── index.tsx
└── EditScreenInfo.tsx
├── constants
├── Layout.ts
└── Colors.ts
├── .gitignore
├── .expo-shared
└── assets.json
├── hooks
├── useColorScheme.ts
└── useCachedResources.ts
├── App.tsx
├── screens
├── TabTwoScreen.tsx
├── NotFoundScreen.tsx
├── ModalScreen.tsx
├── SearchScreen.tsx
└── HomeScreen.tsx
├── app.json
├── README.md
├── navigation
├── LinkingConfiguration.ts
├── index.tsx
└── MainTabNavigator.tsx
├── headers
├── SearchScreenheader.tsx
└── HomeScreenHeader.tsx
├── types.tsx
└── package.json
/assets/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qbentil/weather-app-mobile/HEAD/assets/images/icon.png
--------------------------------------------------------------------------------
/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qbentil/weather-app-mobile/HEAD/assets/images/favicon.png
--------------------------------------------------------------------------------
/assets/images/iconify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qbentil/weather-app-mobile/HEAD/assets/images/iconify.png
--------------------------------------------------------------------------------
/assets/images/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qbentil/weather-app-mobile/HEAD/assets/images/splash.png
--------------------------------------------------------------------------------
/assets/images/weather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qbentil/weather-app-mobile/HEAD/assets/images/weather.png
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "expo/tsconfig.base",
3 | "compilerOptions": {
4 | "strict": true
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/assets/images/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qbentil/weather-app-mobile/HEAD/assets/images/adaptive-icon.png
--------------------------------------------------------------------------------
/assets/images/map-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qbentil/weather-app-mobile/HEAD/assets/images/map-background.png
--------------------------------------------------------------------------------
/assets/fonts/SpaceMono-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qbentil/weather-app-mobile/HEAD/assets/fonts/SpaceMono-Regular.ttf
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo']
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/components/StyledText.tsx:
--------------------------------------------------------------------------------
1 | import { Text, TextProps } from './Themed';
2 |
3 | export function MonoText(props: TextProps) {
4 | return ;
5 | }
6 |
--------------------------------------------------------------------------------
/constants/Layout.ts:
--------------------------------------------------------------------------------
1 | import { Dimensions } from 'react-native';
2 |
3 | const width = Dimensions.get('window').width;
4 | const height = Dimensions.get('window').height;
5 |
6 | export default {
7 | window: {
8 | width,
9 | height,
10 | },
11 | isSmallDevice: width < 375,
12 | };
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .expo/
3 | dist/
4 | npm-debug.*
5 | *.jks
6 | *.p8
7 | *.p12
8 | *.key
9 | *.mobileprovision
10 | *.orig.*
11 | web-build/
12 |
13 | # macOS
14 | .DS_Store
15 | <<<<<<< HEAD
16 | .env
17 | =======
18 |
19 | # .env
20 | .env
21 | >>>>>>> 54f7f10e3277d57311e590f5da92a23785c0f037
22 |
--------------------------------------------------------------------------------
/.expo-shared/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "e997a5256149a4b76e6bfd6cbf519c5e5a0f1d278a3d8fa1253022b03c90473b": true,
3 | "af683c96e0ffd2cf81287651c9433fa44debc1220ca7cb431fe482747f34a505": true,
4 | "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
5 | "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
6 | }
7 |
--------------------------------------------------------------------------------
/components/__tests__/StyledText-test.js:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import renderer from 'react-test-renderer';
3 |
4 | import { MonoText } from '../StyledText';
5 |
6 | it(`renders correctly`, () => {
7 | const tree = renderer.create(Snapshot test!).toJSON();
8 |
9 | expect(tree).toMatchSnapshot();
10 | });
11 |
--------------------------------------------------------------------------------
/hooks/useColorScheme.ts:
--------------------------------------------------------------------------------
1 | import { ColorSchemeName, useColorScheme as _useColorScheme } from 'react-native';
2 |
3 | // The useColorScheme value is always either light or dark, but the built-in
4 | // type suggests that it can be null. This will not happen in practice, so this
5 | // makes it a bit easier to work with.
6 | export default function useColorScheme(): NonNullable {
7 | return _useColorScheme() as NonNullable;
8 | }
9 |
--------------------------------------------------------------------------------
/constants/Colors.ts:
--------------------------------------------------------------------------------
1 | const tintColorLight = '#ffcc00';
2 | const tintColorDark = '#fff';
3 |
4 | export default {
5 | light: {
6 | text: '#000',
7 | background: '#fff',
8 | tint: tintColorLight,
9 | tabIconDefault: '#ccc',
10 | tabIconSelected: tintColorLight,
11 | },
12 | dark: {
13 | text: '#fff',
14 | background: '#000',
15 | tint: tintColorDark,
16 | tabIconDefault: '#ccc',
17 | tabIconSelected: tintColorDark,
18 | },
19 | };
20 |
--------------------------------------------------------------------------------
/components/Icon/index.tsx:
--------------------------------------------------------------------------------
1 | import { Image, Text, View } from 'react-native'
2 |
3 | import React from 'react'
4 |
5 | const defIcon = require('../../assets/images/iconify.png')
6 |
7 | interface Props {
8 | style: any
9 | icon: any
10 | }
11 | const Icon: React.FC =({style='', icon = ''}) => {
12 | // let rIcon = icon == undefined? defIcon: icon
13 | let rIcon = {uri: `https://openweathermap.org/img/wn/${icon}.png`}
14 | return (
15 |
16 | )
17 | }
18 |
19 |
20 | export default Icon
--------------------------------------------------------------------------------
/App.tsx:
--------------------------------------------------------------------------------
1 | import Navigation from './navigation';
2 | import { SafeAreaProvider } from 'react-native-safe-area-context';
3 | import { StatusBar } from 'expo-status-bar';
4 | import useCachedResources from './hooks/useCachedResources';
5 | import useColorScheme from './hooks/useColorScheme';
6 | // navigator.geolocation = require('@react-native-community/geolocation')
7 |
8 | export default function App() {
9 | const isLoadingComplete = useCachedResources();
10 | const colorScheme = useColorScheme();
11 |
12 | if (!isLoadingComplete) {
13 | return null;
14 | } else {
15 | return (
16 |
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/screens/TabTwoScreen.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from 'react-native';
2 |
3 | import EditScreenInfo from '../components/EditScreenInfo';
4 | import { Text, View } from '../components/Themed';
5 |
6 | export default function TabTwoScreen() {
7 | return (
8 |
9 | Tab Two
10 |
11 |
12 |
13 | );
14 | }
15 |
16 | const styles = StyleSheet.create({
17 | container: {
18 | flex: 1,
19 | alignItems: 'center',
20 | justifyContent: 'center',
21 | },
22 | title: {
23 | fontSize: 20,
24 | fontWeight: 'bold',
25 | },
26 | separator: {
27 | marginVertical: 30,
28 | height: 1,
29 | width: '80%',
30 | },
31 | });
32 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "weather-app-mobile",
4 | "slug": "weather-app-mobile",
5 | "version": "1.0.0",
6 | "orientation": "portrait",
7 | "icon": "./assets/images/icon.png",
8 | "scheme": "myapp",
9 | "userInterfaceStyle": "automatic",
10 | "splash": {
11 | "image": "./assets/images/splash.png",
12 | "resizeMode": "contain",
13 | "backgroundColor": "#ffffff"
14 | },
15 | "updates": {
16 | "fallbackToCacheTimeout": 0
17 | },
18 | "assetBundlePatterns": [
19 | "**/*"
20 | ],
21 | "ios": {
22 | "supportsTablet": true
23 | },
24 | "android": {
25 | "adaptiveIcon": {
26 | "foregroundImage": "./assets/images/adaptive-icon.png",
27 | "backgroundColor": "#ffffff"
28 | }
29 | },
30 | "web": {
31 | "favicon": "./assets/images/favicon.png"
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # weather-app-mobile
2 | A Complete Weather APP using React Native & Expo.
3 |
4 |
5 | # UI > HOME SCREEN
6 |
7 |
8 |

9 |

10 |
11 |
12 | # UI > SEARCH SCREEN
13 |
14 |
15 |

16 |

17 |
18 |
19 |
20 | ## Technologies
21 | 1. React Native and Expo
22 | 2. TypeScript
23 | 3. Open Weather Map from Rapid API
24 | 4. Google Locations API
25 |
26 |
27 |
--------------------------------------------------------------------------------
/navigation/LinkingConfiguration.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Learn more about deep linking with React Navigation
3 | * https://reactnavigation.org/docs/deep-linking
4 | * https://reactnavigation.org/docs/configuring-links
5 | */
6 |
7 | import { LinkingOptions } from '@react-navigation/native';
8 | import * as Linking from 'expo-linking';
9 |
10 | import { RootStackParamList } from '../types';
11 |
12 | const linking: LinkingOptions = {
13 | prefixes: [Linking.makeUrl('/')],
14 | config: {
15 | screens: {
16 | Root: {
17 | screens: {
18 | TabOne: {
19 | screens: {
20 | TabOneScreen: 'one',
21 | },
22 | },
23 | TabTwo: {
24 | screens: {
25 | TabTwoScreen: 'two',
26 | },
27 | },
28 | },
29 | },
30 | Modal: 'modal',
31 | NotFound: '*',
32 | },
33 | },
34 | };
35 |
36 | export default linking;
37 |
--------------------------------------------------------------------------------
/screens/NotFoundScreen.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet, TouchableOpacity } from 'react-native';
2 |
3 | import { Text, View } from '../components/Themed';
4 | import { RootStackScreenProps } from '../types';
5 |
6 | export default function NotFoundScreen({ navigation }: RootStackScreenProps<'NotFound'>) {
7 | return (
8 |
9 | This screen doesn't exist.
10 | navigation.replace('Root')} style={styles.link}>
11 | Go to home screen!
12 |
13 |
14 | );
15 | }
16 |
17 | const styles = StyleSheet.create({
18 | container: {
19 | flex: 1,
20 | alignItems: 'center',
21 | justifyContent: 'center',
22 | padding: 20,
23 | },
24 | title: {
25 | fontSize: 20,
26 | fontWeight: 'bold',
27 | },
28 | link: {
29 | marginTop: 15,
30 | paddingVertical: 15,
31 | },
32 | linkText: {
33 | fontSize: 14,
34 | color: '#2e78b7',
35 | },
36 | });
37 |
--------------------------------------------------------------------------------
/screens/ModalScreen.tsx:
--------------------------------------------------------------------------------
1 | import { StatusBar } from 'expo-status-bar';
2 | import { Platform, StyleSheet } from 'react-native';
3 |
4 | import EditScreenInfo from '../components/EditScreenInfo';
5 | import { Text, View } from '../components/Themed';
6 |
7 | export default function ModalScreen() {
8 | return (
9 |
10 | Modal
11 |
12 |
13 |
14 | {/* Use a light status bar on iOS to account for the black space above the modal */}
15 |
16 |
17 | );
18 | }
19 |
20 | const styles = StyleSheet.create({
21 | container: {
22 | flex: 1,
23 | alignItems: 'center',
24 | justifyContent: 'center',
25 | },
26 | title: {
27 | fontSize: 20,
28 | fontWeight: 'bold',
29 | },
30 | separator: {
31 | marginVertical: 30,
32 | height: 1,
33 | width: '80%',
34 | },
35 | });
36 |
--------------------------------------------------------------------------------
/hooks/useCachedResources.ts:
--------------------------------------------------------------------------------
1 | import { FontAwesome } from '@expo/vector-icons';
2 | import * as Font from 'expo-font';
3 | import * as SplashScreen from 'expo-splash-screen';
4 | import { useEffect, useState } from 'react';
5 |
6 | export default function useCachedResources() {
7 | const [isLoadingComplete, setLoadingComplete] = useState(false);
8 |
9 | // Load any resources or data that we need prior to rendering the app
10 | useEffect(() => {
11 | async function loadResourcesAndDataAsync() {
12 | try {
13 | SplashScreen.preventAutoHideAsync();
14 |
15 | // Load fonts
16 | await Font.loadAsync({
17 | ...FontAwesome.font,
18 | 'space-mono': require('../assets/fonts/SpaceMono-Regular.ttf'),
19 | });
20 | } catch (e) {
21 | // We might want to provide this error information to an error reporting service
22 | console.warn(e);
23 | } finally {
24 | setLoadingComplete(true);
25 | SplashScreen.hideAsync();
26 | }
27 | }
28 |
29 | loadResourcesAndDataAsync();
30 | }, []);
31 |
32 | return isLoadingComplete;
33 | }
34 |
--------------------------------------------------------------------------------
/headers/SearchScreenheader.tsx:
--------------------------------------------------------------------------------
1 | import { Appearance, SafeAreaView, StyleSheet, TouchableOpacity, View } from 'react-native';
2 | import { Entypo, FontAwesome5, Ionicons } from '@expo/vector-icons';
3 | import { useEffect, useState } from 'react';
4 |
5 | import Back from '../components/Back';
6 | import Colors from '../constants/Colors';
7 | import { Text } from '../components/Themed';
8 | import tw from 'twrnc'
9 | import useColorScheme from '../hooks/useColorScheme';
10 |
11 | export default function SearchScreenheader() {
12 | const colorScheme = useColorScheme();
13 |
14 | return (
15 |
16 |
17 | Search for City
18 |
19 |
20 | );
21 | }
22 |
23 | const styles = StyleSheet.create({
24 | container: {
25 | alignItems: 'center',
26 | justifyContent: 'center',
27 | },
28 | title: {
29 | fontSize: 20,
30 | fontWeight: 'bold',
31 | },
32 | separator: {
33 | marginVertical: 30,
34 | height: 1,
35 | width: '80%',
36 | },
37 | });
38 |
--------------------------------------------------------------------------------
/components/Back.tsx:
--------------------------------------------------------------------------------
1 | import Colors from "../constants/Colors"
2 | import { Ionicons } from "@expo/vector-icons"
3 | import React from "react"
4 | import { Text } from "./Themed"
5 | import { TouchableOpacity } from "react-native"
6 | import tw from 'twrnc'
7 | import { useNavigation } from "@react-navigation/native"
8 |
9 | interface Props{
10 | showIcon: boolean,
11 | style: any,
12 | label: string
13 | }
14 |
15 | const Back: React.FC = ({showIcon, style, label}) => {
16 |
17 | const navigation = useNavigation()
18 | return (
19 | navigation.goBack()}
22 | style={[tw`flex-row`, style]}
23 | >
24 | {showIcon && (
25 |
31 | )}
32 | {label}
35 |
36 | )
37 | }
38 |
39 |
40 | export default Back;
--------------------------------------------------------------------------------
/types.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Learn more about using TypeScript with React Navigation:
3 | * https://reactnavigation.org/docs/typescript/
4 | */
5 |
6 | import { CompositeScreenProps, NavigatorScreenParams } from '@react-navigation/native';
7 |
8 | import { BottomTabScreenProps } from '@react-navigation/bottom-tabs';
9 | import { NativeStackScreenProps } from '@react-navigation/native-stack';
10 |
11 | declare global {
12 | namespace ReactNavigation {
13 | interface RootParamList extends RootStackParamList {}
14 | }
15 | }
16 |
17 | export type RootStackParamList = {
18 | Root: NavigatorScreenParams | undefined;
19 | Modal: undefined;
20 | NotFound: undefined;
21 | };
22 |
23 | export type RootStackScreenProps = NativeStackScreenProps<
24 | RootStackParamList,
25 | Screen
26 | >;
27 |
28 | export type RootTabParamList = {
29 | Home: undefined;
30 | Search: undefined;
31 | Profile: undefined;
32 | Other: undefined;
33 |
34 | };
35 |
36 | export type RootTabScreenProps = CompositeScreenProps<
37 | BottomTabScreenProps,
38 | NativeStackScreenProps
39 | >;
40 |
41 | export interface FetchWeatherProps {
42 | lon: string,
43 | lat: string
44 | }
45 |
--------------------------------------------------------------------------------
/components/Themed.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Learn more about Light and Dark modes:
3 | * https://docs.expo.io/guides/color-schemes/
4 | */
5 |
6 | import { Text as DefaultText, View as DefaultView } from 'react-native';
7 |
8 | import Colors from '../constants/Colors';
9 | import useColorScheme from '../hooks/useColorScheme';
10 |
11 | export function useThemeColor(
12 | props: { light?: string; dark?: string },
13 | colorName: keyof typeof Colors.light & keyof typeof Colors.dark
14 | ) {
15 | const theme = useColorScheme();
16 | const colorFromProps = props[theme];
17 |
18 | if (colorFromProps) {
19 | return colorFromProps;
20 | } else {
21 | return Colors[theme][colorName];
22 | }
23 | }
24 |
25 | type ThemeProps = {
26 | lightColor?: string;
27 | darkColor?: string;
28 | };
29 |
30 | export type TextProps = ThemeProps & DefaultText['props'];
31 | export type ViewProps = ThemeProps & DefaultView['props'];
32 |
33 | export function Text(props: TextProps) {
34 | const { style, lightColor, darkColor, ...otherProps } = props;
35 | const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text');
36 |
37 | return ;
38 | }
39 |
40 | export function View(props: ViewProps) {
41 | const { style, lightColor, darkColor, ...otherProps } = props;
42 | const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
43 |
44 | return ;
45 | }
46 |
--------------------------------------------------------------------------------
/components/SearchBox/index.tsx:
--------------------------------------------------------------------------------
1 | import { EvilIcons, Ionicons } from '@expo/vector-icons';
2 | import { KeyboardAvoidingView, StyleSheet, TextInput, TouchableOpacity } from 'react-native';
3 | import { Text, View } from '../Themed';
4 |
5 | import Colors from '../../constants/Colors';
6 | import tw from 'twrnc'
7 | import useColorScheme from '../../hooks/useColorScheme';
8 | import { useState } from 'react';
9 |
10 | interface Props{
11 | style: any,
12 | // search: any
13 | }
14 | const SearchBar: React.FC =({style, }) =>{
15 | const colorScheme = useColorScheme();
16 | const [val, setVal] = useState('')
17 | return (
18 |
23 |
24 | setVal(text)}
29 | underlineColorAndroid="transparent"
30 | placeholderTextColor={Colors['light'].tabIconDefault}
31 | returnKeyType = {'search'}
32 | />
33 | {/* */}
34 | setVal('')}>
35 |
36 |
37 |
38 | );
39 | }
40 |
41 | export default SearchBar;
42 |
43 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "weather-app-mobile",
3 | "version": "1.0.0",
4 | "main": "node_modules/expo/AppEntry.js",
5 | "scripts": {
6 | "start": "expo start",
7 | "android": "expo start --android",
8 | "ios": "expo start --ios",
9 | "web": "expo start --web",
10 | "eject": "expo eject",
11 | "test": "jest --watchAll"
12 | },
13 | "jest": {
14 | "preset": "jest-expo"
15 | },
16 | "dependencies": {
17 | "@expo/vector-icons": "^12.0.0",
18 | "@react-native-community/blur": "^3.6.0",
19 | "@react-native-community/geolocation": "^2.0.2",
20 | "@react-navigation/bottom-tabs": "^6.0.5",
21 | "@react-navigation/native": "^6.0.2",
22 | "@react-navigation/native-stack": "^6.1.0",
23 | "@react-navigation/stack": "^6.2.1",
24 | "axios": "^0.27.2",
25 | "expo": "~44.0.0",
26 | "expo-asset": "~8.4.4",
27 | "expo-blur": "~11.0.0",
28 | "expo-constants": "~13.0.0",
29 | "expo-font": "~10.0.4",
30 | "expo-linking": "~3.0.0",
31 | "expo-splash-screen": "~0.14.0",
32 | "expo-status-bar": "~1.2.0",
33 | "expo-web-browser": "~10.1.0",
34 | "moment": "^2.29.3",
35 | "react": "17.0.1",
36 | "react-dom": "17.0.1",
37 | "react-native": "0.64.3",
38 | "react-native-dotenv": "^3.3.1",
39 | "react-native-geolocation-service": "^5.3.0-beta.4",
40 | "react-native-safe-area-context": "3.3.2",
41 | "react-native-screens": "~3.10.1",
42 | "react-native-web": "0.17.1",
43 | "react-navigation": "^4.4.4",
44 | "twrnc": "^3.3.0"
45 | },
46 | "devDependencies": {
47 | "@babel/core": "^7.12.9",
48 | "@types/react": "~17.0.21",
49 | "@types/react-native": "~0.64.12",
50 | "jest": "^26.6.3",
51 | "jest-expo": "~44.0.1",
52 | "react-test-renderer": "17.0.1",
53 | "typescript": "~4.3.5"
54 | },
55 | "private": true
56 | }
57 |
--------------------------------------------------------------------------------
/navigation/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { ColorSchemeName, Pressable } from 'react-native';
4 | import { DarkTheme, DefaultTheme, NavigationContainer } from '@react-navigation/native';
5 | import { RootStackParamList, RootTabParamList, RootTabScreenProps } from '../types';
6 |
7 | import BottomTabNavigator from './MainTabNavigator';
8 | import Colors from '../constants/Colors';
9 | /**
10 | * If you are not familiar with React Navigation, refer to the "Fundamentals" guide:
11 | * https://reactnavigation.org/docs/getting-started
12 | *
13 | */
14 | import { FontAwesome } from '@expo/vector-icons';
15 | import LinkingConfiguration from './LinkingConfiguration';
16 | import ModalScreen from '../screens/ModalScreen';
17 | import NotFoundScreen from '../screens/NotFoundScreen';
18 | import TabOneScreen from '../screens/HomeScreen';
19 | import TabTwoScreen from '../screens/TabTwoScreen';
20 | import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
21 | import { createNativeStackNavigator } from '@react-navigation/native-stack';
22 | import useColorScheme from '../hooks/useColorScheme';
23 |
24 | export default function Navigation({ colorScheme }: { colorScheme: ColorSchemeName }) {
25 | return (
26 |
29 |
30 |
31 | );
32 | }
33 |
34 | /**
35 | * A root stack navigator is often used for displaying modals on top of all other content.
36 | * https://reactnavigation.org/docs/modal
37 | */
38 | const Stack = createNativeStackNavigator();
39 |
40 | function RootNavigator() {
41 | return (
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | );
50 | }
51 |
52 | /**
53 | * A bottom tab navigator displays tab buttons on the bottom of the display to switch screens.
54 | * https://reactnavigation.org/docs/bottom-tab-navigator
55 | */
56 |
57 |
--------------------------------------------------------------------------------
/components/EditScreenInfo.tsx:
--------------------------------------------------------------------------------
1 | import * as WebBrowser from 'expo-web-browser';
2 | import { StyleSheet, TouchableOpacity } from 'react-native';
3 |
4 | import Colors from '../constants/Colors';
5 | import { MonoText } from './StyledText';
6 | import { Text, View } from './Themed';
7 |
8 | export default function EditScreenInfo({ path }: { path: string }) {
9 | return (
10 |
11 |
12 |
16 | Open up the code for this screen:
17 |
18 |
19 |
23 | {path}
24 |
25 |
26 |
30 | Change any of the text, save the file, and your app will automatically update.
31 |
32 |
33 |
34 |
35 |
36 |
37 | Tap here if your app doesn't automatically update after making changes
38 |
39 |
40 |
41 |
42 | );
43 | }
44 |
45 | function handleHelpPress() {
46 | WebBrowser.openBrowserAsync(
47 | 'https://docs.expo.io/get-started/create-a-new-app/#opening-the-app-on-your-phonetablet'
48 | );
49 | }
50 |
51 | const styles = StyleSheet.create({
52 | getStartedContainer: {
53 | alignItems: 'center',
54 | marginHorizontal: 50,
55 | },
56 | homeScreenFilename: {
57 | marginVertical: 7,
58 | },
59 | codeHighlightContainer: {
60 | borderRadius: 3,
61 | paddingHorizontal: 4,
62 | },
63 | getStartedText: {
64 | fontSize: 17,
65 | lineHeight: 24,
66 | textAlign: 'center',
67 | },
68 | helpContainer: {
69 | marginTop: 15,
70 | marginHorizontal: 20,
71 | alignItems: 'center',
72 | },
73 | helpLink: {
74 | paddingVertical: 15,
75 | },
76 | helpLinkText: {
77 | textAlign: 'center',
78 | },
79 | });
80 |
--------------------------------------------------------------------------------
/headers/HomeScreenHeader.tsx:
--------------------------------------------------------------------------------
1 | import { Appearance, SafeAreaView, StyleSheet, TouchableOpacity, View } from 'react-native';
2 | import { Entypo, FontAwesome5, Ionicons } from '@expo/vector-icons';
3 | import { useEffect, useState } from 'react';
4 |
5 | import Colors from '../constants/Colors';
6 | import { Text } from '../components/Themed';
7 | import moment from 'moment';
8 | import tw from 'twrnc'
9 | import useColorScheme from '../hooks/useColorScheme';
10 |
11 | const HomeScreenHeader = () =>{
12 | const colorScheme = useColorScheme();
13 | // const [isEnabled, setIsEnabled] = useState(false);
14 |
15 | // const toggleSwitch = () => setIsEnabled(previousState => !previousState);
16 |
17 | // // add this
18 | // useEffect(()=>{
19 | // const colorScheme = Appearance.getColorScheme();
20 | // if (colorScheme === 'dark') {
21 | // setIsEnabled(true); // true means dark
22 | // }else{
23 | // setIsEnabled(false); // false means light
24 | // }
25 | // },[])
26 |
27 | return (
28 |
29 |
30 | {'Feb 22, 2022'}
31 |
32 |
33 | {'Accra'},
34 | {'GH'}
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | );
49 | }
50 |
51 |
52 | export default HomeScreenHeader
--------------------------------------------------------------------------------
/navigation/MainTabNavigator.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { AntDesign, FontAwesome, Ionicons } from '@expo/vector-icons';
4 | import { RootStackParamList, RootTabParamList, RootTabScreenProps } from '../types';
5 | import { Text, View } from '../components/Themed';
6 |
7 | import Colors from '../constants/Colors';
8 | import HomeScreen from '../screens/HomeScreen';
9 | import { Pressable } from 'react-native';
10 | import SearchScreen from '../screens/SearchScreen';
11 | import TabTwoScreen from '../screens/TabTwoScreen';
12 | import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
13 | import { createStackNavigator } from '@react-navigation/stack';
14 | import useColorScheme from '../hooks/useColorScheme';
15 |
16 | const BottomTab = createBottomTabNavigator();
17 |
18 | export default function BottomTabNavigator() {
19 | const colorScheme = useColorScheme();
20 |
21 | return (
22 |
29 | ) => ({
34 | title: 'Home',
35 | tabBarIcon: ({ color }) => ,
36 | })}
37 | />
38 | ,
44 | }}
45 | />
46 | ,
52 | }}
53 | />
54 | ,
60 | }}
61 |
62 | />
63 |
64 | );
65 | }
66 |
67 | /**
68 | * You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/
69 | */
70 | function TabBarIcon(props: {
71 | name: React.ComponentProps['name'];
72 | color: string;
73 | }) {
74 | return ;
75 | }
76 |
77 | // Each tab has its own navigation stack, you can read more about this pattern here:
78 | // https://reactnavigation.org/docs/tab-based-navigation#a-stack-navigator-for-each-tab
79 | const HomeStack = createStackNavigator();
80 | const SearchStack= createStackNavigator();
81 | const ProfileStack = createStackNavigator();
82 | const StatusStack= createStackNavigator();
83 | // const CallsStack = createStackNavigator();
84 |
--------------------------------------------------------------------------------
/screens/SearchScreen.tsx:
--------------------------------------------------------------------------------
1 | import { Feather, FontAwesome, FontAwesome5, MaterialCommunityIcons, MaterialIcons } from '@expo/vector-icons';
2 | import { ImageBackground, SafeAreaView, StyleSheet, View } from 'react-native';
3 |
4 | import Colors from '../constants/Colors';
5 | import Icon from '../components/Icon';
6 | import { RootTabScreenProps } from '../types';
7 | import SearchBar from '../components/SearchBox';
8 | import SearchScreenheader from '../headers/SearchScreenheader';
9 | import { Text } from '../components/Themed';
10 | import tw from 'twrnc'
11 | import useColorScheme from '../hooks/useColorScheme';
12 |
13 | const image = {uri: "https://www.globe.gov/o/globe-gov-measurements-portlet/img/map-background.png"}
14 | export default function SearchScreen({ navigation }: RootTabScreenProps<'Search'>) {
15 | const colorScheme = useColorScheme();
16 | return (
17 |
18 |
19 |
20 |
21 |
22 |
23 | Temperature
24 | {/* */}
25 |
26 |
27 | 30
28 | Thunder
29 |
30 |
31 |
32 | Wind Speed
33 |
34 |
35 | 30
36 | m/s
37 |
38 |
39 |
40 |
41 |
42 | More cities
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Min Temperature
51 | 8 km/h
52 |
53 |
54 | Max Temperature
55 | 8 km/h
56 |
57 |
58 |
59 |
60 |
61 | Humidy
62 | 8 km/h
63 |
64 |
65 | Pressure
66 | 8 km/h
67 |
68 |
69 |
70 |
71 | );
72 | }
73 |
74 | const styles = StyleSheet.create({
75 | container: {
76 | flex: 1,
77 | justifyContent: 'center',
78 | },
79 | title: {
80 | fontSize: 20,
81 | fontWeight: 'bold',
82 | },
83 | separator: {
84 | marginVertical: 30,
85 | height: 1,
86 | width: '80%',
87 | },
88 | });
89 |
--------------------------------------------------------------------------------
/screens/HomeScreen.tsx:
--------------------------------------------------------------------------------
1 | import { Feather, FontAwesome5 } from '@expo/vector-icons';
2 | import { Image, ImageBackground, SafeAreaView, StyleSheet, View } from 'react-native';
3 |
4 | import Colors from '../constants/Colors';
5 | import HomeScreenHeader from '../headers/HomeScreenHeader';
6 | import Icon from '../components/Icon';
7 | import { RootTabScreenProps } from '../types';
8 | import { Text } from '../components/Themed';
9 | import tw from 'twrnc'
10 | import useColorScheme from '../hooks/useColorScheme';
11 | import { useState } from 'react';
12 |
13 | // import Geolocation from 'react-native-geolocation-service';
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | // navigator.geolocation = require('@react-native-community/geolocation')
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | const image = {uri: "https://www.globe.gov/o/globe-gov-measurements-portlet/img/map-background.png"}
32 | export default function HomeScreen({ navigation }: RootTabScreenProps<'Home'>) {
33 | // const [currentLongitude, setCurrentLongitude] = useState('')
34 | // const [currentLatitude, setCurrentLatitude] = useState('')
35 | const colorScheme = useColorScheme();
36 |
37 | // Geolocation.getCurrentPosition(
38 | // //Will give you the current location
39 | // (position) => {
40 | // //getting the Longitude from the location json
41 | // console.log(JSON.stringify(position.coords.longitude));
42 | // setCurrentLongitude(JSON.stringify(position.coords.longitude));
43 |
44 |
45 | // //getting the Latitude from the location json
46 | // console.log(JSON.stringify(position.coords.latitude));
47 | // setCurrentLatitude(JSON.stringify(position.coords.latitude))
48 |
49 |
50 | // }, (error) => alert(error.message), {
51 | // enableHighAccuracy: true, timeout: 20000, maximumAge: 1000
52 | // }
53 | // );
54 |
55 | // Geolocation.getCurrentPosition(
56 | // position => {
57 | // const initialPosition = JSON.stringify(position);
58 | // let region = {
59 | // latitude: position.coords.latitude,
60 | // longitude: position.coords.longitude,
61 | // latitudeDelta: 0.0922,
62 | // longitudeDelta: 0.0421,
63 | // }
64 | // // setState({initialPosition:region});
65 | // console.log("lat "+position.coords.latitude+" longi "+position.coords.longitude)
66 | // console.log("initialPosition")
67 | // // console.log(this.state.initialPosition)
68 | // },
69 | // error => console.log("Error "+ JSON.stringify(error)),
70 | // {enableHighAccuracy: true, timeout: 20000, maximumAge: 1000},
71 | // );
72 | // this.watchID = Geolocation.watchPosition(position => {
73 | // const lastPosition = JSON.stringify(position);
74 | // this.setState({lastPosition});
75 | // });
76 |
77 |
78 | return (
79 |
80 |
81 |
82 |
83 |
84 | Thunder
85 | 13
86 | O
87 |
88 |
89 |
90 |
91 |
92 | Humidity
93 | 11
94 |
95 |
96 |
97 |
98 | Wind
99 | 11.6
100 |
101 |
102 |
103 | Pressure
104 | 2.78
105 |
106 |
107 |
108 | );
109 | }
110 |
111 | const styles = StyleSheet.create({
112 | container: {
113 | flex: 1,
114 | justifyContent: 'center',
115 | },
116 | title: {
117 | fontSize: 20,
118 | fontWeight: 'bold',
119 | },
120 | separator: {
121 | marginVertical: 30,
122 | height: 1,
123 | width: '80%',
124 | },
125 | });
126 |
--------------------------------------------------------------------------------