Skip to content

Hooks

Custom React hooks for Lager Guru application.

Overview

Lager Guru provides custom React hooks built on top of React Query for data fetching, state management, and real-time updates. All hooks respect tenant isolation and Row-Level Security (RLS).

Authentication Hooks

useAuth()

Provides authentication state and methods.

Source: src/contexts/AuthContext.tsx

Returns:

typescript
{
  user: User | null;
  session: Session | null;
  userRole: UserRole | null;
  loading: boolean;
  signIn: (email: string, password: string) => Promise<{ error: any }>;
  signUp: (email: string, password: string, fullName: string) => Promise<{ error: any }>;
  signOut: () => Promise<void>;
}

Example:

typescript
import { useAuth } from '@/contexts/AuthContext';

function MyComponent() {
  const { user, userRole, signOut } = useAuth();
  
  if (!user) return <div>Please log in</div>;
  
  return (
    <div>
      <p>Logged in as {user.email}</p>
      <p>Role: {userRole}</p>
      <button onClick={signOut}>Sign Out</button>
    </div>
  );
}

Tenant Hooks

useTenants()

Fetches all tenants (super admin only).

Source: src/lib/queries/tenants.ts

Returns: UseQueryResult<Tenant[]>

Example:

typescript
import { useTenants } from '@/lib/queries/tenants';

function TenantsList() {
  const { data: tenants, isLoading } = useTenants();
  
  if (isLoading) return <div>Loading...</div>;
  
  return (
    <ul>
      {tenants?.map(tenant => (
        <li key={tenant.id}>{tenant.name}</li>
      ))}
    </ul>
  );
}

useTenantStats(tenantId: string)

Fetches statistics for a specific tenant.

Parameters:

  • tenantId: Tenant identifier

Returns: UseQueryResult<TenantStats>

Example:

typescript
const { data: stats } = useTenantStats(tenantId);

useTenantUsers(tenantId: string)

Fetches users associated with a tenant.

Parameters:

  • tenantId: Tenant identifier

Returns: UseQueryResult<TenantUser[]>


Zone Hooks

useZones()

Fetches all zones with utilization data and IndexedDB caching.

Source: src/lib/queries/zones.ts

Returns: UseQueryResult<Zone[]>

Features:

  • IndexedDB caching for offline support
  • Background synchronization
  • Real-time utilization data

Example:

typescript
import { useZones } from '@/lib/queries/zones';

function ZonesList() {
  const { data: zones, isLoading } = useZones();
  
  return (
    <div>
      {zones?.map(zone => (
        <div key={zone.id}>
          <h3>{zone.name}</h3>
          <p>Utilization: {zone.utilization}%</p>
        </div>
      ))}
    </div>
  );
}

useZone(id: string)

Fetches a single zone by ID.

Parameters:

  • id: Zone identifier

Returns: UseQueryResult<Zone>


Inventory Hooks

useInventoryItems()

Fetches all inventory items with IndexedDB caching.

Source: src/lib/queries/inventory.ts

Returns: UseQueryResult<InventoryItem[]>

Features:

  • Automatic tenant filtering
  • IndexedDB caching
  • Background sync
  • Zone information included

Example:

typescript
import { useInventoryItems } from '@/lib/queries/inventory';

function InventoryList() {
  const { data: items, isLoading } = useInventoryItems();
  
  return (
    <table>
      {items?.map(item => (
        <tr key={item.id}>
          <td>{item.sku}</td>
          <td>{item.name}</td>
          <td>{item.quantity}</td>
          <td>{item.zone?.name}</td>
        </tr>
      ))}
    </table>
  );
}

useInventoryItem(id: string)

Fetches a single inventory item by ID.

Parameters:

  • id: Item identifier

Returns: UseQueryResult<InventoryItem>

useStockMovements(itemId?: string)

Fetches stock movement history.

Parameters:

  • itemId: Optional item ID to filter movements

Returns: UseQueryResult<StockMovement[]>


Pick List Hooks

usePickLists(filters?)

Fetches pick lists with optional filters.

Source: src/lib/queries/pickLists.ts

Parameters:

typescript
{
  status?: 'pending' | 'picking' | 'completed';
  assigned_to?: string;
}

Returns: UseQueryResult<PickList[]>

Example:

typescript
import { usePickLists } from '@/lib/queries/pickLists';

function PickListsList() {
  const { data: pickLists } = usePickLists({ status: 'pending' });
  
  return (
    <div>
      {pickLists?.map(list => (
        <div key={list.id}>
          <h3>Pick List {list.id}</h3>
          <p>Status: {list.status}</p>
        </div>
      ))}
    </div>
  );
}

usePickList(id: string)

Fetches a single pick list with items.

Parameters:

  • id: Pick list identifier

Returns: UseQueryResult<PickListWithItems>

usePickListItems(pickListId: string)

