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>
61 lines
1.2 KiB
TypeScript
61 lines
1.2 KiB
TypeScript
import { Image, View } from "react-native";
|
|
import { Text } from "@/components/ui/Text";
|
|
import { colors } from "@/lib/theme";
|
|
|
|
function initials(name?: string) {
|
|
if (!name) return "G";
|
|
return name
|
|
.trim()
|
|
.split(/\s+/)
|
|
.slice(0, 2)
|
|
.map((part) => part[0]?.toUpperCase() ?? "")
|
|
.join("");
|
|
}
|
|
|
|
export function Avatar({
|
|
name,
|
|
uri,
|
|
size = 44,
|
|
tone = "brand",
|
|
}: {
|
|
name?: string;
|
|
uri?: string | null;
|
|
size?: number;
|
|
tone?: "brand" | "soft";
|
|
}) {
|
|
if (uri) {
|
|
return (
|
|
<Image
|
|
source={{ uri }}
|
|
style={{
|
|
width: size,
|
|
height: size,
|
|
borderRadius: size / 2,
|
|
backgroundColor: colors.surfaceAlt,
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<View
|
|
style={{
|
|
width: size,
|
|
height: size,
|
|
borderRadius: size / 2,
|
|
backgroundColor: tone === "brand" ? colors.brand : colors.brandSoft,
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
}}
|
|
>
|
|
<Text
|
|
variant="h3"
|
|
color={tone === "brand" ? colors.ink : colors.brandText}
|
|
style={{ fontSize: size * 0.36 }}
|
|
>
|
|
{initials(name)}
|
|
</Text>
|
|
</View>
|
|
);
|
|
}
|