FPSMS-frontend
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

140 rivejä
4.3 KiB

  1. "use client";
  2. import {
  3. Card,
  4. CardContent,
  5. Stack,
  6. TextField,
  7. Typography,
  8. Box,
  9. InputAdornment,
  10. } from "@mui/material";
  11. import { useFormContext, Controller } from "react-hook-form";
  12. import { useTranslation } from "react-i18next";
  13. import { WarehouseInputs } from "@/app/api/warehouse/actions";
  14. const WarehouseDetail: React.FC = () => {
  15. const { t } = useTranslation("warehouse");
  16. const {
  17. register,
  18. control,
  19. formState: { errors },
  20. } = useFormContext<WarehouseInputs>();
  21. return (
  22. <Card>
  23. <CardContent component={Stack} spacing={4}>
  24. <Typography variant="overline" display="block" marginBlockEnd={1}>
  25. {t("Warehouse Detail")}
  26. </Typography>
  27. <Box
  28. sx={{
  29. display: "flex",
  30. alignItems: "flex-start",
  31. gap: 1,
  32. flexWrap: "nowrap",
  33. justifyContent: "flex-start",
  34. }}
  35. >
  36. {/* 樓層 field with F inside on the right - F is automatically generated */}
  37. <Controller
  38. name="store_id"
  39. control={control}
  40. rules={{ required: t("store_id") + " " + t("is required") }}
  41. render={({ field }) => (
  42. <TextField
  43. {...field}
  44. label={t("store_id")}
  45. size="small"
  46. sx={{ width: "150px", minWidth: "120px" }}
  47. InputProps={{
  48. endAdornment: (
  49. <InputAdornment position="end">F</InputAdornment>
  50. ),
  51. }}
  52. onChange={(e) => {
  53. // Automatically remove "F" if user tries to type it (F is auto-generated)
  54. const value = e.target.value.replace(/F/gi, "").trim();
  55. field.onChange(value);
  56. }}
  57. error={Boolean(errors.store_id)}
  58. helperText={errors.store_id?.message}
  59. />
  60. )}
  61. />
  62. <Typography variant="body1" sx={{ mx: 0.5, mt: 1.5 }}>
  63. -
  64. </Typography>
  65. {/* 倉庫 field */}
  66. <Controller
  67. name="warehouse"
  68. control={control}
  69. rules={{ required: t("warehouse") + " " + t("is required") }}
  70. render={({ field }) => (
  71. <TextField
  72. {...field}
  73. label={t("warehouse")}
  74. size="small"
  75. sx={{ width: "150px", minWidth: "120px" }}
  76. error={Boolean(errors.warehouse)}
  77. helperText={errors.warehouse?.message}
  78. />
  79. )}
  80. />
  81. <Typography variant="body1" sx={{ mx: 0.5, mt: 1.5 }}>
  82. -
  83. </Typography>
  84. {/* 區域 field */}
  85. <Controller
  86. name="area"
  87. control={control}
  88. rules={{ required: t("area") + " " + t("is required") }}
  89. render={({ field }) => (
  90. <TextField
  91. {...field}
  92. label={t("area")}
  93. size="small"
  94. sx={{ width: "150px", minWidth: "120px" }}
  95. error={Boolean(errors.area)}
  96. helperText={errors.area?.message}
  97. />
  98. )}
  99. />
  100. <Typography variant="body1" sx={{ mx: 0.5, mt: 1.5 }}>
  101. -
  102. </Typography>
  103. {/* 儲位 field */}
  104. <Controller
  105. name="slot"
  106. control={control}
  107. rules={{ required: t("slot") + " " + t("is required") }}
  108. render={({ field }) => (
  109. <TextField
  110. {...field}
  111. label={t("slot")}
  112. size="small"
  113. sx={{ width: "150px", minWidth: "120px" }}
  114. error={Boolean(errors.slot)}
  115. helperText={errors.slot?.message}
  116. />
  117. )}
  118. />
  119. {/* stockTakeSection field in the same row */}
  120. <Box sx={{ flex: 1, minWidth: "150px", ml: 2 }}>
  121. <TextField
  122. label={t("stockTakeSection")}
  123. fullWidth
  124. size="small"
  125. {...register("stockTakeSection")}
  126. error={Boolean(errors.stockTakeSection)}
  127. helperText={errors.stockTakeSection?.message}
  128. />
  129. </Box>
  130. </Box>
  131. </CardContent>
  132. </Card>
  133. );
  134. };
  135. export default WarehouseDetail;