memento-mobile/ (Expo + React Native + expo-router): - Auth: login email/password → Bearer token (expo-secure-store) - Layout: guard auth → redirect /(auth)/login ou /(tabs)/home - Tabs: Accueil, Carnets, Recherche, Profil - Screens: login, home (recent notes + quick actions), notebooks list, note viewer (WebView HTML), search (texte), notebook detail, profile - Design: tokens brand-accent (#A47148), ink, concrete, paper, border - lib/config.ts: API_URL dev/prod configurable - lib/api.ts: apiFetch avec Bearer token automatique - lib/store.ts: Zustand auth store (login/logout/restore) memento-note/ (API mobile dédiée): - lib/mobile-auth.ts: createMobileToken / verifyMobileToken (HMAC-SHA256, 90j) - POST /api/mobile/auth/login: email+password → token + user - GET /api/mobile/auth/me: valider token, retourner profil - GET /api/mobile/notebooks: liste carnets avec nb notes - GET /api/mobile/notes: notes récentes (filtre par carnet optionnel) - GET /api/mobile/notes/[id]: contenu complet d'une note - GET /api/mobile/search: recherche fulltext titre+contenu Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
74 lines
2.9 KiB
TypeScript
74 lines
2.9 KiB
TypeScript
import { View, Text, TouchableOpacity, ScrollView, Alert } from 'react-native'
|
|
import { SafeAreaView } from 'react-native-safe-area-context'
|
|
import { LogOut, CreditCard, Globe } from 'lucide-react-native'
|
|
import { useAuthStore } from '@/lib/store'
|
|
|
|
const TIER_LABELS: Record<string, string> = {
|
|
FREE: 'Gratuit',
|
|
BASIC: 'Basic',
|
|
PRO: 'Pro',
|
|
BUSINESS: 'Business',
|
|
ENTERPRISE: 'Enterprise',
|
|
}
|
|
|
|
export default function ProfileScreen() {
|
|
const { user, logout } = useAuthStore()
|
|
|
|
const handleLogout = () => {
|
|
Alert.alert(
|
|
'Se déconnecter',
|
|
'Voulez-vous vraiment vous déconnecter ?',
|
|
[
|
|
{ text: 'Annuler', style: 'cancel' },
|
|
{ text: 'Déconnecter', style: 'destructive', onPress: logout },
|
|
]
|
|
)
|
|
}
|
|
|
|
return (
|
|
<SafeAreaView className="flex-1 bg-paper">
|
|
<ScrollView className="flex-1 px-5">
|
|
<Text className="text-2xl font-serif italic text-ink pt-4 pb-6">Profil</Text>
|
|
|
|
{/* User info */}
|
|
<View className="bg-white border border-border rounded-2xl p-5 mb-4">
|
|
<View className="w-14 h-14 rounded-full bg-brand/10 items-center justify-center mb-3">
|
|
<Text className="text-2xl font-bold text-brand">
|
|
{user?.name?.[0]?.toUpperCase() ?? user?.email?.[0]?.toUpperCase() ?? '?'}
|
|
</Text>
|
|
</View>
|
|
<Text className="text-[17px] font-semibold text-ink">{user?.name ?? 'Utilisateur'}</Text>
|
|
<Text className="text-[13px] text-concrete mt-0.5">{user?.email}</Text>
|
|
{user?.tier && (
|
|
<View className="mt-3 self-start bg-brand/10 px-3 py-1 rounded-full">
|
|
<Text className="text-[11px] font-bold text-brand uppercase tracking-wider">
|
|
{TIER_LABELS[user.tier] ?? user.tier}
|
|
</Text>
|
|
</View>
|
|
)}
|
|
</View>
|
|
|
|
{/* Actions */}
|
|
<View className="bg-white border border-border rounded-2xl overflow-hidden mb-4">
|
|
<TouchableOpacity className="flex-row items-center gap-3 px-4 py-3.5 border-b border-border active:bg-border/20">
|
|
<CreditCard size={18} color="#8A8A82" />
|
|
<Text className="text-[15px] text-ink flex-1">Abonnement</Text>
|
|
</TouchableOpacity>
|
|
<TouchableOpacity className="flex-row items-center gap-3 px-4 py-3.5 active:bg-border/20">
|
|
<Globe size={18} color="#8A8A82" />
|
|
<Text className="text-[15px] text-ink flex-1">Ouvrir memento-note.com</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
|
|
<TouchableOpacity
|
|
onPress={handleLogout}
|
|
className="bg-white border border-rose-200 rounded-2xl flex-row items-center gap-3 px-4 py-3.5 active:opacity-70"
|
|
>
|
|
<LogOut size={18} color="#e11d48" />
|
|
<Text className="text-[15px] text-rose-600 font-medium">Se déconnecter</Text>
|
|
</TouchableOpacity>
|
|
</ScrollView>
|
|
</SafeAreaView>
|
|
)
|
|
}
|