113 lines
3.5 KiB
TypeScript
113 lines
3.5 KiB
TypeScript
import { Ionicons } from "@expo/vector-icons";
|
|
import { Redirect, Tabs, usePathname, router } from "expo-router";
|
|
import { Pressable, View } from "react-native";
|
|
import { useState } from "react";
|
|
|
|
import { useAuthContext } from "@/auth/AuthContext";
|
|
import { ContentTabs } from "@/components/features/navigation/ContentTabs";
|
|
import { Sidebar } from "@/components/features/navigation/Sidebar";
|
|
import { SidebarToggle } from "@/components/features/navigation/SidebarToggle";
|
|
import { useAppSelector } from "@/store/hooks";
|
|
import { selectIsMobile } from "@/store/screen/screenSizeSlice";
|
|
import { HeaderControls } from "@/components/features/navigation/HeaderControls";
|
|
import { LoadingSpinner } from "@/components/ui/LoadingSpinner";
|
|
import { UserButton } from "@/components/auth/UserButton";
|
|
|
|
const TabsLayout = () => {
|
|
const isMobile = useAppSelector(selectIsMobile);
|
|
const { isAuthenticated, bootstrapping } = useAuthContext();
|
|
const pathname = usePathname();
|
|
const [mobileHidden, setMobileHidden] = useState(true);
|
|
|
|
if (bootstrapping) {
|
|
return (
|
|
<View className="flex-1 bg-primaryPurpleLight justify-center items-center">
|
|
<LoadingSpinner />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
if (!isAuthenticated) {
|
|
if (pathname !== "/sign-in") {
|
|
return <Redirect href="/sign-in" />;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<View className="flex-1 flex-row">
|
|
<View
|
|
style={{
|
|
flexShrink: 0,
|
|
}}
|
|
>
|
|
<Sidebar
|
|
mobileHidden={isMobile ? mobileHidden : false}
|
|
onRequestMobileToggle={() => setMobileHidden((v) => !v)}
|
|
/>
|
|
</View>
|
|
<View className="flex-1 bg-primaryPurpleLight">
|
|
<View className="relative">
|
|
<View style={{ paddingLeft: isMobile && mobileHidden ? 80 : 0 }}>
|
|
<ContentTabs />
|
|
</View>
|
|
|
|
{isMobile && mobileHidden && (
|
|
<View
|
|
className="absolute z-50"
|
|
style={{
|
|
left: 0,
|
|
top: 0,
|
|
height: 56,
|
|
width: 80,
|
|
backgroundColor: "transparent",
|
|
borderBottomColor: "transparent",
|
|
borderBottomWidth: 0,
|
|
paddingLeft: 4,
|
|
paddingRight: 4,
|
|
display: "flex",
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
}}
|
|
>
|
|
<SidebarToggle
|
|
onPress={() => setMobileHidden(false)}
|
|
showLabel={!mobileHidden}
|
|
/>
|
|
</View>
|
|
)}
|
|
|
|
{isMobile ? (
|
|
<View className="absolute flex flex-row items-center justify-center z-50 right-4 top-2 space-x-3">
|
|
<Pressable className="p-1" onPress={() => router.push("/search")}>
|
|
<Ionicons name="search" size={20} color="white" />
|
|
</Pressable>
|
|
<UserButton />
|
|
</View>
|
|
) : (
|
|
<HeaderControls />
|
|
)}
|
|
</View>
|
|
|
|
<Tabs
|
|
screenOptions={{
|
|
headerShown: false,
|
|
tabBarStyle: { display: "none" },
|
|
}}
|
|
>
|
|
<Tabs.Screen name="index" />
|
|
<Tabs.Screen name="accounts/index" />
|
|
<Tabs.Screen name="logs/index" />
|
|
<Tabs.Screen name="reports/index" />
|
|
<Tabs.Screen name="data-protection/index" />
|
|
<Tabs.Screen name="settings/index" />
|
|
<Tabs.Screen name="search" />
|
|
</Tabs>
|
|
</View>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default TabsLayout;
|