FPSMS-frontend
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

252 行
9.7 KiB

  1. "use client";
  2. import type { DoDetail as DoDetailType } from "@/app/api/do/actions";
  3. import { useRouter } from "next/navigation";
  4. import { useTranslation } from "react-i18next";
  5. import useUploadContext from "../UploadProvider/useUploadContext";
  6. import { FormProvider, SubmitErrorHandler, SubmitHandler, useForm } from "react-hook-form";
  7. import { useCallback, useState } from "react";
  8. import { Button, Stack, Typography, Box, Alert } from "@mui/material";
  9. import ArrowBackIcon from '@mui/icons-material/ArrowBack';
  10. import StartIcon from "@mui/icons-material/Start";
  11. import { releaseDo, assignPickOrderByStore, releaseAssignedPickOrderByStore } from "@/app/api/do/actions";
  12. import DoInfoCard from "./DoInfoCard";
  13. import DoLineTable from "./DoLineTable";
  14. import { useSession } from "next-auth/react";
  15. import { SessionWithTokens } from "@/config/authConfig"; // Import the correct session type
  16. type Props = {
  17. id?: number;
  18. defaultValues: Partial<DoDetailType> | undefined;
  19. }
  20. const DoDetail: React.FC<Props> = ({
  21. defaultValues,
  22. id,
  23. }) => {
  24. const { t } = useTranslation("do")
  25. const router = useRouter();
  26. const { setIsUploading } = useUploadContext();
  27. const [serverError, setServerError] = useState("");
  28. const [successMessage, setSuccessMessage] = useState("");
  29. const [isAssigning, setIsAssigning] = useState(false);
  30. const { data: session } = useSession() as { data: SessionWithTokens | null }; // Use correct session type
  31. const currentUserId = session?.id ? parseInt(session.id) : undefined; // Get user ID from session.id
  32. console.log("🔍 DoSearch - session:", session);
  33. console.log("🔍 DoSearch - currentUserId:", currentUserId);
  34. const formProps = useForm<DoDetailType>({
  35. defaultValues: defaultValues
  36. })
  37. const handleBack = useCallback(() => {
  38. router.replace(`/do`)
  39. }, [])
  40. const handleRelease = useCallback(async () => {
  41. try {
  42. setIsUploading(true)
  43. setServerError("")
  44. setSuccessMessage("")
  45. if (id) {
  46. // Get current user ID from session
  47. const currentUserId = session?.id ? parseInt(session.id) : undefined;
  48. if (!currentUserId) {
  49. setServerError("User session not found. Please login again.");
  50. return;
  51. }
  52. const response = await releaseDo({
  53. id: id,
  54. userId: currentUserId // Pass user ID from session
  55. })
  56. if (response) {
  57. formProps.setValue("status", response.entity.status)
  58. setSuccessMessage(t("DO released successfully! Pick orders created."))
  59. }
  60. }
  61. } catch (e) {
  62. setServerError(t("An error has occurred. Please try again later."));
  63. console.log(e);
  64. } finally {
  65. setIsUploading(false)
  66. }
  67. }, [id, formProps, t, setIsUploading, session]) // Add session to dependencies
  68. // UPDATE STORE-BASED ASSIGNMENT HANDLERS
  69. const handleAssignByStore = useCallback(async (storeId: string) => {
  70. try {
  71. setIsAssigning(true)
  72. setServerError("")
  73. setSuccessMessage("")
  74. // Get current user ID from session
  75. const currentUserId = session?.id ? parseInt(session.id) : undefined;
  76. if (!currentUserId) {
  77. setServerError("User session not found. Please login again.");
  78. return;
  79. }
  80. const response = await assignPickOrderByStore({
  81. storeId: storeId,
  82. assignTo: currentUserId
  83. })
  84. if (response) {
  85. setSuccessMessage(`Pick orders assigned to ${storeId} successfully!`)
  86. console.log("Assignment response:", response)
  87. }
  88. } catch (e) {
  89. setServerError(t("Failed to assign pick orders. Please try again later."));
  90. console.log(e);
  91. } finally {
  92. setIsAssigning(false)
  93. }
  94. }, [t, session]) // Add session to dependencies
  95. const handleReleaseByStore = useCallback(async (storeId: string) => {
  96. try {
  97. setIsAssigning(true)
  98. setServerError("")
  99. setSuccessMessage("")
  100. // Get current user ID from session
  101. const currentUserId = session?.id ? parseInt(session.id) : undefined;
  102. if (!currentUserId) {
  103. setServerError("User session not found. Please login again.");
  104. return;
  105. }
  106. const response = await releaseAssignedPickOrderByStore({
  107. storeId: storeId,
  108. assignTo: currentUserId
  109. })
  110. if (response) {
  111. setSuccessMessage(`Pick orders released for ${storeId} successfully!`)
  112. console.log("Release response:", response)
  113. }
  114. } catch (e) {
  115. setServerError(t("Failed to release pick orders. Please try again later."));
  116. console.log(e);
  117. } finally {
  118. setIsAssigning(false)
  119. }
  120. }, [t, session]) // Add session to dependencies
  121. const onSubmit = useCallback<SubmitHandler<DoDetailType>>(async (data, event) => {
  122. console.log(data)
  123. }, [t])
  124. const onSubmitError = useCallback<SubmitErrorHandler<DoDetailType>>((errors) => {
  125. console.log(errors)
  126. }, [t])
  127. return <>
  128. <FormProvider {...formProps}>
  129. <Stack
  130. spacing={2}
  131. component="form"
  132. onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
  133. >
  134. {serverError && (
  135. <Alert severity="error" sx={{ mb: 2 }}>
  136. {serverError}
  137. </Alert>
  138. )}
  139. {successMessage && (
  140. <Alert severity="success" sx={{ mb: 2 }}>
  141. {successMessage}
  142. </Alert>
  143. )}
  144. {
  145. formProps.watch("status")?.toLowerCase() === "pending" && (
  146. <Stack direction="row" justifyContent="flex-start" gap={1}>
  147. <Button
  148. variant="outlined"
  149. startIcon={<StartIcon />}
  150. onClick={handleRelease}
  151. disabled={isAssigning}
  152. >
  153. {t("Release")}
  154. </Button>
  155. </Stack>
  156. )}
  157. {/* ADD STORE-BASED ASSIGNMENT BUTTONS */}
  158. {
  159. formProps.watch("status")?.toLowerCase() === "released" && (
  160. <Box sx={{ mb: 2 }}>
  161. <Typography variant="h6" gutterBottom>
  162. {t("Pick Order Assignment")}
  163. </Typography>
  164. <Stack direction="row" spacing={2}>
  165. <Button
  166. variant="contained"
  167. color="primary"
  168. onClick={() => handleAssignByStore("2/F")}
  169. disabled={isAssigning}
  170. sx={{ minWidth: 120 }}
  171. >
  172. {t("Assign 2/F")}
  173. </Button>
  174. <Button
  175. variant="contained"
  176. color="secondary"
  177. onClick={() => handleAssignByStore("4/F")}
  178. disabled={isAssigning}
  179. sx={{ minWidth: 120 }}
  180. >
  181. {t("Assign 4/F")}
  182. </Button>
  183. </Stack>
  184. <Stack direction="row" spacing={2} sx={{ mt: 1 }}>
  185. <Button
  186. variant="outlined"
  187. color="primary"
  188. onClick={() => handleReleaseByStore("2/F")}
  189. disabled={isAssigning}
  190. sx={{ minWidth: 120 }}
  191. >
  192. {t("Release 2/F")}
  193. </Button>
  194. <Button
  195. variant="outlined"
  196. color="secondary"
  197. onClick={() => handleReleaseByStore("4/F")}
  198. disabled={isAssigning}
  199. sx={{ minWidth: 120 }}
  200. >
  201. {t("Release 4/F")}
  202. </Button>
  203. </Stack>
  204. </Box>
  205. )}
  206. <DoInfoCard />
  207. <DoLineTable />
  208. <Stack direction="row" justifyContent="flex-end" gap={1}>
  209. <Button
  210. variant="outlined"
  211. startIcon={<ArrowBackIcon />}
  212. onClick={handleBack}
  213. >
  214. {t("Back")}
  215. </Button>
  216. </Stack>
  217. </Stack>
  218. </FormProvider>
  219. </>
  220. }
  221. export default DoDetail;