diff --git a/TaskTerriers/App.tsx b/TaskTerriers/App.tsx
index a2dcedc..0f0606e 100644
--- a/TaskTerriers/App.tsx
+++ b/TaskTerriers/App.tsx
@@ -3,8 +3,10 @@ import { StatusBar } from 'expo-status-bar'
import { Col, Span } from './src/StyleToProps'
import * as SplashScreen from 'expo-splash-screen'
import useFonts from './hooks/useFonts'
-import { BottomTabs } from './navigation/BottomTabNavigator'
+import { BottomTabNavigation } from './src/navigation/BottomTabNavigator'
import { NavigationContainer } from '@react-navigation/native'
+import RootStack from './src/navigation/RootStack'
+import { TaskTerriersNavigationRef } from './src/navigation/NavigationModule'
export default function App() {
const [IsReady, SetIsReady] = useState(false)
@@ -50,8 +52,8 @@ export default function App() {
return (
-
-
+
+
)
diff --git a/TaskTerriers/navigation/BottomTabNavigator.tsx b/TaskTerriers/navigation/BottomTabNavigator.tsx
deleted file mode 100644
index 62ea832..0000000
--- a/TaskTerriers/navigation/BottomTabNavigator.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
-import RequestsTab from '../src/Screens/RequestsTab'
-import ServicesTab from '../src/Screens/ServicesTab'
-import MessagesTab from '../src/Screens/MessagesTab'
-import SettingsTab from '../src/Screens/SettingsTab'
-import { Col, Row, Span } from '../src/StyleToProps'
-import { Ionicons } from '@expo/vector-icons'
-import { BUColor, NeutralColor } from '../src/Libs/Colors'
-import { TouchableOpacity } from 'react-native'
-import { toStyle } from '../src/StyleToProps/withStyleProps'
-import { Style } from '../src/StyleToProps/styleProps'
-import { deviceInfo } from '../src/utilities/deviceInfo'
-
-const Tab = createBottomTabNavigator()
-
-export const BottomTabs = () => {
- return (
- }
- screenOptions={() => {
- return {
- tabBarShowIcon: true,
- tabBarShowLabel: false,
- headerShown: false,
- }
- }}>
- {/* */}
-
-
-
-
- )
-}
-
-const CustomTabBarContent = ({ state, descriptors, navigation }) => {
- return (
-
- {state.routes.map((route, index) => {
- const isFocused = state.index === index
- const { options } = descriptors[route.key]
- const onPress = () => {
- const event = navigation.emit({
- type: 'tabPress',
- target: route.key,
- canPreventDefault: true,
- })
-
- if (!isFocused && !event.defaultPrevented) {
- navigation.navigate(route.name, route.params)
- }
- }
- return (
- )}>
-
-
-
- {route.name}
-
-
-
- )
- })}
-
- )
-}
-
-const LocalTabBarIcon = (props: { focused: boolean; name: React.ComponentProps['name'] }) => {
- switch (props.name) {
- case 'Requests':
- if (props.focused) return
- else return
- case 'Services':
- if (props.focused) return
- else return
- case 'Messages':
- if (props.focused) return
- else return
- case 'Settings':
- if (props.focused) return
- else return
- default:
- return null
- }
-}
diff --git a/TaskTerriers/package.json b/TaskTerriers/package.json
index 2f62e32..0717014 100644
--- a/TaskTerriers/package.json
+++ b/TaskTerriers/package.json
@@ -15,10 +15,12 @@
"@react-navigation/bottom-tabs": "^6.5.11",
"@react-navigation/core": "^6.4.10",
"@react-navigation/native": "^6.1.9",
+ "@react-navigation/stack": "^6.3.20",
"@types/react": "~18.2.14",
"eslint-config-prettier": "^9.0.0",
"expo": "~49.0.15",
"expo-image": "^1.5.1",
+ "expo-navigation-bar": "^2.5.0",
"expo-splash-screen": "~0.20.5",
"expo-status-bar": "~1.6.0",
"prettier": "^3.1.0",
diff --git a/TaskTerriers/src/Screens/ServiceDetailScreen.tsx b/TaskTerriers/src/Screens/ServiceDetailScreen.tsx
new file mode 100644
index 0000000..1e1a60e
--- /dev/null
+++ b/TaskTerriers/src/Screens/ServiceDetailScreen.tsx
@@ -0,0 +1,67 @@
+import React, { useState, useEffect } from 'react'
+import { SafeAreaView, View, StyleSheet, Text, TouchableOpacity } from 'react-native'
+import NavigationBar from '../components/NavigationBar'
+import { IconNames } from '../components/types'
+import { TaskTerriersNavigationModule } from '../navigation/NavigationModule'
+
+interface Props { }
+
+
+const ServiceDetailScreen = ({ navigation, route }) => {
+
+ /*********
+ * recoil
+ *********/
+
+ /**************************
+ * props, navigation prams
+ **************************/
+
+ /*************
+ * state, ref
+ *************/
+
+ const [isRendering, setIsRendering] = useState(true)
+
+ /**************
+ * life cycles
+ **************/
+
+ useEffect(() => {
+ // ComponentDidMount
+
+ // setIsRendering(false)
+ return () => {
+ // ComponentWillUnmount
+ }
+ }, [])
+
+ /************
+ * functions
+ ************/
+
+ const onPressReturn = () => {
+ TaskTerriersNavigationModule.goBack()
+ }
+
+ /*********
+ * render
+ *********/
+
+ const renderNavBar = () => {
+ return
+ }
+
+ /***********
+ * render()
+ ***********/
+
+ return (
+
+ {renderNavBar()}
+
+ )
+
+}
+
+export default ServiceDetailScreen
diff --git a/TaskTerriers/src/Screens/ServicesTab.tsx b/TaskTerriers/src/Screens/ServicesTab.tsx
index adced86..968fbda 100644
--- a/TaskTerriers/src/Screens/ServicesTab.tsx
+++ b/TaskTerriers/src/Screens/ServicesTab.tsx
@@ -5,10 +5,13 @@ import { Col } from '../StyleToProps/Col'
import { Span } from '../StyleToProps'
import NavigationBar from '../components/NavigationBar'
import { IconNames } from '../components/types'
+import { UniversalButton } from '../components/Buttons'
+import { TaskTerriersNavigationModule } from '../navigation/NavigationModule'
+import { Root } from '../navigation/type'
-interface Props {}
+interface Props { }
-const ServicesTab = ({ navigation, route }) => {
+const ServicesTab = ({ route }) => {
/*********
* recoil
*********/
@@ -40,24 +43,36 @@ const ServicesTab = ({ navigation, route }) => {
* functions
************/
+ const onPressButton = () => {
+ return (
+ TaskTerriersNavigationModule.navigate('ServiceDetailScreen')
+ )
+ }
+
/*********
* render
*********/
- // if (isRendering === true) {
- // return null
- // }
+ const renderNavigationBar = () => {
+ return
+ }
+
+ const renderButton = () => {
+ console.log('Clicked button')
+ return
+ }
/***********
* render()
***********/
return (
-
-
-
- this is the ServicesTab
+
+ {renderNavigationBar()}
+
+ {renderButton()}
+
)
}
diff --git a/TaskTerriers/src/Views/TaskTerriersSafeAreaView.tsx b/TaskTerriers/src/Views/TaskTerriersSafeAreaView.tsx
index 3397b54..5b9f26d 100644
--- a/TaskTerriers/src/Views/TaskTerriersSafeAreaView.tsx
+++ b/TaskTerriers/src/Views/TaskTerriersSafeAreaView.tsx
@@ -63,7 +63,7 @@ const TaskTerriersSafeAreaView: React.FC = (props: Props) => {
style={[
{
flex: 1,
- backgroundColor: props?.backgroundColor || NeutralColor['neutral-100'],
+ backgroundColor: props?.backgroundColor || NeutralColor['neutral-80'],
paddingBottom: props.hasBottomSpace ? bottom : undefined,
},
props.style,
diff --git a/TaskTerriers/src/components/Divider/Divider.tsx b/TaskTerriers/src/components/Divider/Divider.tsx
index 049b418..c4cc207 100644
--- a/TaskTerriers/src/components/Divider/Divider.tsx
+++ b/TaskTerriers/src/components/Divider/Divider.tsx
@@ -14,7 +14,7 @@ const Divider: React.FC = ({ color, margin }) => {
return { marginLeft: 16, marginRight: 16 }
}
- return
+ return
}
export { Divider }
diff --git a/TaskTerriers/src/components/NavigationBar.tsx b/TaskTerriers/src/components/NavigationBar.tsx
index 2294339..4d130f2 100644
--- a/TaskTerriers/src/components/NavigationBar.tsx
+++ b/TaskTerriers/src/components/NavigationBar.tsx
@@ -10,10 +10,11 @@ interface NavigationBarProps {
title: TypographyType.Value
hasDivider?: boolean
iconName?: IconName.Value
+ iconAction?: () => void
backgroundColor?: UniversalColorType.Value
}
-const NavigationBar: React.FC = ({ title, hasDivider, iconName, backgroundColor }) => {
+const NavigationBar: React.FC = ({ title, hasDivider, iconName, backgroundColor, iconAction }) => {
/**************************
* props, navigation prams
**************************/
@@ -44,6 +45,9 @@ const NavigationBar: React.FC = ({ title, hasDivider, iconNa
if (backgroundColor) return backgroundColor
return '#ffffff'
}
+ const getHeight = () => {
+ return 54
+ }
/*********
* render
@@ -51,7 +55,16 @@ const NavigationBar: React.FC = ({ title, hasDivider, iconNa
const renderIcon = () => {
if (!iconName) return null
- return
+ if (iconAction) {
+ return (
+
+
+
+ )
+
+ } else {
+ return
+ }
}
const renderTitle = () => {
@@ -62,8 +75,8 @@ const NavigationBar: React.FC = ({ title, hasDivider, iconNa
)
}
- const getHeight = () => {
- return 54
+ const renderDivider = () => {
+ if (hasDivider) return
}
/***********
@@ -71,10 +84,13 @@ const NavigationBar: React.FC = ({ title, hasDivider, iconNa
***********/
return (
-
- {renderIcon()}
- {renderTitle()}
-
+ <>
+
+ {renderIcon()}
+ {renderTitle()}
+
+ {renderDivider()}
+ >
)
}
diff --git a/TaskTerriers/src/components/types.tsx b/TaskTerriers/src/components/types.tsx
index 7943cef..40b7c3b 100644
--- a/TaskTerriers/src/components/types.tsx
+++ b/TaskTerriers/src/components/types.tsx
@@ -24,6 +24,7 @@ export const IconNames = {
MessageOutline: 'chatbox-ellipses-outline',
Setting: 'settings-sharp',
SettingOutline: 'settings-outline',
+ Return: 'chevron-back'
} as const
declare namespace IconName {
@@ -149,7 +150,7 @@ const ListItemPaddingVerticalMap: Record = {
xxlarge: 0,
xxxlarge: 0,
} as const
-declare namespace ListItemType {}
+declare namespace ListItemType { }
declare namespace TabBarType {
type Value = Attr | string
diff --git a/TaskTerriers/src/navigation/AuthStack.tsx b/TaskTerriers/src/navigation/AuthStack.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/TaskTerriers/src/navigation/BottomTabNavigator.tsx b/TaskTerriers/src/navigation/BottomTabNavigator.tsx
new file mode 100644
index 0000000..22058d1
--- /dev/null
+++ b/TaskTerriers/src/navigation/BottomTabNavigator.tsx
@@ -0,0 +1,90 @@
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
+import RequestsTab from '../Screens/RequestsTab'
+import ServicesTab from '../Screens/ServicesTab'
+import MessagesTab from '../Screens/MessagesTab'
+import SettingsTab from '../Screens/SettingsTab'
+import { Col, Row, Span } from '../StyleToProps'
+import { Ionicons } from '@expo/vector-icons'
+import { BUColor, NeutralColor } from '../Libs/Colors'
+import { TouchableOpacity } from 'react-native'
+import { toStyle } from '../StyleToProps/withStyleProps'
+import { Style } from '../StyleToProps/styleProps'
+import { deviceInfo } from '../utilities/deviceInfo'
+
+const Tab = createBottomTabNavigator()
+
+export const BottomTabNavigation = () => {
+ return (
+ }
+ screenOptions={() => {
+ return {
+ tabBarShowIcon: true,
+ tabBarShowLabel: false,
+ headerShown: false,
+ }
+ }}>
+ {/* */}
+
+
+
+
+ )
+}
+
+const CustomTabBarContent = ({ state, descriptors, navigation }) => {
+ return (
+
+ {state.routes.map((route, index) => {
+ const isFocused = state.index === index
+ const { options } = descriptors[route.key]
+ const onPress = () => {
+ const event = navigation.emit({
+ type: 'tabPress',
+ target: route.key,
+ canPreventDefault: true,
+ })
+
+ if (!isFocused && !event.defaultPrevented) {
+ navigation.navigate(route.name, route.params)
+ }
+ }
+ return (
+ )}>
+
+
+
+ {route.name}
+
+
+
+ )
+ })}
+
+ )
+}
+
+const LocalTabBarIcon = (props: { focused: boolean; name: React.ComponentProps['name'] }) => {
+ switch (props.name) {
+ case 'Requests':
+ if (props.focused) return
+ else return
+ case 'Services':
+ if (props.focused) return
+ else return
+ case 'Messages':
+ if (props.focused) return
+ else return
+ case 'Settings':
+ if (props.focused) return
+ else return
+ default:
+ return null
+ }
+}
diff --git a/TaskTerriers/src/navigation/NavigationModule.ts b/TaskTerriers/src/navigation/NavigationModule.ts
new file mode 100644
index 0000000..6132fc7
--- /dev/null
+++ b/TaskTerriers/src/navigation/NavigationModule.ts
@@ -0,0 +1,55 @@
+import React from 'react'
+
+import { NavigationContainerRef, StackActions } from '@react-navigation/native'
+import { NavigationState, PartialState } from '@react-navigation/native'
+import { RootStackParamList } from './type'
+
+export const TaskTerriersNavigationRef: React.RefObject> | undefined = React.createRef()
+
+export function navigate(screenName: string, params?: any) {
+ console.log(' TaskTerriersNavigationRef: ', TaskTerriersNavigationRef)
+ // @ts-ignore
+ TaskTerriersNavigationRef.current?.navigate(screenName, params)
+}
+
+export function push(screenName: string, params?: any) {
+ TaskTerriersNavigationRef.current.dispatch(StackActions.push(screenName, params))
+}
+
+export function pop() {
+ TaskTerriersNavigationRef.current.dispatch(StackActions.pop())
+}
+
+export function goBack() {
+ TaskTerriersNavigationRef.current?.goBack()
+}
+
+export function popToTop() {
+ const targetScreen = TaskTerriersNavigationRef.current.getRootState?.()?.routes?.[0]?.name
+ if (!targetScreen) return
+ // @ts-ignore
+ TaskTerriersNavigationRef.current.navigate(targetScreen)
+}
+
+export function replace(screenName: string, params?: any) {
+ TaskTerriersNavigationRef.current.dispatch(StackActions.replace(screenName, params))
+}
+
+export async function reset(state: PartialState | NavigationState) {
+ TaskTerriersNavigationRef.current?.reset(state)
+}
+
+export function getCurrentScreenName() {
+ return TaskTerriersNavigationRef.current?.getCurrentRoute()?.name || ''
+}
+
+export const TaskTerriersNavigationModule = {
+ navigate,
+ push,
+ pop,
+ goBack,
+ popToTop,
+ replace,
+ reset,
+ getCurrentScreenName,
+}
diff --git a/TaskTerriers/src/navigation/RootStack.tsx b/TaskTerriers/src/navigation/RootStack.tsx
new file mode 100644
index 0000000..5e6ff9d
--- /dev/null
+++ b/TaskTerriers/src/navigation/RootStack.tsx
@@ -0,0 +1,26 @@
+import React from 'react'
+import { createStackNavigator } from '@react-navigation/stack';
+import { RootStackParamList } from './type';
+import NavigationBar from '../components/NavigationBar';
+import { BottomTabNavigation } from './BottomTabNavigator';
+import StackGroup from './StackGroup';
+
+const Stack = createStackNavigator()
+
+const RootStack = () => {
+ return (
+
+
+ {StackGroup()}
+
+
+ )
+}
+export default RootStack
\ No newline at end of file
diff --git a/TaskTerriers/src/navigation/StackGroup.tsx b/TaskTerriers/src/navigation/StackGroup.tsx
new file mode 100644
index 0000000..5d1466e
--- /dev/null
+++ b/TaskTerriers/src/navigation/StackGroup.tsx
@@ -0,0 +1,19 @@
+import React from 'react'
+import { RootStackParamList } from './type'
+import 'react-native-gesture-handler';
+import { createStackNavigator } from '@react-navigation/stack';
+import ServiceDetailScreen from '../Screens/ServiceDetailScreen';
+
+
+const Stack = createStackNavigator()
+const StackGroup = () => {
+ return (
+
+ {/* Services Tab */}
+
+
+ )
+}
+
+export default StackGroup
diff --git a/TaskTerriers/src/navigation/type.ts b/TaskTerriers/src/navigation/type.ts
new file mode 100644
index 0000000..9a54aaf
--- /dev/null
+++ b/TaskTerriers/src/navigation/type.ts
@@ -0,0 +1,19 @@
+type ValueType = string | number | boolean
+
+export type Union> = T extends ReadonlyArray
+ ? T[number]
+ : T extends { [key: string]: infer U }
+ ? U
+ : never
+
+export const Root = {
+ BottomTabNavigation: 'BottomTabNavigation',
+ ServiceDetailScreen: 'ServiceDetailScreen',
+} as const
+
+export type Root = Union
+
+export type RootStackParamList = {
+ [Root.BottomTabNavigation]: object
+ [Root.ServiceDetailScreen]: object
+}
diff --git a/TaskTerriers/yarn.lock b/TaskTerriers/yarn.lock
index e23c603..b22cab7 100644
--- a/TaskTerriers/yarn.lock
+++ b/TaskTerriers/yarn.lock
@@ -1915,6 +1915,15 @@
dependencies:
nanoid "^3.1.23"
+"@react-navigation/stack@^6.3.20":
+ version "6.3.20"
+ resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-6.3.20.tgz#8eec944888f317bb1ba1ff30e7f513806bea16c2"
+ integrity sha512-vE6mgZzOgoa5Uy7ayT97Cj+ZIK7DK+JBYVuKUViILlWZy6IWK7HFDuqoChSbZ1ajTIfAxj/acVGg1jkbAKsToA==
+ dependencies:
+ "@react-navigation/elements" "^1.3.21"
+ color "^4.2.3"
+ warn-once "^0.1.0"
+
"@segment/loosely-validate-event@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@segment/loosely-validate-event/-/loosely-validate-event-2.0.0.tgz#87dfc979e5b4e7b82c5f1d8b722dfd5d77644681"
@@ -3243,6 +3252,14 @@ expo-modules-core@1.5.11:
compare-versions "^3.4.0"
invariant "^2.2.4"
+expo-navigation-bar@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/expo-navigation-bar/-/expo-navigation-bar-2.5.0.tgz#4573eeae5a17afa0fca85fa17d4873af096257c0"
+ integrity sha512-cKwBNh692qBuly7fKeM+XBQSvsOf53CGmmyUNRTuQN7YWOEv9HSFzacPncr/Ne1jR2odML3jGgMO5fA+LnRGGw==
+ dependencies:
+ "@react-native/normalize-color" "^2.0.0"
+ debug "^4.3.2"
+
expo-splash-screen@~0.20.5:
version "0.20.5"
resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.20.5.tgz#ebeba3e3977606830f74f506ab2cc25042bb7efd"