Browse Source

new nav structure

master
azri 5 days ago
parent
commit
b4cb280ad1

app/(tabs)/_layout.tsx → app/(pages)/_layout.tsx View File

@@ -1,14 +1,14 @@
1 1
 import { Tabs } from 'expo-router';
2 2
 import React from 'react';
3 3
 import { Platform } from 'react-native';
4
-
4
+import Icon from 'react-native-vector-icons/MaterialIcons';
5 5
 import { HapticTab } from '@/components/HapticTab';
6 6
 import { IconSymbol } from '@/components/ui/IconSymbol';
7 7
 import TabBarBackground from '@/components/ui/TabBarBackground';
8 8
 import { Colors } from '@/constants/Colors';
9 9
 import { useColorScheme } from '@/hooks/useColorScheme';
10 10
 
11
-export default function TabLayout() {
11
+export default function ScreenLayout() {
12 12
   const colorScheme = useColorScheme();
13 13
 
14 14
   return (
@@ -18,28 +18,46 @@ export default function TabLayout() {
18 18
         headerShown: false,
19 19
         tabBarButton: HapticTab,
20 20
         tabBarBackground: TabBarBackground,
21
+        tabBarIconStyle: {
22
+          marginTop: 10,
23
+        },
21 24
         tabBarStyle: Platform.select({
22 25
           ios: {
23
-            // Use a transparent background on iOS to show the blur effect
24 26
             position: 'absolute',
27
+            height: 70,
28
+          },
29
+          default: {
30
+            backgroundColor: '#396868',
31
+            height: 70,
32
+            borderTopWidth: 0,
33
+            paddingVertical: 10
25 34
           },
26
-          default: {},
27 35
         }),
28
-      }}>
36
+      }}
37
+      >
29 38
       <Tabs.Screen
30 39
         name="index"
31 40
         options={{
32 41
           title: 'Home',
33
-          tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
42
+          tabBarIcon: ({ color }) => <Icon name="home" size={25} color={color} />,
43
+        }}
44
+      />
45
+      <Tabs.Screen
46
+        name="notify"
47
+        options={{
48
+          title: 'Notify',
49
+          tabBarIcon: ({ color }) => <Icon name="edit-document" size={25} color={color} />,
34 50
         }}
35 51
       />
52
+
36 53
       <Tabs.Screen
37
-        name="explore"
54
+        name="profile"
38 55
         options={{
39
-          title: 'Explore',
40
-          tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />,
56
+          title: 'Profile',
57
+          tabBarIcon: ({ color }) => <Icon name="person" size={25} color={color} />,
41 58
         }}
42 59
       />
60
+
43 61
     </Tabs>
44 62
   );
45 63
 }

app/screens/Home.jsx → app/(pages)/index.jsx View File


+ 112
- 0
app/(pages)/notify.jsx View File

