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.
 
 

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