Mobile App - State Management
Documentation de la gestion d'état avec Zustand.
📦 Stores
Workflow Store
// src/store/workflow-store.ts
import { create } from 'zustand';
interface WorkflowState {
workflows: Workflow[];
selectedWorkflow: Workflow | null;
loading: boolean;
error: string | null;
// Actions
fetchWorkflows: () => Promise<void>;
selectWorkflow: (id: string) => void;
executeWorkflow: (id: string, input?: any) => Promise<void>;
clearError: () => void;
}
export const useWorkflowStore = create<WorkflowState>((set, get) => ({
workflows: [],
selectedWorkflow: null,
loading: false,
error: null,
fetchWorkflows: async () => {
set({ loading: true });
try {
const workflows = await api.getWorkflows();
set({ workflows, loading: false });
} catch (error) {
set({ error: error.message, loading: false });
}
},
selectWorkflow: (id) => {
const workflow = get().workflows.find(w => w.id === id);
set({ selectedWorkflow: workflow || null });
},
executeWorkflow: async (id, input) => {
const result = await api.executeWorkflow(id, input);
set(state => ({
workflows: state.workflows.map(w =>
w.id === id ? { ...w, ...result } : w
),
}));
},
clearError: () => set({ error: null }),
}));
Agent Store
// src/store/agent-store.ts
interface AgentState {
agents: Agent[];
activeAgents: number;
fetchAgents: () => Promise<void>;
updateAgentStatus: (id: string, status: AgentStatus) => void;
}
export const useAgentStore = create<AgentState>((set) => ({
agents: [],
activeAgents: 0,
fetchAgents: async () => {
const agents = await api.getAgents();
set({
agents,
activeAgents: agents.filter(a => a.status === 'active').length,
});
},
updateAgentStatus: (id, status) => {
set(state => ({
agents: state.agents.map(a =>
a.id === id ? { ...a, status } : a
),
activeAgents: state.agents.filter(a =>
a.id === id ? status === 'active' : a.status === 'active'
).length,
}));
},
}));
UI Store
// src/store/ui-store.ts
interface UIState {
theme: 'light' | 'dark';
sidebarOpen: boolean;
notifications: Notification[];
toggleTheme: () => void;
toggleSidebar: () => void;
addNotification: (notification: Notification) => void;
markAsRead: (id: string) => void;
}
export const useUIStore = create<UIState>((set) => ({
theme: 'dark',
sidebarOpen: false,
notifications: [],
toggleTheme: () => set(state => ({
theme: state.theme === 'light' ? 'dark' : 'light',
})),
toggleSidebar: () => set(state => ({
sidebarOpen: !state.sidebarOpen,
})),
addNotification: (notification) => set(state => ({
notifications: [...state.notifications, notification],
})),
markAsRead: (id) => set(state => ({
notifications: state.notifications.map(n =>
n.id === id ? { ...n, read: true } : n
),
})),
}));
🎯 Hooks personnalisés
useWorkflows
// src/hooks/use-workflows.ts
export function useWorkflows() {
const { workflows, loading, error, fetchWorkflows } = useWorkflowStore();
useEffect(() => {
fetchWorkflows();
}, []);
return { workflows, loading, error, refetch: fetchWorkflows };
}
useBiometrics
// src/hooks/use-biometrics.ts
import * as LocalAuthentication from 'expo-local-authentication';
export function useBiometrics() {
const [hasBiometrics, setHasBiometrics] = useState(false);
useEffect(() => {
(async () => {
const compatible = await LocalAuthentication.hasHardwareAsync();
const enrolled = await LocalAuthentication.isEnrolledAsync();
setHasBiometrics(compatible && enrolled);
})();
}, []);
const authenticate = async (): Promise<boolean> => {
const result = await LocalAuthentication.authenticateAsync({
promptMessage: 'Authenticate',
fallbackLabel: 'Use Passcode',
});
return result.success;
};
return { hasBiometrics, authenticate };
}
Version : 1.0.0