Fix form keyboard issues and sticky footers in agent screens
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
import React, { memo } from 'react';
|
||||
import { Pressable, StyleSheet, Text, View } from 'react-native';
|
||||
import Ionicons from '@react-native-vector-icons/ionicons';
|
||||
|
||||
import { Button, Card } from '../../../components';
|
||||
import { useTheme } from '../../../theme';
|
||||
import type { InsurancePlan } from '../types';
|
||||
import { formatCompactCurrency, formatCurrency } from '../../../utils/formatters';
|
||||
|
||||
interface InsurancePlanCardProps {
|
||||
plan: InsurancePlan;
|
||||
selected?: boolean;
|
||||
compared?: boolean;
|
||||
onSelect?: () => void;
|
||||
onCompare?: () => void;
|
||||
}
|
||||
|
||||
const InsurancePlanCardComponent = ({
|
||||
plan,
|
||||
selected = false,
|
||||
compared = false,
|
||||
onSelect,
|
||||
onCompare,
|
||||
}: InsurancePlanCardProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Card
|
||||
style={[
|
||||
styles.card,
|
||||
{
|
||||
borderColor: selected ? theme.colors.primary : theme.colors.cardBorder,
|
||||
borderWidth: selected ? 2 : 1,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<View style={styles.header}>
|
||||
<View style={styles.copy}>
|
||||
<Text style={[styles.title, { color: theme.colors.textPrimary }]}>{plan.name}</Text>
|
||||
<Text style={[styles.subtitle, { color: theme.colors.textSecondary }]}>
|
||||
{plan.insurerName}
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[styles.ratioBadge, { backgroundColor: `${theme.colors.accent}14` }]}
|
||||
>
|
||||
<Text style={[styles.ratioValue, { color: theme.colors.accent }]}>
|
||||
{plan.claimSettlementRatio}%
|
||||
</Text>
|
||||
<Text style={[styles.ratioLabel, { color: theme.colors.textSecondary }]}>
|
||||
CSR
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<Text style={[styles.summary, { color: theme.colors.textMuted }]}>{plan.summary}</Text>
|
||||
|
||||
<View style={styles.metrics}>
|
||||
<View style={[styles.metricCard, { backgroundColor: theme.colors.surfaceMuted }]}>
|
||||
<Text style={[styles.metricLabel, { color: theme.colors.textSecondary }]}>
|
||||
Premium
|
||||
</Text>
|
||||
<Text style={[styles.metricValue, { color: theme.colors.textPrimary }]}>
|
||||
{formatCurrency(plan.premium)}
|
||||
</Text>
|
||||
<Text style={[styles.metricCaption, { color: theme.colors.textMuted }]}>
|
||||
{plan.premiumFrequency}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={[styles.metricCard, { backgroundColor: theme.colors.surfaceMuted }]}>
|
||||
<Text style={[styles.metricLabel, { color: theme.colors.textSecondary }]}>
|
||||
Coverage
|
||||
</Text>
|
||||
<Text style={[styles.metricValue, { color: theme.colors.textPrimary }]}>
|
||||
{formatCompactCurrency(plan.coverAmount)}
|
||||
</Text>
|
||||
<Text style={[styles.metricCaption, { color: theme.colors.textMuted }]}>
|
||||
{plan.tenureYears} year tenure
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.listWrap}>
|
||||
{plan.benefits.slice(0, 3).map((benefit) => (
|
||||
<View key={benefit} style={styles.listRow}>
|
||||
<Ionicons name="checkmark-circle" size={16} color={theme.colors.accent} />
|
||||
<Text style={[styles.listText, { color: theme.colors.textPrimary }]}>{benefit}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<View style={styles.actionRow}>
|
||||
<Pressable
|
||||
onPress={onCompare}
|
||||
style={({ pressed }) => [
|
||||
styles.compareButton,
|
||||
{
|
||||
backgroundColor: compared ? `${theme.colors.info}12` : theme.colors.surfaceMuted,
|
||||
opacity: pressed ? 0.9 : 1,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Ionicons
|
||||
name={compared ? 'checkbox' : 'square-outline'}
|
||||
size={18}
|
||||
color={compared ? theme.colors.info : theme.colors.textMuted}
|
||||
/>
|
||||
<Text
|
||||
style={[
|
||||
styles.compareLabel,
|
||||
{ color: compared ? theme.colors.info : theme.colors.textSecondary },
|
||||
]}
|
||||
>
|
||||
Compare
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Button
|
||||
title={selected ? 'Selected' : 'Select Plan'}
|
||||
onPress={onSelect}
|
||||
variant={selected ? 'secondary' : 'primary'}
|
||||
fullWidth={false}
|
||||
style={styles.selectButton}
|
||||
/>
|
||||
</View>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
card: {
|
||||
gap: 14,
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
gap: 12,
|
||||
},
|
||||
copy: {
|
||||
flex: 1,
|
||||
gap: 2,
|
||||
},
|
||||
title: {
|
||||
fontSize: 16,
|
||||
fontWeight: '800',
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 12,
|
||||
fontWeight: '600',
|
||||
},
|
||||
ratioBadge: {
|
||||
minWidth: 68,
|
||||
borderRadius: 14,
|
||||
paddingHorizontal: 10,
|
||||
paddingVertical: 8,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
ratioValue: {
|
||||
fontSize: 16,
|
||||
fontWeight: '900',
|
||||
},
|
||||
ratioLabel: {
|
||||
fontSize: 10,
|
||||
fontWeight: '800',
|
||||
letterSpacing: 0.5,
|
||||
},
|
||||
summary: {
|
||||
fontSize: 13,
|
||||
lineHeight: 18,
|
||||
},
|
||||
metrics: {
|
||||
flexDirection: 'row',
|
||||
gap: 10,
|
||||
},
|
||||
metricCard: {
|
||||
flex: 1,
|
||||
borderRadius: 14,
|
||||
padding: 12,
|
||||
gap: 4,
|
||||
},
|
||||
metricLabel: {
|
||||
fontSize: 11,
|
||||
fontWeight: '700',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: 0.5,
|
||||
},
|
||||
metricValue: {
|
||||
fontSize: 18,
|
||||
fontWeight: '900',
|
||||
},
|
||||
metricCaption: {
|
||||
fontSize: 11,
|
||||
fontWeight: '600',
|
||||
},
|
||||
listWrap: {
|
||||
gap: 8,
|
||||
},
|
||||
listRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
},
|
||||
listText: {
|
||||
flex: 1,
|
||||
fontSize: 12,
|
||||
fontWeight: '600',
|
||||
lineHeight: 17,
|
||||
},
|
||||
actionRow: {
|
||||
flexDirection: 'row',
|
||||
gap: 10,
|
||||
alignItems: 'center',
|
||||
},
|
||||
compareButton: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 12,
|
||||
},
|
||||
compareLabel: {
|
||||
fontSize: 12,
|
||||
fontWeight: '700',
|
||||
},
|
||||
selectButton: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
export const InsurancePlanCard = memo(InsurancePlanCardComponent);
|
||||
Reference in New Issue
Block a user