Stock Count Components Integration Guide
Overview
This guide explains how to integrate the new stock count components into your existing application. The components provide a complete mobile-first, offline-capable stock counting workflow.
Components Added
1. StockCountScannerForm - Mobile Scanner Interface
- Location:
apps/frontend-pwa/src/components/forms/stock-count-entry/StockCountScannerForm.tsx - Purpose: Mobile-first barcode scanning interface with offline support
- Features:
- Barcode scanning (camera + manual input)
- Offline storage with IndexedDB
- Quick quantity buttons (+1, +10, etc.)
- Batch/serial number support
- Bulk entry submission
- Online/offline status handling
2. StockCountMyTasksPage - Mobile Task Management
- Location:
apps/frontend-pwa/src/components/forms/stock-count-task/StockCountMyTasksPage.tsx - Purpose: Mobile view for counters to manage their assigned tasks
- Features:
- Task grouping by status (pending, in progress, submitted)
- Task acceptance workflow
- Navigation to scanner interface
- Mobile-optimized UI
3. StockCountSessionStartForm - Session Lifecycle Management
- Location:
apps/frontend-pwa/src/components/forms/stock-count-session/StockCountSessionStartForm.tsx - Purpose: Complete session lifecycle management
- Features:
- Start session functionality
- Snapshot creation
- Freeze/unfreeze operations
- Session approval and posting
4. StockCountVarianceReviewForm - Enhanced Variance Review
- Location:
apps/frontend-pwa/src/components/forms/stock-count-variance/StockCountVarianceReviewForm.tsx - Purpose: Advanced variance review with task approval/recount
- Features:
- Per-task approval/recount actions
- Threshold-based filtering
- Task status management
- Variance grouping by task
5. useOfflineStorage - Offline Storage Hook
- Location:
apps/frontend-pwa/src/hooks/useOfflineStorage.ts - Purpose: IndexedDB-based offline storage for stock count entries
- Features:
- Task-based entry storage
- Submission queuing
- Data persistence and retrieval
- Clear operations
6. useScanner - Scanner Functionality Hook
- Location:
apps/frontend-pwa/src/hooks/useScanner.ts - Purpose: Barcode scanning functionality
- Features:
- Camera support detection
- Manual input fallback
- Scan sound feedback
- Barcode processing
Integration Steps
Step 1: Install Dependencies
Add barcode scanning library to your project:
cd apps/frontend-pwa
pnpm add @zxing/library @zxing/browser
Step 2: Update Service Methods
The following service methods have been added to stockCountService.ts:
// Device management
export const getDeviceId = (): string
export const generateDeviceId = (): string
// Location freeze/unfreeze
export const freezeLocation = async (token: string, locationId: string, reason: string, sessionId?: string)
export const unfreezeLocation = async (token: string, locationId: string)
// Offline sync
export const getPendingOfflineSubmissions = async (token: string)
export const syncOfflineSubmissions = async (token: string, submissions: StockCountBulkEntrySubmission[])
Step 3: Add Translation Keys
All required translation keys have been added to apps/frontend-pwa/src/i18n/locales/en.json:
stockCount.scanner.*- Scanner interface translationsstockCount.tasks.*- Task management translationsstockCount.session.*- Session lifecycle translationsstockCount.variance.*- Variance review translationsstockCount.taskStatus.*- Task status translations
Step 4: Update Routes
The following routes have been added to MainPage.tsx:
case "/forms/StockCountSessionStartForm":
case "/forms/StockCountMyTasksPage":
case "/forms/StockCountVarianceReviewForm":
case "/forms/StockCountScannerForm":
Step 5: Update Menu Configuration
Add the new menu items to your Firebase Remote Config (pwaMenu.json):
{
"name": "menu.stockCountMyTasks",
"module": "stock-count",
"icon": "assignment",
"order": 3,
"path": "/forms/StockCountMyTasksPage",
"roles": ["counter", "manager"]
}
Usage Examples
1. Navigating to Scanner Form
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
// Navigate to scanner with task data
navigate('/main', {
state: {
selectedForm: '/forms/StockCountScannerForm',
task: taskData,
products: productsList,
onTaskComplete: () => {
// Handle task completion
console.log('Task completed');
}
}
});
2. Opening Session Start Form
navigate('/main', {
state: {
selectedForm: '/forms/StockCountSessionStartForm',
session: sessionData,
onSessionUpdated: (updatedSession) => {
// Handle session update
console.log('Session updated:', updatedSession);
},
onComplete: () => {
// Handle completion
console.log('Session completed');
}
}
});
3. Opening Variance Review
navigate('/main', {
state: {
selectedForm: '/forms/StockCountVarianceReviewForm',
sessionId: 'session-id',
onTaskUpdated: () => {
// Handle task updates
console.log('Task updated');
}
}
});
4. Using Offline Storage
import { useOfflineStorage } from '@/hooks/useOfflineStorage';
const { saveOfflineEntries, getOfflineEntries, clearOfflineEntries } = useOfflineStorage();
// Save entries for a task
await saveOfflineEntries(taskId, entries);
// Get entries for a task
const entries = await getOfflineEntries(taskId);
// Clear entries for a task
await clearOfflineEntries(taskId);
5. Using Scanner Hook
import { useScanner } from '@/hooks/useScanner';
const { startScanning, stopScanning, isScanning, simulateScan } = useScanner();
// Start scanning
startScanning((barcode) => {
console.log('Scanned:', barcode);
// Handle barcode
});
// Stop scanning
stopScanning();
// Simulate scan (for testing)
simulateScan('123456789');
Mobile Navigation
For mobile-specific navigation, you can create dedicated mobile routes:
// In your routing configuration
const mobileRoutes = [
{
path: '/stock-count/my-tasks',
component: StockCountMyTasksPage,
mobile: true
},
{
path: '/stock-count/scanner/:taskId',
component: StockCountScannerForm,
mobile: true
}
];
Offline Functionality
IndexedDB Schema
The offline storage uses the following IndexedDB structure:
- Database:
StockCountOfflineDB - Stores:
entries- Task-based entry storagesubmissions- Pending submission queue
Sync Process
- Online: Entries are submitted immediately
- Offline: Entries are stored locally and queued for sync
- Reconnect: Queued submissions are automatically synced
Device Management
Each device gets a unique ID stored in localStorage:
const deviceId = getDeviceId(); // Gets or creates device ID
Testing
Unit Tests
Create tests for the new components:
// __tests__/StockCountScannerForm.test.tsx
import { render, screen } from '@testing-library/react';
import { StockCountScannerForm } from '../StockCountScannerForm';
test('renders scanner form', () => {
render(<StockCountScannerForm task={mockTask} products={mockProducts} />);
expect(screen.getByText('Stock Count Scanner')).toBeInTheDocument();
});
Integration Tests
Test the complete workflow:
// __tests__/stockCountWorkflow.test.tsx
test('complete stock count workflow', async () => {
// 1. Create session
// 2. Generate tasks
// 3. Start session
// 4. Count items
// 5. Review variances
// 6. Post session
});
Manual Testing
- Barcode Scanning: Test with real barcodes on mobile devices
- Offline Functionality: Test with network disconnected
- Mobile UI: Test on various mobile screen sizes
- Performance: Test with large datasets
Troubleshooting
Common Issues
-
Camera Not Working
- Ensure HTTPS is used (required for camera access)
- Check browser permissions
- Test with manual input fallback
-
Offline Storage Not Working
- Check IndexedDB support
- Verify database initialization
- Check for storage quota issues
-
Sync Issues
- Verify network connectivity
- Check API endpoints
- Review error logs
Debug Tools
// Enable debug logging
localStorage.setItem('debug', 'stock-count:*');
// Check offline storage
const { getPendingSubmissions } = useOfflineStorage();
const pending = await getPendingSubmissions();
console.log('Pending submissions:', pending);
Performance Considerations
- Large Datasets: Implement pagination for large task lists
- Offline Storage: Monitor IndexedDB size and implement cleanup
- Camera Performance: Optimize camera resolution for scanning
- Sync Frequency: Implement background sync with reasonable intervals
Security Considerations
- Device ID: Ensure device IDs are unique and secure
- Offline Data: Encrypt sensitive data in IndexedDB
- API Security: Validate all API calls and implement proper authentication
- Data Integrity: Implement checksums for offline data validation
Future Enhancements
- Photo Capture: Add product photo capture functionality
- Advanced Sync: Implement conflict resolution for offline changes
- Background Sync: Add service worker for background synchronization
- Analytics: Add usage analytics and performance monitoring
- Multi-language: Add support for additional languages
Support
For issues or questions:
- Check the troubleshooting section above
- Review the component documentation
- Check the console for error messages
- Test with the debug tools provided
- Contact the development team with specific error details