// Dans votre composant
import { SyncButton } from './components/SyncButton';
import { SyncStatus } from './components/SyncStatus';
import { useFeedSync } from './hooks/useFeedSync';Le moyen le plus simple d'ajouter la synchronisation à votre application :
function MyComponent() {
return (
<div>
{/* Bouton simple sans label */}
<SyncButton />
{/* Ou avec label */}
<SyncButton showLabel={true} />
</div>
);
}C'est tout ! Le composant gère automatiquement :
- ✅ L'état de synchronisation
- ✅ Les animations
- ✅ La progression
- ✅ Les erreurs
- ✅ L'annulation
// src/components/SourcePanel.tsx
import { SyncButton } from './SyncButton';
export function SourcePanel() {
return (
<div className="source-panel">
{/* ... contenu ... */}
<div className="source-panel-footer">
<SyncButton showLabel={false} />
<button className="footer-btn">+</button>
<button className="footer-btn">⚙</button>
</div>
</div>
);
}// src/components/FeedPanel.tsx
import { SyncButton } from './SyncButton';
import { SyncStatus } from './SyncStatus';
export function FeedPanel() {
return (
<div className="feed-panel">
<div className="feed-panel-header">
<div className="feed-panel-title-row">
<h2>Articles</h2>
<div className="feed-panel-actions">
<SyncButton />
{/* autres boutons */}
</div>
</div>
{/* Afficher le statut compact */}
<SyncStatus compact={true} />
</div>
{/* ... liste des articles ... */}
</div>
);
}function SettingsPanel() {
return (
<div className="settings">
<h3>Synchronisation</h3>
{/* Statut détaillé */}
<SyncStatus />
{/* Options */}
<SyncButton showLabel={true} />
</div>
);
}import { useEffect } from 'react';
import { useFeedSync } from './hooks/useFeedSync';
function App() {
const { syncAll, isSyncing } = useFeedSync();
useEffect(() => {
// Synchroniser au démarrage
syncAll();
// Synchroniser toutes les 5 minutes
const interval = setInterval(() => {
if (!isSyncing) {
syncAll();
}
}, 5 * 60 * 1000);
return () => clearInterval(interval);
}, [syncAll, isSyncing]);
return <div>...</div>;
}function FeedItem({ feedId }) {
const { syncFeed, isSyncing } = useFeedSync();
const handleSync = () => {
syncFeed(feedId);
};
return (
<button onClick={handleSync} disabled={isSyncing}>
Actualiser ce flux
</button>
);
}import { useEffect } from 'react';
import { useFeedSync } from './hooks/useFeedSync';
function SyncNotifications() {
const { syncState } = useFeedSync();
useEffect(() => {
if (syncState.status === 'success') {
// Afficher une notification de succès
console.log('✓ Synchronisation réussie !');
} else if (syncState.status === 'error') {
// Afficher une erreur
console.error('✗ Erreur :', syncState.error);
}
}, [syncState.status, syncState.error]);
return null;
}function CustomSyncUI() {
const { syncState, syncAll, cancelSync, isSyncing } = useFeedSync();
return (
<div className="custom-sync">
{/* Bouton personnalisé */}
<button
onClick={isSyncing ? cancelSync : syncAll}
className={`sync-btn ${syncState.status}`}
>
{isSyncing ? (
<>
<Spinner /> Synchronisation {syncState.progress}%
</>
) : (
<>
<RefreshIcon /> Synchroniser
</>
)}
</button>
{/* Info */}
{syncState.lastSyncTime && (
<small>
Dernière synchro : {syncState.lastSyncTime.toLocaleString()}
</small>
)}
{/* Erreur */}
{syncState.error && (
<div className="error">{syncState.error}</div>
)}
</div>
);
}Actuellement, le hook utilise des données simulées. Voici comment intégrer avec votre backend :
// src/hooks/useFeedSync.ts
const syncAll = useCallback(async () => {
try {
abortControllerRef.current = new AbortController();
setSyncState({ status: 'syncing', ... });
// ⚠️ REMPLACEZ CETTE PARTIE :
// await new Promise(resolve => setTimeout(resolve, 800));
// ✅ PAR VOTRE APPEL API :
const feeds = await fetchFeeds(); // Votre fonction
for (let i = 0; i < feeds.length; i++) {
const feed = feeds[i];
// Fetch RSS feed
const response = await fetch(`/api/feeds/${feed.id}/sync`, {
method: 'POST',
signal: abortControllerRef.current.signal,
});
if (!response.ok) throw new Error('Sync failed');
// Update progress
const progress = ((i + 1) / feeds.length) * 100;
setSyncState(prev => ({ ...prev, progress }));
}
setSyncState({
status: 'success',
lastSyncTime: new Date(),
error: null,
progress: 100,
});
} catch (error) {
// Handle error...
}
}, []);-
Utiliser SyncButton pour une intégration simple
- Parfait pour les barres d'outils et menus
-
Utiliser SyncStatus pour informer l'utilisateur
- Idéal dans les panneaux de paramètres ou dashboards
-
Utiliser useFeedSync pour une logique personnalisée
- Quand vous avez besoin de contrôle total
-
Synchronisation automatique intelligente
// Synchroniser seulement si l'utilisateur est actif const handleVisibilityChange = () => { if (document.visibilityState === 'visible' && !isSyncing) { syncAll(); } };
-
Gérer les erreurs réseau
useEffect(() => { if (syncState.status === 'error') { // Retry après 30 secondes const timeout = setTimeout(() => syncAll(), 30000); return () => clearTimeout(timeout); } }, [syncState.status]);
-
Ne pas synchroniser trop souvent
- Respectez un intervalle minimum (ex: 2-5 minutes)
-
Ne pas bloquer l'UI
- La synchronisation est asynchrone, l'UI reste réactive
-
Ne pas ignorer les erreurs
- Toujours informer l'utilisateur en cas d'échec
/* Dans votre CSS */
.sync-button.syncing {
color: #your-blue !important;
}
.sync-button.success {
color: #your-green !important;
}
.sync-button.error {
color: #your-red !important;
}<SyncButton
style={{
padding: '12px 24px',
background: 'linear-gradient(45deg, #f09, #0af)',
borderRadius: '20px',
}}
/>Solution : Vérifiez que le hook est bien importé et utilisé dans le composant parent.
Solution : Le composant SyncStatus affiche automatiquement la progression. Assurez-vous qu'il est visible pendant la synchronisation.
Solution : Utilisez un polyfill pour les navigateurs plus anciens :
npm install abortcontroller-polyfillSolution : Vérifiez que vos promesses se résolvent correctement et que vous n'avez pas de boucle infinie.
-
Fichiers créés :
src/hooks/useFeedSync.ts- Hook de synchronisationsrc/components/SyncButton.tsx- Bouton de synchronisationsrc/components/SyncStatus.tsx- Affichage du statutsrc/components/SyncExample.tsx- Exemples d'utilisation
-
Documentation complète :
- Voir
SYNC_COMPONENTS_README.mdpour l'API détaillée
- Voir
- Importer les composants nécessaires
- Ajouter
SyncButtondans l'interface - (Optionnel) Ajouter
SyncStatuspour plus d'infos - Tester la synchronisation
- Intégrer avec votre API backend
- Ajouter la synchronisation automatique si nécessaire
- Gérer les erreurs appropriément
- Tester sur mobile/tablette
- Intégrez les composants dans votre application
- Testez les différentes fonctionnalités
- Connectez à votre API backend
- Personnalisez selon vos besoins
- Profitez d'une synchronisation fluide ! 🎉
Besoin d'aide ? Consultez le fichier SyncExample.tsx pour voir tous les cas d'usage en action.