All files / app/(tabs)/profile/components PetCard.tsx

0% Statements 0/5
0% Branches 0/15
0% Functions 0/1
0% Lines 0/4

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                                                                                                                                                                                                                         
import { Card, Text, XStack, YStack } from 'tamagui';
import { IconSymbol } from '@/src/components/ui/IconSymbol';
import { OptimizedImage } from '@/src/components/ui/OptimizedImage';
import { Colors, withAlpha } from '@/src/constants/colors';
import { useThemeAwareColorScheme } from '@/src/hooks/useThemeAwareColorScheme';
import type { Pet } from '@/src/schemas/pet.schema';
 
interface PetCardProps {
  pet: Pet;
  onPress?: () => void;
}
 
/**
 * 宠物卡片组件
 * 展示单个宠物的基本信息
 */
export function PetCard({ pet, onPress }: PetCardProps) {
  const colorScheme = useThemeAwareColorScheme();
  const colors = Colors[colorScheme];
 
  // 防御性检查:如果没有 pet,则不渲染(在 hooks 之后检查)
  if (!pet) return null;
 
  return (
    <Card
      padding="$4"
      borderWidth={1}
      borderColor={withAlpha(colors.icon, 0.188) as any}
      backgroundColor={colors.background as any}
      pressStyle={{
        scale: 0.97,
        opacity: 0.8,
        borderColor: withAlpha(colors.tint, 0.376) as any,
      }}
      hoverStyle={{
        borderColor: withAlpha(colors.tint, 0.251) as any,
      }}
      {...(onPress ? { onPress } : {})}
      animation="quick"
      borderRadius="$4"
    >
      <XStack gap="$4" alignItems="center">
        {/* Pet Photo */}
        {pet.photo_url ? (
          <YStack
            borderRadius="$3"
            overflow="hidden"
            borderWidth={2}
            borderColor={withAlpha(colors.tint, 0.188) as any}
          >
            <OptimizedImage
              source={pet.photo_url}
              style={{
                width: 70,
                height: 70,
              }}
              contentFit="cover"
              cachePolicy="memory-disk"
            />
          </YStack>
        ) : (
          <YStack
            width={70}
            height={70}
            borderRadius="$3"
            backgroundColor={withAlpha(colors.tint, 0.125) as any}
            alignItems="center"
            justifyContent="center"
            borderWidth={2}
            borderColor={withAlpha(colors.tint, 0.188) as any}
          >
            <Text fontSize={40}>🐱</Text>
          </YStack>
        )}
 
        {/* Pet Info */}
        <YStack flex={1} gap="$1">
          <Text fontSize={17} fontWeight="700" color={colors.text as any}>
            {pet.name || '宠物'}
          </Text>
          <XStack gap="$2" alignItems="center">
            <Text fontSize={14} color={colors.icon as any}>
              {pet.species_display ?? pet.species ?? '未知'}
            </Text>
            {pet.age != null && (
              <>
                <Text fontSize={14} color={withAlpha(colors.icon, 0.376) as any}>
                  ·
                </Text>
                <Text fontSize={14} color={colors.icon as any}>
                  {pet.age}岁
                </Text>
              </>
            )}
          </XStack>
          {pet.breed && (
            <Text fontSize={13} color={withAlpha(colors.icon, 0.502) as any} numberOfLines={1}>
              {pet.breed}
            </Text>
          )}
        </YStack>
 
        {/* Arrow Icon */}
        <IconSymbol name="chevron.right" size={20} color={withAlpha(colors.icon, 0.376)} />
      </XStack>
    </Card>
  );
}