stadtwerke/innungsapp/apps/mobile/components/ui/Avatar.tsx

94 lines
2.0 KiB
TypeScript

import { View, Text, Image, ViewStyle, ImageStyle } from 'react-native'
const AVATAR_PALETTES = [
{ bg: '#003B7E', text: '#FFFFFF' },
{ bg: '#1D4ED8', text: '#FFFFFF' },
{ bg: '#059669', text: '#FFFFFF' },
{ bg: '#4338CA', text: '#FFFFFF' },
{ bg: '#B45309', text: '#FFFFFF' },
{ bg: '#0F766E', text: '#FFFFFF' },
]
function getInitials(name: string): string {
return name
.split(' ')
.slice(0, 2)
.map((w) => w[0]?.toUpperCase() ?? '')
.join('')
}
function getPalette(name: string) {
const index = name.charCodeAt(0) % AVATAR_PALETTES.length
return AVATAR_PALETTES[index]
}
interface AvatarProps {
name: string
imageUrl?: string
size?: number
shadow?: boolean
}
export function Avatar({ name, imageUrl, size = 48, shadow = false }: AvatarProps) {
const initials = getInitials(name)
const palette = getPalette(name)
const viewShadowStyle: ViewStyle = shadow
? {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.12,
shadowRadius: 8,
elevation: 3,
}
: {}
const imageShadowStyle: ImageStyle = shadow
? {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.12,
shadowRadius: 8,
}
: {}
if (imageUrl) {
return (
<Image
source={{ uri: imageUrl }}
style={[
{ width: size, height: size, borderRadius: size / 2 },
imageShadowStyle,
]}
/>
)
}
return (
<View
style={[
{
width: size,
height: size,
borderRadius: size / 2,
backgroundColor: palette.bg,
alignItems: 'center',
justifyContent: 'center',
},
viewShadowStyle,
]}
>
<Text
style={{
color: palette.text,
fontSize: size * 0.36,
fontWeight: '700',
letterSpacing: 0.5,
}}
>
{initials}
</Text>
</View>
)
}