umwd-components 0.1.631 → 0.1.632

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import TextField from "@mui/material/TextField";
3
+ interface NumberInputProps extends React.ComponentProps<typeof TextField> {
4
+ label: string;
5
+ minNewValue?: number;
6
+ maxNewValue?: number;
7
+ error?: boolean;
8
+ setValueCallback?: (value: number) => void;
9
+ }
10
+ declare const NumberInput: (props: NumberInputProps) => React.JSX.Element;
11
+ export default NumberInput;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "umwd-components",
3
- "version": "0.1.631",
3
+ "version": "0.1.632",
4
4
  "description": "UMWD Component library",
5
5
  "main": "dist/src/index.js",
6
6
  "module": "dist/src/index.js",
@@ -0,0 +1,70 @@
1
+ import React, { useEffect } from "react";
2
+ import TextField from "@mui/material/TextField";
3
+
4
+ interface NumberInputProps extends React.ComponentProps<typeof TextField> {
5
+ label: string;
6
+ minNewValue?: number;
7
+ maxNewValue?: number;
8
+ error?: boolean;
9
+ setValueCallback?: (value: number) => void;
10
+ }
11
+
12
+ const NumberInput = (props: NumberInputProps) => {
13
+ const { label, minNewValue, maxNewValue } = props;
14
+
15
+ const [value, setValue] = React.useState(0);
16
+
17
+ useEffect(() => {
18
+ props.setValueCallback && props.setValueCallback(value);
19
+ }, [value]);
20
+
21
+ return (
22
+ <TextField
23
+ {...props}
24
+ type="number"
25
+ label={label}
26
+ size="small"
27
+ value={value}
28
+ onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
29
+ const newValue = Number(event.target.value);
30
+ if (minNewValue !== undefined && maxNewValue !== undefined) {
31
+ setValue(Math.max(minNewValue, Math.min(newValue, maxNewValue)));
32
+ } else if (minNewValue !== undefined) {
33
+ setValue(Math.max(newValue, minNewValue));
34
+ } else if (maxNewValue !== undefined) {
35
+ setValue(Math.min(newValue, maxNewValue));
36
+ } else {
37
+ setValue(newValue);
38
+ }
39
+ }}
40
+ inputProps={{
41
+ step: 1,
42
+ min: minNewValue ?? undefined,
43
+ max: maxNewValue ?? undefined,
44
+ }}
45
+ onWheel={(event: React.WheelEvent<HTMLInputElement>) => {
46
+ // `event.currentTarget` is a callable type but is targetting the MUI element
47
+ // whereas `event.target` targets the input element but does not have the callable type, so casting
48
+ (event.target as HTMLInputElement).blur();
49
+ }}
50
+ helperText={`min: ${minNewValue}, max: ${maxNewValue}`}
51
+ error={
52
+ (minNewValue !== undefined && value < minNewValue) ||
53
+ (maxNewValue !== undefined && value > maxNewValue) ||
54
+ props.error
55
+ }
56
+ sx={[
57
+ // You cannot spread `sx` directly because `SxProps` (typeof sx) can be an array.
58
+ { width: "9rem" },
59
+ ...(Array.isArray(props?.sx) ? props.sx : [props.sx]),
60
+ ]}
61
+ /* sx={{
62
+ width: "9rem",
63
+ ...props.sx,
64
+ }} */
65
+ // sx={{ width: "9rem" }}
66
+ />
67
+ );
68
+ };
69
+
70
+ export default NumberInput;
@@ -29,6 +29,7 @@ import DialogActions from "@mui/material/DialogActions";
29
29
  import DialogContent from "@mui/material/DialogContent";
30
30
  import DialogContentText from "@mui/material/DialogContentText";
31
31
  import DialogTitle from "@mui/material/DialogTitle";
32
+ import NumberInput from "../../../components/common/NumberInput";
32
33
 
