222 lines
5.3 KiB
TypeScript
222 lines
5.3 KiB
TypeScript
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
|
import { Redirect, router } from 'expo-router';
|
|
import { useState } from 'react';
|
|
import {
|
|
ActivityIndicator,
|
|
Alert,
|
|
Pressable,
|
|
StyleSheet,
|
|
Text,
|
|
View,
|
|
} from 'react-native';
|
|
|
|
import { Avatar } from '@/components/common/Avatar';
|
|
import { Catamaran, FunnelSans } from '@/constants/fonts';
|
|
import { Palette } from '@/constants/palette';
|
|
import { Radius, Spacing } from '@/constants/styles';
|
|
import { useAuth } from '@/providers/AuthProvider';
|
|
import { sendTestPushNotification } from '@/services/notifications';
|
|
|
|
function SettingsRow({
|
|
label,
|
|
description,
|
|
onPress,
|
|
}: {
|
|
label: string;
|
|
description: string;
|
|
onPress: () => void;
|
|
}) {
|
|
return (
|
|
<Pressable onPress={onPress} style={styles.row}>
|
|
<View style={styles.rowContent}>
|
|
<Text style={styles.rowLabel}>{label}</Text>
|
|
<Text style={styles.rowDescription}>{description}</Text>
|
|
</View>
|
|
<MaterialCommunityIcons
|
|
color={Palette.gray}
|
|
name="chevron-right"
|
|
size={24}
|
|
/>
|
|
</Pressable>
|
|
);
|
|
}
|
|
|
|
export default function SettingsScreen() {
|
|
const { initializing, user } = useAuth();
|
|
const [sendingNotification, setSendingNotification] = useState(false);
|
|
|
|
if (initializing) {
|
|
return (
|
|
<View style={styles.centered}>
|
|
<ActivityIndicator color={Palette.black} />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
if (!user) {
|
|
return <Redirect href="/login" />;
|
|
}
|
|
|
|
const registeredPushTokens = user.expoPushTokens?.length ?? 0;
|
|
|
|
async function handleSendTestNotification() {
|
|
try {
|
|
setSendingNotification(true);
|
|
await sendTestPushNotification();
|
|
Alert.alert(
|
|
'Notification envoyee',
|
|
'Une notification push de test a ete demandee.'
|
|
);
|
|
} catch (error) {
|
|
const message =
|
|
error instanceof Error
|
|
? error.message
|
|
: "Impossible d'envoyer la notification.";
|
|
|
|
Alert.alert('Erreur', message);
|
|
} finally {
|
|
setSendingNotification(false);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
<View style={styles.header}>
|
|
<Text style={styles.title}>Settings</Text>
|
|
<Text style={styles.subtitle}>Gere ton compte et ton profil.</Text>
|
|
</View>
|
|
|
|
<View style={styles.previewCard}>
|
|
<Avatar
|
|
name={user.username}
|
|
size="md"
|
|
uri={user.profilePicture}
|
|
/>
|
|
|
|
<View style={styles.previewContent}>
|
|
<Text style={styles.previewTitle}>{user.username}</Text>
|
|
<Text style={styles.previewSubtitle}>{user.email}</Text>
|
|
</View>
|
|
</View>
|
|
|
|
<View style={styles.section}>
|
|
<Text style={styles.sectionTitle}>Account</Text>
|
|
<View style={styles.sectionCard}>
|
|
<SettingsRow
|
|
description="Photo, pseudo, email et dates de creation."
|
|
label="Profile"
|
|
onPress={() => router.push('/profile')}
|
|
/>
|
|
</View>
|
|
</View>
|
|
|
|
<View style={styles.section}>
|
|
<Text style={styles.sectionTitle}>Notifications</Text>
|
|
<View style={styles.sectionCard}>
|
|
<SettingsRow
|
|
description={
|
|
registeredPushTokens > 0
|
|
? `${registeredPushTokens} appareil(x) enregistre(s).`
|
|
: 'Aucun appareil enregistre pour les notifications.'
|
|
}
|
|
label="Etat des notifications"
|
|
onPress={() => undefined}
|
|
/>
|
|
<SettingsRow
|
|
description={
|
|
sendingNotification
|
|
? 'Envoi en cours...'
|
|
: 'Envoyer une notification push de test.'
|
|
}
|
|
label="Tester une notification"
|
|
onPress={handleSendTestNotification}
|
|
/>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
centered: {
|
|
flex: 1,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
backgroundColor: Palette.cream,
|
|
},
|
|
container: {
|
|
flex: 1,
|
|
paddingHorizontal: Spacing.lg,
|
|
paddingTop: Spacing.xl,
|
|
gap: Spacing.lg,
|
|
backgroundColor: Palette.cream,
|
|
},
|
|
header: {
|
|
gap: Spacing.xs,
|
|
},
|
|
title: {
|
|
...Catamaran.extraBold34,
|
|
color: Palette.black,
|
|
},
|
|
subtitle: {
|
|
...FunnelSans.regular16,
|
|
color: Palette.gray,
|
|
},
|
|
previewCard: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: Spacing.md,
|
|
padding: Spacing.md,
|
|
borderWidth: 1,
|
|
borderColor: Palette.cream,
|
|
borderRadius: Radius.md,
|
|
backgroundColor: Palette.white,
|
|
},
|
|
previewContent: {
|
|
flex: 1,
|
|
gap: Spacing.xs,
|
|
},
|
|
previewTitle: {
|
|
...FunnelSans.medium16,
|
|
color: Palette.black,
|
|
},
|
|
previewSubtitle: {
|
|
...FunnelSans.medium14,
|
|
color: Palette.gray,
|
|
},
|
|
section: {
|
|
gap: Spacing.sm,
|
|
},
|
|
sectionTitle: {
|
|
...FunnelSans.medium12,
|
|
color: Palette.gray,
|
|
textTransform: 'uppercase',
|
|
},
|
|
sectionCard: {
|
|
borderWidth: 1,
|
|
borderColor: Palette.cream,
|
|
borderRadius: Radius.sm,
|
|
backgroundColor: Palette.white,
|
|
overflow: 'hidden',
|
|
},
|
|
row: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: Spacing.md,
|
|
paddingHorizontal: Spacing.md,
|
|
paddingVertical: Spacing.sm,
|
|
},
|
|
rowContent: {
|
|
flex: 1,
|
|
gap: Spacing.xs,
|
|
},
|
|
rowLabel: {
|
|
...FunnelSans.medium16,
|
|
color: Palette.black,
|
|
},
|
|
rowDescription: {
|
|
...FunnelSans.regular16,
|
|
color: Palette.gray,
|
|
},
|
|
});
|