@@ -0,0 +1,112 @@
1
+import React, { useState } from 'react';
2
+import { View, StyleSheet, TextInput, Text, ScrollView } from 'react-native';
3
+import { Appbar, Menu, Avatar, useTheme, Button } from 'react-native-paper';
4
+import Icon from 'react-native-vector-icons/MaterialIcons';
5
+import dpuser from "@/assets/images/userdp.png";
6
+
7
+const Notification = () => {
8
+  const { colors, fonts } = useTheme();
9
+  const [menuVisible, setMenuVisible] = useState(false);
10
+  const [inputContent, setInputContent] = useState("");
11
+
12
+
13
+  const preTextClick = (pretext) => {
14
+    setInputContent(pretext)
15
+  }
16
+
17
+  return (
18
+    <View style={[styles.container, { backgroundColor: colors.background }]}>
19
+      <Appbar.Header>
20
+
21
+        <Avatar.Image size={50} source={dpuser}></Avatar.Image>
22
+
23
+        <View style={styles.titleContainer}>
24
+          <Appbar.Content title="Send Notification" titleStyle={[fonts.titleLarge, styles.title]} />
25
+        </View>
26
+
27
+        {/* Menu Component */}
28
+        <Menu
29
+          visible={menuVisible}
30
+          onDismiss={() => setMenuVisible(false)}
31
+          anchor={
32
+            <Appbar.Action icon="dots-vertical" onPress={() => setMenuVisible(true)} />
33
+          }
34
+        >
35
+          <Menu.Item onPress={() => console.log('Profile Clicked')} title="Profile" />
36
+          <Menu.Item onPress={() => console.log('Settings Clicked')} title="Settings" />
37
+          <Menu.Item onPress={() => console.log('Logout Clicked')} title="Logout" />
38
+        </Menu>
39
+      </Appbar.Header>
40
+
41
+
42
+      <View style={{ flex: 1, marginTop: 20 }}>
43
+        <View style={{ flexDirection: "row", gap: 20, marginBottom: 20 }}>
44
+          <Text style={[fonts.titleLarge, { fontWeight: "bold" }]}>To :</Text>
45
+          <TextInput value='asd' style={{ flex: 1, paddingHorizontal: 20, borderBottomColor: "rgba(0,0,0,0.2)", borderBottomWidth: 1, marginEnd: 20 }}></TextInput>
46
+        </View>
47
+        <TextInput
48
+          style={styles.textArea}
49
+          value={inputContent}
50
+          onChangeText={setInputContent}
51
+          multiline={true} // Enables multi-line input
52
+          numberOfLines={8} // Sets an initial number of visible lines
53
+        />
54
+        <Text style={[fonts.titleLarge, { fontWeight: "bold", marginBottom:20 }]}>Select Pretext</Text>
55
+        <View style={{flex:1}}>
56
+          {[
57
+            "Request to Work From Home",
58
+            "Request for late Check In",
59
+            "Request for early Check Out",
60
+            "Notify for Annual Leave",
61
+            "Notify for Emergency Leave"
62
+          ].map(text => <Text onPress={()=>{preTextClick(text)}} style={[fonts.titleMedium, {marginBottom:20, fontWeight:"bold", color:colors.secondary}]} >{text}</Text> )}
63
+        </View>
64
+      </View>
65
+
66
+    </View>
67
+  );
68
+};
69
+
70
+const styles = StyleSheet.create({
71
+  container: {
72
+    flex: 1,
73
+    padding: 20,
74
+    width: '100%',
75
+  },
76
+  textArea: {
77
+    height: 220,
78
+    borderColor: "#ccc",
79
+    borderWidth: 1,
80
+    padding: 10,
81
+    borderRadius: 8,
82
+    textAlignVertical: "top", // Makes text start from the top-left
83
+    backgroundColor: "#fff",
84
+    marginBottom:20
85
+  },
86
+  badge: {
87
+    backgroundColor: "#BB5C3F",
88
+    color: "#FFF",
89
+    borderRadius: 100,
90
+    paddingVertical: 4,
91
+    paddingHorizontal: 6,
92
+    fontSize: 10,
93
+    fontWeight: "400",
94
+    verticalAlign: "middle",
95
+    marginStart: 5
96
+  },
97
+  titleContainer: {
98
+    flex: 1,
99
+    alignItems: 'center',
100
+  },
101
+  title: {
102
+    fontWeight: 'bold',
103
+  },
104
+  icon: {
105
+    padding: 10,
106
+    position: "absolute",
107
+    right: 10,
108
+    color: "#D9D9D9"
109
+  }
110
+});
111
+
112
+export default Notification;

+ 112
- 0
app/(pages)/profile.jsx View File

