WellNuo/app/profile/support.tsx
Sergei 48384f07c5 Full project sync - app updates and profile screens
Changes:
- Updated app.json, eas.json configurations
- Modified login, chat, profile, dashboard screens
- Added profile subpages (about, edit, help, language,
  notifications, privacy, subscription, support, terms)
- Updated BeneficiaryContext
- Updated API service and types
- Updated discussion questions scheme
- Added .history to gitignore

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-12 16:26:13 -08:00

476 lines
13 KiB
TypeScript

import React, { useState } from 'react';
import {
View,
Text,
StyleSheet,
ScrollView,
TouchableOpacity,
TextInput,
Linking,
Alert,
KeyboardAvoidingView,
Platform,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { SafeAreaView } from 'react-native-safe-area-context';
import { router } from 'expo-router';
import { AppColors, BorderRadius, FontSizes, Spacing } from '@/constants/theme';
interface ContactMethodProps {
icon: keyof typeof Ionicons.glyphMap;
iconColor: string;
iconBgColor: string;
title: string;
subtitle: string;
onPress: () => void;
}
function ContactMethod({
icon,
iconColor,
iconBgColor,
title,
subtitle,
onPress,
}: ContactMethodProps) {
return (
<TouchableOpacity style={styles.contactMethod} onPress={onPress}>
<View style={[styles.contactIcon, { backgroundColor: iconBgColor }]}>
<Ionicons name={icon} size={24} color={iconColor} />
</View>
<View style={styles.contactContent}>
<Text style={styles.contactTitle}>{title}</Text>
<Text style={styles.contactSubtitle}>{subtitle}</Text>
</View>
<Ionicons name="chevron-forward" size={20} color={AppColors.textMuted} />
</TouchableOpacity>
);
}
export default function SupportScreen() {
const [subject, setSubject] = useState('');
const [message, setMessage] = useState('');
const [category, setCategory] = useState('');
const [isSending, setIsSending] = useState(false);
const categories = [
'Technical Issue',
'Billing Question',
'Feature Request',
'Account Help',
'Emergency',
'Other',
];
const handleCall = () => {
Linking.openURL('tel:+15551234567').catch(() => {
Alert.alert('Error', 'Unable to make phone call');
});
};
const handleEmail = () => {
Linking.openURL('mailto:support@wellnuo.com?subject=Support Request').catch(() => {
Alert.alert('Error', 'Unable to open email client');
});
};
const handleChat = () => {
Alert.alert(
'Live Chat',
'Connecting to a support agent...\n\nEstimated wait time: 2 minutes',
[
{ text: 'Cancel', style: 'cancel' },
{ text: 'Start Chat', onPress: () => Alert.alert('Coming Soon', 'Live chat feature coming soon!') },
]
);
};
const handleSendTicket = async () => {
if (!category) {
Alert.alert('Error', 'Please select a category');
return;
}
if (!subject.trim()) {
Alert.alert('Error', 'Please enter a subject');
return;
}
if (!message.trim()) {
Alert.alert('Error', 'Please describe your issue');
return;
}
setIsSending(true);
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 1500));
setIsSending(false);
Alert.alert(
'Ticket Submitted',
'Thank you for contacting us!\n\nTicket #WN-2024-12345\n\nWe\'ll respond within 24 hours.',
[{ text: 'OK', onPress: () => router.back() }]
);
};
return (
<SafeAreaView style={styles.container} edges={['bottom']}>
<KeyboardAvoidingView
style={styles.keyboardView}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
<ScrollView showsVerticalScrollIndicator={false}>
{/* Quick Contact */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Quick Contact</Text>
<View style={styles.card}>
<ContactMethod
icon="call"
iconColor="#10B981"
iconBgColor="#D1FAE5"
title="Call Us"
subtitle="+1 (555) 123-4567"
onPress={handleCall}
/>
<View style={styles.divider} />
<ContactMethod
icon="mail"
iconColor="#3B82F6"
iconBgColor="#DBEAFE"
title="Email Support"
subtitle="support@wellnuo.com"
onPress={handleEmail}
/>
<View style={styles.divider} />
<ContactMethod
icon="chatbubbles"
iconColor="#8B5CF6"
iconBgColor="#EDE9FE"
title="Live Chat"
subtitle="Available 24/7"
onPress={handleChat}
/>
</View>
</View>
{/* Support Hours */}
<View style={styles.section}>
<View style={styles.hoursCard}>
<Ionicons name="time" size={24} color={AppColors.primary} />
<View style={styles.hoursContent}>
<Text style={styles.hoursTitle}>Support Hours</Text>
<Text style={styles.hoursText}>Phone: Mon-Fri 8am-8pm EST</Text>
<Text style={styles.hoursText}>Email & Chat: 24/7</Text>
<Text style={styles.hoursText}>Emergency: 24/7</Text>
</View>
</View>
</View>
{/* Submit a Ticket */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Submit a Ticket</Text>
<View style={styles.formCard}>
{/* Category */}
<View style={styles.inputGroup}>
<Text style={styles.label}>Category *</Text>
<View style={styles.categoryContainer}>
{categories.map((cat) => (
<TouchableOpacity
key={cat}
style={[
styles.categoryChip,
category === cat && styles.categoryChipSelected,
]}
onPress={() => setCategory(cat)}
>
<Text
style={[
styles.categoryChipText,
category === cat && styles.categoryChipTextSelected,
]}
>
{cat}
</Text>
</TouchableOpacity>
))}
</View>
</View>
{/* Subject */}
<View style={styles.inputGroup}>
<Text style={styles.label}>Subject *</Text>
<TextInput
style={styles.input}
value={subject}
onChangeText={setSubject}
placeholder="Brief description of your issue"
placeholderTextColor={AppColors.textMuted}
/>
</View>
{/* Message */}
<View style={styles.inputGroup}>
<Text style={styles.label}>Message *</Text>
<TextInput
style={[styles.input, styles.textArea]}
value={message}
onChangeText={setMessage}
placeholder="Please describe your issue in detail. Include any error messages or steps to reproduce the problem."
placeholderTextColor={AppColors.textMuted}
multiline
numberOfLines={5}
textAlignVertical="top"
/>
</View>
{/* Attachments hint */}
<View style={styles.attachmentHint}>
<Ionicons name="attach" size={16} color={AppColors.textMuted} />
<Text style={styles.attachmentHintText}>
Need to attach screenshots? Reply to your ticket email.
</Text>
</View>
{/* Submit Button */}
<TouchableOpacity
style={[styles.submitButton, isSending && styles.submitButtonDisabled]}
onPress={handleSendTicket}
disabled={isSending}
>
<Text style={styles.submitButtonText}>
{isSending ? 'Sending...' : 'Submit Ticket'}
</Text>
</TouchableOpacity>
</View>
</View>
{/* FAQ Link */}
<View style={styles.section}>
<TouchableOpacity
style={styles.faqLink}
onPress={() => router.push('/profile/help')}
>
<View style={styles.faqLinkContent}>
<Ionicons name="help-circle" size={24} color={AppColors.primary} />
<View style={styles.faqLinkText}>
<Text style={styles.faqLinkTitle}>Check our Help Center</Text>
<Text style={styles.faqLinkSubtitle}>
Find answers to common questions
</Text>
</View>
</View>
<Ionicons name="chevron-forward" size={20} color={AppColors.textMuted} />
</TouchableOpacity>
</View>
{/* Emergency Notice */}
<View style={styles.emergencyNotice}>
<Ionicons name="warning" size={20} color={AppColors.error} />
<Text style={styles.emergencyText}>
If you're experiencing a medical emergency, please call 911 or your local
emergency services immediately.
</Text>
</View>
</ScrollView>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: AppColors.surface,
},
keyboardView: {
flex: 1,
},
section: {
marginTop: Spacing.md,
},
sectionTitle: {
fontSize: FontSizes.sm,
fontWeight: '600',
color: AppColors.textSecondary,
paddingHorizontal: Spacing.lg,
paddingVertical: Spacing.sm,
textTransform: 'uppercase',
},
card: {
backgroundColor: AppColors.background,
},
contactMethod: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: Spacing.md,
paddingHorizontal: Spacing.lg,
},
contactIcon: {
width: 48,
height: 48,
borderRadius: BorderRadius.md,
justifyContent: 'center',
alignItems: 'center',
},
contactContent: {
flex: 1,
marginLeft: Spacing.md,
},
contactTitle: {
fontSize: FontSizes.base,
fontWeight: '500',
color: AppColors.textPrimary,
},
contactSubtitle: {
fontSize: FontSizes.sm,
color: AppColors.textSecondary,
marginTop: 2,
},
divider: {
height: 1,
backgroundColor: AppColors.border,
marginLeft: Spacing.lg + 48 + Spacing.md,
},
hoursCard: {
flexDirection: 'row',
backgroundColor: AppColors.background,
marginHorizontal: Spacing.lg,
padding: Spacing.md,
borderRadius: BorderRadius.lg,
alignItems: 'flex-start',
},
hoursContent: {
flex: 1,
marginLeft: Spacing.md,
},
hoursTitle: {
fontSize: FontSizes.base,
fontWeight: '600',
color: AppColors.textPrimary,
marginBottom: Spacing.xs,
},
hoursText: {
fontSize: FontSizes.sm,
color: AppColors.textSecondary,
marginTop: 2,
},
formCard: {
backgroundColor: AppColors.background,
padding: Spacing.lg,
},
inputGroup: {
marginBottom: Spacing.md,
},
label: {
fontSize: FontSizes.sm,
fontWeight: '600',
color: AppColors.textPrimary,
marginBottom: Spacing.xs,
},
input: {
backgroundColor: AppColors.surface,
borderRadius: BorderRadius.md,
paddingHorizontal: Spacing.md,
paddingVertical: Spacing.md,
fontSize: FontSizes.base,
color: AppColors.textPrimary,
borderWidth: 1,
borderColor: AppColors.border,
},
textArea: {
minHeight: 120,
paddingTop: Spacing.md,
},
categoryContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
marginTop: Spacing.xs,
},
categoryChip: {
paddingHorizontal: Spacing.md,
paddingVertical: Spacing.xs,
borderRadius: BorderRadius.full,
backgroundColor: AppColors.surface,
marginRight: Spacing.xs,
marginBottom: Spacing.xs,
borderWidth: 1,
borderColor: AppColors.border,
},
categoryChipSelected: {
backgroundColor: AppColors.primary,
borderColor: AppColors.primary,
},
categoryChipText: {
fontSize: FontSizes.sm,
color: AppColors.textSecondary,
},
categoryChipTextSelected: {
color: AppColors.white,
},
attachmentHint: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: Spacing.lg,
},
attachmentHintText: {
fontSize: FontSizes.xs,
color: AppColors.textMuted,
marginLeft: Spacing.xs,
},
submitButton: {
backgroundColor: AppColors.primary,
borderRadius: BorderRadius.lg,
paddingVertical: Spacing.md,
alignItems: 'center',
},
submitButtonDisabled: {
opacity: 0.6,
},
submitButtonText: {
fontSize: FontSizes.base,
fontWeight: '600',
color: AppColors.white,
},
faqLink: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: AppColors.background,
marginHorizontal: Spacing.lg,
padding: Spacing.md,
borderRadius: BorderRadius.lg,
},
faqLinkContent: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
},
faqLinkText: {
marginLeft: Spacing.md,
},
faqLinkTitle: {
fontSize: FontSizes.base,
fontWeight: '500',
color: AppColors.textPrimary,
},
faqLinkSubtitle: {
fontSize: FontSizes.xs,
color: AppColors.textMuted,
marginTop: 2,
},
emergencyNotice: {
flexDirection: 'row',
alignItems: 'flex-start',
backgroundColor: '#FEE2E2',
marginHorizontal: Spacing.lg,
marginVertical: Spacing.lg,
padding: Spacing.md,
borderRadius: BorderRadius.lg,
},
emergencyText: {
flex: 1,
fontSize: FontSizes.xs,
color: AppColors.error,
marginLeft: Spacing.sm,
lineHeight: 18,
},
});