# Chapitre 3 : Hooks utilitaires SmartCommon fournit des hooks utilitaires pour les tâches courantes. ## useNavigation Navigation programmatique avec React Router. ```javascript import { useNavigation } from '@cap-rel/smartcommon'; function MyComponent() { const navigate = useNavigation(); return (
API URL: {config.api.prefixUrl}
Mode: {config.debug ? 'Debug' : 'Production'}
Le {dateOnly} à {timeOnly}
Fenêtre : {width} x {height}
; } ``` ## useFile Utilitaires pour la manipulation de fichiers. ### Redimensionner une image ```javascript import { useFile } from '@cap-rel/smartcommon'; function ImageUploader({ onUpload }) { const { resizeImage } = useFile(); const handleFileChange = async (e) => { const file = e.target.files[0]; if (!file) return; // Redimensionner avant upload const base64 = await resizeImage(file, { maxWidth: 1920, maxHeight: 1080, quality: 85 }); // base64 = "data:image/jpeg;base64,..." onUpload(base64); }; return ( ); } ``` ## useDb Base de données IndexedDB via Dexie pour le stockage local de grandes quantités de données. ### Configuration ```javascript import { useDb } from '@cap-rel/smartcommon'; const db = useDb({ name: 'myApp', version: 1, stores: { items: 'id++, name, category, createdAt', logs: 'id++, action, timestamp' }, debug: true }); ``` ### Opérations CRUD ```javascript function ItemsManager() { const db = useDb({ name: 'myApp', version: 1, stores: { items: 'id++, name, category' } }); // Créer const addItem = async (item) => { const id = await db.items.add(item); console.log('Item créé avec id:', id); return id; }; // Lire tous const getAllItems = async () => { return db.items.toArray(); }; // Lire un const getItem = async (id) => { return db.items.get(id); }; // Modifier const updateItem = async (id, changes) => { await db.items.update(id, changes); }; // Supprimer const deleteItem = async (id) => { await db.items.delete(id); }; // ... } ``` ### Requêtes avancées ```javascript // Filtrer par valeur const electronics = await db.items .where('category') .equals('electronics') .toArray(); // Filtrer par plage const expensiveItems = await db.items .where('price') .above(100) .toArray(); // Trier const sorted = await db.items .orderBy('createdAt') .reverse() .toArray(); // Limiter const first10 = await db.items .limit(10) .toArray(); // Compter const count = await db.items.count(); // Recherche texte const matching = await db.items .filter(item => item.name.includes('test')) .toArray(); ``` ### Exemple : Mode offline ```javascript import { useEffect } from 'react'; import { useApi, useDb, useStates } from '@cap-rel/smartcommon'; function OfflineCapableList() { const api = useApi(); const db = useDb({ name: 'myApp', version: 1, stores: { items: 'id, name, synced' } }); const st = useStates({ initialStates: { items: [], loading: true } }); useEffect(() => { loadItems(); }, []); const loadItems = async () => { try { // Essayer de charger depuis l'API const data = await api.private.get('items').json(); // Sauvegarder en local await db.items.clear(); await db.items.bulkAdd(data.map(i => ({ ...i, synced: true }))); st.set('items', data); } catch (err) { // En cas d'erreur réseau, charger depuis IndexedDB console.log('Mode offline - chargement local'); const localItems = await db.items.toArray(); st.set('items', localItems); } finally { st.set('loading', false); } }; const addItem = async (item) => { // Sauvegarder localement d'abord const id = await db.items.add({ ...item, synced: false }); // Mettre à jour l'UI st.set('items', [...st.get('items'), { ...item, id }]); // Tenter de synchroniser try { const result = await api.private.post('items', { json: item }).json(); await db.items.update(id, { ...result, synced: true }); } catch (err) { console.log('Sync échouée, sera retentée plus tard'); } }; // ... } ``` ## useAnimation Gestion d'animations avec Framer Motion. ```javascript import { useAnimation } from '@cap-rel/smartcommon'; import { motion } from 'framer-motion'; function AnimatedList({ items }) { const { start } = useAnimation(); return (