33
34
  const INITIAL_STATE = {
34
35
  zodErrors: null,
@@ -46,7 +47,6 @@ const ItemLines: React.FC<ItemLinesProps> = ({ items }) => {
46
47
  const [selectedItems, setSelectedItems] = useState<number[]>([]);
47
48
 
48
49
  const [showCustomReason, setShowCustomReason] = useState(false);
49
- const [unopenedConfirmation, setUnopenedConfirmation] = useState(false);
50
50
 
51
51
  const updateItemsToReturn = (
52
52
  index: number,
@@ -126,77 +126,112 @@ const ItemLines: React.FC<ItemLinesProps> = ({ items }) => {
126
126
  />
127
127
  <Stack spacing={1}>
128
128
  {items.map((item, index) => (
129
- <Stack spacing={1}>
130
- <Typography variant="body1">
131
- Line Item Number: {item.line_item_number}
132
- </Typography>
133
- <Typography variant="body1">
134
- Part Number: {item.product?.product_number}
135
- </Typography>
136
- <Typography variant="body1">
137
- Quantity Ordered: {item.ordered_quantity}
138
- </Typography>
139
- {/* */}
140
- <TextualAmountUpdater
141
- label="Quantity to return"
142
- currentValue={item.ordered_quantity}
143
- totalValue={item.ordered_quantity}
144
- minNewValue={0}
145
- maxNewValue={item.ordered_quantity}
146
- handleChange={(newValue) => {
147
- console.log(newValue);
148
- updateItemsToReturn(index, "returned_quantity", newValue);
149
- }}
150
- color="info"
151
- />
152
- <Typography variant="body1">Reason for return:</Typography>
153
- <TextField
154
- value={itemsToReturn[index]?.reason}
155
- select
156
- SelectProps={{
157
- native: true,
158
- }}
159
- variant="outlined"
160
- fullWidth
161
- onChange={(e) => {
162
- const reason = e.target.value;
163
- if (reason === "other") {
164
- setShowCustomReason(true);
165
- } else {
166
- setShowCustomReason(false);
167
- }
168
- updateItemsToReturn(index, "reason", reason as ReturnReason);
169
- }}
170
- >
171
- <option value="damaged">Damaged on arrival</option>
172
- <option value="not_as_described">Not as described</option>
173
- <option value="wrong_item">Wrong item</option>
174
- <option value="other">Other</option>
175
- </TextField>
176
- {showCustomReason && (
177
- <TextField
178
- value={itemsToReturn[index].other_reason}
179
- label="Custom reason"
180
- variant="outlined"
181
- fullWidth
129
+ <>
130
+ <Stack spacing={1} direction={"row"} alignItems={"center"}>
131
+ <Checkbox
132
+ checked={selectedItems.includes(index)}
182
133
  onChange={(e) => {
183
- const customReason = e.target.value;
184
- updateItemsToReturn(index, "other_reason", customReason);
134
+ if (e.target.checked) {
135
+ setSelectedItems([...selectedItems, index]);
136
+ } else {
137
+ setSelectedItems(
138
+ selectedItems.filter((i) => i !== index)
139
+ );
140
+ }
185
141
  }}
186
142
  />
143
+ <Typography variant="body1">
144
+ Line Item Number: {item.line_item_number}
145
+ </Typography>
146
+ <Typography variant="body1">
147
+ Part Number: {item.product?.product_number}
148
+ </Typography>
149
+ <Typography variant="body1">
150
+ Quantity Ordered: {item.ordered_quantity}
151
+ </Typography>
152
+ </Stack>
153
+
154
+ {selectedItems.includes(index) && (
155
+ <>
156
+ <Stack direction={"row"} spacing={1} alignItems={"center"}>
157
+ <NumberInput
158
+ label="Quantity to return"
159
+ minNewValue={0}
160
+ maxNewValue={item.ordered_quantity}
161
+ setValueCallback={(newValue) => {
162
+ updateItemsToReturn(
163
+ index,
164
+ "returned_quantity",
165
+ newValue
166
+ );
167
+ }}
168
+ sx={{ width: "12rem" }}
169
+ />
170
+ {/* <TextualAmountUpdater
171
+ label="Quantity to return"
172
+ currentValue={item.ordered_quantity}
173
+ totalValue={item.ordered_quantity}
174
+ minNewValue={0}
175
+ maxNewValue={item.ordered_quantity}
176
+ handleChange={(newValue) => {
177
+ // console.log(newValue);
178
+ updateItemsToReturn(index, "returned_quantity", newValue);
179
+ }}
180
+ color="info"
181
+ /> */}
182
+ <Divider orientation="vertical" flexItem />
183
+ <Typography variant="body1" sx={{ width: "12rem" }}>
184
+ Reason for return:
185
+ </Typography>
186
+ <TextField
187
+ value={itemsToReturn[index]?.reason}
188
+ select
189
+ SelectProps={{
190
+ native: true,
191
+ }}
192
+ variant="outlined"
193
+ fullWidth
194
+ onChange={(e) => {
195
+ const reason = e.target.value;
196
+ if (reason === "other") {
197
+ setShowCustomReason(true);
198
+ } else {
199
+ setShowCustomReason(false);
200
+ }
201
+ updateItemsToReturn(
202
+ index,
203
+ "reason",
204
+ reason as ReturnReason
205
+ );
206
+ }}
207
+ >
208
+ <option value="damaged">Damaged on arrival</option>
209
+ <option value="not_as_described">Not as described</option>
210
+ <option value="wrong_item">Wrong item</option>
211
+ <option value="other">Other</option>
212
+ </TextField>
213
+ </Stack>
214
+ {showCustomReason && (
215
+ <TextField
216
+ value={itemsToReturn[index].other_reason}
217
+ label="Custom reason"
218
+ variant="outlined"
219
+ fullWidth
220
+ onChange={(e) => {
221
+ const customReason = e.target.value;
222
+ updateItemsToReturn(
223
+ index,
224
+ "other_reason",
225
+ customReason
226
+ );
227
+ }}
228
+ />
229
+ )}
230
+ </>
187
231
  )}
188
- {/* TODO ??? <Checkbox
189
- checked={selectedItems.includes(index)}
190
- onChange={(e) => {
191
- if (e.target.checked) {
192
- setSelectedItems([...selectedItems, index]);
193
- } else {
194
- setSelectedItems(selectedItems.filter((i) => i !== index));
195
- }
196
- }}
197
- /> */}
232
+
198
233
  <Divider />
199
- </Stack>
234
+ </>
200
235
  ))}
201
236
  </Stack>
202
237
  </Stack>