@@ -0,0 +1,112 @@
1
+import React, { useState } from 'react';
2
+import { View, StyleSheet, TextInput, Text, ScrollView } from 'react-native';
3
+import { Appbar, Menu, Avatar, useTheme, Button } from 'react-native-paper';
4
+import Icon from 'react-native-vector-icons/MaterialIcons';
5
+import dpuser from "@/assets/images/userdp.png";
6
+
7
+const Notification = () => {
8
+  const { colors, fonts } = useTheme();
9
+  const [menuVisible, setMenuVisible] = useState(false);
10
+  const [inputContent, setInputContent] = useState("");
11
+
12
+
13
+  const preTextClick = (pretext) => {
14
+    setInputContent(pretext)
15
+  }
16
+
17
+  return (
18
+    <View style={[styles.container, { backgroundColor: colors.background }]}>
19
+      <Appbar.Header>
20
+
21
+        <Avatar.Image size={50} source={dpuser}></Avatar.Image>
22
+
23
+        <View style={styles.titleContainer}>
24
+          <Appbar.Content title="Send Notification" titleStyle={[fonts.titleLarge, styles.title]} />
25
+        </View>
26
+
27
+        {/* Menu Component */}
28
+        <Menu
29
+          visible={menuVisible}
30
+          onDismiss={() => setMenuVisible(false)}
31
+          anchor={
32
+            <Appbar.Action icon="dots-vertical" onPress={() => setMenuVisible(true)} />
33
+          }
34
+        >
35
+          <Menu.Item onPress={() => console.log('Profile Clicked')} title="Profile" />
36
+          <Menu.Item onPress={() => console.log('Settings Clicked')} title="Settings" />
37
+          <Menu.Item onPress={() => console.log('Logout Clicked')} title="Logout" />
38
+        </Menu>
39
+      </Appbar.Header>
40
+
41
+
42
+      <View style={{ flex: 1, marginTop: 20 }}>
43
+        <View style={{ flexDirection: "row", gap: 20, marginBottom: 20 }}>
44
+          <Text style={[fonts.titleLarge, { fontWeight: "bold" }]}>To :</Text>
45
+          <TextInput value='asd' style={{ flex: 1, paddingHorizontal: 20, borderBottomColor: "rgba(0,0,0,0.2)", borderBottomWidth: 1, marginEnd: 20 }}></TextInput>
46
+        </View>
47
+        <TextInput
48
+          style={styles.textArea}
49
+          value={inputContent}
50
+          onChangeText={setInputContent}
51
+          multiline={true} // Enables multi-line input
52
+          numberOfLines={8} // Sets an initial number of visible lines
53
+        />
54
+        <Text style={[fonts.titleLarge, { fontWeight: "bold", marginBottom:20 }]}>Select Pretext</Text>
55
+        <View style={{flex:1}}>
56
+          {[
57
+            "Request to Work From Home",
58
+            "Request for late Check In",
59
+            "Request for early Check Out",
60
+            "Notify for Annual Leave",
61
+            "Notify for Emergency Leave"
62
+          ].map(text => <Text onPress={()=>{preTextClick(text)}} style={[fonts.titleMedium, {marginBottom:20, fontWeight:"bold", color:colors.secondary}]} >{text}</Text> )}
63
+        </View>
64
+      </View>
65
+
66
+    </View>
67
+  );
68
+};
69
+
70
+const styles = StyleSheet.create({
71
+  container: {
72
+    flex: 1,
73
+    padding: 20,
74
+    width: '100%',
75
+  },
76
+  textArea: {
77
+    height: 220,
78
+    borderColor: "#ccc",
79
+    borderWidth: 1,
80
+    padding: 10,
81
+    borderRadius: 8,
82
+    textAlignVertical: "top", // Makes text start from the top-left
83
+    backgroundColor: "#fff",
84
+    marginBottom:20
85
+  },
86
+  badge: {
87
+    backgroundColor: "#BB5C3F",
88
+    color: "#FFF",
89
+    borderRadius: 100,
90
+    paddingVertical: 4,
91
+    paddingHorizontal: 6,
92
+    fontSize: 10,
93
+    fontWeight: "400",
94
+    verticalAlign: "middle",
95
+    marginStart: 5
96
+  },
97
+  titleContainer: {
98
+    flex: 1,
99
+    alignItems: 'center',
100
+  },
101
+  title: {
102
+    fontWeight: 'bold',
103
+  },
104
+  icon: {
105
+    padding: 10,
106
+    position: "absolute",
107
+    right: 10,
108
+    color: "#D9D9D9"
109
+  }
110
+});
111
+
112
+export default Notification;

