FPSMS-frontend
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 

161 linhas
4.8 KiB

  1. "use client";
  2. import React, { useState, useEffect } from "react";
  3. import { useTranslation } from "react-i18next";
  4. import { BomWeightingScoreResult } from "@/app/api/settings/bomWeighting";
  5. import { fetchBomWeightingScoresClient } from "@/app/api/settings/bomWeighting/client";
  6. import type { BomScoreResult } from "@/app/api/bom";
  7. import { fetchBomScoresClient } from "@/app/api/bom/client";
  8. import BomWeightingScoreTable from "@/components/BomWeightingScoreTable";
  9. import BomScoreTable from "@/components/BomScoreTable";
  10. import Tabs from "@mui/material/Tabs";
  11. import Tab from "@mui/material/Tab";
  12. import Box from "@mui/material/Box";
  13. import Paper from "@mui/material/Paper";
  14. interface Props {
  15. bomWeightingScores: BomWeightingScoreResult[];
  16. }
  17. const BomWeightingTabs: React.FC<Props> = ({ bomWeightingScores: initialBomWeightingScores }) => {
  18. const { t } = useTranslation("common");
  19. const [tab, setTab] = useState(0);
  20. const [bomWeightingScores, setBomWeightingScores] = useState<BomWeightingScoreResult[]>(initialBomWeightingScores);
  21. const [bomScores, setBomScores] = useState<BomScoreResult[] | null>(null);
  22. const [loadingScores, setLoadingScores] = useState(false);
  23. const [loadError, setLoadError] = useState<string | null>(null);
  24. const loadBomScores = React.useCallback(async () => {
  25. try {
  26. setLoadingScores(true);
  27. setLoadError(null);
  28. console.log("Fetching BOM scores from /bom/scores...");
  29. const data = await fetchBomScoresClient();
  30. console.log("BOM scores received:", data);
  31. setBomScores(data || []);
  32. } catch (err: any) {
  33. console.error("Failed to load BOM scores:", err);
  34. const errorMsg =
  35. err?.response?.data?.message || err?.message || t("Update Failed") || "Load failed";
  36. setLoadError(errorMsg);
  37. setBomScores([]);
  38. } finally {
  39. setLoadingScores(false);
  40. }
  41. }, [t]);
  42. const loadBomWeightingScores = React.useCallback(async () => {
  43. try {
  44. console.log("Fetching BOM weighting scores...");
  45. const data = await fetchBomWeightingScoresClient();
  46. console.log("BOM weighting scores received:", data);
  47. setBomWeightingScores(data || []);
  48. } catch (err: any) {
  49. console.error("Failed to load BOM weighting scores:", err);
  50. }
  51. }, []);
  52. const handleWeightingUpdated = React.useCallback(async () => {
  53. // Refresh both weighting scores and BOM scores
  54. await Promise.all([
  55. loadBomWeightingScores(),
  56. loadBomScores()
  57. ]);
  58. }, [loadBomWeightingScores, loadBomScores]);
  59. // Sync initial prop values
  60. useEffect(() => {
  61. setBomWeightingScores(initialBomWeightingScores);
  62. }, [initialBomWeightingScores]);
  63. useEffect(() => {
  64. if (tab !== 1) return;
  65. void loadBomScores();
  66. }, [tab, loadBomScores]);
  67. return (
  68. <>
  69. <Paper
  70. variant="outlined"
  71. sx={{
  72. mb: 2,
  73. borderBottomLeftRadius: 0,
  74. borderBottomRightRadius: 0,
  75. }}
  76. >
  77. <Tabs
  78. value={tab}
  79. onChange={(_, v) => setTab(v)}
  80. indicatorColor="primary"
  81. textColor="primary"
  82. sx={{
  83. pl: 2,
  84. minHeight: 44,
  85. }}
  86. >
  87. <Tab
  88. label={t("Material Weighting")}
  89. value={0}
  90. sx={{ textTransform: "none", fontSize: 16, px: 3, minHeight: 44 }}
  91. />
  92. <Tab
  93. label={t("Material Score")}
  94. value={1}
  95. sx={{ textTransform: "none", fontSize: 16, px: 3, minHeight: 44 }}
  96. />
  97. </Tabs>
  98. </Paper>
  99. <Box>
  100. {tab === 0 && (
  101. <BomWeightingScoreTable
  102. bomWeightingScores={bomWeightingScores}
  103. onWeightingUpdated={handleWeightingUpdated}
  104. />
  105. )}
  106. {tab === 1 && (
  107. loadingScores ? (
  108. <Paper
  109. variant="outlined"
  110. sx={{
  111. p: 3,
  112. borderTopLeftRadius: 0,
  113. borderTopRightRadius: 0,
  114. }}
  115. >
  116. <div className="text-slate-700">{t("Loading")}</div>
  117. </Paper>
  118. ) : loadError ? (
  119. <Paper
  120. variant="outlined"
  121. sx={{
  122. p: 3,
  123. borderTopLeftRadius: 0,
  124. borderTopRightRadius: 0,
  125. }}
  126. >
  127. <div className="text-slate-700 text-red-600">{loadError}</div>
  128. </Paper>
  129. ) : bomScores && bomScores.length > 0 ? (
  130. <BomScoreTable boms={bomScores} />
  131. ) : (
  132. <Paper
  133. variant="outlined"
  134. sx={{
  135. p: 3,
  136. borderTopLeftRadius: 0,
  137. borderTopRightRadius: 0,
  138. }}
  139. >
  140. <div className="text-slate-700">{t("No data available")}</div>
  141. </Paper>
  142. )
  143. )}
  144. </Box>
  145. </>
  146. );
  147. };
  148. export default BomWeightingTabs;