Fix form keyboard issues and sticky footers in agent screens
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import React, { memo } from 'react';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
import Ionicons from '@react-native-vector-icons/ionicons';
|
||||
|
||||
import { useTheme } from '../../../theme';
|
||||
import { formatDate } from '../../../utils/formatters';
|
||||
import { Card } from '../../../components';
|
||||
|
||||
interface TimelineStep {
|
||||
stage: string;
|
||||
timestamp: string;
|
||||
active: boolean;
|
||||
}
|
||||
|
||||
interface LoanTimelineCardProps {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
timeline: TimelineStep[];
|
||||
}
|
||||
|
||||
const LoanTimelineCardComponent = ({ title, subtitle, timeline }: LoanTimelineCardProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Card style={styles.card}>
|
||||
<View style={styles.header}>
|
||||
<Text style={[styles.title, { color: theme.colors.textPrimary }]}>{title}</Text>
|
||||
{subtitle && (
|
||||
<Text style={[styles.subtitle, { color: theme.colors.textSecondary }]}>{subtitle}</Text>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.timeline}>
|
||||
{timeline.map((step, index) => {
|
||||
const isLast = index === timeline.length - 1;
|
||||
const isCompleted = step.active && step.timestamp !== '';
|
||||
const isCurrent = step.active && step.timestamp === '' && index > 0
|
||||
? false
|
||||
: step.active && !timeline[index + 1]?.active;
|
||||
const isPending = !step.active;
|
||||
|
||||
let dotColor = theme.colors.textMuted;
|
||||
let iconName = 'ellipse-outline';
|
||||
if (isCompleted) {
|
||||
dotColor = theme.colors.success;
|
||||
iconName = 'checkmark-circle';
|
||||
} else if (isCurrent) {
|
||||
dotColor = theme.colors.primary;
|
||||
iconName = 'radio-button-on';
|
||||
}
|
||||
|
||||
return (
|
||||
<View key={index} style={styles.stepRow}>
|
||||
<View style={styles.stepIndicator}>
|
||||
<Ionicons name={iconName as any} size={20} color={dotColor} />
|
||||
{!isLast && (
|
||||
<View
|
||||
style={[
|
||||
styles.connector,
|
||||
{
|
||||
backgroundColor: isCompleted ? theme.colors.success : theme.colors.cardBorder,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
<View style={[styles.stepContent, !isLast && styles.stepContentSpaced]}>
|
||||
<Text
|
||||
style={[
|
||||
styles.stepLabel,
|
||||
{
|
||||
color: isPending ? theme.colors.textMuted : theme.colors.textPrimary,
|
||||
fontWeight: isCurrent ? '800' : '600',
|
||||
},
|
||||
]}
|
||||
>
|
||||
{step.stage}
|
||||
</Text>
|
||||
{step.timestamp ? (
|
||||
<Text style={[styles.stepTime, { color: theme.colors.textMuted }]}>
|
||||
{formatDate(step.timestamp)}
|
||||
</Text>
|
||||
) : (
|
||||
<Text style={[styles.stepTime, { color: theme.colors.textMuted }]}>Pending</Text>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
card: { gap: 14 },
|
||||
header: { gap: 4 },
|
||||
title: { fontSize: 16, fontWeight: '800' },
|
||||
subtitle: { fontSize: 13, lineHeight: 18 },
|
||||
timeline: { gap: 0 },
|
||||
stepRow: { flexDirection: 'row', gap: 12 },
|
||||
stepIndicator: { alignItems: 'center', width: 24 },
|
||||
connector: { width: 2, flex: 1, minHeight: 20 },
|
||||
stepContent: { flex: 1, paddingTop: 1 },
|
||||
stepContentSpaced: { paddingBottom: 16 },
|
||||
stepLabel: { fontSize: 14 },
|
||||
stepTime: { fontSize: 12, marginTop: 2 },
|
||||
});
|
||||
|
||||
export const LoanTimelineCard = memo(LoanTimelineCardComponent);
|
||||
Reference in New Issue
Block a user