This repository has been archived on 2026-08-11. You can view files and clone it, but cannot push or open issues or pull requests.
Gishen-Mob/components/ui/FloatingTabBar.tsx
kirukib 5391780b9b Ship Rx Care tab, notifications inbox, and guest pickup codes.
Replace the profile tab with prescription management (inline reminders and family invite), add a shared tab top bar, separate notifications from orders, and support any-branch guest checkout with GSH codes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 15:35:51 +03:00

144 lines
3.7 KiB
TypeScript

import { Ionicons } from "@expo/vector-icons";
import { Tabs } from "expo-router";
import { View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useTranslation } from "react-i18next";
import { Text } from "@/components/ui/Text";
import { colors, fonts, radii, shadows } from "@/lib/theme";
import { useCartStore } from "@/lib/stores/cartStore";
function TabIcon({
name,
focused,
badge,
}: {
name: keyof typeof Ionicons.glyphMap;
focused: boolean;
badge?: number;
}) {
return (
<View style={{ width: 46, height: 40, alignItems: "center", justifyContent: "center" }}>
<View
style={{
width: 40,
height: 32,
borderRadius: radii.pill,
alignItems: "center",
justifyContent: "center",
backgroundColor: focused ? colors.brandSoft : "transparent",
}}
>
<Ionicons
name={name}
size={20}
color={focused ? colors.brandText : colors.subtle}
/>
</View>
{badge ? (
<View
style={{
position: "absolute",
top: -2,
right: 2,
minWidth: 17,
height: 17,
paddingHorizontal: 4,
borderRadius: 9,
backgroundColor: colors.danger,
alignItems: "center",
justifyContent: "center",
borderWidth: 2,
borderColor: colors.surface,
}}
>
<Text variant="micro" color={colors.surface} style={{ fontSize: 9, lineHeight: 12 }}>
{badge > 9 ? "9+" : badge}
</Text>
</View>
) : null}
</View>
);
}
export function FloatingTabBar() {
const insets = useSafeAreaInsets();
const { t } = useTranslation();
const cartCount = useCartStore((s) => s.totalItems());
return (
<Tabs
screenOptions={{
headerShown: false,
tabBarActiveTintColor: colors.brandText,
tabBarInactiveTintColor: colors.subtle,
tabBarLabelStyle: {
fontFamily: fonts.semibold,
fontSize: 11,
marginTop: 2,
},
tabBarItemStyle: { paddingTop: 8 },
tabBarStyle: [
{
position: "absolute",
left: 16,
right: 16,
bottom: Math.max(insets.bottom, 12),
height: 68,
borderRadius: radii.xl,
backgroundColor: colors.surface,
borderTopWidth: 0,
borderWidth: 1,
borderColor: colors.line,
paddingBottom: 8,
},
shadows.md,
],
}}
>
<Tabs.Screen
name="index"
options={{
title: t("common.home"),
tabBarIcon: ({ focused }) => (
<TabIcon name={focused ? "home" : "home-outline"} focused={focused} />
),
}}
/>
<Tabs.Screen
name="favorites"
options={{
title: t("common.favorites"),
tabBarIcon: ({ focused }) => (
<TabIcon name={focused ? "heart" : "heart-outline"} focused={focused} />
),
}}
/>
<Tabs.Screen
name="cart"
options={{
title: t("common.cart"),
tabBarIcon: ({ focused }) => (
<TabIcon
name={focused ? "bag-handle" : "bag-handle-outline"}
focused={focused}
badge={cartCount}
/>
),
}}
/>
<Tabs.Screen
name="prescriptions"
options={{
title: t("common.prescriptions"),
tabBarIcon: ({ focused }) => (
<TabIcon
name={focused ? "medkit" : "medkit-outline"}
focused={focused}
/>
),
}}
/>
</Tabs>
);
}