import React from 'react' import axios from 'axios' import {toast} from 'react-hot-toast' import {StockBatch, StockEntry, StockPosition, StockSection} from '@/types' import {FontAwesomeIcon} from '@fortawesome/react-fontawesome' import {faCheckCircle, faTimesCircle} from '@fortawesome/free-solid-svg-icons' interface Props { onClose: () => void selectedSection: StockSection | null selectedPosition: StockPosition | null } const SetStockModal: React.FC = ({onClose, selectedSection, selectedPosition}) => { const [quantity, setQuantity] = React.useState('') const [isDropdownOpen, setIsDropdownOpen] = React.useState(false) const [selectedEntry, setSelectedEntry] = React.useState(null) const [loading, setLoading] = React.useState(false) const [isSuggestionsOpen, setIsSuggestionsOpen] = React.useState(false) const [activeTab, setActiveTab] = React.useState<'batch' | 'item'>('item') const handleSelect = (entry: StockEntry) => { setSelectedEntry(entry) setIsDropdownOpen(false) } const parsedQty = parseInt(quantity, 10) const isNumber = !isNaN(parsedQty) const capacity = selectedSection ? selectedSection.capacity : 0 const exceedsItem = isNumber && parsedQty > selectedEntry?.count const exceedsCapacity = isNumber && parsedQty > capacity const hasError = exceedsItem || exceedsCapacity const readyToScan = selectedEntry !== null && isNumber && parsedQty >= 1 && !exceedsItem && !exceedsCapacity // Called when “Simulate Scan (ID=3)” is clicked const handleScan = async () => { if (!selectedEntry || !selectedSection) return if (!readyToScan) { toast.error('Please fix validation errors before confirming.') return } setLoading(true) const toastId = toast.loading('Storing…') try { let response response = await axios.post( '/api/pdaView/storeStock', { entry_id: selectedEntry?.id, section_id: selectedSection?.section_id, current_section: selectedEntry?.sections[0].section_id, count_to_be_stored: parsedQty, }, {withCredentials: true} ) const {data} = response console.log('data', data) if (!data.success) { toast.dismiss(toastId) switch (data.error) { case 'validation_failed': toast.error('Validation failed. Check inputs.') break case 'not_found': toast.error('Entry or section not found.') break case 'section_occupied': toast.error('That section is already occupied.') break case 'insufficient_capacity': toast.error('Not enough capacity in this section.') break case 'server_error': default: toast.error(data.message ?? 'Server error during storing.') break } setLoading(false) return } toast.dismiss(toastId) toast.success('Stored successfully.') resetAndClose() } catch (err: any) { toast.dismiss() if (err.response && err.response.data) { const payload = err.response.data if (payload.error === 'validation_failed') { toast.error('Validation failed. Check inputs.') } else if (payload.error === 'not_found') { toast.error('Entry or section not found.') } else if (payload.error === 'section_occupied') { toast.error('That section is already occupied.') } else if (payload.error === 'insufficient_capacity') { toast.error('Not enough capacity in this section.') } else { toast.error(payload.message || 'Unknown error occurred.') } } else { toast.error('Network error. Please try again.') } setLoading(false) } } const resetAndClose = () => { setQuantity('') setSelectedEntry(null) setLoading(false) setIsSuggestionsOpen(false) setIsDropdownOpen(false) onClose() } const sectionEntries = React.useMemo(() => { // 1) Strip out the `entries` field from each section const sectionsWithoutEntries = selectedPosition?.sections.map(({entries, ...sec}) => sec) || [] // 2) Flatten all entries, and tag each with: // - the cleaned-up sections array // - its own sectionId / sectionAddress return ( selectedPosition?.sections.flatMap((section) => section.entries.map((entry) => ({ ...entry, sections: sectionsWithoutEntries, sectionId: section.section_id, sectionAddress: section.storage_address, })) ) || [] ) }, [selectedPosition]) return (

Store Stock

{/* Product Dropdown */}
    {sectionEntries.map((entry) => { const stocked = entry.count_stocked const total = entry.count const remaining = total - stocked return (
  • ) })} {sectionEntries.length === 0 && (
  • No items available
  • )}
{/* Quantity Input */}
setQuantity(e.target.value)} className={`input input-bordered w-full ${hasError ? 'border-red-500' : ''}`} min="1" max={selectedEntry?.count} required /> {selectedEntry && ( Max items: {selectedEntry?.count} | Capacity: {capacity} )} {/* Validation Messages */} {(exceedsItem || exceedsCapacity) && (
{exceedsItem && (
Item quantity exceeded
)} {exceedsCapacity && (
Maximum capacity exceeded
)}
)} {/* Success indicator if valid */} {readyToScan && (
Ready to store
)}
{selectedSection && (
Selected section: {selectedSection.storage_address}
)} {/* Buttons: Suggested Sections & Simulate Scan */}
{/* Waiting for scan indicator */} {readyToScan && !loading && (
{loading ? 'Storing…' : selectedSection ? 'Waiting for confirm' : 'Waiting for section scan...'}
)} {/* Cancel Button */}
{/* Suggested Sections Modal */} {isSuggestionsOpen && (

Suggested Sections

  • Section A (ID: 1)
  • Section B (ID: 2)
  • Section C (ID: 3)
  • Section D (ID: 4)
)}
) } export default SetStockModal