102 lines
3.0 KiB
TypeScript
102 lines
3.0 KiB
TypeScript
import { useQuery } from '@tanstack/react-query';
|
|
import { Stack, useLocalSearchParams } from 'expo-router';
|
|
import { ActivityIndicator, ScrollView, Text, View } from 'react-native';
|
|
|
|
import { getCurrentUserId, pb } from '@/services/pocketbase';
|
|
import type { ContactRecord } from '@/types/collections';
|
|
import { formatPocketBaseError } from '@/utils/pocketbaseErrors';
|
|
|
|
function routeParamId(raw: string | string[] | undefined): string | undefined {
|
|
if (raw == null) return undefined;
|
|
return Array.isArray(raw) ? raw[0] : raw;
|
|
}
|
|
|
|
export default function ContactDetailScreen() {
|
|
const { id: rawId } = useLocalSearchParams<{ id?: string | string[] }>();
|
|
const id = routeParamId(rawId);
|
|
const uid = getCurrentUserId();
|
|
|
|
const q = useQuery({
|
|
queryKey: ['contact', id],
|
|
queryFn: async () => {
|
|
if (!id) throw new Error('id');
|
|
return pb.collection('contacts').getOne<ContactRecord>(id);
|
|
},
|
|
enabled: Boolean(id),
|
|
});
|
|
|
|
if (!id) {
|
|
return (
|
|
<>
|
|
<Stack.Screen options={{ title: 'Contact', headerShown: true }} />
|
|
<View className="flex-1 items-center justify-center p-6">
|
|
<Text>Identifiant manquant.</Text>
|
|
</View>
|
|
</>
|
|
);
|
|
}
|
|
|
|
if (q.isPending) {
|
|
return (
|
|
<>
|
|
<Stack.Screen options={{ title: '…', headerShown: true }} />
|
|
<View className="flex-1 items-center justify-center">
|
|
<ActivityIndicator color="#1D4ED8" />
|
|
</View>
|
|
</>
|
|
);
|
|
}
|
|
|
|
if (q.error || !q.data) {
|
|
return (
|
|
<>
|
|
<Stack.Screen options={{ title: 'Erreur', headerShown: true }} />
|
|
<View className="flex-1 items-center justify-center p-6">
|
|
<Text className="text-center text-red-700">
|
|
{q.error ? formatPocketBaseError(q.error) : 'Introuvable.'}
|
|
</Text>
|
|
</View>
|
|
</>
|
|
);
|
|
}
|
|
|
|
const c = q.data;
|
|
if (uid && c.user !== uid) {
|
|
return (
|
|
<>
|
|
<Stack.Screen options={{ title: 'Contact', headerShown: true }} />
|
|
<View className="flex-1 items-center justify-center p-6">
|
|
<Text>Accès refusé.</Text>
|
|
</View>
|
|
</>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Stack.Screen options={{ title: c.nom, headerShown: true }} />
|
|
<ScrollView className="flex-1 bg-slate-50 p-4">
|
|
<Text className="text-xl font-bold text-slate-900">
|
|
{c.prenom ? `${c.prenom} ` : ''}
|
|
{c.nom}
|
|
</Text>
|
|
{c.societe ? <Text className="mt-1 text-slate-600">{c.societe}</Text> : null}
|
|
<Text className="mt-3 text-sm text-slate-500">Catégorie</Text>
|
|
<Text className="text-base text-slate-900">{c.categorie}</Text>
|
|
{c.email ? (
|
|
<>
|
|
<Text className="mt-3 text-sm text-slate-500">Email</Text>
|
|
<Text className="text-base text-slate-900">{c.email}</Text>
|
|
</>
|
|
) : null}
|
|
{c.telephone ? (
|
|
<>
|
|
<Text className="mt-3 text-sm text-slate-500">Téléphone</Text>
|
|
<Text className="text-base text-slate-900">{c.telephone}</Text>
|
|
</>
|
|
) : null}
|
|
</ScrollView>
|
|
</>
|
|
);
|
|
}
|