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/TabTopBar.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

104 lines
3.2 KiB
TypeScript

import { Ionicons } from "@expo/vector-icons";
import { router } from "expo-router";
import { Pressable, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Avatar } from "@/components/ui/Avatar";
import { Text } from "@/components/ui/Text";
import { routes } from "@/lib/routes";
import { useAuthStore } from "@/lib/stores/authStore";
import { useNotificationStore } from "@/lib/stores/notificationStore";
import { colors, gutter } from "@/lib/theme";
function greetingForNow() {
const hour = new Date().getHours();
if (hour < 12) return "Good morning";
if (hour < 17) return "Good afternoon";
return "Good evening";
}
/** Shared top bar for all bottom-tab screens (avatar → profile, bell → notifications). */
export function TabTopBar({
subtitle,
}: {
/** Optional line under the user name, e.g. the current tab context */
subtitle?: string;
}) {
const insets = useSafeAreaInsets();
const user = useAuthStore((s) => s.user);
const unread = useNotificationStore((s) => s.unreadCount());
return (
<View
style={{
paddingTop: insets.top + 10,
paddingHorizontal: gutter,
paddingBottom: 10,
backgroundColor: colors.page,
}}
>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Pressable
onPress={() => router.push(routes.profile)}
style={{ flexDirection: "row", alignItems: "center", gap: 12, flex: 1 }}
accessibilityRole="button"
accessibilityLabel="Open profile"
>
<Avatar name={user?.name} uri={user?.avatarUri} size={46} />
<View style={{ flex: 1 }}>
<Text variant="caption" color={colors.subtle}>
{subtitle || greetingForNow()}
</Text>
<Text variant="h3" numberOfLines={1}>
{user?.name?.split(" ")[0] || "Guest"}
</Text>
</View>
</Pressable>
<Pressable
onPress={() => router.push(routes.notifications)}
accessibilityRole="button"
accessibilityLabel="Notifications"
style={{
width: 44,
height: 44,
borderRadius: 22,
backgroundColor: colors.surface,
borderWidth: 1,
borderColor: colors.line,
alignItems: "center",
justifyContent: "center",
}}
>
<Ionicons name="notifications-outline" size={20} color={colors.ink} />
{unread > 0 ? (
<View
style={{
position: "absolute",
top: 8,
right: 9,
minWidth: 16,
height: 16,
borderRadius: 8,
backgroundColor: colors.danger,
alignItems: "center",
justifyContent: "center",
paddingHorizontal: 3,
}}
>
<Text variant="micro" color={colors.surface}>
{unread > 9 ? "9+" : unread}
</Text>
</View>
) : null}
</Pressable>
</View>
</View>
);
}