Compare commits
6 Commits
resourcing
...
resourcing
| Author | SHA1 | Date | |
|---|---|---|---|
| 258e20751e | |||
| 564ea68d29 | |||
| 4701fce07c | |||
| d58304a146 | |||
| 5577ef5d1e | |||
| c1bee77629 |
@@ -1,4 +1,5 @@
|
|||||||
import { AccentColor, MainColor } from "@/constants/color-palet";
|
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||||
|
import { Styles } from "@/styles/global-styles";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import { router, Stack } from "expo-router";
|
import { router, Stack } from "expo-router";
|
||||||
|
|
||||||
@@ -7,16 +8,16 @@ export default function ApplicationLayout() {
|
|||||||
<>
|
<>
|
||||||
<Stack
|
<Stack
|
||||||
screenOptions={{
|
screenOptions={{
|
||||||
headerStyle: { backgroundColor: MainColor.darkblue },
|
headerStyle: Styles.headerStyle,
|
||||||
headerTitleStyle: { color: MainColor.yellow, fontWeight: "bold" },
|
headerTitleStyle: Styles.headerTitleStyle,
|
||||||
headerTitleAlign: "center",
|
headerTitleAlign: "center",
|
||||||
contentStyle: {
|
contentStyle: {
|
||||||
borderBottomColor: AccentColor.blue,
|
borderBottomColor: AccentColor.blue,
|
||||||
borderBottomWidth: 2,
|
borderBottomWidth: 2,
|
||||||
},
|
},
|
||||||
headerLargeStyle: {
|
// headerLargeStyle: {
|
||||||
backgroundColor: MainColor.darkblue,
|
// backgroundColor: MainColor.darkblue,
|
||||||
},
|
// },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
@@ -28,7 +29,7 @@ export default function ApplicationLayout() {
|
|||||||
name="search"
|
name="search"
|
||||||
size={20}
|
size={20}
|
||||||
color={MainColor.yellow}
|
color={MainColor.yellow}
|
||||||
onPress={() => router.back()}
|
onPress={() => router.push("/(application)/user-search")}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
headerRight: () => (
|
headerRight: () => (
|
||||||
@@ -36,7 +37,7 @@ export default function ApplicationLayout() {
|
|||||||
name="notifications"
|
name="notifications"
|
||||||
size={20}
|
size={20}
|
||||||
color={MainColor.yellow}
|
color={MainColor.yellow}
|
||||||
onPress={() => router.back()}
|
onPress={() => router.push("/(application)/notifications")}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
@@ -73,7 +74,7 @@ export default function ApplicationLayout() {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="market-place/index"
|
name="marketplace/index"
|
||||||
options={{
|
options={{
|
||||||
title: "Market Place",
|
title: "Market Place",
|
||||||
headerLeft: () => (
|
headerLeft: () => (
|
||||||
@@ -87,7 +88,8 @@ export default function ApplicationLayout() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Stack.Screen
|
{/* Profile */}
|
||||||
|
{/* <Stack.Screen
|
||||||
name="profile/index"
|
name="profile/index"
|
||||||
options={{
|
options={{
|
||||||
title: "Profile",
|
title: "Profile",
|
||||||
@@ -100,6 +102,84 @@ export default function ApplicationLayout() {
|
|||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
|
/> */}
|
||||||
|
|
||||||
|
{/* <Stack.Screen
|
||||||
|
name="profile/[id]"
|
||||||
|
options={{
|
||||||
|
title: "Profile",
|
||||||
|
headerLeft: () => (
|
||||||
|
<Ionicons
|
||||||
|
name="arrow-back"
|
||||||
|
size={20}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
onPress={() => router.back()}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/> */}
|
||||||
|
|
||||||
|
{/* Event */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="event/(tabs)"
|
||||||
|
options={{
|
||||||
|
title: "Event",
|
||||||
|
headerLeft: () => (
|
||||||
|
<Ionicons
|
||||||
|
name="arrow-back"
|
||||||
|
size={20}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
onPress={() => router.push("/(application)/home")}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Stack.Screen
|
||||||
|
name="event/detail/[id]"
|
||||||
|
options={{
|
||||||
|
title: "Detail",
|
||||||
|
headerLeft: () => (
|
||||||
|
<Ionicons
|
||||||
|
name="arrow-back"
|
||||||
|
size={20}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
onPress={() => router.back()}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* User Search */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="user-search/index"
|
||||||
|
options={{
|
||||||
|
title: "Pencarian Pengguna",
|
||||||
|
headerLeft: () => (
|
||||||
|
<Ionicons
|
||||||
|
name="arrow-back"
|
||||||
|
size={20}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
onPress={() => router.back()}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Notification */}
|
||||||
|
<Stack.Screen
|
||||||
|
name="notifications/index"
|
||||||
|
options={{
|
||||||
|
title: "Notifikasi",
|
||||||
|
headerLeft: () => (
|
||||||
|
<Ionicons
|
||||||
|
name="arrow-back"
|
||||||
|
size={20}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
onPress={() => router.back()}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
@@ -86,7 +85,7 @@ const CustomTabNavigator = () => {
|
|||||||
activeIcon: "notifications",
|
activeIcon: "notifications",
|
||||||
label: "Forum",
|
label: "Forum",
|
||||||
component: NotificationScreen,
|
component: NotificationScreen,
|
||||||
path: "/(application)/(home-tabs)/forum",
|
path: "/forum",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "profile",
|
id: "profile",
|
||||||
@@ -94,7 +93,7 @@ const CustomTabNavigator = () => {
|
|||||||
activeIcon: "person",
|
activeIcon: "person",
|
||||||
label: "Katalog",
|
label: "Katalog",
|
||||||
component: ProfileScreen,
|
component: ProfileScreen,
|
||||||
path: "/(application)/(home-tabs)/katalog",
|
path: "/profile",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -102,7 +101,7 @@ const CustomTabNavigator = () => {
|
|||||||
// Function untuk handle tab press
|
// Function untuk handle tab press
|
||||||
const handleTabPress = (tabId: string) => {
|
const handleTabPress = (tabId: string) => {
|
||||||
setActiveTab(tabId);
|
setActiveTab(tabId);
|
||||||
// setShowHome(false); // Hide home when any tab is pressed
|
setShowHome(false); // Hide home when any tab is pressed
|
||||||
};
|
};
|
||||||
|
|
||||||
// Determine which component to show
|
// Determine which component to show
|
||||||
@@ -110,8 +109,9 @@ const CustomTabNavigator = () => {
|
|||||||
if (showHome || activeTab === "home") {
|
if (showHome || activeTab === "home") {
|
||||||
return HomeScreen;
|
return HomeScreen;
|
||||||
}
|
}
|
||||||
const selectedTab = tabs.find((tab) => tab.id === activeTab);
|
// const selectedTab = tabs.find((tab) => tab.id === activeTab);
|
||||||
return selectedTab ? selectedTab.component : HomeScreen;
|
// return selectedTab ? selectedTab.component : HomeScreen;
|
||||||
|
return HomeScreen
|
||||||
};
|
};
|
||||||
|
|
||||||
const ActiveComponent = getActiveComponent();
|
const ActiveComponent = getActiveComponent();
|
||||||
@@ -135,7 +135,7 @@ const CustomTabNavigator = () => {
|
|||||||
label={e.label}
|
label={e.label}
|
||||||
isActive={activeTab === e.id && !showHome}
|
isActive={activeTab === e.id && !showHome}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
// handleTabPress(e.id);
|
handleTabPress(e.id);
|
||||||
router.push(e.path as any);
|
router.push(e.path as any);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
64
app/(application)/event/(tabs)/_layout.tsx
Normal file
64
app/(application)/event/(tabs)/_layout.tsx
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { FontAwesome5, Ionicons } from "@expo/vector-icons";
|
||||||
|
import { Tabs } from "expo-router";
|
||||||
|
|
||||||
|
export default function EventLayout() {
|
||||||
|
return (
|
||||||
|
<Tabs
|
||||||
|
screenOptions={{
|
||||||
|
headerShown: false,
|
||||||
|
tabBarActiveTintColor: MainColor.yellow,
|
||||||
|
tabBarInactiveTintColor: MainColor.white,
|
||||||
|
tabBarStyle: {
|
||||||
|
backgroundColor: MainColor.darkblue,
|
||||||
|
},
|
||||||
|
// tabBarButton: HapticTab,
|
||||||
|
// tabBarBackground: BlurTabBarBackground,
|
||||||
|
// tabBarStyle: Platform.select({
|
||||||
|
// ios: {
|
||||||
|
// // Use a transparent background on iOS to show the blur effect
|
||||||
|
// position: "absolute",
|
||||||
|
// },
|
||||||
|
// default: {},
|
||||||
|
// }),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="index"
|
||||||
|
options={{
|
||||||
|
title: "Home",
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<Ionicons size={20} name="home" color={color} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="status"
|
||||||
|
options={{
|
||||||
|
title: "Status",
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<Ionicons size={20} name="list" color={color} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="kontribusi"
|
||||||
|
options={{
|
||||||
|
title: "Kontribusi",
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<Ionicons size={20} name="extension-puzzle" color={color} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="riwayat"
|
||||||
|
options={{
|
||||||
|
title: "Riwayat",
|
||||||
|
tabBarIcon: ({ color }) => (
|
||||||
|
<FontAwesome5 size={20} name="history" color={color} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Tabs>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
app/(application)/event/(tabs)/index.tsx
Normal file
25
app/(application)/event/(tabs)/index.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
||||||
|
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||||
|
import { Styles } from "@/styles/global-styles";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
import { Text, TouchableHighlight, View } from "react-native";
|
||||||
|
|
||||||
|
export default function Event() {
|
||||||
|
return (
|
||||||
|
<ViewWrapper>
|
||||||
|
<TouchableHighlight onPress={() => router.push("/event/detail/1")}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
padding: 20,
|
||||||
|
backgroundColor: MainColor.darkblue,
|
||||||
|
borderRadius: 10,
|
||||||
|
borderColor: AccentColor.blue,
|
||||||
|
borderWidth: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={Styles.textLabel}>Event</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableHighlight>
|
||||||
|
</ViewWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
11
app/(application)/event/(tabs)/kontribusi.tsx
Normal file
11
app/(application)/event/(tabs)/kontribusi.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
||||||
|
import { Styles } from "@/styles/global-styles";
|
||||||
|
import { Text } from "react-native";
|
||||||
|
|
||||||
|
export default function Kontribusi() {
|
||||||
|
return (
|
||||||
|
<ViewWrapper>
|
||||||
|
<Text style={Styles.textLabel}>Kontribusi</Text>
|
||||||
|
</ViewWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
11
app/(application)/event/(tabs)/riwayat.tsx
Normal file
11
app/(application)/event/(tabs)/riwayat.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
||||||
|
import { Styles } from "@/styles/global-styles";
|
||||||
|
import { Text } from "react-native";
|
||||||
|
|
||||||
|
export default function Riwayat() {
|
||||||
|
return (
|
||||||
|
<ViewWrapper>
|
||||||
|
<Text style={Styles.textLabel}>Riwayat</Text>
|
||||||
|
</ViewWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
11
app/(application)/event/(tabs)/status.tsx
Normal file
11
app/(application)/event/(tabs)/status.tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
||||||
|
import { Styles } from "@/styles/global-styles";
|
||||||
|
import { Text } from "react-native";
|
||||||
|
|
||||||
|
export default function Status() {
|
||||||
|
return (
|
||||||
|
<ViewWrapper>
|
||||||
|
<Text style={Styles.textLabel}>Status</Text>
|
||||||
|
</ViewWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
14
app/(application)/event/detail/[id].tsx
Normal file
14
app/(application)/event/detail/[id].tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
||||||
|
import { Styles } from "@/styles/global-styles";
|
||||||
|
import { useLocalSearchParams } from "expo-router";
|
||||||
|
import { Text } from "react-native";
|
||||||
|
|
||||||
|
export default function DetailEvent() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
console.log("id event >", id);
|
||||||
|
return (
|
||||||
|
<ViewWrapper>
|
||||||
|
<Text style={Styles.textLabel}>Detail Event {id}</Text>
|
||||||
|
</ViewWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import NewHomeView from "@/screens/Home/UiHome";
|
import UiHome from "@/screens/Home/UiHome";
|
||||||
|
|
||||||
export default function Application() {
|
export default function Application() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NewHomeView />
|
<UiHome />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
9
app/(application)/notifications/index.tsx
Normal file
9
app/(application)/notifications/index.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Text, View } from "react-native";
|
||||||
|
|
||||||
|
export default function Notifications() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text>Notifications</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Text, View } from "react-native";
|
import { Text, View } from "react-native";
|
||||||
|
|
||||||
export default function Profile() {
|
export default function Portofolio() {
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<Text>Profile</Text>
|
<Text>Portofolio</Text>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
11
app/(application)/portofolio/create/[id].tsx
Normal file
11
app/(application)/portofolio/create/[id].tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { Text, View } from "react-native";
|
||||||
|
import { useLocalSearchParams } from "expo-router";
|
||||||
|
|
||||||
|
export default function PortofolioCreate() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text>Portofolio Create {id}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
131
app/(application)/profile/[id].tsx
Normal file
131
app/(application)/profile/[id].tsx
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
|
||||||
|
import { IMenuDrawerItem } from "@/components/_Interface/types";
|
||||||
|
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
||||||
|
import AlertCustom from "@/components/Alert/AlertCustom";
|
||||||
|
import DrawerCustom from "@/components/Drawer/DrawerCustom";
|
||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
|
import { DRAWER_HEIGHT } from "@/constants/constans-value";
|
||||||
|
import Profile_MenuDrawerSection from "@/screens/Profile/menuDrawerSection";
|
||||||
|
import { Styles } from "@/styles/global-styles";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { router, Stack, useLocalSearchParams } from "expo-router";
|
||||||
|
import React, { useRef, useState } from "react";
|
||||||
|
import { Animated, Text, TouchableOpacity } from "react-native";
|
||||||
|
|
||||||
|
export default function Profile() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
||||||
|
const [showLogoutAlert, setShowLogoutAlert] = useState(false);
|
||||||
|
|
||||||
|
const drawerItems: IMenuDrawerItem[] = [
|
||||||
|
{
|
||||||
|
icon: "create",
|
||||||
|
label: "Edit profile",
|
||||||
|
path: "/(application)/profile/edit",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "camera",
|
||||||
|
label: "Ubah foto profile",
|
||||||
|
path: `/(application)/profile/update-photo/${id}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "image",
|
||||||
|
label: "Ubah latar belakang",
|
||||||
|
path: `/(application)/profile/update-background/${id}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "add-circle",
|
||||||
|
label: "Tambah portofolio",
|
||||||
|
path: `/(application)/portofolio/create/${id}`,
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// icon: "settings",
|
||||||
|
// label: "Dashboard Admin",
|
||||||
|
// path: `/(application)/profile/dashboard-admin`,
|
||||||
|
// },
|
||||||
|
{ icon: "log-out", label: "Keluar", color: "red", path: "" },
|
||||||
|
];
|
||||||
|
|
||||||
|
// Animasi menggunakan translateY (lebih kompatibel)
|
||||||
|
const drawerAnim = useRef(new Animated.Value(DRAWER_HEIGHT)).current; // mulai di luar bawah layar
|
||||||
|
|
||||||
|
const openDrawer = () => {
|
||||||
|
setIsDrawerOpen(true);
|
||||||
|
Animated.timing(drawerAnim, {
|
||||||
|
toValue: 0,
|
||||||
|
duration: 300,
|
||||||
|
useNativeDriver: true,
|
||||||
|
}).start();
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeDrawer = () => {
|
||||||
|
Animated.timing(drawerAnim, {
|
||||||
|
toValue: DRAWER_HEIGHT, // sesuaikan dengan tinggi drawer Anda
|
||||||
|
duration: 300,
|
||||||
|
useNativeDriver: true,
|
||||||
|
}).start(() => {
|
||||||
|
setIsDrawerOpen(false); // baru ganti state setelah animasi selesai
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLogout = () => {
|
||||||
|
console.log("User logout");
|
||||||
|
router.replace("/");
|
||||||
|
setShowLogoutAlert(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ViewWrapper>
|
||||||
|
{/* Header */}
|
||||||
|
<Stack.Screen
|
||||||
|
options={{
|
||||||
|
title: "Profile",
|
||||||
|
headerLeft: () => (
|
||||||
|
<Ionicons
|
||||||
|
name="arrow-back"
|
||||||
|
size={20}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
onPress={() => router.back()}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
headerRight: () => (
|
||||||
|
<TouchableOpacity onPress={openDrawer}>
|
||||||
|
<Ionicons
|
||||||
|
name="ellipsis-vertical"
|
||||||
|
size={20}
|
||||||
|
color={MainColor.yellow}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Text style={Styles.textLabel}>Profile {id}</Text>
|
||||||
|
</ViewWrapper>
|
||||||
|
|
||||||
|
{/* Drawer Komponen Eksternal */}
|
||||||
|
<DrawerCustom
|
||||||
|
height={350}
|
||||||
|
isVisible={isDrawerOpen}
|
||||||
|
drawerAnim={drawerAnim}
|
||||||
|
closeDrawer={closeDrawer}
|
||||||
|
>
|
||||||
|
<Profile_MenuDrawerSection
|
||||||
|
drawerItems={drawerItems}
|
||||||
|
setShowLogoutAlert={setShowLogoutAlert}
|
||||||
|
/>
|
||||||
|
</DrawerCustom>
|
||||||
|
|
||||||
|
{/* Alert Komponen Eksternal */}
|
||||||
|
<AlertCustom
|
||||||
|
isVisible={showLogoutAlert}
|
||||||
|
onLeftPress={() => setShowLogoutAlert(false)}
|
||||||
|
onRightPress={handleLogout}
|
||||||
|
title="Apakah anda yakin ingin keluar?"
|
||||||
|
textLeft="Batal"
|
||||||
|
textRight="Keluar"
|
||||||
|
colorRight={MainColor.red}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
9
app/(application)/profile/edit.tsx
Normal file
9
app/(application)/profile/edit.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Text, View } from "react-native";
|
||||||
|
|
||||||
|
export default function ProfileEdit() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text>Profile Edit</Text>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
11
app/(application)/profile/update-background/[id].tsx
Normal file
11
app/(application)/profile/update-background/[id].tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { Text, View } from "react-native";
|
||||||
|
import { useLocalSearchParams } from "expo-router";
|
||||||
|
|
||||||
|
export default function UpdatePhotoBackground() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text>Update Photo Background {id}</Text>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
11
app/(application)/profile/update-photo/[id].tsx
Normal file
11
app/(application)/profile/update-photo/[id].tsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { Text, View } from "react-native";
|
||||||
|
import { useLocalSearchParams } from "expo-router";
|
||||||
|
|
||||||
|
export default function UpdatePhotoProfile() {
|
||||||
|
const { id } = useLocalSearchParams();
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text>Update Photo Profile {id}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Text, View } from "react-native";
|
import { Text, View } from "react-native";
|
||||||
|
|
||||||
export default function Event() {
|
export default function UserSearch() {
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<Text>Event</Text>
|
<Text>User Search</Text>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,34 +1,71 @@
|
|||||||
import { MainColor } from "@/constants/color-palet";
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import { Stack } from "expo-router";
|
import { Stack } from "expo-router";
|
||||||
|
import "react-native-gesture-handler";
|
||||||
import { SafeAreaProvider } from "react-native-safe-area-context";
|
import { SafeAreaProvider } from "react-native-safe-area-context";
|
||||||
|
|
||||||
export default function RootLayout() {
|
export default function RootLayout() {
|
||||||
return (
|
return (
|
||||||
<SafeAreaProvider
|
<>
|
||||||
style={{
|
<SafeAreaProvider>
|
||||||
backgroundColor: MainColor.darkblue,
|
<Stack
|
||||||
}}
|
screenOptions={{
|
||||||
>
|
headerStyle: { backgroundColor: MainColor.darkblue },
|
||||||
<Stack
|
headerTitleStyle: { color: MainColor.yellow, fontWeight: "bold" },
|
||||||
screenOptions={{
|
headerTitleAlign: "center",
|
||||||
headerStyle: { backgroundColor: MainColor.darkblue },
|
// contentStyle: {
|
||||||
headerTitleStyle: { color: MainColor.yellow, fontWeight: "bold" },
|
// borderBottomColor: AccentColor.blue,
|
||||||
headerTitleAlign: "center",
|
// borderBottomWidth: 2,
|
||||||
// contentStyle: {
|
// },
|
||||||
// borderBottomColor: AccentColor.blue,
|
// headerLargeStyle: {
|
||||||
// borderBottomWidth: 2,
|
// backgroundColor: MainColor.darkblue,
|
||||||
// },
|
// },
|
||||||
// headerLargeStyle: {
|
// headerShadowVisible: false,
|
||||||
// backgroundColor: MainColor.darkblue,
|
}}
|
||||||
// },
|
>
|
||||||
// headerShadowVisible: false,
|
<Stack.Screen name="index" options={{ headerShown: false }} />
|
||||||
}}
|
<Stack.Screen name="verification" options={{ headerShown: false }} />
|
||||||
>
|
<Stack.Screen name="register" options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="index" options={{ headerShown: false }} />
|
<Stack.Screen name="(application)" options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="verification" options={{ headerShown: false }} />
|
</Stack>
|
||||||
<Stack.Screen name="register" options={{ headerShown: false }} />
|
</SafeAreaProvider>
|
||||||
<Stack.Screen name="(application)" options={{ headerShown: false }} />
|
</>
|
||||||
</Stack>
|
// <SafeAreaProvider
|
||||||
</SafeAreaProvider>
|
// style={{
|
||||||
|
// backgroundColor: AccentColor.darkblue,
|
||||||
|
// }}
|
||||||
|
// >
|
||||||
|
// <SafeAreaView
|
||||||
|
// edges={[
|
||||||
|
// "bottom",
|
||||||
|
// // "top",
|
||||||
|
// ]}
|
||||||
|
// style={{
|
||||||
|
// flex: 1,
|
||||||
|
// // paddingTop: StatusBar.currentHeight,
|
||||||
|
// // backgroundColor: MainColor.darkblue,
|
||||||
|
// }}
|
||||||
|
// >
|
||||||
|
// <Stack
|
||||||
|
// screenOptions={{
|
||||||
|
// headerStyle: { backgroundColor: MainColor.darkblue },
|
||||||
|
// headerTitleStyle: { color: MainColor.yellow, fontWeight: "bold" },
|
||||||
|
// headerTitleAlign: "center",
|
||||||
|
// // contentStyle: {
|
||||||
|
// // borderBottomColor: AccentColor.blue,
|
||||||
|
// // borderBottomWidth: 2,
|
||||||
|
// // },
|
||||||
|
// // headerLargeStyle: {
|
||||||
|
// // backgroundColor: MainColor.darkblue,
|
||||||
|
// // },
|
||||||
|
// // headerShadowVisible: false,
|
||||||
|
// }}
|
||||||
|
// >
|
||||||
|
// <Stack.Screen name="index" options={{ headerShown: false }} />
|
||||||
|
// <Stack.Screen name="verification" options={{ headerShown: false }} />
|
||||||
|
// <Stack.Screen name="register" options={{ headerShown: false }} />
|
||||||
|
// <Stack.Screen name="(application)" options={{ headerShown: false }} />
|
||||||
|
// </Stack>
|
||||||
|
// </SafeAreaView>
|
||||||
|
// </SafeAreaProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
19
bun.lock
19
bun.lock
@@ -6,18 +6,19 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@expo/vector-icons": "^14.1.0",
|
"@expo/vector-icons": "^14.1.0",
|
||||||
"@react-navigation/bottom-tabs": "^7.4.2",
|
"@react-navigation/bottom-tabs": "^7.4.2",
|
||||||
|
"@react-navigation/drawer": "^7.5.2",
|
||||||
"@react-navigation/elements": "^2.3.8",
|
"@react-navigation/elements": "^2.3.8",
|
||||||
"@react-navigation/native": "^7.1.6",
|
"@react-navigation/native": "^7.1.6",
|
||||||
"@react-navigation/native-stack": "^7.3.21",
|
"@react-navigation/native-stack": "^7.3.21",
|
||||||
"@types/react-native-vector-icons": "^6.4.18",
|
"@types/react-native-vector-icons": "^6.4.18",
|
||||||
"expo": "~53.0.12",
|
"expo": "53.0.13",
|
||||||
"expo-blur": "~14.1.5",
|
"expo-blur": "~14.1.5",
|
||||||
"expo-constants": "~17.1.6",
|
"expo-constants": "~17.1.6",
|
||||||
"expo-font": "~13.3.1",
|
"expo-font": "~13.3.1",
|
||||||
"expo-haptics": "~14.1.4",
|
"expo-haptics": "~14.1.4",
|
||||||
"expo-image": "~2.3.0",
|
"expo-image": "~2.3.0",
|
||||||
"expo-linking": "~7.1.5",
|
"expo-linking": "~7.1.5",
|
||||||
"expo-router": "~5.1.0",
|
"expo-router": "~5.1.1",
|
||||||
"expo-splash-screen": "~0.30.9",
|
"expo-splash-screen": "~0.30.9",
|
||||||
"expo-status-bar": "~2.2.3",
|
"expo-status-bar": "~2.2.3",
|
||||||
"expo-symbols": "~0.4.5",
|
"expo-symbols": "~0.4.5",
|
||||||
@@ -390,6 +391,8 @@
|
|||||||
|
|
||||||
"@react-navigation/core": ["@react-navigation/core@7.11.0", "", { "dependencies": { "@react-navigation/routers": "^7.4.1", "escape-string-regexp": "^4.0.0", "nanoid": "^3.3.11", "query-string": "^7.1.3", "react-is": "^19.1.0", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": ">= 18.2.0" } }, "sha512-LfYPtxsMjldJ80BBeedaDCN0LE81WU1NP4V9Ia3wSrCPTAXt11y6holaBUrmUMVQVqpEyPRQrjwrT1QkfGKquw=="],
|
"@react-navigation/core": ["@react-navigation/core@7.11.0", "", { "dependencies": { "@react-navigation/routers": "^7.4.1", "escape-string-regexp": "^4.0.0", "nanoid": "^3.3.11", "query-string": "^7.1.3", "react-is": "^19.1.0", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": ">= 18.2.0" } }, "sha512-LfYPtxsMjldJ80BBeedaDCN0LE81WU1NP4V9Ia3wSrCPTAXt11y6holaBUrmUMVQVqpEyPRQrjwrT1QkfGKquw=="],
|
||||||
|
|
||||||
|
"@react-navigation/drawer": ["@react-navigation/drawer@7.5.2", "", { "dependencies": { "@react-navigation/elements": "^2.5.2", "color": "^4.2.3", "react-native-drawer-layout": "^4.1.11", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "@react-navigation/native": "^7.1.14", "react": ">= 18.2.0", "react-native": "*", "react-native-gesture-handler": ">= 2.0.0", "react-native-reanimated": ">= 2.0.0", "react-native-safe-area-context": ">= 4.0.0", "react-native-screens": ">= 4.0.0" } }, "sha512-1FSo+DyJe2zlIcQBhHcayZCe2aAF2JF+rpn7HnVnTV2HaCEpgJ0/zgHIa9MZByKntp/aSexL9YkDFQhQj2+7ag=="],
|
||||||
|
|
||||||
"@react-navigation/elements": ["@react-navigation/elements@2.4.5", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.1.12", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-rzoQQ07dZGA3h608imB1nAZ2rPw9vZ2xc2K36XSZoV/7IZRDxI4BCIj38Wc4saQaYhfJIoeVssK4+6IwhZBedg=="],
|
"@react-navigation/elements": ["@react-navigation/elements@2.4.5", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.1.12", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-rzoQQ07dZGA3h608imB1nAZ2rPw9vZ2xc2K36XSZoV/7IZRDxI4BCIj38Wc4saQaYhfJIoeVssK4+6IwhZBedg=="],
|
||||||
|
|
||||||
"@react-navigation/native": ["@react-navigation/native@7.1.12", "", { "dependencies": { "@react-navigation/core": "^7.11.0", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*" } }, "sha512-ezHzrZN+9SE4Co6/H8MgDWlBxfJbVc5xi8szRi2QW8eJlsZsAvgGqtKs4YECraV4Yr9zW8RCzNuUxYiQiPMtEQ=="],
|
"@react-navigation/native": ["@react-navigation/native@7.1.12", "", { "dependencies": { "@react-navigation/core": "^7.11.0", "escape-string-regexp": "^4.0.0", "fast-deep-equal": "^3.1.3", "nanoid": "^3.3.11", "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*" } }, "sha512-ezHzrZN+9SE4Co6/H8MgDWlBxfJbVc5xi8szRi2QW8eJlsZsAvgGqtKs4YECraV4Yr9zW8RCzNuUxYiQiPMtEQ=="],
|
||||||
@@ -802,7 +805,7 @@
|
|||||||
|
|
||||||
"exec-async": ["exec-async@2.2.0", "", {}, "sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw=="],
|
"exec-async": ["exec-async@2.2.0", "", {}, "sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw=="],
|
||||||
|
|
||||||
"expo": ["expo@53.0.12", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "0.24.15", "@expo/config": "~11.0.10", "@expo/config-plugins": "~10.0.3", "@expo/fingerprint": "0.13.1", "@expo/metro-config": "0.20.15", "@expo/vector-icons": "^14.0.0", "babel-preset-expo": "~13.2.1", "expo-asset": "~11.1.5", "expo-constants": "~17.1.6", "expo-file-system": "~18.1.10", "expo-font": "~13.3.1", "expo-keep-awake": "~14.1.4", "expo-modules-autolinking": "2.1.12", "expo-modules-core": "2.4.0", "react-native-edge-to-edge": "1.6.0", "whatwg-url-without-unicode": "8.0.0-3" }, "peerDependencies": { "@expo/dom-webview": "*", "@expo/metro-runtime": "*", "react": "*", "react-native": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/dom-webview"], "bin": { "expo": "bin/cli", "expo-modules-autolinking": "bin/autolinking", "fingerprint": "bin/fingerprint" } }, "sha512-dtmED749hkxDWCcvtD++tb8bAm3Twv8qnUOXzVyXA5owNG0mwDIz0HveJTpWK1UzkY4HcTVRezDf0tflZJ+JXQ=="],
|
"expo": ["expo@53.0.13", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "0.24.15", "@expo/config": "~11.0.10", "@expo/config-plugins": "~10.0.3", "@expo/fingerprint": "0.13.1", "@expo/metro-config": "0.20.15", "@expo/vector-icons": "^14.0.0", "babel-preset-expo": "~13.2.1", "expo-asset": "~11.1.5", "expo-constants": "~17.1.6", "expo-file-system": "~18.1.10", "expo-font": "~13.3.1", "expo-keep-awake": "~14.1.4", "expo-modules-autolinking": "2.1.12", "expo-modules-core": "2.4.0", "react-native-edge-to-edge": "1.6.0", "whatwg-url-without-unicode": "8.0.0-3" }, "peerDependencies": { "@expo/dom-webview": "*", "@expo/metro-runtime": "*", "react": "*", "react-native": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/dom-webview", "@expo/metro-runtime", "react-native-webview"], "bin": { "expo": "bin/cli", "fingerprint": "bin/fingerprint", "expo-modules-autolinking": "bin/autolinking" } }, "sha512-QDdEEbFErUmm2IHR/UPKKIRLN3z5MmN2QLx0aPlOEGOx295buSUE42u6f7TppkgJn0BUX3f7wFaHRo86+G+Trg=="],
|
||||||
|
|
||||||
"expo-asset": ["expo-asset@11.1.5", "", { "dependencies": { "@expo/image-utils": "^0.7.4", "expo-constants": "~17.1.5" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-GEQDCqC25uDBoXHEnXeBuwpeXvI+3fRGvtzwwt0ZKKzWaN+TgeF8H7c76p3Zi4DfBMFDcduM0CmOvJX+yCCLUQ=="],
|
"expo-asset": ["expo-asset@11.1.5", "", { "dependencies": { "@expo/image-utils": "^0.7.4", "expo-constants": "~17.1.5" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-GEQDCqC25uDBoXHEnXeBuwpeXvI+3fRGvtzwwt0ZKKzWaN+TgeF8H7c76p3Zi4DfBMFDcduM0CmOvJX+yCCLUQ=="],
|
||||||
|
|
||||||
@@ -826,7 +829,7 @@
|
|||||||
|
|
||||||
"expo-modules-core": ["expo-modules-core@2.4.0", "", { "dependencies": { "invariant": "^2.2.4" } }, "sha512-Ko5eHBdvuMykjw9P9C9PF54/wBSsGOxaOjx92I5BwgKvEmUwN3UrXFV4CXzlLVbLfSYUQaLcB220xmPfgvT7Fg=="],
|
"expo-modules-core": ["expo-modules-core@2.4.0", "", { "dependencies": { "invariant": "^2.2.4" } }, "sha512-Ko5eHBdvuMykjw9P9C9PF54/wBSsGOxaOjx92I5BwgKvEmUwN3UrXFV4CXzlLVbLfSYUQaLcB220xmPfgvT7Fg=="],
|
||||||
|
|
||||||
"expo-router": ["expo-router@5.1.0", "", { "dependencies": { "@expo/metro-runtime": "5.0.4", "@expo/server": "^0.6.2", "@radix-ui/react-slot": "1.2.0", "@react-navigation/bottom-tabs": "^7.3.10", "@react-navigation/native": "^7.1.6", "@react-navigation/native-stack": "^7.3.10", "client-only": "^0.0.1", "invariant": "^2.2.4", "react-fast-compare": "^3.2.2", "react-native-is-edge-to-edge": "^1.1.6", "schema-utils": "^4.0.1", "semver": "~7.6.3", "server-only": "^0.0.1", "shallowequal": "^1.1.0" }, "peerDependencies": { "@react-navigation/drawer": "^7.3.9", "expo": "*", "expo-constants": "*", "expo-linking": "*", "react-native-reanimated": "*", "react-native-safe-area-context": "*", "react-native-screens": "*" }, "optionalPeers": ["@react-navigation/drawer"] }, "sha512-mnKpw35W6kKPpZm+ZxQei6HGUx2JO3znzqJZInzqrTZMgfAcHGgvP9AQFjg/Qi/Qy1CxunB9aQnqE9JPbSwbpw=="],
|
"expo-router": ["expo-router@5.1.1", "", { "dependencies": { "@expo/metro-runtime": "5.0.4", "@expo/server": "^0.6.3", "@radix-ui/react-slot": "1.2.0", "@react-navigation/bottom-tabs": "^7.3.10", "@react-navigation/native": "^7.1.6", "@react-navigation/native-stack": "^7.3.10", "client-only": "^0.0.1", "invariant": "^2.2.4", "react-fast-compare": "^3.2.2", "react-native-is-edge-to-edge": "^1.1.6", "schema-utils": "^4.0.1", "semver": "~7.6.3", "server-only": "^0.0.1", "shallowequal": "^1.1.0" }, "peerDependencies": { "@react-navigation/drawer": "^7.3.9", "expo": "*", "expo-constants": "*", "expo-linking": "*", "react-native-reanimated": "*", "react-native-safe-area-context": "*", "react-native-screens": "*" }, "optionalPeers": ["@react-navigation/drawer", "react-native-reanimated"] }, "sha512-KYAp/SwkPVgY+8OI+UPGENZG4j+breoOMXmZ01s99U7X0dpSihKGSNpK6LkEoU31MXMLuUHGYYwD00zm9aqcSg=="],
|
||||||
|
|
||||||
"expo-splash-screen": ["expo-splash-screen@0.30.9", "", { "dependencies": { "@expo/prebuild-config": "^9.0.6" }, "peerDependencies": { "expo": "*" } }, "sha512-curHUaZxUTZ2dWvz32ao3xPv5mJr1LBqn5V8xm/IULAehB9RGCn8iKiROMN1PYebSG+56vPMuJmBm9P+ayvJpA=="],
|
"expo-splash-screen": ["expo-splash-screen@0.30.9", "", { "dependencies": { "@expo/prebuild-config": "^9.0.6" }, "peerDependencies": { "expo": "*" } }, "sha512-curHUaZxUTZ2dWvz32ao3xPv5mJr1LBqn5V8xm/IULAehB9RGCn8iKiROMN1PYebSG+56vPMuJmBm9P+ayvJpA=="],
|
||||||
|
|
||||||
@@ -1352,6 +1355,8 @@
|
|||||||
|
|
||||||
"react-native-country-codes-picker": ["react-native-country-codes-picker@2.3.5", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-dDQhd0bVvlmgb84NPhTOmTk5UVYPHtk3lqZI+BPb61H1rC2IDrTvPWENg6u1DMGliqWHQDBYpeH37zvxxQL71w=="],
|
"react-native-country-codes-picker": ["react-native-country-codes-picker@2.3.5", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-dDQhd0bVvlmgb84NPhTOmTk5UVYPHtk3lqZI+BPb61H1rC2IDrTvPWENg6u1DMGliqWHQDBYpeH37zvxxQL71w=="],
|
||||||
|
|
||||||
|
"react-native-drawer-layout": ["react-native-drawer-layout@4.1.11", "", { "dependencies": { "use-latest-callback": "^0.2.4" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*", "react-native-gesture-handler": ">= 2.0.0", "react-native-reanimated": ">= 2.0.0" } }, "sha512-31gilubSKPLToy31/bb0hhgOOenHYJq4JC7g/JkIEqBqSWzoCgiOlccDHlBRG+MV37UtXZnJN2spj3VusdCd4A=="],
|
||||||
|
|
||||||
"react-native-edge-to-edge": ["react-native-edge-to-edge@1.6.0", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-2WCNdE3Qd6Fwg9+4BpbATUxCLcouF6YRY7K+J36KJ4l3y+tWN6XCqAC4DuoGblAAbb2sLkhEDp4FOlbOIot2Og=="],
|
"react-native-edge-to-edge": ["react-native-edge-to-edge@1.6.0", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-2WCNdE3Qd6Fwg9+4BpbATUxCLcouF6YRY7K+J36KJ4l3y+tWN6XCqAC4DuoGblAAbb2sLkhEDp4FOlbOIot2Og=="],
|
||||||
|
|
||||||
"react-native-gesture-handler": ["react-native-gesture-handler@2.24.0", "", { "dependencies": { "@egjs/hammerjs": "^2.0.17", "hoist-non-react-statics": "^3.3.0", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-ZdWyOd1C8axKJHIfYxjJKCcxjWEpUtUWgTOVY2wynbiveSQDm8X/PDyAKXSer/GOtIpjudUbACOndZXCN3vHsw=="],
|
"react-native-gesture-handler": ["react-native-gesture-handler@2.24.0", "", { "dependencies": { "@egjs/hammerjs": "^2.0.17", "hoist-non-react-statics": "^3.3.0", "invariant": "^2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-ZdWyOd1C8axKJHIfYxjJKCcxjWEpUtUWgTOVY2wynbiveSQDm8X/PDyAKXSer/GOtIpjudUbACOndZXCN3vHsw=="],
|
||||||
@@ -1770,6 +1775,8 @@
|
|||||||
|
|
||||||
"@react-navigation/bottom-tabs/@react-navigation/elements": ["@react-navigation/elements@2.5.2", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.1.14", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-aGC3ukF5+lXuiF5bK7bJyRuWCE+Tk4MZ3GoQpAb7u7+m0KmsquliDhj4UCWEUU5kUoCeoRAUvv+1lKcYKf+WTQ=="],
|
"@react-navigation/bottom-tabs/@react-navigation/elements": ["@react-navigation/elements@2.5.2", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.1.14", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-aGC3ukF5+lXuiF5bK7bJyRuWCE+Tk4MZ3GoQpAb7u7+m0KmsquliDhj4UCWEUU5kUoCeoRAUvv+1lKcYKf+WTQ=="],
|
||||||
|
|
||||||
|
"@react-navigation/drawer/@react-navigation/elements": ["@react-navigation/elements@2.5.2", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.1.14", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-aGC3ukF5+lXuiF5bK7bJyRuWCE+Tk4MZ3GoQpAb7u7+m0KmsquliDhj4UCWEUU5kUoCeoRAUvv+1lKcYKf+WTQ=="],
|
||||||
|
|
||||||
"@react-navigation/native-stack/@react-navigation/elements": ["@react-navigation/elements@2.5.2", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.1.14", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-aGC3ukF5+lXuiF5bK7bJyRuWCE+Tk4MZ3GoQpAb7u7+m0KmsquliDhj4UCWEUU5kUoCeoRAUvv+1lKcYKf+WTQ=="],
|
"@react-navigation/native-stack/@react-navigation/elements": ["@react-navigation/elements@2.5.2", "", { "dependencies": { "color": "^4.2.3", "use-latest-callback": "^0.2.4", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.1.14", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-aGC3ukF5+lXuiF5bK7bJyRuWCE+Tk4MZ3GoQpAb7u7+m0KmsquliDhj4UCWEUU5kUoCeoRAUvv+1lKcYKf+WTQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||||
@@ -1820,10 +1827,6 @@
|
|||||||
|
|
||||||
"expo-modules-autolinking/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
"expo-modules-autolinking/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
||||||
|
|
||||||
"expo-router/@react-navigation/bottom-tabs": ["@react-navigation/bottom-tabs@7.3.16", "", { "dependencies": { "@react-navigation/elements": "^2.4.5", "color": "^4.2.3" }, "peerDependencies": { "@react-navigation/native": "^7.1.12", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0", "react-native-screens": ">= 4.0.0" } }, "sha512-BOVtrq5J3zV3T9CeQexX20JrjECWwIgUJj0Uj0DTVuZdvPIf1AHKHDQSWcG6XqDsbqFQu9yCAfRlnt0WwdRP2w=="],
|
|
||||||
|
|
||||||
"expo-router/@react-navigation/native-stack": ["@react-navigation/native-stack@7.3.17", "", { "dependencies": { "@react-navigation/elements": "^2.4.5", "warn-once": "^0.1.1" }, "peerDependencies": { "@react-navigation/native": "^7.1.12", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0", "react-native-screens": ">= 4.0.0" } }, "sha512-nPJv5E/7MYZ5NPD0sFP9DjSawEQ1fYXe0sCZT1C5EHGWK08p3+5HkVScXofDDqUtI/q6UU23uE1YoxVWgRbDRw=="],
|
|
||||||
|
|
||||||
"expo-router/semver": ["semver@7.6.3", "", { "bin": "bin/semver.js" }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="],
|
"expo-router/semver": ["semver@7.6.3", "", { "bin": "bin/semver.js" }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="],
|
||||||
|
|
||||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||||
|
|||||||
127
components/Alert/AlertCustom.tsx
Normal file
127
components/Alert/AlertCustom.tsx
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||||
|
import { TEXT_SIZE_LARGE } from "@/constants/constans-value";
|
||||||
|
import React from "react";
|
||||||
|
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
||||||
|
|
||||||
|
interface AlertCustomProps {
|
||||||
|
isVisible: boolean;
|
||||||
|
onLeftPress: () => void;
|
||||||
|
onRightPress: () => void;
|
||||||
|
title?: string;
|
||||||
|
message?: string;
|
||||||
|
textLeft?: string;
|
||||||
|
textRight?: string;
|
||||||
|
colorLeft?: string;
|
||||||
|
colorRight?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AlertCustom({
|
||||||
|
isVisible,
|
||||||
|
onLeftPress,
|
||||||
|
onRightPress,
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
textLeft,
|
||||||
|
textRight,
|
||||||
|
colorLeft,
|
||||||
|
colorRight,
|
||||||
|
}: AlertCustomProps) {
|
||||||
|
if (!isVisible) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.overlay}>
|
||||||
|
<View style={styles.alertBox}>
|
||||||
|
{title && message ? (
|
||||||
|
<>
|
||||||
|
<Text style={styles.alertTitle}>{title}</Text>
|
||||||
|
<Text style={styles.alertMessage}>{message}</Text>
|
||||||
|
</>
|
||||||
|
) : title ? (
|
||||||
|
<Text style={styles.alertTitle}>{title}</Text>
|
||||||
|
) : (
|
||||||
|
<Text style={styles.alertMessage}>{message}</Text>
|
||||||
|
)}
|
||||||
|
<View style={styles.alertButtons}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.alertButton,
|
||||||
|
colorLeft ? { backgroundColor: colorLeft } : styles.leftButton,
|
||||||
|
]}
|
||||||
|
onPress={onLeftPress}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>{textLeft}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[
|
||||||
|
styles.alertButton,
|
||||||
|
colorRight ? { backgroundColor: colorRight } : styles.rightButton,
|
||||||
|
]}
|
||||||
|
onPress={onRightPress}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>{textRight}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
overlay: {
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
backgroundColor: "rgba(0,0,0,0.5)",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
zIndex: 999,
|
||||||
|
},
|
||||||
|
alertBox: {
|
||||||
|
width: "90%",
|
||||||
|
backgroundColor: MainColor.darkblue,
|
||||||
|
borderColor: AccentColor.blue,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 10,
|
||||||
|
padding: 20,
|
||||||
|
alignItems: "center",
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: 2 },
|
||||||
|
shadowOpacity: 0.25,
|
||||||
|
elevation: 5,
|
||||||
|
},
|
||||||
|
alertTitle: {
|
||||||
|
fontSize: TEXT_SIZE_LARGE,
|
||||||
|
fontWeight: "bold",
|
||||||
|
marginBottom: 20,
|
||||||
|
color: MainColor.white,
|
||||||
|
},
|
||||||
|
alertMessage: {
|
||||||
|
textAlign: "center",
|
||||||
|
marginBottom: 20,
|
||||||
|
color: MainColor.white,
|
||||||
|
},
|
||||||
|
alertButtons: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
width: "100%",
|
||||||
|
},
|
||||||
|
alertButton: {
|
||||||
|
flex: 1,
|
||||||
|
padding: 10,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginHorizontal: 5,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
leftButton: {
|
||||||
|
backgroundColor: "gray",
|
||||||
|
},
|
||||||
|
rightButton: {
|
||||||
|
backgroundColor: MainColor.green,
|
||||||
|
},
|
||||||
|
buttonText: {
|
||||||
|
color: "white",
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
});
|
||||||
150
components/Drawer/DrawerCustom.tsx
Normal file
150
components/Drawer/DrawerCustom.tsx
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
import React, { useRef } from "react";
|
||||||
|
import {
|
||||||
|
Animated,
|
||||||
|
PanResponder,
|
||||||
|
StyleSheet,
|
||||||
|
View
|
||||||
|
} from "react-native";
|
||||||
|
|
||||||
|
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||||
|
import { DRAWER_HEIGHT } from "@/constants/constans-value";
|
||||||
|
|
||||||
|
interface DrawerCustomProps {
|
||||||
|
children?: React.ReactNode;
|
||||||
|
height?: number;
|
||||||
|
isVisible: boolean;
|
||||||
|
drawerAnim: Animated.Value;
|
||||||
|
closeDrawer: () => void;
|
||||||
|
// openLogoutAlert: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DrawerCustom({
|
||||||
|
children,
|
||||||
|
height,
|
||||||
|
isVisible,
|
||||||
|
drawerAnim,
|
||||||
|
closeDrawer,
|
||||||
|
}: // openLogoutAlert,
|
||||||
|
DrawerCustomProps) {
|
||||||
|
const panResponder = useRef(
|
||||||
|
PanResponder.create({
|
||||||
|
onMoveShouldSetPanResponder: (_, gestureState) => {
|
||||||
|
return gestureState.dy > 10; // gesek ke bawah
|
||||||
|
},
|
||||||
|
onPanResponderMove: (_, gestureState) => {
|
||||||
|
const offset = gestureState.dy;
|
||||||
|
if (offset >= 0 && offset <= DRAWER_HEIGHT) {
|
||||||
|
drawerAnim.setValue(offset);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onPanResponderRelease: (_, gestureState) => {
|
||||||
|
if (gestureState.dy > 200) {
|
||||||
|
closeDrawer();
|
||||||
|
} else {
|
||||||
|
Animated.spring(drawerAnim, {
|
||||||
|
toValue: 0,
|
||||||
|
useNativeDriver: true,
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).current;
|
||||||
|
|
||||||
|
if (!isVisible) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* Overlay Gelap */}
|
||||||
|
<View
|
||||||
|
style={styles.overlay}
|
||||||
|
pointerEvents="auto"
|
||||||
|
onTouchStart={closeDrawer}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Custom Bottom Drawer */}
|
||||||
|
<Animated.View
|
||||||
|
style={[
|
||||||
|
styles.drawer,
|
||||||
|
{
|
||||||
|
height: height || DRAWER_HEIGHT,
|
||||||
|
transform: [{ translateY: drawerAnim }],
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
{...panResponder.panHandlers}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[styles.headerBar, { backgroundColor: MainColor.white }]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{children}
|
||||||
|
|
||||||
|
{/* <TouchableOpacity
|
||||||
|
style={styles.menuItem}
|
||||||
|
onPress={() => {
|
||||||
|
alert("Pilihan 1 diklik");
|
||||||
|
closeDrawer();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text>Menu Item 1</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.menuItem}
|
||||||
|
onPress={() => {
|
||||||
|
alert("Pilihan 2 diklik");
|
||||||
|
closeDrawer();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text>Menu Item 2</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.menuItem}
|
||||||
|
onPress={() => alert("Logout via Alert bawaan")}
|
||||||
|
>
|
||||||
|
<Text style={{ color: "red" }}>Keluar</Text>
|
||||||
|
</TouchableOpacity> */}
|
||||||
|
</Animated.View>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
overlay: {
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
backgroundColor: "black",
|
||||||
|
opacity: 0.6,
|
||||||
|
zIndex: 998,
|
||||||
|
},
|
||||||
|
drawer: {
|
||||||
|
position: "absolute",
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
backgroundColor: AccentColor.darkblue,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
padding: 20,
|
||||||
|
shadowColor: "#000",
|
||||||
|
shadowOffset: { width: 0, height: -2 },
|
||||||
|
shadowOpacity: 0.2,
|
||||||
|
elevation: 5,
|
||||||
|
zIndex: 999,
|
||||||
|
},
|
||||||
|
headerBar: {
|
||||||
|
width: 40,
|
||||||
|
height: 5,
|
||||||
|
backgroundColor: MainColor.white,
|
||||||
|
borderRadius: 5,
|
||||||
|
alignSelf: "center",
|
||||||
|
marginVertical: 10,
|
||||||
|
},
|
||||||
|
menuItem: {
|
||||||
|
padding: 15,
|
||||||
|
},
|
||||||
|
});
|
||||||
57
components/Drawer/MenuDrawerDynamicGird.tsx
Normal file
57
components/Drawer/MenuDrawerDynamicGird.tsx
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { AccentColor, MainColor } from "@/constants/color-palet";
|
||||||
|
import { ICON_SIZE_MEDIUM, TEXT_SIZE_SMALL } from "@/constants/constans-value";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { View, TouchableOpacity, Text, StyleSheet } from "react-native";
|
||||||
|
|
||||||
|
const MenuDrawerDynamicGrid = ({ data, columns = 3, onPressItem }: any) => {
|
||||||
|
const numColumns = columns;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{data.map((item: any, index: any) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
key={index}
|
||||||
|
style={[styles.itemContainer, { flexBasis: `${100 / numColumns}%` }]}
|
||||||
|
onPress={() => onPressItem?.(item)}
|
||||||
|
>
|
||||||
|
<View style={styles.iconContainer}>
|
||||||
|
<Ionicons
|
||||||
|
name={item.icon}
|
||||||
|
size={ICON_SIZE_MEDIUM}
|
||||||
|
color={item.color || MainColor.white}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.label}>{item.label}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MenuDrawerDynamicGrid;
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flexDirection: "row",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
padding: 0,
|
||||||
|
},
|
||||||
|
itemContainer: {
|
||||||
|
padding: 10,
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
iconContainer: {
|
||||||
|
width: 56,
|
||||||
|
height: 56,
|
||||||
|
borderRadius: 28,
|
||||||
|
backgroundColor: AccentColor.blue,
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
marginTop: 10,
|
||||||
|
fontSize: TEXT_SIZE_SMALL,
|
||||||
|
textAlign: "center",
|
||||||
|
color: MainColor.white,
|
||||||
|
},
|
||||||
|
});
|
||||||
27
components/_Interface/types.ts
Normal file
27
components/_Interface/types.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { Href } from "expo-router";
|
||||||
|
|
||||||
|
export { ICustomTab, ITabs, IMenuDrawerItem };
|
||||||
|
|
||||||
|
interface ICustomTab {
|
||||||
|
icon: string;
|
||||||
|
label: string;
|
||||||
|
isActive: boolean;
|
||||||
|
onPress: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ITabs {
|
||||||
|
id: string;
|
||||||
|
icon: string;
|
||||||
|
activeIcon: string;
|
||||||
|
label: string;
|
||||||
|
path: Href;
|
||||||
|
isActive: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IMenuDrawerItem {
|
||||||
|
icon: string;
|
||||||
|
label: string;
|
||||||
|
path?: string;
|
||||||
|
color?: string;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
import { MainColor } from "@/constants/color-palet";
|
||||||
import { Styles } from "@/styles/global-styles";
|
import { Styles } from "@/styles/global-styles";
|
||||||
import { ImageBackground, ScrollView, View } from "react-native";
|
import { ImageBackground, ScrollView, View } from "react-native";
|
||||||
import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";
|
import { SafeAreaView } from "react-native-safe-area-context";
|
||||||
|
|
||||||
interface ViewWrapperProps {
|
interface ViewWrapperProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
@@ -16,7 +17,7 @@ const ViewWrapper = ({
|
|||||||
const assetBackground = require("../../assets/images/main-background.png");
|
const assetBackground = require("../../assets/images/main-background.png");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaProvider>
|
<>
|
||||||
<SafeAreaView
|
<SafeAreaView
|
||||||
edges={[
|
edges={[
|
||||||
"bottom",
|
"bottom",
|
||||||
@@ -25,6 +26,7 @@ const ViewWrapper = ({
|
|||||||
style={{
|
style={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
// paddingTop: StatusBar.currentHeight,
|
// paddingTop: StatusBar.currentHeight,
|
||||||
|
backgroundColor: MainColor.darkblue,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
|
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
|
||||||
@@ -42,7 +44,36 @@ const ViewWrapper = ({
|
|||||||
</ScrollView>
|
</ScrollView>
|
||||||
{tabBarComponent}
|
{tabBarComponent}
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
</SafeAreaProvider>
|
</>
|
||||||
|
|
||||||
|
// <SafeAreaProvider>
|
||||||
|
// <SafeAreaView
|
||||||
|
// edges={[
|
||||||
|
// "bottom",
|
||||||
|
// // "top",
|
||||||
|
// ]}
|
||||||
|
// style={{
|
||||||
|
// flex: 1,
|
||||||
|
// // paddingTop: StatusBar.currentHeight,
|
||||||
|
// backgroundColor: MainColor.darkblue,
|
||||||
|
// }}
|
||||||
|
// >
|
||||||
|
// <ScrollView contentContainerStyle={{ flexGrow: 1 }}>
|
||||||
|
// {withBackground ? (
|
||||||
|
// <ImageBackground
|
||||||
|
// source={assetBackground}
|
||||||
|
// resizeMode="cover"
|
||||||
|
// style={Styles.imageBackground}
|
||||||
|
// >
|
||||||
|
// <View style={Styles.containerWithBackground}>{children}</View>
|
||||||
|
// </ImageBackground>
|
||||||
|
// ) : (
|
||||||
|
// <View style={Styles.container}>{children}</View>
|
||||||
|
// )}
|
||||||
|
// </ScrollView>
|
||||||
|
// {tabBarComponent}
|
||||||
|
// </SafeAreaView>
|
||||||
|
// </SafeAreaProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
15
constants/constans-value.ts
Normal file
15
constants/constans-value.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
export {
|
||||||
|
TEXT_SIZE_SMALL,
|
||||||
|
TEXT_SIZE_MEDIUM,
|
||||||
|
TEXT_SIZE_LARGE,
|
||||||
|
ICON_SIZE_SMALL,
|
||||||
|
ICON_SIZE_MEDIUM,
|
||||||
|
DRAWER_HEIGHT,
|
||||||
|
};
|
||||||
|
|
||||||
|
const TEXT_SIZE_SMALL = 12;
|
||||||
|
const TEXT_SIZE_MEDIUM = 14;
|
||||||
|
const TEXT_SIZE_LARGE = 16;
|
||||||
|
const ICON_SIZE_SMALL = 20;
|
||||||
|
const ICON_SIZE_MEDIUM = 24;
|
||||||
|
const DRAWER_HEIGHT = 500; // tinggi drawer5
|
||||||
1
eas.build.android
Normal file
1
eas.build.android
Normal file
@@ -0,0 +1 @@
|
|||||||
|
eas build --profile preview
|
||||||
7
eas.json
7
eas.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"cli": {
|
"cli": {
|
||||||
"version": ">= 16.12.0",
|
"version": ">= 16.10.0",
|
||||||
"appVersionSource": "remote"
|
"appVersionSource": "remote"
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
@@ -9,7 +9,10 @@
|
|||||||
"distribution": "internal"
|
"distribution": "internal"
|
||||||
},
|
},
|
||||||
"preview": {
|
"preview": {
|
||||||
"distribution": "internal"
|
"distribution": "internal",
|
||||||
|
"android": {
|
||||||
|
"buildType": "apk"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"production": {
|
"production": {
|
||||||
"autoIncrement": true
|
"autoIncrement": true
|
||||||
|
|||||||
@@ -13,18 +13,19 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@expo/vector-icons": "^14.1.0",
|
"@expo/vector-icons": "^14.1.0",
|
||||||
"@react-navigation/bottom-tabs": "^7.4.2",
|
"@react-navigation/bottom-tabs": "^7.4.2",
|
||||||
|
"@react-navigation/drawer": "^7.5.2",
|
||||||
"@react-navigation/elements": "^2.3.8",
|
"@react-navigation/elements": "^2.3.8",
|
||||||
"@react-navigation/native": "^7.1.6",
|
"@react-navigation/native": "^7.1.6",
|
||||||
"@react-navigation/native-stack": "^7.3.21",
|
"@react-navigation/native-stack": "^7.3.21",
|
||||||
"@types/react-native-vector-icons": "^6.4.18",
|
"@types/react-native-vector-icons": "^6.4.18",
|
||||||
"expo": "~53.0.12",
|
"expo": "53.0.13",
|
||||||
"expo-blur": "~14.1.5",
|
"expo-blur": "~14.1.5",
|
||||||
"expo-constants": "~17.1.6",
|
"expo-constants": "~17.1.6",
|
||||||
"expo-font": "~13.3.1",
|
"expo-font": "~13.3.1",
|
||||||
"expo-haptics": "~14.1.4",
|
"expo-haptics": "~14.1.4",
|
||||||
"expo-image": "~2.3.0",
|
"expo-image": "~2.3.0",
|
||||||
"expo-linking": "~7.1.5",
|
"expo-linking": "~7.1.5",
|
||||||
"expo-router": "~5.1.0",
|
"expo-router": "~5.1.1",
|
||||||
"expo-splash-screen": "~0.30.9",
|
"expo-splash-screen": "~0.30.9",
|
||||||
"expo-status-bar": "~2.2.3",
|
"expo-status-bar": "~2.2.3",
|
||||||
"expo-symbols": "~0.4.5",
|
"expo-symbols": "~0.4.5",
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { MaterialCommunityIcons } from "@expo/vector-icons";
|
|||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
import { Text, View } from "react-native";
|
import { Text, View } from "react-native";
|
||||||
|
|
||||||
|
|
||||||
export default function RegisterView() {
|
export default function RegisterView() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -43,17 +42,17 @@ export default function RegisterView() {
|
|||||||
router.push("/(application)/home")
|
router.push("/(application)/home")
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Spacing />
|
{/* <Spacing />
|
||||||
{/* <ButtonCustom
|
<ButtonCustom
|
||||||
title="Home"
|
title="Coba"
|
||||||
backgroundColor={MainColor.yellow}
|
backgroundColor={MainColor.yellow}
|
||||||
textColor={MainColor.black}
|
textColor={MainColor.black}
|
||||||
radius={10}
|
radius={10}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
console.log("Home clicked");
|
console.log("Home clicked");
|
||||||
router.push("/(application)/home");
|
router.push("/(application)/coba");
|
||||||
}}
|
}}
|
||||||
/> */}
|
/> */}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
|
|||||||
@@ -1,112 +1,26 @@
|
|||||||
/* eslint-disable no-unused-expressions */
|
// import { ITabs } from "@/components/_Interface/types";
|
||||||
import Spacing from "@/components/_ShareComponent/Spacing";
|
import Spacing from "@/components/_ShareComponent/Spacing";
|
||||||
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
||||||
import { AccentColor, MainColor } from "@/constants/color-palet";
|
import { useNavigation } from "expo-router";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import React, { useEffect } from "react";
|
||||||
import { Href, router } from "expo-router";
|
|
||||||
import React from "react";
|
|
||||||
import {
|
|
||||||
Dimensions,
|
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
TouchableOpacity,
|
|
||||||
View,
|
|
||||||
} from "react-native";
|
|
||||||
import Home_BottomFeatureSection from "./bottomFeatureSection";
|
import Home_BottomFeatureSection from "./bottomFeatureSection";
|
||||||
import Home_ImageSection from "./imageSection";
|
import Home_ImageSection from "./imageSection";
|
||||||
|
import TabSection from "./tabSection";
|
||||||
|
import { tabsHome } from "./tabsList";
|
||||||
import Home_FeatureSection from "./topFeatureSection";
|
import Home_FeatureSection from "./topFeatureSection";
|
||||||
|
|
||||||
interface Tabs {
|
export default function UiHome() {
|
||||||
id: string;
|
const navigation = useNavigation();
|
||||||
icon: string;
|
|
||||||
activeIcon: string;
|
|
||||||
label: string;
|
|
||||||
path: Href;
|
|
||||||
isActive: boolean;
|
|
||||||
disabled: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { width } = Dimensions.get("window");
|
useEffect(() => {
|
||||||
|
navigation.setOptions({});
|
||||||
|
}, [navigation]);
|
||||||
|
|
||||||
export default function NewHomeView() {
|
|
||||||
const tabs: Tabs[] = [
|
|
||||||
{
|
|
||||||
id: "forum",
|
|
||||||
icon: "chatbubble-ellipses-outline",
|
|
||||||
activeIcon: "chatbubble-ellipses",
|
|
||||||
label: "Forum",
|
|
||||||
path: "/forum",
|
|
||||||
isActive: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "marketplace",
|
|
||||||
icon: "cart-outline",
|
|
||||||
activeIcon: "cart",
|
|
||||||
label: "Marketplace",
|
|
||||||
path: "/market-place",
|
|
||||||
isActive: false,
|
|
||||||
disabled: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "maps",
|
|
||||||
icon: "map-outline",
|
|
||||||
activeIcon: "map",
|
|
||||||
label: "Maps",
|
|
||||||
path: "/maps",
|
|
||||||
isActive: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "profile",
|
|
||||||
icon: "person-outline",
|
|
||||||
activeIcon: "person",
|
|
||||||
label: "Profile",
|
|
||||||
path: "/profile",
|
|
||||||
isActive: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const CustomTab = ({ icon, label, isActive, onPress, disabled }: any) => (
|
|
||||||
<TouchableOpacity
|
|
||||||
style={[styles.tabItem, isActive && styles.activeTab]}
|
|
||||||
onPress={onPress}
|
|
||||||
activeOpacity={0.7}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={[styles.iconContainer, isActive && styles.activeIconContainer]}
|
|
||||||
>
|
|
||||||
<Ionicons name={icon} size={20} color={isActive ? "#fff" : "#666"} />
|
|
||||||
</View>
|
|
||||||
<Text style={[styles.tabLabel, isActive && styles.activeTabLabel]}>
|
|
||||||
{label}
|
|
||||||
</Text>
|
|
||||||
{isActive && <View style={styles.activeIndicator} />}
|
|
||||||
</TouchableOpacity>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper tabBarComponent={<TabSection tabs={tabsHome} />}>
|
||||||
tabBarComponent={
|
{/* Content Image */}
|
||||||
<View style={styles.tabBar}>
|
|
||||||
<View style={styles.tabContainer}>
|
|
||||||
{tabs.map((e) => (
|
|
||||||
<CustomTab
|
|
||||||
key={e.id}
|
|
||||||
icon={e.icon}
|
|
||||||
label={e.label}
|
|
||||||
isActive={e.isActive}
|
|
||||||
onPress={() => {
|
|
||||||
e.disabled ? console.log("disabled") : router.push(e.path);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Home_ImageSection />
|
<Home_ImageSection />
|
||||||
<Spacing height={10} />
|
<Spacing height={10} />
|
||||||
|
|
||||||
@@ -121,74 +35,3 @@ export default function NewHomeView() {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
tabBar: {
|
|
||||||
backgroundColor: MainColor.darkblue,
|
|
||||||
borderTopColor: AccentColor.blue,
|
|
||||||
borderTopWidth: 1,
|
|
||||||
// borderTopEndRadius: 10,
|
|
||||||
// borderTopStartRadius: 10,
|
|
||||||
// tintColor: MainColor.yellow
|
|
||||||
// paddingBottom: 20,
|
|
||||||
// paddingTop: 10,
|
|
||||||
// shadowColor: AccentColor.blue,
|
|
||||||
// shadowOffset: {
|
|
||||||
// width: 0,
|
|
||||||
// height: -2,
|
|
||||||
// },
|
|
||||||
// shadowOpacity: 0.9,
|
|
||||||
// shadowRadius: 3,
|
|
||||||
// elevation: 5,
|
|
||||||
},
|
|
||||||
tabContainer: {
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-around",
|
|
||||||
alignItems: "center",
|
|
||||||
paddingHorizontal: 0,
|
|
||||||
},
|
|
||||||
tabItem: {
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
paddingVertical: 8,
|
|
||||||
paddingHorizontal: 12,
|
|
||||||
minWidth: width / 5,
|
|
||||||
position: "relative",
|
|
||||||
},
|
|
||||||
activeTab: {
|
|
||||||
transform: [{ scale: 1.05 }],
|
|
||||||
},
|
|
||||||
iconContainer: {
|
|
||||||
padding: 8,
|
|
||||||
borderRadius: 20,
|
|
||||||
// marginBottom: 4,
|
|
||||||
},
|
|
||||||
activeIconContainer: {
|
|
||||||
// backgroundColor: "#007AFF",
|
|
||||||
// shadowColor: "#007AFF",
|
|
||||||
// shadowOffset: {
|
|
||||||
// width: 0,
|
|
||||||
// height: 2,
|
|
||||||
// },
|
|
||||||
// shadowOpacity: 0.3,
|
|
||||||
// shadowRadius: 4,
|
|
||||||
// elevation: 4,
|
|
||||||
},
|
|
||||||
tabLabel: {
|
|
||||||
fontSize: 10,
|
|
||||||
color: "#666",
|
|
||||||
fontWeight: "500",
|
|
||||||
},
|
|
||||||
activeTabLabel: {
|
|
||||||
color: MainColor.white,
|
|
||||||
fontWeight: "600",
|
|
||||||
},
|
|
||||||
activeIndicator: {
|
|
||||||
position: "absolute",
|
|
||||||
bottom: -2,
|
|
||||||
width: 4,
|
|
||||||
height: 4,
|
|
||||||
borderRadius: 2,
|
|
||||||
backgroundColor: "#007AFF",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
51
screens/Home/tabSection.tsx
Normal file
51
screens/Home/tabSection.tsx
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { ICustomTab, ITabs } from "@/components/_Interface/types";
|
||||||
|
import { Styles } from "@/styles/global-styles";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
import React from "react";
|
||||||
|
import { Text, TouchableOpacity, View } from "react-native";
|
||||||
|
|
||||||
|
|
||||||
|
const CustomTab = ({ icon, label, isActive, onPress }: ICustomTab) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[Styles.tabItem, isActive && Styles.activeTab]}
|
||||||
|
onPress={onPress}
|
||||||
|
activeOpacity={0.7}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[Styles.iconContainer, isActive && Styles.activeIconContainer]}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name={icon as any}
|
||||||
|
size={20}
|
||||||
|
color={isActive ? "#fff" : "#666"}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text style={[Styles.tabLabel, isActive && Styles.activeTabLabel]}>
|
||||||
|
{label}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function TabSection({ tabs }: { tabs: ITabs[] }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<View style={Styles.tabBar}>
|
||||||
|
<View style={Styles.tabContainer}>
|
||||||
|
{tabs.map((e) => (
|
||||||
|
<CustomTab
|
||||||
|
key={e.id}
|
||||||
|
icon={e.icon}
|
||||||
|
label={e.label}
|
||||||
|
isActive={e.isActive}
|
||||||
|
onPress={() => {
|
||||||
|
// eslint-disable-next-line no-unused-expressions
|
||||||
|
e.disabled ? console.log("disabled") : router.push(e.path);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
40
screens/Home/tabsList.ts
Normal file
40
screens/Home/tabsList.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { ITabs } from "@/components/_Interface/types";
|
||||||
|
|
||||||
|
export const tabsHome: ITabs[] = [
|
||||||
|
{
|
||||||
|
id: "forum",
|
||||||
|
icon: "chatbubble-ellipses-outline",
|
||||||
|
activeIcon: "chatbubble-ellipses",
|
||||||
|
label: "Forum",
|
||||||
|
path: "/forum",
|
||||||
|
isActive: true,
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "marketplace",
|
||||||
|
icon: "cart-outline",
|
||||||
|
activeIcon: "cart",
|
||||||
|
label: "Marketplace",
|
||||||
|
path: "/marketplace",
|
||||||
|
isActive: false,
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "maps",
|
||||||
|
icon: "map-outline",
|
||||||
|
activeIcon: "map",
|
||||||
|
label: "Maps",
|
||||||
|
path: "/maps",
|
||||||
|
isActive: true,
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "profile",
|
||||||
|
icon: "person-outline",
|
||||||
|
activeIcon: "person",
|
||||||
|
label: "Profile",
|
||||||
|
path: "/profile/coba-id",
|
||||||
|
isActive: true,
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -9,7 +9,7 @@ export default function Home_FeatureSection() {
|
|||||||
<View style={stylesHome.gridContainer}>
|
<View style={stylesHome.gridContainer}>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={stylesHome.gridItem}
|
style={stylesHome.gridItem}
|
||||||
onPress={() => router.push("/(application)/event")}
|
onPress={() => router.push("/(application)/event/(tabs)")}
|
||||||
>
|
>
|
||||||
<Ionicons name="analytics" size={48} color="white" />
|
<Ionicons name="analytics" size={48} color="white" />
|
||||||
<Text style={stylesHome.gridLabel}>Event</Text>
|
<Text style={stylesHome.gridLabel}>Event</Text>
|
||||||
@@ -28,7 +28,7 @@ export default function Home_FeatureSection() {
|
|||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={stylesHome.gridContainer}>
|
{/* <View style={stylesHome.gridContainer}>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={stylesHome.gridItem}
|
style={stylesHome.gridItem}
|
||||||
onPress={() => router.push("/(application)/event")}
|
onPress={() => router.push("/(application)/event")}
|
||||||
@@ -48,7 +48,7 @@ export default function Home_FeatureSection() {
|
|||||||
<Ionicons name="heart" size={48} color="white" />
|
<Ionicons name="heart" size={48} color="white" />
|
||||||
<Text style={stylesHome.gridLabel}>Crowdfunding</Text>
|
<Text style={stylesHome.gridLabel}>Crowdfunding</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View> */}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
31
screens/Profile/menuDrawerSection.tsx
Normal file
31
screens/Profile/menuDrawerSection.tsx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { IMenuDrawerItem } from "@/components/_Interface/types";
|
||||||
|
import MenuDrawerDynamicGrid from "@/components/Drawer/MenuDrawerDynamicGird";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
|
||||||
|
export default function Profile_MenuDrawerSection({
|
||||||
|
drawerItems,
|
||||||
|
setShowLogoutAlert,
|
||||||
|
}: {
|
||||||
|
drawerItems: IMenuDrawerItem[];
|
||||||
|
setShowLogoutAlert: (value: boolean) => void;
|
||||||
|
}) {
|
||||||
|
const handlePress = (item: IMenuDrawerItem) => {
|
||||||
|
if (item.label === "Keluar") {
|
||||||
|
// console.log("Logout clicked");
|
||||||
|
setShowLogoutAlert(true);
|
||||||
|
} else {
|
||||||
|
router.push(item.path as any);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* Menu Items */}
|
||||||
|
<MenuDrawerDynamicGrid
|
||||||
|
data={drawerItems}
|
||||||
|
columns={4} // Ubah ke 2 jika ingin 2 kolom per baris
|
||||||
|
onPressItem={handlePress}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
import { StyleSheet } from "react-native";
|
import { Dimensions, StyleSheet } from "react-native";
|
||||||
import { MainColor } from "../constants/color-palet";
|
import { AccentColor, MainColor } from "../constants/color-palet";
|
||||||
|
|
||||||
|
const { width } = Dimensions.get("window");
|
||||||
|
|
||||||
export const Styles = StyleSheet.create({
|
export const Styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
@@ -17,7 +19,7 @@ export const Styles = StyleSheet.create({
|
|||||||
height: "100%",
|
height: "100%",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
},
|
},
|
||||||
|
|
||||||
// AUTHENTICATION
|
// AUTHENTICATION
|
||||||
authContainer: {
|
authContainer: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
@@ -37,7 +39,7 @@ export const Styles = StyleSheet.create({
|
|||||||
color: MainColor.yellow,
|
color: MainColor.yellow,
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
},
|
},
|
||||||
|
|
||||||
// TEXT & LABEL
|
// TEXT & LABEL
|
||||||
textLabel: {
|
textLabel: {
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@@ -47,7 +49,7 @@ export const Styles = StyleSheet.create({
|
|||||||
|
|
||||||
// Stack Header Style
|
// Stack Header Style
|
||||||
headerStyle: {
|
headerStyle: {
|
||||||
backgroundColor: MainColor.darkblue,
|
backgroundColor: AccentColor.darkblue,
|
||||||
},
|
},
|
||||||
headerTitleStyle: {
|
headerTitleStyle: {
|
||||||
color: MainColor.yellow,
|
color: MainColor.yellow,
|
||||||
@@ -61,4 +63,75 @@ export const Styles = StyleSheet.create({
|
|||||||
paddingBlock: 10,
|
paddingBlock: 10,
|
||||||
backgroundColor: MainColor.darkblue,
|
backgroundColor: MainColor.darkblue,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// =============== TAB =============== //
|
||||||
|
tabBar: {
|
||||||
|
backgroundColor: MainColor.darkblue,
|
||||||
|
borderTopColor: AccentColor.blue,
|
||||||
|
borderTopWidth: 1,
|
||||||
|
// borderTopEndRadius: 10,
|
||||||
|
// borderTopStartRadius: 10,
|
||||||
|
// tintColor: MainColor.yellow
|
||||||
|
// paddingBottom: 20,
|
||||||
|
// paddingTop: 10,
|
||||||
|
// shadowColor: AccentColor.blue,
|
||||||
|
// shadowOffset: {
|
||||||
|
// width: 0,
|
||||||
|
// height: -2,
|
||||||
|
// },
|
||||||
|
// shadowOpacity: 0.9,
|
||||||
|
// shadowRadius: 3,
|
||||||
|
// elevation: 5,
|
||||||
|
},
|
||||||
|
tabContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
alignItems: "center",
|
||||||
|
paddingHorizontal: 0,
|
||||||
|
},
|
||||||
|
tabItem: {
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
minWidth: width / 5,
|
||||||
|
position: "relative",
|
||||||
|
},
|
||||||
|
activeTab: {
|
||||||
|
transform: [{ scale: 1.05 }],
|
||||||
|
},
|
||||||
|
iconContainer: {
|
||||||
|
padding: 8,
|
||||||
|
borderRadius: 20,
|
||||||
|
// marginBottom: 4,
|
||||||
|
},
|
||||||
|
activeIconContainer: {
|
||||||
|
// backgroundColor: "#007AFF",
|
||||||
|
// shadowColor: "#007AFF",
|
||||||
|
// shadowOffset: {
|
||||||
|
// width: 0,
|
||||||
|
// height: 2,
|
||||||
|
// },
|
||||||
|
// shadowOpacity: 0.3,
|
||||||
|
// shadowRadius: 4,
|
||||||
|
// elevation: 4,
|
||||||
|
},
|
||||||
|
tabLabel: {
|
||||||
|
fontSize: 10,
|
||||||
|
color: "#666",
|
||||||
|
fontWeight: "500",
|
||||||
|
},
|
||||||
|
activeTabLabel: {
|
||||||
|
color: MainColor.white,
|
||||||
|
fontWeight: "600",
|
||||||
|
},
|
||||||
|
activeIndicator: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: -2,
|
||||||
|
width: 4,
|
||||||
|
height: 4,
|
||||||
|
borderRadius: 2,
|
||||||
|
backgroundColor: "#007AFF",
|
||||||
|
},
|
||||||
|
// =============== TAB =============== //
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user