umwd-components 0.1.623 → 0.1.624

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.
Files changed (56) hide show
  1. package/dist/node_modules/base64-js/index.js +1 -1
  2. package/dist/node_modules/ieee754/index.js +1 -1
  3. package/dist/node_modules/prop-types/node_modules/react-is/index.js +1 -1
  4. package/dist/node_modules/safe-buffer/index.js +1 -1
  5. package/dist/src/components/e-commerce/iro/CreateIROForm.js +7 -0
  6. package/dist/src/components/e-commerce/iro/IROItemFields.js +6 -0
  7. package/dist/src/components/e-commerce/iro/IROItemUpdater.js +6 -0
  8. package/dist/src/components/e-commerce/iro/IroItemDisplay.js +6 -0
  9. package/dist/src/components/e-commerce/iro/IroStatusIndicator.js +7 -0
  10. package/dist/src/components/e-commerce/iro/ManageIROForm.js +6 -0
  11. package/dist/src/components/e-commerce/iro/RmaForm.js +7 -0
  12. package/dist/src/components/e-commerce/iro/TextualIROItemUpdater.js +6 -0
  13. package/dist/src/components/e-commerce/iro/TextualManageIROForm.js +6 -0
  14. package/dist/src/components/e-commerce/opo/ManageOpoForm.js +1 -1
  15. package/dist/src/components/e-commerce/opo/TextualManageOpoForm.js +1 -1
  16. package/dist/src/components/logistics/ipo/ManageIPOForm.js +1 -1
  17. package/dist/src/components/logistics/ipo/TextualManageIPOForm.js +1 -1
  18. package/dist/src/data/actions/e-commerce/iro/createIroAction.js +7 -0
  19. package/dist/src/data/actions/e-commerce/iro/updateIroAction.js +7 -0
  20. package/dist/src/data/services/common/confirmation-service.js +7 -0
  21. package/dist/src/index.js +1 -1
  22. package/dist/tsconfig.build.tsbuildinfo +1 -1
  23. package/dist/types/components/e-commerce/iro/CreateIROForm.d.ts +3 -0
  24. package/dist/types/components/e-commerce/iro/IROItemFields.d.ts +5 -0
  25. package/dist/types/components/e-commerce/iro/IROItemUpdater.d.ts +4 -0
  26. package/dist/types/components/e-commerce/iro/IroItemDisplay.d.ts +4 -0
  27. package/dist/types/components/e-commerce/iro/IroStatusIndicator.d.ts +10 -0
  28. package/dist/types/components/e-commerce/iro/ManageIROForm.d.ts +3 -0
  29. package/dist/types/components/e-commerce/iro/RmaForm.d.ts +3 -0
  30. package/dist/types/components/e-commerce/iro/TextualIROItemUpdater.d.ts +4 -0
  31. package/dist/types/components/e-commerce/iro/TextualManageIROForm.d.ts +3 -0
  32. package/dist/types/data/actions/e-commerce/iro/createIroAction.d.ts +5 -0
  33. package/dist/types/data/actions/e-commerce/iro/updateIroAction.d.ts +1 -0
  34. package/dist/types/index.d.ts +12 -1
  35. package/dist/types/types/e-commerce/iro/types.d.ts +89 -0
  36. package/package.json +1 -1
  37. package/src/components/e-commerce/iro/CreateIROForm.tsx +134 -0
  38. package/src/components/e-commerce/iro/IROItemFields.tsx +171 -0
  39. package/src/components/e-commerce/iro/IROItemUpdater.tsx +140 -0
  40. package/src/components/e-commerce/iro/IroItemDisplay.tsx +41 -0
  41. package/src/components/e-commerce/iro/IroStatusIndicator.tsx +81 -0
  42. package/src/components/e-commerce/iro/ManageIROForm.tsx +450 -0
  43. package/src/components/e-commerce/iro/RmaForm.tsx +225 -0
  44. package/src/components/e-commerce/iro/TextualIROItemUpdater.tsx +217 -0
  45. package/src/components/e-commerce/iro/TextualManageIROForm.tsx +456 -0
  46. package/src/components/e-commerce/opo/ManageOpoForm.tsx +1 -1
  47. package/src/components/e-commerce/opo/TextualManageOpoForm.tsx +1 -1
  48. package/src/components/logistics/ipo/ManageIPOForm.tsx +1 -1
  49. package/src/components/logistics/ipo/TextualManageIPOForm.tsx +1 -3
  50. package/src/data/actions/e-commerce/iro/createIroAction.ts +46 -0
  51. package/src/data/actions/e-commerce/iro/updateIroAction.ts +43 -0
  52. package/src/data/services/{logistics/ipo → common}/confirmation-service.ts +2 -2
  53. package/src/index.ts +14 -1
  54. package/src/types/e-commerce/iro/types.ts +109 -0
  55. package/dist/src/data/services/logistics/ipo/confirmation-service.js +0 -7
  56. /package/dist/types/data/services/{logistics/ipo → common}/confirmation-service.d.ts +0 -0
