Features
Fonctionnalités en Temps Réel
Expérience utilisateur réactive avec WebSocket et retours visuels instantanés.
Fonctionnalités en Temps Réel
Company Manager offre une expérience utilisateur réactive avec des mises à jour en temps réel et des retours visuels instantanés.
Notifications et Alertes
Toast Notifications
- Utilisation de Sonner pour les notifications
- Thèmes personnalisés avec ShadCN
- Gestion de la file d'attente
- Priorités et durées configurables
// Configuration des toasts
const toastConfig = {
position: 'top-right',
duration: 3000,
closeButton: true,
theme: {
success: 'bg-green-500',
error: 'bg-red-500',
info: 'bg-blue-500',
},
};
// Exemple d'utilisation
const notifyUpdate = (message: string, type: 'success' | 'error' | 'info') => {
toast[type](message, toastConfig);
};Indicateurs de Chargement
- Loaders contextuels
- Skeletons pour le chargement initial
- Spinners pour les actions
- États de chargement globaux
// Composant de loader
const LoadingSpinner = () => {
return (
<div className="flex items-center justify-center">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
</div>
);
};WebSocket et Temps Réel
Configuration WebSocket
// Configuration du client WebSocket
const wsClient = new WebSocketClient({
url: process.env.NEXT_PUBLIC_WS_URL,
options: {
reconnect: true,
reconnectInterval: 1000,
maxReconnectAttempts: 5,
},
});
// Hook personnalisé pour les connexions WebSocket
const useWebSocketConnection = (channel: string) => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
const subscription = wsClient
.subscribe(channel)
.pipe(
retry(3),
catchError(handleError)
)
.subscribe(setData, setError);
return () => subscription.unsubscribe();
}, [channel]);
return { data, error };
};Suivi des Commandes
- Mises à jour en temps réel
- Notifications de statut
- Historique des modifications
- Actions rapides
// Hook de suivi de commande
const useOrderTracking = (orderId: string) => {
const { data } = useWebSocketConnection(`order:${orderId}`);
const orderStatus = useMemo(() => {
return data?.status || 'pending';
}, [data]);
return {
status: orderStatus,
lastUpdate: data?.timestamp,
history: data?.history || [],
};
};Retours Visuels
Animations et Transitions
- Transitions fluides entre états
- Animations de chargement
- Effets de survol
- Retours d'action
// Composant de transition
const TransitionWrapper = ({ children, isVisible }) => {
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: isVisible ? 1 : 0 }}
transition={{ duration: 0.2 }}
>
{children}
</motion.div>
);
};États Interactifs
- Validation en temps réel
- Messages d'erreur contextuels
- Indicateurs de progression
- États de formulaire
Optimisation Performance
Stratégies de Cache
- Cache côté client
- Invalidation sélective
- Préchargement des données
- Gestion de l'état local
// Configuration du cache React Query
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60, // 1 minute
cacheTime: 1000 * 60 * 5, // 5 minutes
retry: 3,
refetchOnWindowFocus: false,
},
},
});Gestion des Ressources
- Lazy loading des composants
- Optimisation des images
- Bundling intelligent
- Code splitting
Bonnes Pratiques
-
Expérience Utilisateur
- Retours immédiats
- États de chargement clairs
- Messages d'erreur explicites
- Animations fluides
-
Performance
- Debounce des événements
- Throttling des requêtes
- Optimisation du rendu
- Gestion de la mémoire
-
Maintenance
- Monitoring des connexions
- Logs des événements
- Métriques de performance
- Tests de charge
Composants Réutilisables
// Hook de formulaire en temps réel
const useRealTimeForm = <T extends object>(
initialData: T,
onUpdate: (data: T) => Promise<void>
) => {
const form = useForm<T>({
defaultValues: initialData,
});
const { watch, formState } = form;
useEffect(() => {
const subscription = watch((value) => {
if (formState.isDirty) {
onUpdate(value as T);
}
});
return () => subscription.unsubscribe();
}, [watch, formState.isDirty, onUpdate]);
return form;
};
// Composant de badge de statut
const StatusBadge = ({ status, animate = true }) => {
return (
<span
className={clsx(
'px-2 py-1 rounded-full text-sm',
statusStyles[status],
animate && 'animate-pulse'
)}
>
{status}
</span>
);
};