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:
{
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:
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:
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:
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:
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:
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:
{
status?: 'pending' | 'picking' | 'completed';
assigned_to?: string;
}Returns: UseQueryResult<PickList[]>
Example:
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:
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:
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:
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
Safety Hooks
useSafetyDashboard()
Fetches safety dashboard data for workers and drivers.
Source: src/lib/safetyPro/checklistService.ts
Returns: UseQueryResult<SafetyDashboardData>
Features:
- Loads assigned checklists
- Loads user's own incidents
- Loads corrective actions (workers only)
- Role-based filtering
Example:
import { useSafetyDashboard } from '@/lib/safetyPro/checklistService';
function WorkerSafetyDashboard() {
const { data, isLoading } = useSafetyDashboard();
if (isLoading) return <Loading />;
return (
<div>
<h2>My Checklists: {data?.checklists.length}</h2>
<h2>My Incidents: {data?.incidents.length}</h2>
</div>
);
}useIncidentReport()
Mutation hook for reporting safety incidents.
Source: src/lib/safetyPro/index.ts
Returns: UseMutationResult
Parameters:
{
category: 'injury' | 'near_miss' | 'hazard' | 'property_damage' | 'chemical' | 'haccp' | 'hygiene' | 'machine_failure';
severity: 'low' | 'medium' | 'high' | 'critical';
description: string;
location?: string;
zone_id?: string;
attachments?: string[];
}Example:
import { useIncidentReport } from '@/lib/safetyPro';
function ReportIncidentForm() {
const reportIncident = useIncidentReport();
const handleSubmit = async (data) => {
await reportIncident.mutateAsync({
category: 'hazard',
severity: 'medium',
description: 'Slippery floor in warehouse',
location: 'Warehouse A, Zone 3'
});
};
return <form onSubmit={handleSubmit}>...</form>;
}useChecklistExecution()
Mutation hook for submitting checklist execution results.
Source: src/lib/safetyPro/checklistService.ts
Returns: UseMutationResult
Parameters:
{
checklist_id: string;
answers: Record<string, 'yes' | 'no' | 'na'>;
}Example:
import { useChecklistExecution } from '@/lib/safetyPro/checklistService';
function ChecklistForm({ checklistId }) {
const submitChecklist = useChecklistExecution();
const handleSubmit = async (answers) => {
await submitChecklist.mutateAsync({
checklist_id: checklistId,
answers: {
'item-1': 'yes',
'item-2': 'no',
'item-3': 'na'
}
});
};
return <form onSubmit={handleSubmit}>...</form>;
}useTrainingProgress()
Fetches user's training progress and completion status.
Source: src/lib/safetyPro/trainingService.ts
Returns: UseQueryResult<TrainingProgress[]>
Features:
- Shows completed trainings
- Shows pending trainings
- Includes completion dates and signatures
Example:
import { useTrainingProgress } from '@/lib/safetyPro/trainingService';
function TrainingProgress() {
const { data: progress } = useTrainingProgress();
return (
<div>
{progress?.map(training => (
<div key={training.id}>
<h3>{training.title}</h3>
<p>Status: {training.completed ? 'Completed' : 'Pending'}</p>
</div>
))}
</div>
);
}useUserLanguage()
Manages user language preference.
Source: src/lib/i18n-helpers.ts
Functions:
getUserLanguage(): Get user's language preferenceupdateUserLanguage(language): Update user's language preferencegetTenantLanguage(): Get tenant's default languagedetectLanguage(): Detect language using priority chain
Example:
import { getUserLanguage, updateUserLanguage } from '@/lib/i18n-helpers';
async function LanguageSwitcher() {
const currentLanguage = await getUserLanguage();
const handleChange = async (newLanguage: 'de' | 'en' | 'bg') => {
await updateUserLanguage(newLanguage);
// Language preference is saved to profiles.language
};
return (
<select value={currentLanguage} onChange={e => handleChange(e.target.value)}>
<option value="de">Deutsch</option>
<option value="en">English</option>
<option value="bg">Български</option>
</select>
);
}Utility Hooks
useDebounce(value, delay)
Debounces a value, useful for search inputs.
Source: src/hooks/use-debounce.ts
Parameters:
value: Value to debouncedelay: Delay in milliseconds
Returns: Debounced value
Example:
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
// 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
Always check loading states:
typescriptconst { data, isLoading, error } = useInventoryItems(); if (isLoading) return <Loading />; if (error) return <Error />;Use enabled for conditional queries:
typescriptconst { data } = useZone(zoneId, { enabled: !!zoneId });Leverage caching: Hooks automatically cache data, reducing API calls
Handle errors: Always handle error states appropriately
Use real-time hooks: For live data, use real-time hooks instead of polling
Related Documentation
- Context Providers - React context providers
- API Reference - Complete API documentation
- React Query - Underlying query library