@@ -0,0 +1,41 @@
1
+ import React from "react";
2
+ import Stack from "@mui/material/Stack";
3
+ import Typography from "@mui/material/Typography";
4
+
5
+ import { IroItemDisplayProps } from "../../../types/e-commerce/iro/types";
6
+ import ImagePreviewTooltip from "../../../components/common/ImagePreviewTooltip";
7
+
8
+ function IroItemDisplay({ item, index, image }: IroItemDisplayProps) {
9
+ const { line_item_number, product, returned_quantity } = item;
10
+
11
+ return (
12
+ <Stack spacing={1} key={index}>
13
+ {item && (
14
+ <Stack
15
+ direction={"row"}
16
+ justifyContent={"space-between"}
17
+ alignItems={"center"}
18
+ >
19
+ <Stack spacing={1}>
20
+ <Typography variant="body1">
21
+ Line Item Number: {line_item_number}
22
+ </Typography>
23
+ <Typography variant="body1">
24
+ Part Number: {product?.product_number}
25
+ </Typography>
26
+ <Typography variant="body1">
27
+ Quantity Ordered: {returned_quantity}
28
+ </Typography>
29
+ </Stack>
30
+ {image && (
31
+ <>
32
+ <ImagePreviewTooltip image={image} label={item.product?.title} />
33
+ </>
34
+ )}
35
+ </Stack>
36
+ )}
37
+ </Stack>
38
+ );
39
+ }
40
+
41
+ export default IroItemDisplay;
@@ -0,0 +1,81 @@
1
+ "use client";
2
+
3
+ import React from "react";
4
+
5
+ import Chip from "@mui/material/Chip";
6
+
7
+ import { IpoStatus } from "../../../types/logistics/Ipo";
8
+ import { Role } from "../../../types/auth/Role";
9
+
10
+ interface IroStatusIndicatorProps {
11
+ status: IpoStatus;
12
+ provider_id?: string;
13
+ role?: Role;
14
+ }
15
+
16
+ const statusColorArray: {
17
+ status: IpoStatus;
18
+ color: "warning" | "info" | "success" | "error" | "default";
19
+ }[] = [
20
+ { status: "placed", color: "info" },
21
+ { status: "ordered", color: "info" },
22
+ { status: "logistics_operator_process", color: "info" },
23
+ { status: "released_on_stock", color: "info" },
24
+ { status: "done", color: "success" },
25
+ { status: "cancelled", color: "error" },
26
+ { status: null, color: "default" },
27
+ ];
28
+
29
+ const enduserStatusColorArray: {
30
+ status: IpoStatus;
31
+ color: "warning" | "info" | "success" | "error" | "default";
32
+ }[] = [
33
+ { status: "placed", color: "warning" },
34
+ { status: "ordered", color: "info" },
35
+ { status: "logistics_operator_process", color: "info" },
36
+ { status: "released_on_stock", color: "info" },
37
+ { status: "done", color: "success" },
38
+ { status: "cancelled", color: "error" },
39
+ { status: null, color: "default" },
40
+ ];
41
+
42
+ const dispatcherStatusColorArray: {
43
+ status: IpoStatus;
44
+ color: "warning" | "info" | "success" | "error" | "default";
45
+ }[] = [
46
+ { status: "placed", color: "info" },
47
+ { status: "ordered", color: "warning" },
48
+ { status: "logistics_operator_process", color: "info" },
49
+ { status: "released_on_stock", color: "info" },
50
+ { status: "done", color: "success" },
51
+ { status: "cancelled", color: "error" },
52
+ { status: null, color: "default" },
53
+ ];
54
+
55
+ export const IroStatusIndicator: React.FC<IroStatusIndicatorProps> = ({
56
+ status,
57
+ role,
58
+ }) => {
59
+ const readableStatus = status
60
+ ? status
61
+ .split("_")
62
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
63
+ .join(" ")
64
+ : "Unknown";
65
+
66
+ return (
67
+ <Chip
68
+ label={readableStatus}
69
+ color={
70
+ role === "enduser"
71
+ ? enduserStatusColorArray.find((s) => s.status === status)?.color ||
72
+ "default"
73
+ : role === "dispatcher"
74
+ ? dispatcherStatusColorArray.find((s) => s.status === status)
75
+ ?.color || "default"
76
+ : statusColorArray.find((s) => s.status === status)?.color ||
77
+ "default"
78
+ }
79
+ />
80
+ );
81
+ };
@@ -0,0 +1,450 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { useFormState } from "react-dom";
3
+ import { updateIpoAction } from "../../../data/actions/logistics/ipo/updateIpoAction";
4
+ import { UploadBase64MediaForm } from "../../../components/common/media/UploadBase64MediaForm";
5
+ import downloadBase64File from "../../../data/loaders/common/media/downloadBase64File";
6
+ import ItemUpdater from "./IROItemUpdater";
7
+ import ItemDisplay from "./IroItemDisplay";
8
+ import {
9
+ IroItem,
10
+ ManageIroFormProps,
11
+ } from "../../../types/e-commerce/iro/types";
12
+ import NotesDisplay from "../../logistics/note/NotesDisplay";
13
+ import NoteTakingComponent from "../../logistics/note/NoteTakingComponent";
14
+ import { StrapiErrors } from "../../../components/StrapiErrors";
15
+ import { SubmitButton } from "../../../components/SubmitButton";
16
+ import Alert from "@mui/material/Alert";
17
+ import Dialog from "@mui/material/Dialog";
18
+ import DialogActions from "@mui/material/DialogActions";
19
+ import DialogContent from "@mui/material/DialogContent";
20
+ import DialogTitle from "@mui/material/DialogTitle";
21
+ import Typography from "@mui/material/Typography";
22
+ import Button from "@mui/material/Button";
23
+ import Grid from "@mui/material/Grid";
24
+ import Box from "@mui/material/Box";
25
+ import Paper from "@mui/material/Paper";
26
+ import Stack from "@mui/material/Stack";
27
+ import Divider from "@mui/material/Divider";
28
+ import Card from "@mui/material/Card";
29
+ import CardContent from "@mui/material/CardContent";
30
+ import { confirmationService } from "../../../data/services/common/confirmation-service";
31
+
32
+ const INITIAL_STATE = {
33
+ zodErrors: null,
34
+ strapiErrors: null,
35
+ data: null,
36
+ message: null,
37
+ };
38
+
39
+ /* const CONFIRMATION_STATE = {
40
+ zodErrors: null,
41
+ strapiErrors: null,
42
+ data: null,
43
+ message: null,
44
+ };
45
+
46
+ function ConfirmFormDialog({
47
+ open,
48
+ handleClose,
49
+ orderID,
50
+ currentStatus,
51
+ revalidateCallback,
52
+ }: {
53
+ open: boolean;
54
+ handleClose: () => void;
55
+ orderID: number;
56
+ currentStatus: "placed" | "released_on_stock";
57
+ revalidateCallback?: () => void;
58
+ }) {
59
+ const [formState, formAction] = useFormState(
60
+ updateIpoAction,
61
+ CONFIRMATION_STATE
62
+ );
63
+
64
+ useEffect(() => {
65
+ if (formState?.message === "Ipo Updated") {
66
+ revalidateCallback && revalidateCallback();
67
+ handleClose();
68
+ }
69
+ }, [formState?.message]);
70
+
71
+ return (
72
+ <Dialog open={open}>
73
+ <form action={formAction}>
74
+ <input name="id" type="hidden" value={orderID} />
75
+ <input
76
+ name="status"
77
+ type="hidden"
78
+ value={currentStatus === "placed" ? "ordered" : "done"}
79
+ />
80
+ <DialogTitle>Confirm Order</DialogTitle>
81
+ <DialogContent>
82
+ <Stack spacing={2}>
83
+ <Typography>
84
+ Are you sure you want to confirm this order?
85
+ </Typography>
86
+ <Typography>Current status: {currentStatus}</Typography>
87
+ </Stack>
88
+ </DialogContent>
89
+ <DialogActions>
90
+ <SubmitButton text="Confirm" loadingText="Loading..." />
91
+ <StrapiErrors error={formState?.strapiErrors} />
92
+ {formState?.message && (
93
+ <Alert severity="error">{formState?.message}</Alert>
94
+ )}
95
+ <Button variant="contained" color="secondary" onClick={handleClose}>
96
+ Cancel
97
+ </Button>
98
+ </DialogActions>
99
+ </form>
100
+ </Dialog>
101
+ );
102
+ } */
103
+
104
+ function ConfirmFormDialog({
105
+ open,
106
+ handleClose,
107
+ orderID,
108
+ currentStatus,
109
+ revalidateCallback,
110
+ }: {
111
+ open: boolean;
112
+ handleClose: () => void;
113
+ orderID: number;
114
+ currentStatus: "placed" | "released_on_stock";
115
+ revalidateCallback?: () => void;
116
+ }) {
117
+ return (
118
+ <Dialog open={open}>
119
+ <DialogTitle>Confirm Order</DialogTitle>
120
+ <DialogContent>
121
+ <Stack spacing={2}>
122
+ <Typography>Are you sure you want to confirm this order?</Typography>
123
+ <Typography>Current status: {currentStatus}</Typography>
124
+ </Stack>
125
+ </DialogContent>
126
+ <DialogActions>
127
+ <Button
128
+ variant="contained"
129
+ onClick={(e) => {
130
+ confirmationService("ipos", [orderID]);
131
+ revalidateCallback && revalidateCallback();
132
+ }}
133
+ >
134
+ Confirm
135
+ </Button>
136
+ <Button variant="contained" onClick={handleClose}>
137
+ Cancel
138
+ </Button>
139
+ </DialogActions>
140
+ </Dialog>
141
+ );
142
+ }
143
+
144
+ export default function ManageIROForm({
145
+ data,
146
+ sx,
147
+ revalidateCallback,
148
+ handleClose,
149
+ role,
150
+ }: ManageIroFormProps) {
151
+ // TODO bind to id of IRO
152
+ const [formState, formAction] = useFormState(updateIpoAction, INITIAL_STATE);
153
+
154
+ const [items, setItems] = useState<IroItem[]>(
155
+ data.items.data ? data.items.data : []
156
+ );
157
+ const [confirmDialogOpen, setConfirmDialogOpen] = useState(false);
158
+
159
+ const parseItems = (items: IroItem[]) => {
160
+ return items.map((item) => {
161
+ return {
162
+ id: item.id,
163
+ received_quantity: item.received_quantity,
164
+ registered_quantity: item.registered_quantity,
165
+ released_quantity: item.released_quantity,
166
+ };
167
+ });
168
+ };
169
+
170
+ const handleUpdateQuantity = (
171
+ value: number,
172
+ itemID: number,
173
+ type: "received_quantity" | "registered_quantity" | "released_quantity"
174
+ ) => {
175
+ const newItems = [...items];
176
+ const index = newItems.findIndex((item) => item.id === itemID);
177
+ newItems[index][type] = value;
178
+ setItems(newItems);
179
+ };
180
+
181
+ const handleRemoveReportAtIndex = (itemID: number, index: number) => {
182
+ console.log(items);
183
+ console.log(itemID, index);
184
+ console.log("handleRemoveReportAtIndex");
185
+ };
186
+
187
+ return (
188
+ <Box
189
+ sx={[
190
+ // You cannot spread `sx` directly because `SxProps` (typeof sx) can be an array.
191
+ ...(Array.isArray(sx) ? sx : [sx]),
192
+ ]}
193
+ >
194
+ <Grid container spacing={2}>
195
+ <Grid item xs={12}>
196
+ <Stack spacing={2}>
197
+ <Stack
198
+ direction={"row"}
199
+ spacing={2}
200
+ justifyContent={"space-between"}
201
+ >
202
+ <Stack spacing={2}>
203
+ <Typography variant="h3" component={"h1"}>
204
+ Management Inbound Purchase Order
205
+ </Typography>
206
+ <Typography variant="body1">
207
+ Manage arrival, registration and recieval of purchase order
208
+ </Typography>
209
+ </Stack>
210
+ <NoteTakingComponent
211
+ content=""
212
+ related={[{ id: data.id, __type: "api::logistics.ipo" }]}
213
+ revalidateCallback={revalidateCallback}
214
+ />
215
+ </Stack>
216
+ <Divider />
217
+ </Stack>
218
+ </Grid>
219
+ <Grid item xs={6}>
220
+ <Stack spacing={1}>
221
+ <Typography variant="h5">Details</Typography>
222
+
223
+ <Stack direction="row" spacing={2}>
224
+ <Typography variant="body1" width={"250px"}>
225
+ Purchase Order Number
226
+ </Typography>
227
+ <Typography variant="body2">{data.iro_number}</Typography>
228
+ </Stack>
229
+
230
+ <Stack direction="row" spacing={2}>
231
+ <Typography variant="body1" width={"250px"}>
232
+ Custom reference
233
+ </Typography>
234
+ {/* <Typography variant="body2">{data.custom_reference}</Typography> */}
235
+ </Stack>
236
+
237
+ <Stack direction="row" spacing={2}>
238
+ <Typography variant="body1" width={"250px"}>
239
+ Order Date
240
+ </Typography>
241
+
242
+ <Typography variant="body2">{data.return_date}</Typography>
243
+ </Stack>
244
+
245
+ <Stack direction="row" spacing={2}>
246
+ <Typography variant="body1" width={"250px"}>
247
+ Supplier
248
+ </Typography>
249
+ {/* <Typography variant="body2">
250
+ {data.vendor_profile?.business_credentials?.company_name}
251
+ </Typography> */}
252
+ </Stack>
253
+
254
+ <Stack direction="row" spacing={2}>
255
+ <Typography variant="body1" width={"250px"}>
256
+ Order Status
257
+ </Typography>
258
+ <Typography variant="body2" width={"250px"}>
259
+ {data.status}
260
+ </Typography>
261
+ </Stack>
262
+
263
+ {/* {(data.status === "placed" ||
264
+ data.status === "released_on_stock") &&
265
+ role === "enduser" && (
266
+ <>
267
+ <Button
268
+ variant="contained"
269
+ color="primary"
270
+ onClick={() => setConfirmDialogOpen(true)}
271
+ >
272
+ Confirm order
273
+ </Button>
274
+ <Alert severity="warning">
275
+ Please confirm the order as soon as possible, only upon
276
+ confirmation this order will be available to the dispatcher
277
+ </Alert>
278
+ <ConfirmFormDialog
279
+ open={confirmDialogOpen}
280
+ handleClose={() => setConfirmDialogOpen(false)}
281
+ orderID={data.id}
282
+ currentStatus={data.status}
283
+ revalidateCallback={revalidateCallback}
284
+ />
285
+ </>
286
+ )} */}
287
+ </Stack>
288
+ </Grid>
289
+ <Grid item xs={12}>
290
+ <Stack spacing={2}>
291
+ <Typography variant="h5">Documents</Typography>
292
+ <Paper sx={{ p: 2 }}>
293
+ <Stack spacing={1}>
294
+ {/* order confirmation is only visible to enduser, delivery note is
295
+ visible to both enduser and dispatcher*/}
296
+ {/* if there is a order confirmation, show the order confirmation,
297
+ if there is no order confirmation show the upload fields */}
298
+ {role === "enduser" && (
299
+ <>
300
+ {/* {data.order_confirmation ? (
301
+ <>
302
+ <Typography variant="h6">Order Confirmation</Typography>
303
+ <Typography>{data.order_confirmation?.name}</Typography>
304
+ <Button
305
+ variant="contained"
306
+ onClick={() => {
307
+ downloadBase64File(
308
+ `api/ipos/${data.id}`,
309
+ "order_confirmation"
310
+ );
311
+ }}
312
+ >
313
+ Download
314
+ </Button>
315
+ </>
316
+ ) : (
317
+ <>
318
+ <Typography variant="h5">Order Confirmation</Typography>
319
+ <Typography variant="body1">
320
+ Here you can upload the the order confirmation for
321
+ this order
322
+ </Typography>
323
+ <Typography variant="body1">FileUpload</Typography>
324
+ <Divider />
325
+ <UploadBase64MediaForm // This form manages it's own state internally
326
+ reference="api::logistics.ipo"
327
+ refID={data.id}
328
+ field="order_confirmation"
329
+ multiple={false}
330
+ accept="text/*,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"
331
+ path="api/ipos"
332
+ componentName="order_confirmation"
333
+ componentReference="common.base64-encoded-media"
334
+ revalidateCallback={revalidateCallback}
335
+ />
336
+ </>
337
+ )} */}
338
+ </>
339
+ )}
340
+ {/* {data.delivery_note ? (
341
+ <>
342
+ <Typography variant="h6">Delivery Note</Typography>
343
+ <Typography>{data.delivery_note?.name}</Typography>
344
+ <Button
345
+ variant="contained"
346
+ onClick={() => {
347
+ downloadBase64File(
348
+ `api/ipos/${data.id}`,
349
+ "delivery_note"
350
+ );
351
+ }}
352
+ >
353
+ Download
354
+ </Button>
355
+ </>
356
+ ) : (
357
+ <>
358
+ <Typography variant="h5">Delivery Note</Typography>
359
+ <Typography variant="body1">
360
+ Here you can upload the the delivery note for this order
361
+ </Typography>
362
+ <Divider />
363
+ <UploadBase64MediaForm
364
+ reference="api::logistics.ipo"
365
+ refID={data.id}
366
+ field="delivery_note"
367
+ multiple={false}
368
+ accept="text/*,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"
369
+ path="api/ipos"
370
+ componentName="delivery_note"
371
+ componentReference="common.base64-encoded-media"
372
+ revalidateCallback={revalidateCallback}
373
+ />
374
+ </>
375
+ )} */}
376
+ </Stack>
377
+ </Paper>
378
+ </Stack>
379
+ </Grid>
380
+
381
+ {data?.notes?.data?.length > 0 && (
382
+ <Grid item xs={12}>
383
+ <Stack spacing={2}>
384
+ <Typography variant="h5">Notes</Typography>
385
+ <NotesDisplay notes={data.notes.data} />
386
+ <Divider />
387
+ </Stack>
388
+ </Grid>
389
+ )}
390
+
391
+ <Grid item xs={12}>
392
+ <Stack spacing={1}>
393
+ <Typography variant="h5">Items</Typography>
394
+ {/* {data.status === "placed" && (
395
+ <Alert severity="warning">
396
+ Before confirmation you cannot update the items
397
+ </Alert>
398
+ )} */}
399
+ <Divider />
400
+ <form action={formAction}>
401
+ {/** INFO - This form is for updating the items, it should be a separate form from the one that
402
+ * uploads the files since forms cannot be nested in HTML, however the SubmitButton component
403
+ * should be within the form, thats why the form spans two grid items
404
+ * */}
405
+ <input name="id" type="hidden" value={data.id} />
406
+ {data?.items?.data &&
407
+ data.items.data.map((item: IroItem, index: number) => {
408
+ console.log("item", item);
409
+ return (
410
+ <Paper sx={{ p: 2, mb: 2 }} key={index}>
411
+ {/* {data.status === "placed" ? (
412
+ <ItemDisplay
413
+ item={item}
414
+ index={index}
415
+ image={item?.product?.image}
416
+ />
417
+ ) : (
418
+ <ItemUpdater
419
+ item={item}
420
+ index={index}
421
+ handleUpdateQuantity={handleUpdateQuantity}
422
+ image={item?.product?.image}
423
+ // handleRemoveReportAtIndex={handleRemoveReportAtIndex}
424
+ revalidateCallback={revalidateCallback}
425
+ />
426
+ )} */}
427
+ </Paper>
428
+ );
429
+ })}
430
+ <Paper sx={{ p: 2 }}>
431
+ <Stack direction="row" spacing={2} justifyContent={"end"}>
432
+ <SubmitButton text="Update items" loadingText="Loading..." />
433
+ <StrapiErrors error={formState?.strapiErrors} />
434
+ {formState?.message && (
435
+ <Alert severity="error">{formState?.message}</Alert>
436
+ )}
437
+ </Stack>
438
+ </Paper>
439
+ <input
440
+ type="hidden"
441
+ name="items"
442
+ value={JSON.stringify(parseItems(items))}
443
+ />
444
+ </form>
445
+ </Stack>
446
+ </Grid>
447
+ </Grid>
448
+ </Box>
449
+ );
450
+ }