project setup
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { router, usePathname } from "expo-router";
|
||||
import { Pressable, Text, View } from "react-native";
|
||||
|
||||
import { useAppSelector } from "@/store/hooks";
|
||||
import { selectIsMobile } from "@/store/screen/screenSizeSlice";
|
||||
import { IoniconsName } from "@/types/index";
|
||||
import { useRoleAccess } from "@/hooks/useRoleAccess";
|
||||
|
||||
const HIDDEN_PATHS = ["/accounts/admins", "/accounts/todos"];
|
||||
|
||||
interface TabItem {
|
||||
label: string;
|
||||
route: string;
|
||||
icon?: IoniconsName;
|
||||
}
|
||||
|
||||
interface TabGroup {
|
||||
basePath: string;
|
||||
tabs: TabItem[];
|
||||
}
|
||||
|
||||
export const ContentTabs = () => {
|
||||
const pathname = usePathname();
|
||||
const isMobile = useAppSelector(selectIsMobile);
|
||||
const { isManager } = useRoleAccess();
|
||||
|
||||
// Hide top tabs when user lacks permission and is on restricted Accounts pages
|
||||
if (!isManager && HIDDEN_PATHS.includes(pathname)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tabGroups: TabGroup[] = [
|
||||
{
|
||||
basePath: "/",
|
||||
tabs: [
|
||||
{
|
||||
label: "Dashboard",
|
||||
route: "/user-dashboard/index",
|
||||
icon: "home",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
basePath: "/accounts",
|
||||
tabs: [
|
||||
{
|
||||
label: "Users",
|
||||
route: "/accounts/users",
|
||||
icon: "person-outline",
|
||||
},
|
||||
...(isManager
|
||||
? [
|
||||
{
|
||||
label: "Admins",
|
||||
route: "/accounts/admins",
|
||||
icon: "settings" as IoniconsName,
|
||||
},
|
||||
{
|
||||
label: "Todos",
|
||||
route: "/accounts/todos",
|
||||
icon: "list" as IoniconsName,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
},
|
||||
{
|
||||
basePath: "/logs",
|
||||
tabs: [{ label: "System", route: "/logs/system", icon: "server" }],
|
||||
},
|
||||
{
|
||||
basePath: "/reports",
|
||||
tabs: [{ label: "Inbox", route: "/reports/inbox", icon: "mail" }],
|
||||
},
|
||||
{
|
||||
basePath: "/data-protection",
|
||||
tabs: [
|
||||
{ label: "General", route: "/data-protection/general", icon: "cog" },
|
||||
],
|
||||
},
|
||||
{
|
||||
basePath: "/settings",
|
||||
tabs: [{ label: "General", route: "/settings/general", icon: "cog" }],
|
||||
},
|
||||
];
|
||||
|
||||
let currentSection = "";
|
||||
|
||||
if (
|
||||
pathname.includes("/dashboard") ||
|
||||
pathname === "/(tabs)" ||
|
||||
pathname === "/"
|
||||
) {
|
||||
currentSection = "/";
|
||||
} else if (pathname.includes("/accounts")) {
|
||||
currentSection = "/accounts";
|
||||
} else if (pathname.includes("/settings")) {
|
||||
currentSection = "/settings";
|
||||
} else if (pathname.includes("/logs")) {
|
||||
currentSection = "/logs";
|
||||
} else if (pathname.includes("/reports")) {
|
||||
currentSection = "/reports";
|
||||
} else if (pathname.includes("/data-protection")) {
|
||||
currentSection = "/data-protection";
|
||||
}
|
||||
|
||||
const activeGroup = tabGroups.find(
|
||||
(group) => group.basePath === currentSection
|
||||
);
|
||||
if (!activeGroup || activeGroup.tabs.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isTabActive = (tabRoute: string) => {
|
||||
if (tabRoute === "/user-dashboard/index") {
|
||||
if (pathname === "/(tabs)" || pathname === "/") {
|
||||
return true;
|
||||
}
|
||||
return pathname.includes("/user-dashboard");
|
||||
}
|
||||
|
||||
const routeSegments = tabRoute.split("/");
|
||||
const lastSegment = routeSegments[routeSegments.length - 1];
|
||||
|
||||
return pathname.includes(lastSegment);
|
||||
};
|
||||
|
||||
return (
|
||||
<View
|
||||
className={`bg-primaryPurpleLight ${isMobile ? "px-1" : "px-2"} ${
|
||||
isMobile ? "pt-2 pb-0" : "pt-3"
|
||||
}`}
|
||||
>
|
||||
<View className={`flex-row ${isMobile ? "justify-start gap-3" : ""}`}>
|
||||
{activeGroup.tabs.map((tab, index) => {
|
||||
const active = isTabActive(tab.route);
|
||||
return (
|
||||
<Pressable
|
||||
key={index}
|
||||
onPress={() => router.push(tab.route as any)}
|
||||
className={`relative mx-1 border-b-2 transition-colors duration-200
|
||||
${active ? "border-white" : "border-transparent"}
|
||||
${isMobile ? "px-1" : "px-4"}
|
||||
`}
|
||||
style={{ paddingBottom: isMobile ? 6 : 4 }}
|
||||
>
|
||||
{isMobile ? (
|
||||
<View className="items-center">
|
||||
<Ionicons
|
||||
name={tab.icon as IoniconsName}
|
||||
size={20}
|
||||
color="white"
|
||||
style={{ opacity: active ? 1 : 0.7 }}
|
||||
/>
|
||||
<Text
|
||||
className="text-white text-[10px] mt-0.5"
|
||||
style={{ opacity: active ? 1 : 0.7 }}
|
||||
>
|
||||
{tab.label}
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
<Text
|
||||
className={`text-base text-white transition-colors duration-200
|
||||
${active ? "font-medium" : "font-normal"}
|
||||
`}
|
||||
>
|
||||
{tab.label}
|
||||
</Text>
|
||||
)}
|
||||
</Pressable>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user