chore: durcit la configuration pour la production
- mobile: externalise l'URL d'API via EXPO_PUBLIC_API_URL (repli localhost en dev) - backend: .env.example adapté au projet (PostgreSQL, JWT, FRONTEND_URL, Redis) - frontend/mobile: ajoute .env.example (+ exception gitignore front) - mobile: supprime les 4 `any` (helper getApiError, type Feed, glyphMap Ionicons) - backend: normalise le style PSR-12 via Pint (13 fichiers) Tests backend 15/15, mobile tsc 0, Pint pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,12 +3,13 @@ import { Ionicons } from '@expo/vector-icons';
|
||||
import { useRouter } from 'expo-router';
|
||||
import { useFeeds } from '@/hooks/useFeeds';
|
||||
import { Colors } from '@/lib/colors';
|
||||
import type { Feed } from '@/types';
|
||||
|
||||
export default function InfoListScreen() {
|
||||
const { data: feeds, isLoading } = useFeeds();
|
||||
const router = useRouter();
|
||||
|
||||
const renderItem = ({ item }: { item: any }) => (
|
||||
const renderItem = ({ item }: { item: Feed }) => (
|
||||
<TouchableOpacity
|
||||
style={styles.card}
|
||||
onPress={() => router.push(`/(tabs)/info/${item.slug}`)}
|
||||
|
||||
@@ -67,10 +67,10 @@ export default function ProfileScreen() {
|
||||
);
|
||||
}
|
||||
|
||||
function MenuItem({ icon, label }: { icon: string; label: string }) {
|
||||
function MenuItem({ icon, label }: { icon: keyof typeof Ionicons.glyphMap; label: string }) {
|
||||
return (
|
||||
<TouchableOpacity style={styles.menuItem}>
|
||||
<Ionicons name={icon as any} size={20} color={Colors.gray[600]} />
|
||||
<Ionicons name={icon} size={20} color={Colors.gray[600]} />
|
||||
<Text style={styles.menuLabel}>{label}</Text>
|
||||
<Ionicons name="chevron-forward" size={18} color={Colors.gray[300]} />
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useState } from 'react';
|
||||
import { View, Text, TextInput, TouchableOpacity, StyleSheet, Alert, KeyboardAvoidingView, Platform, ScrollView } from 'react-native';
|
||||
import { Link, useRouter } from 'expo-router';
|
||||
import { useAuthStore } from '@/lib/auth-store';
|
||||
import { getApiError } from '@/lib/api';
|
||||
import { Colors } from '@/lib/colors';
|
||||
|
||||
export default function LoginScreen() {
|
||||
@@ -20,8 +21,8 @@ export default function LoginScreen() {
|
||||
try {
|
||||
await login(email, password);
|
||||
router.replace('/(tabs)');
|
||||
} catch (error: any) {
|
||||
Alert.alert('Erreur', error.response?.data?.message || 'Identifiants incorrects');
|
||||
} catch (error) {
|
||||
Alert.alert('Erreur', getApiError(error).message || 'Identifiants incorrects');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { View, Text, TextInput, TouchableOpacity, StyleSheet, Alert, KeyboardAvo
|
||||
import { Link, useRouter } from 'expo-router';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { useAuthStore } from '@/lib/auth-store';
|
||||
import { getApiError } from '@/lib/api';
|
||||
import { Colors } from '@/lib/colors';
|
||||
|
||||
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
@@ -43,9 +44,10 @@ export default function RegisterScreen() {
|
||||
consentement_rgpd: consentement,
|
||||
});
|
||||
router.replace('/(tabs)');
|
||||
} catch (error: any) {
|
||||
const msg = error.response?.data?.message || 'Erreur lors de l\'inscription';
|
||||
const apiErrors = error.response?.data?.errors;
|
||||
} catch (error) {
|
||||
const data = getApiError(error);
|
||||
const msg = data.message || 'Erreur lors de l\'inscription';
|
||||
const apiErrors = data.errors;
|
||||
if (apiErrors) {
|
||||
const mapped: Record<string, string> = {};
|
||||
Object.entries(apiErrors).forEach(([k, v]) => { mapped[k] = Array.isArray(v) ? v[0] as string : String(v); });
|
||||
|
||||
Reference in New Issue
Block a user