From 6dfc76ad92e3e6aebec168270a957e5aa9efbc4f Mon Sep 17 00:00:00 2001 From: Daniel Bedeleanu Date: Sun, 19 Apr 2026 12:24:25 +0300 Subject: [PATCH] refactor: extract useSync hook from page.tsx --- frontend/app/page.tsx | 25 +++++++------------------ frontend/hooks/useSync.ts | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 frontend/hooks/useSync.ts diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx index aed004a2..878623c9 100644 --- a/frontend/app/page.tsx +++ b/frontend/app/page.tsx @@ -6,6 +6,7 @@ import { inventoryApi } from '@/lib/api'; import { fetchAndCacheItems, syncOfflineOperations } from '@/lib/sync'; import { useScanner } from '@/hooks/useScanner'; import { useStockAdjustment } from '@/hooks/useStockAdjustment'; +import { useSync } from '@/hooks/useSync'; import Scanner from '@/components/Scanner'; import AIOnboarding from '@/components/AIOnboarding'; import PageShell from '@/components/PageShell'; @@ -55,7 +56,6 @@ export default function Home() { const [isEditing, setIsEditing] = useState(false); const [editedItem, setEditedItem] = useState>({}); const [trashReason, setTrashReason] = useState('Damaged'); - const [syncing, setSyncing] = useState(false); const [currentUser, setCurrentUser] = useState(null); const [categories, setCategories] = useState([]); const [comparisonModal, setComparisonModal] = useState<{ show: boolean, newItem: any, existingItem: any, existingId: number | null }>({ show: false, newItem: null, existingItem: null, existingId: null }); @@ -106,6 +106,12 @@ export default function Home() { onInventoryUpdate: setInventory }); + const { syncing, handleSync } = useSync({ + isOnline, + currentUser, + onInventoryUpdate: setInventory + }); + useEffect(() => { if (!localStorage.getItem('inventory_token')) { window.location.href = '/login'; @@ -248,23 +254,6 @@ export default function Home() { loadInventory(); }; - const handleSync = useCallback(async () => { - if (!isOnline || !currentUser) return; - setSyncing(true); - try { - const result = await syncOfflineOperations(currentUser.id); - if (result.success > 0) { - toast.success(`Synced ${result.success} operations!`); - } - await loadInventory(); - } catch (error) { - console.error("Sync failed", error); - } finally { - setSyncing(false); - } - }, [isOnline, currentUser]); - - const handleUpdateItem = async () => { if (!selectedItem) return; try { diff --git a/frontend/hooks/useSync.ts b/frontend/hooks/useSync.ts new file mode 100644 index 00000000..4a072cb8 --- /dev/null +++ b/frontend/hooks/useSync.ts @@ -0,0 +1,39 @@ +import { useCallback, useState } from 'react'; +import { toast } from 'react-hot-toast'; +import { syncOfflineOperations, fetchAndCacheItems } from '@/lib/sync'; + +interface UseSyncOptions { + isOnline: boolean; + currentUser: any; + onInventoryUpdate?: (items: any[]) => void; +} + +export function useSync(options: UseSyncOptions) { + const { isOnline, currentUser, onInventoryUpdate } = options; + const [syncing, setSyncing] = useState(false); + + const handleSync = useCallback(async () => { + if (!isOnline || !currentUser) return; + setSyncing(true); + try { + const result = await syncOfflineOperations(currentUser.id); + if (result.success > 0) { + toast.success(`Synced ${result.success} operations!`); + } + const fresh = await fetchAndCacheItems(); + if (onInventoryUpdate) { + onInventoryUpdate(fresh); + } + } catch (error) { + console.error("Sync failed", error); + toast.error("Sync failed"); + } finally { + setSyncing(false); + } + }, [isOnline, currentUser, onInventoryUpdate]); + + return { + syncing, + handleSync + }; +}