Files
digital-pilates/components/ui/InfoCard.tsx
richarjiang 7c8538f5c6 feat(medications): 添加AI用药分析功能
- 集成流式AI分析接口,支持实时展示分析结果
- 添加VIP权限校验和会员弹窗引导
- 使用Markdown渲染AI分析内容
- 优化底部按钮布局,AI分析按钮占2/3宽度
- 支持请求取消和错误处理
- 自动滚动到分析结果区域
- InfoCard组件优化,图标、标签和箭头排列在同一行
2025-11-12 17:07:42 +08:00

117 lines
2.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { Colors } from '@/constants/Colors';
import { Ionicons } from '@expo/vector-icons';
import React from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export interface InfoCardProps {
label: string;
value: string;
icon: keyof typeof Ionicons.glyphMap;
colors: (typeof Colors)[keyof typeof Colors];
onPress?: () => void;
clickable?: boolean;
}
export const InfoCard: React.FC<InfoCardProps> = ({
label,
value,
icon,
colors,
onPress,
clickable = false,
}) => {
// 渲染图标 - 始终使用普通 View
const renderIcon = () => {
return (
<View style={[
styles.infoCardIcon,
]}>
<Ionicons name={icon} size={16} color="#4C6EF5" />
</View>
);
};
// 卡片内容 - icon、label 和箭头在同一行
const cardContent = (
<View style={[
styles.infoCard,
{ backgroundColor: colors.surface || '#fff' }
]}>
<View style={styles.header}>
{renderIcon()}
<Text style={[styles.infoCardLabel, { color: colors.textSecondary }]}>{label}</Text>
{clickable && (
<View style={styles.infoCardArrow}>
<Ionicons name="chevron-forward" size={16} color={colors.textMuted} />
</View>
)}
</View>
<Text style={[styles.infoCardValue, { color: colors.text }]}>{value}</Text>
</View>
);
// 如果可点击且有onPress回调使用TouchableOpacity包装
if (clickable && onPress) {
return (
<TouchableOpacity
style={styles.container}
onPress={onPress}
activeOpacity={0.7}
>
{cardContent}
</TouchableOpacity>
);
}
// 不可点击的版本
return (
<View style={styles.container}>
{cardContent}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
infoCard: {
flex: 1,
borderRadius: 20,
padding: 16,
backgroundColor: '#FFFFFF',
gap: 8,
position: 'relative',
},
infoCardArrow: {
marginLeft: 'auto',
width: 24,
height: 24,
borderRadius: 12,
alignItems: 'center',
justifyContent: 'center',
},
infoCardIcon: {
width: 28,
height: 28,
borderRadius: 14,
alignItems: 'center',
justifyContent: 'center',
},
header: {
flexDirection: 'row',
alignItems: 'center',
gap: 4,
},
infoCardLabel: {
fontSize: 13,
color: '#6B7280',
},
infoCardValue: {
fontSize: 14,
fontWeight: '600',
color: '#1F2933',
},
});
export default InfoCard;