Fix form keyboard issues and sticky footers in agent screens
This commit is contained in:
@@ -0,0 +1,272 @@
|
||||
import React from 'react';
|
||||
import { Share, StyleSheet, Text, View, Pressable, Linking } from 'react-native';
|
||||
import { NativeStackScreenProps } from '@react-navigation/native-stack';
|
||||
import Ionicons from '@react-native-vector-icons/ionicons';
|
||||
|
||||
import { Card, ScreenShell, Button } from '../../../components';
|
||||
import { ServicesStackParamList } from '../../../navigation/types';
|
||||
import { useTheme } from '../../../theme';
|
||||
import { useSchemes } from '../hooks/useSchemes';
|
||||
import { Accordion } from '../components/Accordion';
|
||||
|
||||
type Props = NativeStackScreenProps<ServicesStackParamList, 'SchemeDetails'>;
|
||||
|
||||
export default function SchemeDetailScreen({ route, navigation }: Props) {
|
||||
const { schemeId } = route.params;
|
||||
const theme = useTheme();
|
||||
const { schemes, bookmarks, toggleBookmark } = useSchemes();
|
||||
|
||||
const scheme = schemes.find((s) => s.id === schemeId);
|
||||
const isBookmarked = bookmarks.includes(schemeId);
|
||||
|
||||
if (!scheme) {
|
||||
return (
|
||||
<ScreenShell title="Not Found">
|
||||
<View style={styles.errorContainer}>
|
||||
<Text style={{ color: theme.colors.textPrimary }}>Scheme not found.</Text>
|
||||
</View>
|
||||
</ScreenShell>
|
||||
);
|
||||
}
|
||||
|
||||
const handleShare = async () => {
|
||||
try {
|
||||
await Share.share({
|
||||
message: `${scheme.title}\n\n${scheme.description}\n\nLearn more on BankCBS!`,
|
||||
title: scheme.title,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error sharing scheme', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleApply = async () => {
|
||||
if (scheme.isNew || scheme.type === 'GOVT_SCHEME') {
|
||||
navigation.navigate('SchemeEnrollment', { schemeId });
|
||||
} else if (scheme.applyUrl) {
|
||||
const supported = await Linking.canOpenURL(scheme.applyUrl);
|
||||
if (supported) {
|
||||
await Linking.openURL(scheme.applyUrl);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const rightContent = (
|
||||
<View style={styles.headerActions}>
|
||||
<Pressable onPress={handleShare} style={[styles.actionBtn, { backgroundColor: theme.colors.surfaceMuted }]}>
|
||||
<Ionicons name="share-social-outline" size={20} color={theme.colors.textPrimary} />
|
||||
</Pressable>
|
||||
<Pressable
|
||||
onPress={() => toggleBookmark(schemeId)}
|
||||
style={[styles.actionBtn, { backgroundColor: isBookmarked ? `${theme.colors.primary}15` : theme.colors.surfaceMuted }]}
|
||||
>
|
||||
<Ionicons
|
||||
name={isBookmarked ? 'bookmark' : 'bookmark-outline'}
|
||||
size={20}
|
||||
color={isBookmarked ? theme.colors.primary : theme.colors.textPrimary}
|
||||
/>
|
||||
</Pressable>
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<ScreenShell
|
||||
title="Details"
|
||||
subtitle={scheme.type.replace('_', ' ')}
|
||||
rightContent={rightContent}
|
||||
>
|
||||
<View style={styles.container}>
|
||||
<View style={styles.metaRow}>
|
||||
<View style={[styles.typeBadge, { backgroundColor: `${theme.colors.primary}12` }]}>
|
||||
<Text style={[styles.typeText, { color: theme.colors.primary }]}>{scheme.type.replace('_', ' ')}</Text>
|
||||
</View>
|
||||
<View style={[styles.categoryBadge, { backgroundColor: theme.colors.surfaceMuted }]}>
|
||||
<Text style={[styles.categoryText, { color: theme.colors.textSecondary }]}>{scheme.category}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<Text style={[styles.title, { color: theme.colors.textPrimary }]}>{scheme.title}</Text>
|
||||
|
||||
<Card variant="glass" style={styles.overviewCard}>
|
||||
<Text style={[styles.description, { color: theme.colors.textSecondary }]}>
|
||||
{scheme.description}
|
||||
</Text>
|
||||
</Card>
|
||||
|
||||
<View style={styles.section}>
|
||||
<Text style={[styles.sectionTitle, { color: theme.colors.textPrimary }]}>About the Scheme</Text>
|
||||
<Text style={[styles.contentText, { color: theme.colors.textPrimary }]}>
|
||||
{scheme.content}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{scheme.benefits && (
|
||||
<View style={styles.section}>
|
||||
<Text style={[styles.sectionTitle, { color: theme.colors.textPrimary }]}>Key Benefits</Text>
|
||||
{scheme.benefits.map((benefit, idx) => (
|
||||
<View key={idx} style={styles.listRow}>
|
||||
<Ionicons name="checkmark-circle" size={18} color={theme.colors.success} />
|
||||
<Text style={[styles.listText, { color: theme.colors.textSecondary }]}>{benefit}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{scheme.eligibility && (
|
||||
<View style={styles.section}>
|
||||
<Text style={[styles.sectionTitle, { color: theme.colors.textPrimary }]}>Eligibility Criteria</Text>
|
||||
{scheme.eligibility.map((criterion, idx) => (
|
||||
<View key={idx} style={styles.listRow}>
|
||||
<Ionicons name="information-circle-outline" size={18} color={theme.colors.primary} />
|
||||
<Text style={[styles.listText, { color: theme.colors.textSecondary }]}>{criterion}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{scheme.premiumInfo && (
|
||||
<View style={styles.section}>
|
||||
<Text style={[styles.sectionTitle, { color: theme.colors.textPrimary }]}>Premium & Contributions</Text>
|
||||
<View style={[styles.highlightCard, { backgroundColor: theme.colors.surfaceMuted }]}>
|
||||
<Text style={[styles.highlightText, { color: theme.colors.textPrimary }]}>{scheme.premiumInfo}</Text>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{scheme.faqs && scheme.faqs.length > 0 && (
|
||||
<View style={styles.section}>
|
||||
<Text style={[styles.sectionTitle, { color: theme.colors.textPrimary }]}>Frequently Asked Questions</Text>
|
||||
{scheme.faqs.map((faq, idx) => (
|
||||
<Accordion key={idx} title={faq.question}>
|
||||
<Text style={[styles.faqAnswer, { color: theme.colors.textSecondary }]}>
|
||||
{faq.answer}
|
||||
</Text>
|
||||
</Accordion>
|
||||
))}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{scheme.applyUrl && (
|
||||
<View style={styles.footerAction}>
|
||||
<Button
|
||||
title={scheme.type === 'GOVT_SCHEME' ? "Enroll Now" : "Apply Now"}
|
||||
onPress={handleApply}
|
||||
/>
|
||||
<Text style={[styles.disclaimer, { color: theme.colors.textMuted }]}>
|
||||
{scheme.type === 'GOVT_SCHEME'
|
||||
? "* Enrolling digitally will trigger an OTP verification sent to your registered mobile."
|
||||
: "* Clicking Apply Now will redirect you to the official government portal."}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</ScreenShell>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
paddingHorizontal: 16,
|
||||
paddingBottom: 40,
|
||||
},
|
||||
headerActions: {
|
||||
flexDirection: 'row',
|
||||
gap: 8,
|
||||
},
|
||||
actionBtn: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
metaRow: {
|
||||
flexDirection: 'row',
|
||||
gap: 8,
|
||||
alignItems: 'center',
|
||||
marginBottom: 12,
|
||||
},
|
||||
typeBadge: {
|
||||
paddingHorizontal: 10,
|
||||
paddingVertical: 4,
|
||||
borderRadius: 8,
|
||||
},
|
||||
typeText: {
|
||||
fontSize: 11,
|
||||
fontWeight: '800',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: 0.5,
|
||||
},
|
||||
categoryBadge: {
|
||||
paddingHorizontal: 10,
|
||||
paddingVertical: 4,
|
||||
borderRadius: 8,
|
||||
},
|
||||
categoryText: {
|
||||
fontSize: 11,
|
||||
fontWeight: '700',
|
||||
},
|
||||
title: {
|
||||
fontSize: 24,
|
||||
fontWeight: '800',
|
||||
lineHeight: 30,
|
||||
marginBottom: 16,
|
||||
},
|
||||
overviewCard: {
|
||||
padding: 16,
|
||||
marginBottom: 24,
|
||||
},
|
||||
description: {
|
||||
fontSize: 15,
|
||||
lineHeight: 22,
|
||||
fontWeight: '500',
|
||||
},
|
||||
section: {
|
||||
marginBottom: 28,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '800',
|
||||
marginBottom: 12,
|
||||
},
|
||||
contentText: {
|
||||
fontSize: 16,
|
||||
lineHeight: 24,
|
||||
},
|
||||
listRow: {
|
||||
flexDirection: 'row',
|
||||
gap: 12,
|
||||
marginBottom: 10,
|
||||
alignItems: 'flex-start',
|
||||
},
|
||||
listText: {
|
||||
fontSize: 15,
|
||||
lineHeight: 20,
|
||||
flex: 1,
|
||||
},
|
||||
highlightCard: {
|
||||
padding: 16,
|
||||
borderRadius: 12,
|
||||
},
|
||||
highlightText: {
|
||||
fontSize: 15,
|
||||
fontWeight: '600',
|
||||
},
|
||||
faqAnswer: {
|
||||
fontSize: 14,
|
||||
lineHeight: 20,
|
||||
},
|
||||
footerAction: {
|
||||
marginTop: 10,
|
||||
gap: 12,
|
||||
},
|
||||
disclaimer: {
|
||||
fontSize: 11,
|
||||
textAlign: 'center',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
errorContainer: {
|
||||
padding: 20,
|
||||
alignItems: 'center',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user