Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 115 additions & 3 deletions apps/mobile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ export const api = initClient(apiContract, {

## 🔐 Flux d'authentification

L'authentification utilise un **Context React** pour gérer l'état global de la session.

### 1. Connexion
```typescript
const { data, error } = await authClient.signIn.email({
Expand All @@ -90,12 +92,24 @@ if (sessionData.data) {
}
```

### 3. Déconnexion
### 3. Déconnexion (via Context)
```typescript
await authClient.signOut();
setSession(null);
import { useAuth } from './components/AuthProvider';

export default function AccountScreen() {
const { logout } = useAuth();

const handleLogout = async () => {
await logout(); // Déconnexion + redirection automatique vers LoginScreen
};
}
```

Le pattern avec `useAuth()` permet :
- ✅ Accès global à la fonction de déconnexion
- ✅ Redirection automatique vers le LoginScreen
- ✅ Pas de prop drilling

## 🧩 Intégration des packages partagés

L'app mobile utilise tous les packages partagés du monorepo :
Expand Down Expand Up @@ -159,6 +173,104 @@ pnpm --filter api dev
2. Scanner le QR code affiché dans le terminal
3. L'app se charge avec l'écran de connexion

## 📦 Build et déploiement de l'APK

### Prérequis
- Compte Expo créé et authentifié : `npx eas login`
- Projet EAS configuré

### Profils de build disponibles

Le projet utilise **EAS Build** avec 3 profils configurés dans `eas.json` :

| Profil | Usage | API URL |
|--------|-------|---------|
| `development` | Dev avec hot reload | Variable d'env locale |
| `preview` | Test en prod (APK) | `https://api.dropit-app.fr` |
| `production` | Publication Play Store | Variable d'env prod |

### Build d'un APK pour tester (Preview)

```bash
# Se placer dans le dossier mobile
cd apps/mobile

# Build APK avec le profil preview (connecté à l'API de prod)
npx eas build --platform android --profile preview

# Le build se fait dans le cloud Expo
# Temps estimé : 5-10 minutes
# Vous recevrez un lien pour télécharger l'APK
```

### Build local (plus rapide)

```bash
# Build local sans utiliser les serveurs Expo
npx eas build --platform android --profile preview --local

# Nécessite Android SDK installé localement
```

### Installation de l'APK sur votre téléphone

1. Une fois le build terminé, EAS vous donne un **lien de téléchargement**
2. Téléchargez l'APK sur votre téléphone
3. Activez "Sources inconnues" dans les paramètres Android
4. Installez l'APK

### Variables d'environnement

Le profil **preview** utilise automatiquement :
```bash
EXPO_PUBLIC_API_URL=https://api.dropit-app.fr
```

Pour changer l'URL de l'API, modifiez `eas.json` :
```json
{
"build": {
"preview": {
"env": {
"EXPO_PUBLIC_API_URL": "https://votre-api.com"
}
}
}
}
```

### Commandes utiles EAS

```bash
# Lister les builds précédents
npx eas build:list

# Voir les détails d'un build
npx eas build:view [BUILD_ID]

# Build iOS (nécessite compte Apple Developer)
npx eas build --platform ios --profile preview

# Soumettre à Google Play Store (production)
npx eas submit --platform android
```

### Troubleshooting builds

**Erreur "Not logged in"**
```bash
npx eas login
```

**Build qui échoue**
```bash
# Vérifier les logs détaillés sur :
# https://expo.dev/accounts/[votre-compte]/projects/dropit-mobile/builds
```

**APK trop gros**
- Utilisez le profil `production` qui active Hermes et optimise automatiquement

## 🔧 Configuration réseau

Pour tester sur un appareil physique, assurez-vous que :
Expand Down
7 changes: 4 additions & 3 deletions apps/mobile/src/components/AccountScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import {
Alert,
} from 'react-native';
import { StatusBar } from 'expo-status-bar';
import { authClient } from '../lib/auth-client';
import { useAuth } from './AuthProvider';
import BottomNavigation from './BottomNavigation';

interface AccountScreenProps {
onTabPress: (tab: 'pr' | 'dashboard' | 'account') => void;
}

export default function AccountScreen({ onTabPress }: AccountScreenProps) {
const { logout } = useAuth();

const handleLogout = async () => {
Alert.alert(
'Déconnexion',
Expand All @@ -27,8 +29,7 @@ export default function AccountScreen({ onTabPress }: AccountScreenProps) {
style: 'destructive',
onPress: async () => {
try {
await authClient.signOut();
// L'AuthProvider détectera automatiquement la déconnexion
await logout();
} catch (error) {
console.error('Logout error:', error);
Alert.alert('Erreur', 'Erreur lors de la déconnexion');
Expand Down
28 changes: 22 additions & 6 deletions apps/mobile/src/components/AuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, createContext, useContext } from 'react';
import { View, Text, ActivityIndicator, StyleSheet } from 'react-native';
import { authClient } from '../lib/auth-client';
import LoginScreen from './LoginScreen';
Expand All @@ -24,6 +24,20 @@ interface Session {
};
}

interface AuthContextType {
logout: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType | null>(null);

export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within AuthProvider');
}
return context;
};

export default function AuthProvider({ children }: AuthProviderProps) {
const [session, setSession] = useState<Session | null>(null);
const [isLoading, setIsLoading] = useState(true);
Expand Down Expand Up @@ -64,13 +78,14 @@ export default function AuthProvider({ children }: AuthProviderProps) {
await initializeAuth();
};

const handleLogout = async () => {
const logout = async () => {
try {
await authClient.signOut();
setSession(null);
console.log('Logged out successfully');
} catch (error) {
console.error('Logout error:', error);
throw error;
}
};

Expand All @@ -91,10 +106,11 @@ export default function AuthProvider({ children }: AuthProviderProps) {

// Session active, afficher l'app
return (
<View style={styles.container}>
{children}
{/* Vous pouvez ajouter un bouton de déconnexion ici pour les tests */}
</View>
<AuthContext.Provider value={{ logout }}>
<View style={styles.container}>
{children}
</View>
</AuthContext.Provider>
);
}

Expand Down
4 changes: 2 additions & 2 deletions apps/mobile/src/components/BottomNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ export default function BottomNavigation({ activeTab, onTabPress }: BottomNaviga

const styles = StyleSheet.create({
container: {
paddingBottom: 40, // Safe area for iPhone
paddingTop: 20,
paddingBottom: 50,
paddingTop: 10,
backgroundColor: '#191d26',
},
navigationBar: {
Expand Down