WellNuo/app/(tabs)/profile/notifications.tsx
Sergei abcc380984 Sync all changes - profile restructure and scheme updates
- Restructured profile screens location
- Updated beneficiary detail page
- Updated API service
- Updated all scheme files (MainScheme, ENV API, Discussion, AppStore, SysAnal)
- Added PageHeader component

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

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

383 lines
11 KiB
TypeScript

import React, { useState } from 'react';
import {
View,
Text,
StyleSheet,
ScrollView,
Switch,
TouchableOpacity,
Alert,
} 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';
interface NotificationSettingProps {
icon: keyof typeof Ionicons.glyphMap;
iconColor: string;
iconBgColor: string;
title: string;
description: string;
value: boolean;
onValueChange: (value: boolean) => void;
}
function NotificationSetting({
icon,
iconColor,
iconBgColor,
title,
description,
value,
onValueChange,
}: NotificationSettingProps) {
return (
<View style={styles.settingRow}>
<View style={[styles.iconContainer, { backgroundColor: iconBgColor }]}>
<Ionicons name={icon} size={20} color={iconColor} />
</View>
<View style={styles.settingContent}>
<Text style={styles.settingTitle}>{title}</Text>
<Text style={styles.settingDescription}>{description}</Text>
</View>
<Switch
value={value}
onValueChange={onValueChange}
trackColor={{ false: '#E5E7EB', true: AppColors.primaryLight }}
thumbColor={value ? AppColors.primary : '#9CA3AF'}
/>
</View>
);
}
export default function NotificationsScreen() {
// Alert types
const [emergencyAlerts, setEmergencyAlerts] = useState(true);
const [activityAlerts, setActivityAlerts] = useState(true);
const [lowBattery, setLowBattery] = useState(true);
const [dailySummary, setDailySummary] = useState(false);
const [weeklySummary, setWeeklySummary] = useState(true);
// Delivery methods
const [pushEnabled, setPushEnabled] = useState(true);
const [emailEnabled, setEmailEnabled] = useState(false);
const [smsEnabled, setSmsEnabled] = useState(false);
// Quiet hours
const [quietHours, setQuietHours] = useState(false);
const [quietStart, setQuietStart] = useState('22:00');
const [quietEnd, setQuietEnd] = useState('07:00');
const handleSave = () => {
Alert.alert(
'Settings Saved',
'Your notification preferences have been updated.',
[{ text: 'OK', onPress: () => router.back() }]
);
};
const handleQuietHoursConfig = () => {
Alert.alert(
'Quiet Hours',
`Current: ${quietStart} - ${quietEnd}\n\nDuring quiet hours, only emergency alerts will be delivered.`,
[
{ text: 'Cancel', style: 'cancel' },
{ text: 'Set Start Time', onPress: () => Alert.alert('Coming Soon', 'Time picker coming soon!') },
]
);
};
return (
<SafeAreaView style={styles.container} edges={['top', 'bottom']}>
<PageHeader title="Notifications" />
<ScrollView showsVerticalScrollIndicator={false}>
{/* Alert Types */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Alert Types</Text>
<View style={styles.card}>
<NotificationSetting
icon="warning"
iconColor="#EF4444"
iconBgColor="#FEE2E2"
title="Emergency Alerts"
description="Falls, inactivity, SOS button"
value={emergencyAlerts}
onValueChange={setEmergencyAlerts}
/>
<View style={styles.divider} />
<NotificationSetting
icon="walk"
iconColor="#3B82F6"
iconBgColor="#DBEAFE"
title="Activity Alerts"
description="Unusual activity patterns"
value={activityAlerts}
onValueChange={setActivityAlerts}
/>
<View style={styles.divider} />
<NotificationSetting
icon="battery-half"
iconColor="#F59E0B"
iconBgColor="#FEF3C7"
title="Low Battery"
description="Device battery warnings"
value={lowBattery}
onValueChange={setLowBattery}
/>
<View style={styles.divider} />
<NotificationSetting
icon="today"
iconColor="#10B981"
iconBgColor="#D1FAE5"
title="Daily Summary"
description="Daily wellness report"
value={dailySummary}
onValueChange={setDailySummary}
/>
<View style={styles.divider} />
<NotificationSetting
icon="calendar"
iconColor="#8B5CF6"
iconBgColor="#EDE9FE"
title="Weekly Summary"
description="Weekly health digest"
value={weeklySummary}
onValueChange={setWeeklySummary}
/>
</View>
</View>
{/* Delivery Methods */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Delivery Methods</Text>
<View style={styles.card}>
<NotificationSetting
icon="notifications"
iconColor={AppColors.primary}
iconBgColor="#DBEAFE"
title="Push Notifications"
description="Alerts on your device"
value={pushEnabled}
onValueChange={setPushEnabled}
/>
<View style={styles.divider} />
<NotificationSetting
icon="mail"
iconColor="#6366F1"
iconBgColor="#E0E7FF"
title="Email Notifications"
description="Summaries to your inbox"
value={emailEnabled}
onValueChange={setEmailEnabled}
/>
<View style={styles.divider} />
<NotificationSetting
icon="chatbubble"
iconColor="#EC4899"
iconBgColor="#FCE7F3"
title="SMS Notifications"
description="Text message alerts"
value={smsEnabled}
onValueChange={(value) => {
if (value) {
Alert.alert(
'SMS Notifications',
'SMS notifications require a verified phone number. Would you like to add one?',
[
{ text: 'Cancel', style: 'cancel' },
{
text: 'Add Phone',
onPress: () => router.push('/profile/edit')
},
]
);
} else {
setSmsEnabled(false);
}
}}
/>
</View>
</View>
{/* Quiet Hours */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Quiet Hours</Text>
<View style={styles.card}>
<NotificationSetting
icon="moon"
iconColor="#6366F1"
iconBgColor="#E0E7FF"
title="Enable Quiet Hours"
description="Silence non-emergency alerts"
value={quietHours}
onValueChange={setQuietHours}
/>
{quietHours && (
<>
<View style={styles.divider} />
<TouchableOpacity style={styles.timeRow} onPress={handleQuietHoursConfig}>
<View style={styles.timeInfo}>
<Ionicons name="time-outline" size={20} color={AppColors.textSecondary} />
<Text style={styles.timeLabel}>Quiet Period</Text>
</View>
<View style={styles.timeValue}>
<Text style={styles.timeText}>{quietStart} - {quietEnd}</Text>
<Ionicons name="chevron-forward" size={20} color={AppColors.textMuted} />
</View>
</TouchableOpacity>
</>
)}
</View>
<Text style={styles.quietNote}>
Emergency alerts will always be delivered, even during quiet hours.
</Text>
</View>
{/* Test Notification */}
<View style={styles.section}>
<TouchableOpacity
style={styles.testButton}
onPress={() => {
Alert.alert(
'Test Notification Sent',
'A test push notification has been sent to your device.',
[{ text: 'OK' }]
);
}}
>
<Ionicons name="paper-plane-outline" size={20} color={AppColors.primary} />
<Text style={styles.testButtonText}>Send Test Notification</Text>
</TouchableOpacity>
</View>
</ScrollView>
{/* Save Button */}
<View style={styles.footer}>
<TouchableOpacity style={styles.saveButton} onPress={handleSave}>
<Text style={styles.saveButtonText}>Save Preferences</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: AppColors.surface,
},
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,
},
settingRow: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: Spacing.md,
paddingHorizontal: Spacing.lg,
},
iconContainer: {
width: 40,
height: 40,
borderRadius: BorderRadius.md,
justifyContent: 'center',
alignItems: 'center',
},
settingContent: {
flex: 1,
marginLeft: Spacing.md,
},
settingTitle: {
fontSize: FontSizes.base,
fontWeight: '500',
color: AppColors.textPrimary,
},
settingDescription: {
fontSize: FontSizes.xs,
color: AppColors.textMuted,
marginTop: 2,
},
divider: {
height: 1,
backgroundColor: AppColors.border,
marginLeft: Spacing.lg + 40 + Spacing.md,
},
timeRow: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingVertical: Spacing.md,
paddingHorizontal: Spacing.lg,
},
timeInfo: {
flexDirection: 'row',
alignItems: 'center',
},
timeLabel: {
fontSize: FontSizes.base,
color: AppColors.textPrimary,
marginLeft: Spacing.sm,
},
timeValue: {
flexDirection: 'row',
alignItems: 'center',
},
timeText: {
fontSize: FontSizes.sm,
color: AppColors.textSecondary,
marginRight: Spacing.xs,
},
quietNote: {
fontSize: FontSizes.xs,
color: AppColors.textMuted,
paddingHorizontal: Spacing.lg,
paddingTop: Spacing.sm,
},
testButton: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: AppColors.background,
paddingVertical: Spacing.md,
marginHorizontal: Spacing.lg,
borderRadius: BorderRadius.lg,
borderWidth: 1,
borderColor: AppColors.primary,
},
testButtonText: {
fontSize: FontSizes.base,
fontWeight: '500',
color: AppColors.primary,
marginLeft: Spacing.sm,
},
footer: {
padding: Spacing.lg,
backgroundColor: AppColors.background,
borderTopWidth: 1,
borderTopColor: AppColors.border,
},
saveButton: {
backgroundColor: AppColors.primary,
borderRadius: BorderRadius.lg,
paddingVertical: Spacing.md,
alignItems: 'center',
},
saveButtonText: {
fontSize: FontSizes.base,
fontWeight: '600',
color: AppColors.white,
},
});