+ 0
- 109
app/(tabs)/explore.tsx View File

@@ -1,109 +0,0 @@
1
-import { StyleSheet, Image, Platform } from 'react-native';
2
-
3
-import { Collapsible } from '@/components/Collapsible';
4
-import { ExternalLink } from '@/components/ExternalLink';
5
-import ParallaxScrollView from '@/components/ParallaxScrollView';
6
-import { ThemedText } from '@/components/ThemedText';
7
-import { ThemedView } from '@/components/ThemedView';
8
-import { IconSymbol } from '@/components/ui/IconSymbol';
9
-
10
-export default function TabTwoScreen() {
11
-  return (
12
-    <ParallaxScrollView
13
-      headerBackgroundColor={{ light: '#D0D0D0', dark: '#353636' }}
14
-      headerImage={
15
-        <IconSymbol
16
-          size={310}
17
-          color="#808080"
18
-          name="chevron.left.forwardslash.chevron.right"
19
-          style={styles.headerImage}
20
-        />
21
-      }>
22
-      <ThemedView style={styles.titleContainer}>
23
-        <ThemedText type="title">Explore</ThemedText>
24
-      </ThemedView>
25
-      <ThemedText>This app includes example code to help you get started.</ThemedText>
26
-      <Collapsible title="File-based routing">
27
-        <ThemedText>
28
-          This app has two screens:{' '}
29
-          <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> and{' '}
30
-          <ThemedText type="defaultSemiBold">app/(tabs)/explore.tsx</ThemedText>
31
-        </ThemedText>
32
-        <ThemedText>
33
-          The layout file in <ThemedText type="defaultSemiBold">app/(tabs)/_layout.tsx</ThemedText>{' '}
34
-          sets up the tab navigator.
35
-        </ThemedText>
36
-        <ExternalLink href="https://docs.expo.dev/router/introduction">
37
-          <ThemedText type="link">Learn more</ThemedText>
38
-        </ExternalLink>
39
-      </Collapsible>
40
-      <Collapsible title="Android, iOS, and web support">
41
-        <ThemedText>
42
-          You can open this project on Android, iOS, and the web. To open the web version, press{' '}
43
-          <ThemedText type="defaultSemiBold">w</ThemedText> in the terminal running this project.
44
-        </ThemedText>
45
-      </Collapsible>
46
-      <Collapsible title="Images">
47
-        <ThemedText>
48
-          For static images, you can use the <ThemedText type="defaultSemiBold">@2x</ThemedText> and{' '}
49
-          <ThemedText type="defaultSemiBold">@3x</ThemedText> suffixes to provide files for
50
-          different screen densities
51
-        </ThemedText>
52
-        <Image source={require('@/assets/images/react-logo.png')} style={{ alignSelf: 'center' }} />
53
-        <ExternalLink href="https://reactnative.dev/docs/images">
54
-          <ThemedText type="link">Learn more</ThemedText>
55
-        </ExternalLink>
56
-      </Collapsible>
57
-      <Collapsible title="Custom fonts">
58
-        <ThemedText>
59
-          Open <ThemedText type="defaultSemiBold">app/_layout.tsx</ThemedText> to see how to load{' '}
60
-          <ThemedText style={{ fontFamily: 'SpaceMono' }}>
61
-            custom fonts such as this one.
62
-          </ThemedText>
63
-        </ThemedText>
64
-        <ExternalLink href="https://docs.expo.dev/versions/latest/sdk/font">
65
-          <ThemedText type="link">Learn more</ThemedText>
66
-        </ExternalLink>
67
-      </Collapsible>
68
-      <Collapsible title="Light and dark mode components">
69
-        <ThemedText>
70
-          This template has light and dark mode support. The{' '}
71
-          <ThemedText type="defaultSemiBold">useColorScheme()</ThemedText> hook lets you inspect
72
-          what the user's current color scheme is, and so you can adjust UI colors accordingly.
73
-        </ThemedText>
74
-        <ExternalLink href="https://docs.expo.dev/develop/user-interface/color-themes/">
75
-          <ThemedText type="link">Learn more</ThemedText>
76
-        </ExternalLink>
77
-      </Collapsible>
78
-      <Collapsible title="Animations">
79
-        <ThemedText>
80
-          This template includes an example of an animated component. The{' '}
81
-          <ThemedText type="defaultSemiBold">components/HelloWave.tsx</ThemedText> component uses
82
-          the powerful <ThemedText type="defaultSemiBold">react-native-reanimated</ThemedText>{' '}
83
-          library to create a waving hand animation.
84
-        </ThemedText>
85
-        {Platform.select({
86
-          ios: (
87
-            <ThemedText>
88
-              The <ThemedText type="defaultSemiBold">components/ParallaxScrollView.tsx</ThemedText>{' '}
89
-              component provides a parallax effect for the header image.
90
-            </ThemedText>
91
-          ),
92
-        })}
93
-      </Collapsible>
94
-    </ParallaxScrollView>
95
-  );
96
-}
97
-
98
-const styles = StyleSheet.create({
99
-  headerImage: {
100
-    color: '#808080',
101
-    bottom: -90,
102
-    left: -35,
103
-    position: 'absolute',
104
-  },
105
-  titleContainer: {
106
-    flexDirection: 'row',
107
-    gap: 8,
108
-  },
109
-});

