feat: application n8n Pilot complète (Expo managed workflow)

- Stack : Expo Router, Axios, Zustand, React Native Paper (thème sombre), date-fns
- Sécurité : secrets dans Android Keystore via expo-secure-store, TLS obligatoire,
  headers X-N8N-API-KEY + X-App-Token injectés par intercepteur Axios
- API : client.ts centralisé + workflows.ts + executions.ts (TypeScript strict)
- Store : Zustand appStore avec chargement depuis secure store au démarrage
- Hooks : usePolling (générique), useWorkflows, useExecutions
- Composants : StatusBadge, WorkflowCard, ExecutionCard, SkeletonLoader
- Screens : Dashboard, Workflows, Executions, Logs (détail exécution), Settings
- Navigation Expo Router : 4 tabs + stack Logs + écran Setup initial
- Docs : INSTALL.md, UPDATE.md, BACKUP.md, HAPROXY.md, SECURITY.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-20 17:31:55 +02:00
parent ea1705d3b0
commit 92e67d0769
41 changed files with 4891 additions and 58 deletions
+81
View File
@@ -0,0 +1,81 @@
import React from 'react';
import { Tabs } from 'expo-router';
import { useTheme } from 'react-native-paper';
import { MaterialCommunityIcons } from '@expo/vector-icons';
/**
* Props pour les icônes de tab — typage strict MaterialCommunityIcons.
*/
interface TabIconProps {
name: React.ComponentProps<typeof MaterialCommunityIcons>['name'];
color: string;
size: number;
}
/** Composant d'icône de tab — évite la répétition du rendu inline */
const TabIcon: React.FC<TabIconProps> = ({ name, color, size }) => (
<MaterialCommunityIcons name={name} size={size} color={color} />
);
/**
* Layout de navigation par onglets (4 tabs principaux).
* Les logs d'exécution sont accessibles via le Stack navigator (pas de tab dédié)
* pour garder la nav propre et hiérarchiquement correcte.
*/
export default function TabsLayout() {
const theme = useTheme();
return (
<Tabs
screenOptions={{
tabBarStyle: {
backgroundColor: theme.colors.surface,
borderTopColor: theme.colors.surfaceVariant,
borderTopWidth: 1,
},
tabBarActiveTintColor: theme.colors.primary,
tabBarInactiveTintColor: theme.colors.onSurfaceVariant,
headerStyle: { backgroundColor: theme.colors.surface },
headerTintColor: theme.colors.onSurface,
headerTitleStyle: { color: theme.colors.onSurface },
}}
>
<Tabs.Screen
name="index"
options={{
title: 'Dashboard',
tabBarIcon: ({ color, size }) => (
<TabIcon name="view-dashboard-outline" color={color} size={size} />
),
}}
/>
<Tabs.Screen
name="workflows"
options={{
title: 'Workflows',
tabBarIcon: ({ color, size }) => (
<TabIcon name="sitemap-outline" color={color} size={size} />
),
}}
/>
<Tabs.Screen
name="executions"
options={{
title: 'Exécutions',
tabBarIcon: ({ color, size }) => (
<TabIcon name="history" color={color} size={size} />
),
}}
/>
<Tabs.Screen
name="settings"
options={{
title: 'Paramètres',
tabBarIcon: ({ color, size }) => (
<TabIcon name="cog-outline" color={color} size={size} />
),
}}
/>
</Tabs>
);
}