Ship Expo Router screens, seeded stores, and polished UX so auth, shop, checkout, prescriptions, loyalty, family, and account processes work end-to-end offline. Co-authored-by: Cursor <cursoragent@cursor.com>
110 lines
2.6 KiB
TypeScript
110 lines
2.6 KiB
TypeScript
import { Ionicons } from "@expo/vector-icons";
|
|
import { Pressable, View } from "react-native";
|
|
import { Text } from "@/components/ui/Text";
|
|
import { colors, radii } from "@/lib/theme";
|
|
|
|
export function CategoryTile({
|
|
icon,
|
|
label,
|
|
selected,
|
|
onPress,
|
|
}: {
|
|
icon: keyof typeof Ionicons.glyphMap;
|
|
label: string;
|
|
selected?: boolean;
|
|
onPress?: () => void;
|
|
}) {
|
|
return (
|
|
<Pressable
|
|
onPress={onPress}
|
|
style={({ pressed }) => ({
|
|
width: 72,
|
|
alignItems: "center",
|
|
gap: 7,
|
|
opacity: pressed ? 0.85 : 1,
|
|
})}
|
|
>
|
|
<View
|
|
style={{
|
|
width: 56,
|
|
height: 56,
|
|
borderRadius: radii.md,
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
backgroundColor: selected ? colors.brand : colors.surface,
|
|
borderWidth: 1,
|
|
borderColor: selected ? colors.brand : colors.line,
|
|
}}
|
|
>
|
|
<Ionicons name={icon} size={23} color={selected ? colors.ink : colors.brandText} />
|
|
</View>
|
|
<Text
|
|
variant="micro"
|
|
color={selected ? colors.ink : colors.muted}
|
|
numberOfLines={1}
|
|
center
|
|
>
|
|
{label}
|
|
</Text>
|
|
</Pressable>
|
|
);
|
|
}
|
|
|
|
/** Larger square action used for the prescription entry points on Home. */
|
|
export function ActionTile({
|
|
icon,
|
|
title,
|
|
subtitle,
|
|
tone = "brand",
|
|
onPress,
|
|
}: {
|
|
icon: keyof typeof Ionicons.glyphMap;
|
|
title: string;
|
|
subtitle: string;
|
|
tone?: "brand" | "surface";
|
|
onPress?: () => void;
|
|
}) {
|
|
const brand = tone === "brand";
|
|
|
|
return (
|
|
<Pressable
|
|
onPress={onPress}
|
|
style={({ pressed }) => ({
|
|
flex: 1,
|
|
backgroundColor: brand ? colors.brand : colors.surface,
|
|
borderRadius: radii.card,
|
|
borderWidth: 1,
|
|
borderColor: brand ? colors.brand : colors.line,
|
|
padding: 14,
|
|
gap: 10,
|
|
opacity: pressed ? 0.92 : 1,
|
|
})}
|
|
>
|
|
<View
|
|
style={{
|
|
width: 36,
|
|
height: 36,
|
|
borderRadius: 12,
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
backgroundColor: brand ? "rgba(16,20,16,0.12)" : colors.brandSoft,
|
|
}}
|
|
>
|
|
<Ionicons name={icon} size={19} color={brand ? colors.ink : colors.brandText} />
|
|
</View>
|
|
<View>
|
|
<Text variant="h3" color={colors.ink}>
|
|
{title}
|
|
</Text>
|
|
<Text
|
|
variant="caption"
|
|
color={brand ? "rgba(16,20,16,0.62)" : colors.subtle}
|
|
style={{ marginTop: 2 }}
|
|
>
|
|
{subtitle}
|
|
</Text>
|
|
</View>
|
|
</Pressable>
|
|
);
|
|
}
|