+ 0
- 25
app/(tabs)/index.jsx View File

@@ -1,25 +0,0 @@
1
-// App.js
2
-import React, { useState } from 'react';
3
-import { PaperProvider } from 'react-native-paper';
4
-import { lightTheme, darkTheme } from '../../theme';
5
-import Welcome from '../screens/Welcome';
6
-import Home from '../screens/Home';
7
-import Request from '../screens/Request';
8
-import Status from '../screens/Status';
9
-import Notification from '../screens/Notification';
10
-import { Button, Switch } from 'react-native-paper';
11
-import { View } from 'react-native';
12
-
13
-const App = () => {
14
-  const [isDarkMode, setIsDarkMode] = useState(false);
15
-
16
-  return (
17
-    <PaperProvider theme={lightTheme}>
18
-      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
19
-        <Notification />
20
-      </View>
21
-    </PaperProvider>
22
-  );
23
-};
24
-
25
-export default App;

+ 5
- 10
app/_layout.tsx View File

@@ -1,8 +1,6 @@
1
-import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
2 1
 import { useFonts } from 'expo-font';
3 2
 import { Stack } from 'expo-router';
4 3
 import * as SplashScreen from 'expo-splash-screen';
5
-import { StatusBar } from 'expo-status-bar';
6 4
 import { useEffect } from 'react';
7 5
 import 'react-native-reanimated';
8 6
 
@@ -12,7 +10,7 @@ import { useColorScheme } from '@/hooks/useColorScheme';
12 10
 SplashScreen.preventAutoHideAsync();
13 11
 
14 12
 export default function RootLayout() {
15
-  const colorScheme = useColorScheme();
13
+
16 14
   const [loaded] = useFonts({
17 15
     SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
18 16
   });
@@ -28,12 +26,9 @@ export default function RootLayout() {
28 26
   }
29 27
 
30 28
   return (
31
-    <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
32
-      <Stack>
33
-        <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
34
-        <Stack.Screen name="+not-found" />
35
-      </Stack>
36
-      <StatusBar style="auto" />
37
-    </ThemeProvider>
29
+    <Stack>
30
+      <Stack.Screen name="(pages)" options={{ headerShown: false }} />
31
+      <Stack.Screen name="+not-found" />
32
+    </Stack>
38 33
   );
39 34
 }

+ 38
- 0
app/bak__layout.tsx View File

