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>
104 lines
3.2 KiB
TypeScript
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>
|
|
);
|
|
}
|