| @@ -710,9 +710,9 @@ const printQrcode = useCallback( | |||
| </Typography> | |||
| </Grid> | |||
| {stockInLineInfo.jobOrderId ? ( | |||
| <FgStockInForm itemDetail={stockInLineInfo} disabled={viewOnly || showPutaway} /> | |||
| <FgStockInForm itemDetail={stockInLineInfo} disabled={viewOnly || showPutaway} compactFields /> | |||
| ) : ( | |||
| <StockInForm itemDetail={stockInLineInfo} disabled={viewOnly || showPutaway} /> | |||
| <StockInForm itemDetail={stockInLineInfo} disabled={viewOnly || showPutaway} compactFields /> | |||
| ) | |||
| } | |||
| {skipQc === false && ( | |||
| @@ -161,7 +161,7 @@ const CalculateExpiryDateModal: React.FC<Props> = ({ | |||
| style={{ | |||
| flex: 10, | |||
| marginBottom: "20px", | |||
| width: "80%", | |||
| width: "70%", | |||
| // height: "80%", | |||
| position: "fixed", | |||
| top: "50%", | |||
| @@ -191,8 +191,8 @@ const CalculateExpiryDateModal: React.FC<Props> = ({ | |||
| adapterLocale={`${language}-hk`} | |||
| > | |||
| <Stack sx={{mb: 1}}> | |||
| <Typography variant="h4" component="h2" sx={{ fontWeight: 'bold', mb: 2 }}> | |||
| {t("Fill in Expiry Date")} | |||
| <Typography variant="h6" component="h2" sx={{ fontWeight: 'bold', mb: 2 }}> | |||
| {t("Fill in Expiry Date")} | |||
| </Typography> | |||
| </Stack> | |||
| <Stack> | |||
| @@ -228,12 +228,13 @@ const CalculateExpiryDateModal: React.FC<Props> = ({ | |||
| display: 'flex', | |||
| justifyContent: 'center', | |||
| alignItems: 'center', | |||
| height: '100%', | |||
| alignSelf: 'flex-start', | |||
| mt: '8px', // align icon with vertical center of MUI outlined input | |||
| height: 56, | |||
| }}> | |||
| <Add sx={{ | |||
| fontSize: '60px', color:'secondary.main', | |||
| transform: 'translate(10%, 15%)', | |||
| }}/> | |||
| fontSize: '1.25rem', color:'secondary.main', | |||
| }}/> | |||
| </Grid> | |||
| <Grid item xs={4}> | |||
| <ShelfLifeInput | |||
| @@ -252,9 +253,11 @@ const CalculateExpiryDateModal: React.FC<Props> = ({ | |||
| display: 'flex', | |||
| justifyContent: 'center', | |||
| alignItems: 'center', | |||
| height: '100%', | |||
| alignSelf: 'flex-start', | |||
| mt: '8px', | |||
| height: 56, | |||
| }}> | |||
| <SwapHoriz sx={{fontSize: '80px', color:'secondary.main'}}/> | |||
| <SwapHoriz sx={{fontSize: '1.25rem', color:'secondary.main'}}/> | |||
| </Grid> | |||
| <Grid item xs={4}> | |||
| <DatePicker | |||
| @@ -291,7 +294,6 @@ const CalculateExpiryDateModal: React.FC<Props> = ({ | |||
| name="submit" | |||
| variant="contained" | |||
| startIcon={<Check />} | |||
| sx={{fontSize: '24px'}} | |||
| disabled={expiryDate === undefined || hasError} | |||
| onClick={handleSubmit} | |||
| > | |||
| @@ -47,6 +47,8 @@ interface Props { | |||
| // qc: QcItemWithChecks[]; | |||
| disabled: boolean; | |||
| putawayMode?: boolean; | |||
| /** When true, use compact field sizing to match Putaway Detail (上架詳情) section. */ | |||
| compactFields?: boolean; | |||
| } | |||
| type EntryError = | |||
| | { | |||
| @@ -90,6 +92,7 @@ const FgStockInForm: React.FC<Props> = ({ | |||
| itemDetail, | |||
| disabled, | |||
| putawayMode = false, | |||
| compactFields = false, | |||
| }) => { | |||
| const { | |||
| t, | |||
| @@ -186,7 +189,7 @@ return ( | |||
| {...register("productLotNo", { | |||
| // required: "productLotNo required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| /> | |||
| </Grid> | |||
| @@ -199,7 +202,7 @@ return ( | |||
| {...register("itemName", { | |||
| // required: "productLotNo required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| // error={Boolean(errors.productLotNo)} | |||
| // helperText={errors.productLotNo?.message} | |||
| @@ -221,7 +224,7 @@ return ( | |||
| > | |||
| <DatePicker | |||
| {...field} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? { width: '100%' } : textfieldSx} | |||
| label={t("receiptDate")} | |||
| value={dayjs(watch("receiptDate"))} | |||
| format={OUTPUT_DATE_FORMAT} | |||
| @@ -234,6 +237,7 @@ return ( | |||
| inputRef={field.ref} | |||
| slotProps={{ | |||
| textField: { | |||
| fullWidth: true, | |||
| // required: true, | |||
| error: Boolean(errors.receiptDate?.message), | |||
| helperText: errors.receiptDate?.message, | |||
| @@ -255,7 +259,7 @@ return ( | |||
| {...register("lotNo", { | |||
| // required: "productLotNo required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| error={Boolean(errors.productLotNo)} | |||
| helperText={errors.productLotNo?.message} | |||
| @@ -267,7 +271,7 @@ return ( | |||
| {...register("productLotNo", { | |||
| // required: "productLotNo required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| error={Boolean(errors.productLotNo)} | |||
| helperText={errors.productLotNo?.message} | |||
| @@ -286,7 +290,7 @@ return ( | |||
| > | |||
| <DatePicker | |||
| {...field} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| label={t("productionDate")} | |||
| value={productionDate ? dayjs(productionDate) : undefined} | |||
| format={OUTPUT_DATE_FORMAT} | |||
| @@ -326,7 +330,7 @@ return ( | |||
| > | |||
| <DatePicker | |||
| {...field} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| label={t("productionDate")} | |||
| value={productionDate ? dayjs(productionDate) : undefined} | |||
| disabled={disabled} | |||
| @@ -359,7 +363,7 @@ return ( | |||
| {...register("qty", { | |||
| required: "qty required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| /> | |||
| </Grid></> | |||
| @@ -377,7 +381,7 @@ return ( | |||
| > | |||
| <DatePicker | |||
| {...field} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? { width: '100%' } : textfieldSx} | |||
| label={t("expiryDate")} | |||
| value={expiryDateValue ? dayjs(expiryDateValue) : null} // Use null instead of undefined | |||
| format={OUTPUT_DATE_FORMAT} | |||
| @@ -395,15 +399,21 @@ return ( | |||
| onClose={() => setOpenExpDatePicker(false)} | |||
| slotProps={{ | |||
| textField: { | |||
| fullWidth: true, | |||
| InputProps: { | |||
| ...(!disabled && { | |||
| endAdornment: ( | |||
| <InputAdornment position='end'> | |||
| <InputAdornment position="end"> | |||
| <Button | |||
| type="button" | |||
| variant="contained" | |||
| color="primary" | |||
| sx={{ fontSize: '24px' }} | |||
| size="small" | |||
| sx={{ | |||
| fontSize: compactFields ? '0.875rem' : '24px', | |||
| whiteSpace: 'nowrap', | |||
| flexShrink: 0, | |||
| }} | |||
| onClick={handleOpenModal} | |||
| > | |||
| {t("Calculate Expiry Date")} | |||
| @@ -428,7 +438,7 @@ return ( | |||
| <TextField | |||
| label={t("acceptedQty")} | |||
| fullWidth | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| value={itemDetail.acceptedQty} | |||
| // disabled={true} | |||
| @@ -443,7 +453,7 @@ return ( | |||
| {...register("receivedQty", { | |||
| required: "receivedQty required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| /> | |||
| )} | |||
| @@ -456,7 +466,7 @@ return ( | |||
| required: "uom required!", | |||
| })} | |||
| // value={uom?.code} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| /> | |||
| </Grid> | |||
| @@ -465,7 +475,7 @@ return ( | |||
| <TextField | |||
| label={t("processedQty")} | |||
| fullWidth | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| value={itemDetail.putAwayLines?.reduce((sum, p) => sum + p.qty, 0) ?? 0} | |||
| /> | |||
| @@ -474,7 +484,7 @@ return ( | |||
| <TextField | |||
| label={t("acceptedQty")} | |||
| fullWidth | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| {...register("acceptedQty", { | |||
| required: "acceptedQty required!", | |||
| @@ -486,7 +496,7 @@ return ( | |||
| <TextField | |||
| label={t("acceptedQty")} | |||
| fullWidth | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| {...register("acceptedQty", { | |||
| required: "acceptedQty required!", | |||
| @@ -529,7 +539,7 @@ return ( | |||
| open={openModal} | |||
| onClose={handleOnModalClose} | |||
| onSubmit={handleReturnExpiryDate} | |||
| textfieldSx={textfieldSx} | |||
| textfieldSx={compactFields ? undefined : textfieldSx} | |||
| /> | |||
| </> | |||
| ); | |||
| @@ -114,7 +114,7 @@ const ShelfLifeInput: React.FC<ShelfLifeInputProps> = ({ value = 0, onChange = ( | |||
| inputMode: 'numeric', | |||
| pattern: '[0-9]*', | |||
| }} | |||
| size="small" | |||
| size="medium" | |||
| /> | |||
| <TextField | |||
| label="月" | |||
| @@ -126,7 +126,7 @@ const ShelfLifeInput: React.FC<ShelfLifeInputProps> = ({ value = 0, onChange = ( | |||
| inputMode: 'numeric', | |||
| pattern: '[0-9]*', | |||
| }} | |||
| size="small" | |||
| size="medium" | |||
| /> | |||
| <TextField | |||
| label="日" | |||
| @@ -138,11 +138,11 @@ const ShelfLifeInput: React.FC<ShelfLifeInputProps> = ({ value = 0, onChange = ( | |||
| inputMode: 'numeric', | |||
| pattern: '[0-9]*', | |||
| }} | |||
| size="small" | |||
| size="medium" | |||
| /> | |||
| </ShelfLifeContainer> | |||
| {showHelperText && ( | |||
| <FormHelperText sx={{ fontSize: '2rem', mt: 1 }}> | |||
| <FormHelperText sx={{ fontSize: '0.875rem', mt: 1 }}> | |||
| {label}: <span style={{ color: totalDays < 1 ? 'red':'inherit' }}> | |||
| {/* {formatDuration(duration.years, duration.months, duration.days)} */} | |||
| {totalDays} 日 | |||
| @@ -34,6 +34,8 @@ interface Props { | |||
| // qc: QcItemWithChecks[]; | |||
| disabled: boolean; | |||
| putawayMode?: boolean; | |||
| /** When true, use compact field sizing to match Putaway Detail (上架詳情) section. */ | |||
| compactFields?: boolean; | |||
| } | |||
| type EntryError = | |||
| | { | |||
| @@ -77,6 +79,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| itemDetail, | |||
| disabled, | |||
| putawayMode = false, | |||
| compactFields = false, | |||
| }) => { | |||
| const { | |||
| t, | |||
| @@ -169,7 +172,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| {...register("dnNo", { | |||
| // required: "productLotNo required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={disabled} | |||
| // error={Boolean(errors.productLotNo)} | |||
| // helperText={errors.productLotNo?.message} | |||
| @@ -182,7 +185,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| {...register("itemName", { | |||
| // required: "productLotNo required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| // error={Boolean(errors.productLotNo)} | |||
| // helperText={errors.productLotNo?.message} | |||
| @@ -195,7 +198,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| {...register("poCode", { | |||
| // required: "productLotNo required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| // error={Boolean(errors.productLotNo)} | |||
| // helperText={errors.productLotNo?.message} | |||
| @@ -216,7 +219,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| > | |||
| <DatePicker | |||
| {...field} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? { width: '100%' } : textfieldSx} | |||
| label={t("receiptDate")} | |||
| value={dayjs(watch("receiptDate"))} | |||
| format={OUTPUT_DATE_FORMAT} | |||
| @@ -229,6 +232,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| inputRef={field.ref} | |||
| slotProps={{ | |||
| textField: { | |||
| fullWidth: true, | |||
| // required: true, | |||
| error: Boolean(errors.receiptDate?.message), | |||
| helperText: errors.receiptDate?.message, | |||
| @@ -247,7 +251,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| {...register("supplier", { | |||
| // required: "productLotNo required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| /> | |||
| </Grid> | |||
| @@ -261,7 +265,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| {...register("lotNo", { | |||
| // required: "productLotNo required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={disabled} | |||
| error={Boolean(errors.productLotNo)} | |||
| helperText={errors.productLotNo?.message} | |||
| @@ -273,7 +277,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| {...register("productLotNo", { | |||
| // required: "productLotNo required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={disabled} | |||
| error={Boolean(errors.productLotNo)} | |||
| helperText={errors.productLotNo?.message} | |||
| @@ -292,7 +296,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| > | |||
| <DatePicker | |||
| {...field} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? { width: '100%' } : textfieldSx} | |||
| label={t("expiryDate")} | |||
| value={expiryDate ? dayjs(expiryDate) : undefined} | |||
| format={OUTPUT_DATE_FORMAT} | |||
| @@ -309,14 +313,20 @@ const StockInForm: React.FC<Props> = ({ | |||
| onClose={() => setOpenExpDatePicker(false)} | |||
| slotProps={{ | |||
| textField: { | |||
| fullWidth: true, | |||
| InputProps: { | |||
| ...(!disabled && {endAdornment: ( | |||
| <InputAdornment position='end'> | |||
| <InputAdornment position="end"> | |||
| <Button | |||
| type="button" | |||
| variant="contained" | |||
| color="primary" | |||
| sx={{ fontSize: '24px' }} | |||
| size="small" | |||
| sx={{ | |||
| fontSize: compactFields ? '0.875rem' : '24px', | |||
| whiteSpace: 'nowrap', | |||
| flexShrink: 0, | |||
| }} | |||
| onClick={handleOpenModal} | |||
| > | |||
| {t("Calculate Expiry Date")} | |||
| @@ -344,7 +354,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| {...register("receivedQty", { | |||
| required: "receivedQty required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| /> | |||
| </Grid> | |||
| @@ -355,7 +365,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| {...register("qty", { | |||
| required: "qty required!", | |||
| })} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| /> | |||
| </Grid></> | |||
| @@ -365,7 +375,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| <TextField | |||
| label={t("acceptedQty")} | |||
| fullWidth | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| value={itemDetail.acceptedQty} | |||
| // disabled={true} | |||
| @@ -383,7 +393,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| required: "uom required!", | |||
| })} | |||
| // value={uom?.code} | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| /> | |||
| </Grid> | |||
| @@ -392,7 +402,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| <TextField | |||
| label={t("processedQty")} | |||
| fullWidth | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| value={itemDetail.putAwayLines?.reduce((sum, p) => sum + p.qty, 0) ?? 0} | |||
| // disabled={true} | |||
| @@ -404,7 +414,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| <TextField | |||
| label={t("acceptedQty")} | |||
| fullWidth | |||
| sx={textfieldSx} | |||
| sx={compactFields ? undefined : textfieldSx} | |||
| disabled={true} | |||
| {...register("acceptedQty", { | |||
| required: "acceptedQty required!", | |||
| @@ -452,7 +462,7 @@ const StockInForm: React.FC<Props> = ({ | |||
| open={openModal} | |||
| onClose={handleOnModalClose} | |||
| onSubmit={handleReturnExpiryDate} | |||
| textfieldSx={textfieldSx} | |||
| textfieldSx={compactFields ? undefined : textfieldSx} | |||
| /> | |||
| </> | |||
| ); | |||