mobile: fix navigation (typed routes), extract C tokens to lib/theme.ts
- lib/theme.ts: C design tokens dans fichier dédié (plus d'import circulaire _layout)
- app/_layout.tsx: importe C depuis @/lib/theme, ré-exporte pour compatibilité
- Tous les écrans: import C depuis '@/lib/theme' au lieu de '../_layout'
- Toutes les navigations: router.push({ pathname, params }) au lieu de template strings
-> Fix réel du bug 'impossible d'ouvrir carnet/note' avec Expo Router v6
- package.json: expo-web-browser ajouté (pour Google OAuth étape suivante)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
||||
Alert, StyleSheet,
|
||||
} from 'react-native'
|
||||
import { useAuthStore } from '@/lib/store'
|
||||
import { C } from '../_layout'
|
||||
import { C } from '@/lib/theme'
|
||||
|
||||
export default function LoginScreen() {
|
||||
const [email, setEmail] = useState('')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Tabs } from 'expo-router'
|
||||
import { BookOpen, Search, Home, User } from 'lucide-react-native'
|
||||
import { C } from '../_layout'
|
||||
import { C } from '@/lib/theme'
|
||||
|
||||
export default function TabsLayout() {
|
||||
return (
|
||||
|
||||
@@ -9,7 +9,7 @@ import { CalendarDays, Search, BookOpen, Clock, ChevronRight } from 'lucide-reac
|
||||
import { apiFetch } from '@/lib/api'
|
||||
import { ENDPOINTS } from '@/lib/config'
|
||||
import { useAuthStore } from '@/lib/store'
|
||||
import { C } from '../_layout'
|
||||
import { C } from '@/lib/theme'
|
||||
|
||||
interface Note {
|
||||
id: string
|
||||
@@ -45,7 +45,7 @@ export default function HomeScreen() {
|
||||
const res = await apiFetch(ENDPOINTS.dailyNote)
|
||||
if (res.ok) {
|
||||
const data = await res.json()
|
||||
router.push(`/note/${data.id}`)
|
||||
router.push({ pathname: '/note/[id]', params: { id: data.id } })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ export default function HomeScreen() {
|
||||
: recentNotes.map((note, i) => (
|
||||
<TouchableOpacity
|
||||
key={note.id}
|
||||
onPress={() => router.push(`/note/${note.id}`)}
|
||||
onPress={() => router.push({ pathname: '/note/[id]', params: { id: note.id } })}
|
||||
style={[s.noteRow, i === recentNotes.length - 1 && { borderBottomWidth: 0 }]}
|
||||
activeOpacity={0.6}
|
||||
>
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useRouter } from 'expo-router'
|
||||
import { ChevronRight, BookOpen, Folder } from 'lucide-react-native'
|
||||
import { apiFetch } from '@/lib/api'
|
||||
import { ENDPOINTS } from '@/lib/config'
|
||||
import { C } from '../_layout'
|
||||
import { C } from '@/lib/theme'
|
||||
|
||||
interface Notebook {
|
||||
id: string
|
||||
@@ -72,7 +72,7 @@ export default function NotebooksScreen() {
|
||||
contentContainerStyle={s.list}
|
||||
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={() => { setRefreshing(true); load() }} tintColor={C.brand} />}
|
||||
renderItem={({ item }) => (
|
||||
<TouchableOpacity onPress={() => router.push(`/notebook/${item.id}`)} style={s.card} activeOpacity={0.7}>
|
||||
<TouchableOpacity onPress={() => router.push({ pathname: '/notebook/[id]', params: { id: item.id } })} style={s.card} activeOpacity={0.7}>
|
||||
<View style={[s.iconWrap, { backgroundColor: (item.color || C.brand) + '18' }]}>
|
||||
<NotebookIcon icon={item.icon} color={item.color} />
|
||||
</View>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { View, Text, TouchableOpacity, ScrollView, Alert, StyleSheet } from 'rea
|
||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||
import { LogOut, CreditCard, Globe } from 'lucide-react-native'
|
||||
import { useAuthStore } from '@/lib/store'
|
||||
import { C } from '../_layout'
|
||||
import { C } from '@/lib/theme'
|
||||
|
||||
const TIER_LABELS: Record<string, string> = {
|
||||
FREE: 'Gratuit',
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Search as SearchIcon, X } from 'lucide-react-native'
|
||||
import { useRouter } from 'expo-router'
|
||||
import { apiFetch } from '@/lib/api'
|
||||
import { ENDPOINTS } from '@/lib/config'
|
||||
import { C } from '../_layout'
|
||||
import { C } from '@/lib/theme'
|
||||
|
||||
interface SearchResult {
|
||||
id: string
|
||||
@@ -67,7 +67,7 @@ export default function SearchScreen() {
|
||||
keyExtractor={(item) => item.id}
|
||||
contentContainerStyle={s.list}
|
||||
renderItem={({ item }) => (
|
||||
<TouchableOpacity onPress={() => router.push(`/note/${item.id}`)} style={s.card}>
|
||||
<TouchableOpacity onPress={() => router.push({ pathname: '/note/[id]', params: { id: item.id } })} style={s.card}>
|
||||
<Text style={s.cardTitle} numberOfLines={1}>{item.title || 'Sans titre'}</Text>
|
||||
{item.snippet && <Text style={s.snippet} numberOfLines={2}>{item.snippet}</Text>}
|
||||
{item.notebookName && <Text style={s.nb}>{item.notebookName}</Text>}
|
||||
|
||||
@@ -4,6 +4,10 @@ import { SafeAreaProvider } from 'react-native-safe-area-context'
|
||||
import { StatusBar } from 'expo-status-bar'
|
||||
import { View, ActivityIndicator, StyleSheet } from 'react-native'
|
||||
import { useAuthStore } from '@/lib/store'
|
||||
import { C } from '@/lib/theme'
|
||||
|
||||
// Ré-exporter C pour la compatibilité avec les anciens imports
|
||||
export { C } from '@/lib/theme'
|
||||
|
||||
export default function RootLayout() {
|
||||
const { user, loading, restore } = useAuthStore()
|
||||
@@ -35,18 +39,6 @@ export default function RootLayout() {
|
||||
)
|
||||
}
|
||||
|
||||
export const C = {
|
||||
brand: '#A47148',
|
||||
ink: '#1A1A18',
|
||||
paper: '#FAFAF8',
|
||||
concrete: '#8A8A82',
|
||||
border: '#E8E6E0',
|
||||
white: '#FFFFFF',
|
||||
rose: '#e11d48',
|
||||
roseBg: '#fff1f2',
|
||||
roseBorder: '#fecdd3',
|
||||
}
|
||||
|
||||
const s = StyleSheet.create({
|
||||
loader: { flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: C.paper },
|
||||
})
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ArrowLeft, Share2 } from 'lucide-react-native'
|
||||
import { WebView } from 'react-native-webview'
|
||||
import { apiFetch } from '@/lib/api'
|
||||
import { ENDPOINTS } from '@/lib/config'
|
||||
import { C } from '../_layout'
|
||||
import { C } from '@/lib/theme'
|
||||
|
||||
interface Note {
|
||||
id: string
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useLocalSearchParams, useRouter } from 'expo-router'
|
||||
import { ArrowLeft } from 'lucide-react-native'
|
||||
import { apiFetch } from '@/lib/api'
|
||||
import { ENDPOINTS } from '@/lib/config'
|
||||
import { C } from '../_layout'
|
||||
import { C } from '@/lib/theme'
|
||||
|
||||
interface Note {
|
||||
id: string
|
||||
@@ -56,7 +56,7 @@ export default function NotebookScreen() {
|
||||
contentContainerStyle={s.list}
|
||||
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={() => { setRefreshing(true); load() }} tintColor={C.brand} />}
|
||||
renderItem={({ item }) => (
|
||||
<TouchableOpacity onPress={() => router.push(`/note/${item.id}`)} style={s.card}>
|
||||
<TouchableOpacity onPress={() => router.push({ pathname: '/note/[id]', params: { id: item.id } })} style={s.card}>
|
||||
<Text style={s.cardTitle} numberOfLines={1}>{item.title || 'Sans titre'}</Text>
|
||||
<Text style={s.cardDate}>
|
||||
{new Date(item.updatedAt).toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' })}
|
||||
|
||||
@@ -13,6 +13,7 @@ interface AuthState {
|
||||
user: User | null
|
||||
loading: boolean
|
||||
login: (email: string, password: string) => Promise<void>
|
||||
loginWithToken: (token: string, user: User) => Promise<void>
|
||||
logout: () => Promise<void>
|
||||
restore: () => Promise<void>
|
||||
}
|
||||
|
||||
12
memento-mobile/lib/theme.ts
Normal file
12
memento-mobile/lib/theme.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
// Design tokens partagés — ne pas importer depuis _layout pour éviter les circularités
|
||||
export const C = {
|
||||
brand: '#A47148',
|
||||
ink: '#1A1A18',
|
||||
paper: '#FAFAF8',
|
||||
concrete: '#8A8A82',
|
||||
border: '#E8E6E0',
|
||||
white: '#FFFFFF',
|
||||
rose: '#e11d48',
|
||||
roseBg: '#fff1f2',
|
||||
roseBorder: '#fecdd3',
|
||||
}
|
||||
@@ -26,7 +26,8 @@
|
||||
"react-native-screens": "~4.16.0",
|
||||
"react-native-svg": "15.12.0",
|
||||
"react-native-webview": "13.15.0",
|
||||
"zustand": "^5.0.2"
|
||||
"zustand": "^5.0.2",
|
||||
"expo-web-browser": "~14.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
|
||||
Reference in New Issue
Block a user