Files
walden-tech-screen/src/app/(authenticated)/binner/components/ProductInfo/ProductInfo.tsx
mifi 7119957c9e Initial commit
Load this up somewhere where I can setup CI/CD
2024-01-24 13:05:19 -05:00

113 lines
5.2 KiB
TypeScript

import { useContext, useEffect, useRef, useState } from 'react';
import { faker } from '@faker-js/faker';
import { dateToOrdinal, ordinalToDate } from '@/app/lib/ordinalDate';
import { Product } from '@/app/lib/product.enum';
import { SupplyChainContext } from '@/app/lib/context/SupplyChain/SupplyChainContext';
import { ParsedBarcode, barcodeToProduct } from '@/app/lib/barcode';
import { BinnerContext } from '../../context/BinnerContext';
import { useGetProcessorByBarcodeId } from '../../hooks';
import styles from './ProductInfo.module.scss';
export function ProductInfo() {
const { item, setItem } = useContext(BinnerContext);
const { processors } = useContext(SupplyChainContext);
const [inputItem, setInputItem] = useState<Partial<ParsedBarcode> | null>(null);
const dateRef = useRef<HTMLInputElement>(null);
const weightRef = useRef<HTMLInputElement>(null);
const getProcessorByBarcodeId = useGetProcessorByBarcodeId();
const isCompleteItem = (item: Partial<ParsedBarcode> | null) => item && !!(item?.product && item?.date && item?.processor && item?.weight);
const [isEntryMode, setIsEntryMode] = useState(!isCompleteItem(item));
useEffect(() => {
setIsEntryMode(!isCompleteItem(item));
}, [item])
useEffect(() => {
if (isCompleteItem(inputItem)) {
setItem(barcodeToProduct(`${inputItem?.product}${inputItem?.date}${inputItem?.processor}${inputItem?.weight}`));
setInputItem(null);
}
setIsEntryMode(!isCompleteItem(inputItem));
}, [inputItem])
return (
<div className={styles.productInfo}>
<div className={styles.attributes}>
<div className={styles.card}>
<label htmlFor="product">Product</label>
{isEntryMode ? (
<select
id="product"
defaultValue=""
onChange={(e) => setInputItem({ ...inputItem || {}, product: e.currentTarget.value })}
>
<option value="">Select a product</option>
{Object.keys(Product).map((product) => (
<option key={product} value={Product[product]}>{product}</option>
))}
</select>
) : (
<input id="product" value={item?.product!} contentEditable={false} />
)}
</div>
<div className={styles.card}>
<label htmlFor="date">Packaged Date</label>
<input
id="date" value={!!item ? ordinalToDate(item.date).toDateString() : ''}
contentEditable={isEntryMode}
ref={dateRef}
onChange={(e) => {
dateRef.current.value = e.currentTarget.value;
setInputItem({ ...inputItem || {}, date: dateToOrdinal(new Date(e.currentTarget.value)) })
}}
/>
</div>
<div className={styles.card}>
<label htmlFor="processor">Processor</label>
{isEntryMode ? (
<select
id="processor"
defaultValue=""
onChange={(e) => setInputItem({ ...inputItem || {}, processor: e.currentTarget.value })}
>
<option value="">Select a processor</option>
{processors.map((processor) => (
<option key={processor._id} value={processor.barcode_id}>{processor.name}</option>
))}
</select>
) : (
<input id="processor" value={!!item ? (getProcessorByBarcodeId(item.processor)?.name ?? 'unknown/invalid processor') : ''} contentEditable={false} />
)}
</div>
<div className={styles.card}>
<label htmlFor="weight">Weight</label>
<div className={styles.inputWithButton}>
<input
id="weight"
value={!!item ? `${item.weight} lbs.` : ''}
contentEditable={false}
tabIndex={-1}
ref={weightRef}
/>
{isEntryMode && (
<button
onClick={(e) => {
const weight = faker.number.int({ min: 1000, max: 1999 });
weightRef.current.value = `${weight / 100} lbs`; setInputItem({ ...inputItem || {}, weight })
}}
tabIndex={0}
>
Weight from Scale
</button>
)}
</div>
</div>
</div>
</div>
);
}