Fetches items for a specific pick list.

Parameters:

  • pickListId: Pick list identifier

Returns: UseQueryResult<PickListItem[]>


Floorplan Hooks

useFloorplans()

Fetches all floorplans.

Source: src/lib/queries/floorplan.ts

Returns: UseQueryResult<Floorplan[]>

Example:

typescript
import { useFloorplans } from '@/lib/queries/floorplan';

function FloorplanList() {
  const { data: floorplans } = useFloorplans();
  
  return (
    <div>
      {floorplans?.map(fp => (
        <div key={fp.id}>{fp.name}</div>
      ))}
    </div>
  );
}

useFloorplan(id: string)

Fetches a single floorplan by ID.

Parameters:

  • id: Floorplan identifier

Returns: UseQueryResult<Floorplan>


Dashboard Hooks

useDashboardSnapshot()

Fetches consolidated dashboard data in a single request.

Source: src/lib/queries/dashboard.ts

Returns: UseQueryResult<DashboardSnapshot | null>

Features:

  • Fetches zones, inventory, pick lists, drivers, and settings in one call
  • Background refetch every 12 seconds
  • Returns null if user not associated with tenant

Example:

typescript
import { useDashboardSnapshot } from '@/lib/queries/dashboard';

function Dashboard() {
  const { data: snapshot } = useDashboardSnapshot();
  
  if (!snapshot) return <div>Not associated with tenant</div>;
  
  return (
    <div>
      <p>Zones: {snapshot.zones.length}</p>
      <p>Inventory Items: {snapshot.inventoryItems.length}</p>
      <p>Active Pick Lists: {snapshot.pickLists.length}</p>
    </div>
  );
}

Real-Time Hooks

usePickListsRealtime()

Subscribes to real-time pick list updates.

Source: src/lib/queries/realtime.ts

Returns: Real-time subscription (automatically updates React Query cache)

Example:

typescript
import { usePickListsRealtime } from '@/lib/queries/realtime';

function PickListsLive() {
  usePickListsRealtime(); // Sets up real-time subscription
  const { data: pickLists } = usePickLists();
  
  // pickLists will automatically update when changes occur
  return <div>...</div>;
}

useAllRealtime()

Subscribes to all real-time updates (pick lists, shipments, inventory, etc.).

Source: src/lib/queries/realtime.ts


Equipment Hooks

useEquipment()

Fetches all equipment.

Source: src/lib/queries/equipment.ts

Returns: UseQueryResult<Equipment[]>

useEquipmentItem(id: string)

Fetches a single equipment item.

Parameters:

  • id: Equipment identifier

Returns: UseQueryResult<Equipment>


Shipment Hooks

useShipments(filters?)

Fetches shipments with optional filters.

Source: src/lib/queries/shipments.ts

Returns: UseQueryResult<Shipment[]>

useShipment(id: string)

Fetches a single shipment.

Parameters:

  • id: Shipment identifier

Returns: UseQueryResult<Shipment>


Analytics Hooks

usePickAnalytics()

Fetches pick list analytics.

Source: src/hooks/usePickAnalytics.ts

Returns: Analytics data for pick operations


Utility Hooks

useDebounce(value, delay)

Debounces a value, useful for search inputs.

Source: src/hooks/use-debounce.ts

Parameters:

  • value: Value to debounce
  • delay: Delay in milliseconds

Returns: Debounced value

Example:

typescript
import { useDebounce } from '@/hooks/use-debounce';

function SearchInput() {
  const [search, setSearch] = useState('');
  const debouncedSearch = useDebounce(search, 300);
  
  // debouncedSearch updates 300ms after user stops typing
  return <input value={search} onChange={e => setSearch(e.target.value)} />;
}

useMobile()

Detects if device is mobile.

Source: src/hooks/use-mobile.tsx

Returns: boolean


Mutation Hooks

All mutation hooks follow the pattern use[Action][Entity]() and return a useMutation result.

Examples

typescript
// Create inventory item
const createItem = useCreateInventoryItem();
createItem.mutate({ sku: 'SKU-001', name: 'Item', quantity: 100 });

// Update pick list
const updatePickList = useUpdatePickList();
updatePickList.mutate({ id, status: 'completed' });

// Delete equipment
const deleteEquipment = useDeleteEquipment();
deleteEquipment.mutate(equipmentId);

Best Practices

  1. Always check loading states:

    typescript
    const { data, isLoading, error } = useInventoryItems();
    if (isLoading) return <Loading />;
    if (error) return <Error />;
  2. Use enabled for conditional queries:

    typescript
    const { data } = useZone(zoneId, { enabled: !!zoneId });
  3. Leverage caching: Hooks automatically cache data, reducing API calls

  4. Handle errors: Always handle error states appropriately

  5. Use real-time hooks: For live data, use real-time hooks instead of polling


Released under Commercial License