Files
AthenaFE/components/features/navigation/ContentTabs.tsx
T
2025-11-02 10:08:56 +01:00

179 lines
4.8 KiB
TypeScript

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>
);
};