@@ -0,0 +1,38 @@
1
+import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
2
+import { useFonts } from 'expo-font';
3
+import { Stack } from 'expo-router';
4
+import * as SplashScreen from 'expo-splash-screen';
5
+import { StatusBar } from 'expo-status-bar';
6
+import { useEffect } from 'react';
7
+import 'react-native-reanimated';
8
+
9
+import { useColorScheme } from '@/hooks/useColorScheme';
10
+
11
+// Prevent the splash screen from auto-hiding before asset loading is complete.
12
+SplashScreen.preventAutoHideAsync();
13
+
14
+export default function RootLayout() {
15
+  const colorScheme = useColorScheme();
16
+  const [loaded] = useFonts({
17
+    SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
18
+  });
19
+
20
+  useEffect(() => {
21
+    if (loaded) {
22
+      SplashScreen.hideAsync();
23
+    }
24
+  }, [loaded]);
25
+
26
+  if (!loaded) {
27
+    return null;
28
+  }
29
+
30
+  return (
31
+    <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
32
+      <Stack>
33
+        <Stack.Screen name="(screen)" options={{ headerShown: false }} />
34
+        <Stack.Screen name="+not-found" />
35
+      </Stack>
36
+    </ThemeProvider>
37
+  );
38
+}

+ 70
- 0
components/Navbar.jsx View File

@@ -0,0 +1,70 @@
1
+import React from 'react';
2
+import { View, StyleSheet, Pressable, Text } from 'react-native';
3
+import Icon from 'react-native-vector-icons/MaterialIcons';
4
+import { usePathname } from 'expo-router';
5
+import { Link } from 'expo-router';
6
+
7
+const navItems = [
8
+    {
9
+        href: '/',
10
+        icon: 'home',
11
+        label: 'Home',
12
+        onPress: () => console.log("home"),
13
+    },
14
+    {
15
+        href: '/notify',
16
+        icon: 'edit-document',
17
+        label: 'Notify',
18
+        onPress: () => console.log("notify"),
19
+    },
20
+    {
21
+        href: '/explore',
22
+        icon: 'person',
23
+        label: 'Profile',
24
+        onPress: () => console.log("profile"),
25
+    },
26
+];
27
+
28
+const NavItem = ({ href, icon, label, onPress, isActive }) => (
29
+    <Link href={href}>
30
+        <Pressable onPress={onPress} style={[styles.navItem]}>
31
+            <Icon name={icon} size={30} style={[styles.icon, {opacity: isActive ? 1 : 0.5}]} />
32
+            <Text style={[styles.textLink, {opacity: isActive ? 1 : 0.5}]}>{label}</Text>
33
+        </Pressable>
34
+    </Link>
35
+);
36
+
37
+export function Navbar() {
38
+
39
+    const pathName = usePathname();
40
+
41
+    return (
42
+        <View style={styles.navContainer}>
43
+            {navItems.map((item, index) => (
44
+                <NavItem key={index} {...item} isActive={pathName == item.href} />
45
+            ))}
46
+        </View>
47
+    );
48
+}
49
+
50
+const styles = StyleSheet.create({
51
+    navContainer: {
52
+        backgroundColor: "#396868",
53
+        paddingVertical: 10,
54
+        width: "100%",
55
+        flexDirection: "row",
56
+        justifyContent: "space-evenly",
57
+    },
58
+    navItem: {
59
+        alignItems: 'center',
60
+    },
61
+    icon: {
62
+        color: "#FFF",
63
+        active:{
64
+            color:"#"
65
+        }
66
+    },
67
+    textLink: {
68
+        color: "#FFF",
69
+    },
70
+});

+ 2
- 2
constants/Colors.ts View File

@@ -3,8 +3,8 @@
3 3
  * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
4 4
  */
5 5
 
6
-const tintColorLight = '#0a7ea4';
7
-const tintColorDark = '#fff';
6
+const tintColorLight = '#FFF';
7
+const tintColorDark = '#FFF';
8 8
 
9 9
 export const Colors = {
10 10
   light: {

+ 1
- 0
tsconfig.json View File

@@ -11,6 +11,7 @@
11 11
   "include": [
12 12
     "**/*.ts",
13 13
     "**/*.tsx",
14
+    "**/*.jsx",
14 15
     ".expo/types/**/*.ts",
15 16
     "expo-env.d.ts"
16 17
   ]

Loading…
Cancel
Save