import React, { useState } from 'react';
import {
View,
Text,
StyleSheet,
ScrollView,
TouchableOpacity,
TextInput,
Linking,
Alert,
KeyboardAvoidingView,
Platform,
Modal,
} 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';
import { PageHeader } from '@/components/PageHeader';
// Mock data for tickets
const mockTickets = [
{
id: 'WN-2024-12341',
subject: 'Notifications not working',
category: 'Technical Issue',
status: 'resolved',
createdAt: '2024-12-08',
updatedAt: '2024-12-10',
messages: [
{
from: 'user',
text: 'I am not receiving push notifications when my mother triggers an alert. I have notifications enabled in the app settings.',
date: '2024-12-08 14:32',
},
{
from: 'support',
text: 'Thank you for reaching out! Let me help you with this. Could you please confirm that notifications are also enabled in your device settings (Settings > WellNuo > Notifications)?',
date: '2024-12-08 15:45',
agent: 'Sarah M.',
},
{
from: 'user',
text: 'Oh, I checked and they were disabled there. I enabled them now.',
date: '2024-12-09 09:12',
},
{
from: 'support',
text: 'Great! That should fix it. Please let us know if you have any other issues. Have a wonderful day!',
date: '2024-12-09 09:30',
agent: 'Sarah M.',
},
],
},
{
id: 'WN-2024-12338',
subject: 'How to add a second beneficiary?',
category: 'Account Help',
status: 'resolved',
createdAt: '2024-12-05',
updatedAt: '2024-12-06',
messages: [
{
from: 'user',
text: 'I want to add my father as a second beneficiary. How can I do that?',
date: '2024-12-05 11:20',
},
{
from: 'support',
text: 'Hello! To add a second beneficiary:\n\n1. Go to Dashboard\n2. Tap the + button or "Add Beneficiary"\n3. Enter their details and sensor ID\n\nNote: Free plan supports 1 beneficiary. For multiple beneficiaries, consider upgrading to WellNuo Pro. Would you like more information about our plans?',
date: '2024-12-05 12:15',
agent: 'Mike R.',
},
{
from: 'user',
text: 'Thank you! I upgraded to Pro and it works now.',
date: '2024-12-06 08:45',
},
],
},
{
id: 'WN-2024-12345',
subject: 'Battery status shows wrong percentage',
category: 'Technical Issue',
status: 'open',
createdAt: '2024-12-11',
updatedAt: '2024-12-11',
messages: [
{
from: 'user',
text: 'The sensor shows 15% battery in the app, but I just charged it fully yesterday. Is there something wrong with the sensor?',
date: '2024-12-11 16:20',
},
{
from: 'support',
text: 'Hi there! This could be a sync issue. Please try the following:\n\n1. Force close the WellNuo app\n2. Wait 30 seconds\n3. Reopen the app\n\nIf the issue persists, try restarting the sensor by pressing the reset button for 5 seconds. Let me know the results!',
date: '2024-12-11 17:05',
agent: 'Alex K.',
},
],
},
{
id: 'WN-2024-12340',
subject: 'Request: Add medication reminders',
category: 'Feature Request',
status: 'in_progress',
createdAt: '2024-12-07',
updatedAt: '2024-12-10',
messages: [
{
from: 'user',
text: 'It would be great if WellNuo could also send medication reminders to my beneficiaries. Is this something you\'re considering?',
date: '2024-12-07 10:15',
},
{
from: 'support',
text: 'Thank you for your feedback! We love hearing feature suggestions from our users.\n\nMedication reminders are actually on our roadmap! Our development team is working on this feature, and we expect to release it in Q1 2025.\n\nWe\'ve added your vote to this feature request. You\'ll be notified when it becomes available!',
date: '2024-12-07 14:30',
agent: 'Emma T.',
},
{
from: 'support',
text: 'Quick update: The medication reminders feature has moved to active development. We\'re targeting a late January release. Stay tuned!',
date: '2024-12-10 09:00',
agent: 'Emma T.',
},
],
},
];
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 (
{title}
{subtitle}
);
}
const getStatusColor = (status: string) => {
switch (status) {
case 'open':
return '#3B82F6';
case 'in_progress':
return '#F59E0B';
case 'resolved':
return '#10B981';
default:
return AppColors.textMuted;
}
};
const getStatusBgColor = (status: string) => {
switch (status) {
case 'open':
return '#DBEAFE';
case 'in_progress':
return '#FEF3C7';
case 'resolved':
return '#D1FAE5';
default:
return AppColors.surface;
}
};
const getStatusLabel = (status: string) => {
switch (status) {
case 'open':
return 'Open';
case 'in_progress':
return 'In Progress';
case 'resolved':
return 'Resolved';
default:
return status;
}
};
export default function SupportScreen() {
const [subject, setSubject] = useState('');
const [message, setMessage] = useState('');
const [category, setCategory] = useState('');
const [isSending, setIsSending] = useState(false);
const [selectedTicket, setSelectedTicket] = useState(null);
const [showTicketModal, setShowTicketModal] = useState(false);
const [activeTab, setActiveTab] = useState<'contact' | 'tickets'>('tickets');
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);
setSubject('');
setMessage('');
setCategory('');
Alert.alert(
'Ticket Submitted',
'Thank you for contacting us!\n\nTicket #WN-2024-12346\n\nWe\'ll respond within 24 hours.',
[{ text: 'OK' }]
);
};
const openTicket = (ticket: typeof mockTickets[0]) => {
setSelectedTicket(ticket);
setShowTicketModal(true);
};
const renderTicketModal = () => (
setShowTicketModal(false)}
>
{/* Modal Header */}
setShowTicketModal(false)}>
Ticket Details
{selectedTicket && (
{/* Ticket Info */}
Ticket ID
{selectedTicket.id}
Category
{selectedTicket.category}
Status
{getStatusLabel(selectedTicket.status)}
Created
{selectedTicket.createdAt}
{/* Subject */}
Subject
{selectedTicket.subject}
{/* Messages */}
Conversation
{selectedTicket.messages.map((msg, index) => (
{msg.from === 'user' ? 'You' : `Support (${(msg as any).agent})`}
{msg.date}
{msg.text}
))}
{/* Reply section for open tickets */}
{selectedTicket.status !== 'resolved' && (
Reply
Alert.alert('Coming Soon', 'Reply functionality will be available in a future update.')}
>
Send Reply
)}
)}
);
return (
{/* Tabs */}
setActiveTab('tickets')}
>
My Tickets
setActiveTab('contact')}
>
New Ticket
{activeTab === 'tickets' ? (
<>
{/* My Tickets */}
My Tickets ({mockTickets.length})
{mockTickets.map((ticket) => (
openTicket(ticket)}
>
{ticket.id}
{getStatusLabel(ticket.status)}
{ticket.subject}
{ticket.category}
Updated: {ticket.updatedAt}
{ticket.messages.length} message{ticket.messages.length !== 1 ? 's' : ''}
))}
>
) : (
<>
{/* Quick Contact */}
Quick Contact
{/* Support Hours */}
Support Hours
Phone: Mon-Fri 8am-8pm EST
Email & Chat: 24/7
Emergency: 24/7
{/* Submit a Ticket */}
Submit a Ticket
{/* Category */}
Category *
{categories.map((cat) => (
setCategory(cat)}
>
{cat}
))}
{/* Subject */}
Subject *
{/* Message */}
Message *
{/* Submit Button */}
{isSending ? 'Sending...' : 'Submit Ticket'}
>
)}
{/* FAQ Link */}
router.push('/(tabs)/profile/help')}
>
Check our Help Center
Find answers to common questions
{/* Emergency Notice */}
If you're experiencing a medical emergency, please call 911 or your local
emergency services immediately.
{/* Ticket Detail Modal */}
{renderTicketModal()}
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: AppColors.surface,
},
keyboardView: {
flex: 1,
},
tabsContainer: {
flexDirection: 'row',
backgroundColor: AppColors.background,
borderBottomWidth: 1,
borderBottomColor: AppColors.border,
},
tab: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
paddingVertical: Spacing.md,
gap: Spacing.xs,
},
tabActive: {
borderBottomWidth: 2,
borderBottomColor: AppColors.primary,
},
tabText: {
fontSize: FontSizes.sm,
fontWeight: '500',
color: AppColors.textMuted,
},
tabTextActive: {
color: AppColors.primary,
},
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,
},
ticketsList: {
paddingHorizontal: Spacing.lg,
gap: Spacing.sm,
},
ticketCard: {
backgroundColor: AppColors.background,
borderRadius: BorderRadius.lg,
padding: Spacing.md,
borderWidth: 1,
borderColor: AppColors.border,
},
ticketHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: Spacing.xs,
},
ticketId: {
fontSize: FontSizes.xs,
fontWeight: '600',
color: AppColors.primary,
},
statusBadge: {
paddingHorizontal: Spacing.sm,
paddingVertical: 2,
borderRadius: BorderRadius.full,
},
statusBadgeText: {
fontSize: FontSizes.xs,
fontWeight: '600',
},
ticketSubject: {
fontSize: FontSizes.base,
fontWeight: '500',
color: AppColors.textPrimary,
marginBottom: Spacing.sm,
},
ticketFooter: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
ticketCategory: {
flexDirection: 'row',
alignItems: 'center',
gap: 4,
},
ticketCategoryText: {
fontSize: FontSizes.xs,
color: AppColors.textMuted,
},
ticketDate: {
fontSize: FontSizes.xs,
color: AppColors.textMuted,
},
ticketMessages: {
flexDirection: 'row',
alignItems: 'center',
gap: 4,
marginTop: Spacing.xs,
paddingTop: Spacing.xs,
borderTopWidth: 1,
borderTopColor: AppColors.border,
},
ticketMessagesText: {
fontSize: FontSizes.xs,
color: AppColors.textMuted,
},
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: 100,
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,
},
submitButton: {
backgroundColor: AppColors.primary,
borderRadius: BorderRadius.lg,
paddingVertical: Spacing.md,
alignItems: 'center',
marginTop: Spacing.sm,
},
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,
},
// Modal styles
modalContainer: {
flex: 1,
backgroundColor: AppColors.surface,
},
modalHeader: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: Spacing.lg,
paddingVertical: Spacing.md,
backgroundColor: AppColors.background,
borderBottomWidth: 1,
borderBottomColor: AppColors.border,
},
modalTitle: {
fontSize: FontSizes.lg,
fontWeight: '600',
color: AppColors.textPrimary,
},
modalContent: {
flex: 1,
},
ticketInfo: {
backgroundColor: AppColors.background,
padding: Spacing.lg,
marginBottom: Spacing.md,
},
ticketInfoRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: Spacing.xs,
},
ticketInfoLabel: {
fontSize: FontSizes.sm,
color: AppColors.textSecondary,
},
ticketInfoValue: {
fontSize: FontSizes.sm,
fontWeight: '500',
color: AppColors.textPrimary,
},
ticketSubjectContainer: {
backgroundColor: AppColors.background,
padding: Spacing.lg,
marginBottom: Spacing.md,
},
ticketSubjectLabel: {
fontSize: FontSizes.sm,
color: AppColors.textSecondary,
marginBottom: Spacing.xs,
},
ticketSubjectText: {
fontSize: FontSizes.base,
fontWeight: '600',
color: AppColors.textPrimary,
},
messagesContainer: {
padding: Spacing.lg,
},
messagesTitle: {
fontSize: FontSizes.sm,
fontWeight: '600',
color: AppColors.textSecondary,
marginBottom: Spacing.md,
textTransform: 'uppercase',
},
messageCard: {
backgroundColor: AppColors.background,
borderRadius: BorderRadius.lg,
padding: Spacing.md,
marginBottom: Spacing.sm,
borderLeftWidth: 3,
borderLeftColor: AppColors.primary,
},
messageCardSupport: {
borderLeftColor: '#10B981',
backgroundColor: '#F0FDF4',
},
messageHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: Spacing.xs,
},
messageFrom: {
flexDirection: 'row',
alignItems: 'center',
gap: Spacing.xs,
},
messageFromText: {
fontSize: FontSizes.sm,
fontWeight: '600',
color: AppColors.textPrimary,
},
messageDate: {
fontSize: FontSizes.xs,
color: AppColors.textMuted,
},
messageText: {
fontSize: FontSizes.sm,
color: AppColors.textPrimary,
lineHeight: 20,
},
replySection: {
padding: Spacing.lg,
backgroundColor: AppColors.background,
marginTop: Spacing.md,
},
replyTitle: {
fontSize: FontSizes.sm,
fontWeight: '600',
color: AppColors.textSecondary,
marginBottom: Spacing.sm,
textTransform: 'uppercase',
},
replyInput: {
backgroundColor: AppColors.surface,
borderRadius: BorderRadius.md,
paddingHorizontal: Spacing.md,
paddingVertical: Spacing.md,
fontSize: FontSizes.base,
color: AppColors.textPrimary,
borderWidth: 1,
borderColor: AppColors.border,
minHeight: 100,
marginBottom: Spacing.md,
},
replyButton: {
backgroundColor: AppColors.primary,
borderRadius: BorderRadius.lg,
paddingVertical: Spacing.md,
alignItems: 'center',
},
replyButtonText: {
fontSize: FontSizes.base,
fontWeight: '600',
color: AppColors.white,
},
});