Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 

320 рядки
12 KiB

  1. import * as React from "react";
  2. import Grid from "@mui/material/Grid";
  3. import { useState, useEffect, useMemo } from "react";
  4. import Paper from "@mui/material/Paper";
  5. import { TFunction } from "i18next";
  6. import { useTranslation } from "react-i18next";
  7. import { Card, CardHeader } from "@mui/material";
  8. import CustomSearchForm from "../CustomSearchForm/CustomSearchForm";
  9. import CustomDatagrid from "../CustomDatagrid/CustomDatagrid";
  10. import ReactApexChart from "react-apexcharts";
  11. import { ApexOptions } from "apexcharts";
  12. import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid";
  13. import ReportProblemIcon from "@mui/icons-material/ReportProblem";
  14. import dynamic from "next/dynamic";
  15. import "../../app/global.css";
  16. import { AnyARecord, AnyCnameRecord } from "dns";
  17. import SearchBox, { Criterion } from "../SearchBox";
  18. import ProgressByClientSearch from "@/components/ProgressByClientSearch";
  19. import { Suspense } from "react";
  20. import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked';
  21. import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked';
  22. import { useRouter } from "next/navigation";
  23. interface Props {
  24. Title: string;
  25. TeamId: number;
  26. TotalActiveProjectNumber: number;
  27. TotalFees: number;
  28. TotalBudget: number;
  29. TotalCumulative: number;
  30. TotalInvoicedAmount: number;
  31. TotalUnInvoicedAmount: number;
  32. TotalReceivedAmount: number;
  33. CashFlowStatus: string;
  34. CostPerformanceIndex: number;
  35. ClickedIndex: number;
  36. ProjectedCPI: number;
  37. ProjectedCashFlowStatus: string;
  38. Index: number;
  39. }
  40. const dataBaseStyle:any = { color: "#6b87cf", textAlign: "right" }
  41. const dataNegativeStyle:any = { color: "#f896aa", textAlign: "right" }
  42. const dataPositiveStyle:any = { color: "#71d19e", textAlign: "right" }
  43. const ProjectFinancialCard: React.FC<Props> = ({
  44. Title,
  45. TeamId,
  46. TotalActiveProjectNumber,
  47. TotalFees,
  48. TotalBudget,
  49. TotalCumulative,
  50. TotalInvoicedAmount,
  51. TotalUnInvoicedAmount,
  52. TotalReceivedAmount,
  53. CashFlowStatus,
  54. CostPerformanceIndex,
  55. ClickedIndex,
  56. ProjectedCPI,
  57. ProjectedCashFlowStatus,
  58. Index,
  59. }) => {
  60. const router = useRouter();
  61. const [SearchCriteria, setSearchCriteria] = React.useState({});
  62. const { t } = useTranslation("dashboard");
  63. const handleCheckProjectStatusClick = (TeamId:number) => {
  64. router.push(`/dashboard/ProjectStatusByTeam?teamLeadId=${TeamId}`);
  65. };
  66. const borderColor =
  67. CashFlowStatus === "Negative"
  68. ? "border-red-300 border-solid"
  69. : "border-green-200 border-solid";
  70. const selectedBackgroundColor =
  71. ClickedIndex === Index ? "rgb(235 235 235)" : "rgb(255 255 255)";
  72. return (
  73. <Card
  74. style={{
  75. maxWidth: "25%",
  76. minWidth: "280px",
  77. boxShadow:
  78. "0 0px 10px 0 rgba(0, 0, 0, 0.08), 0 0px 10px 0 rgba(0, 0, 0, 0.08)",
  79. backgroundColor: selectedBackgroundColor,
  80. }}
  81. className={`${borderColor}`}
  82. >
  83. <div
  84. className="text-xl mt-2 font-medium inline-block"
  85. style={{ width: "100%", textAlign: "center", color: "#898d8d" }}
  86. >
  87. {ClickedIndex === Index ?
  88. <div className="w-full" style={{ overflow: 'hidden' }}>
  89. <div className=" float-right mt-1 mr-5 text-gray-500"><RadioButtonCheckedIcon /></div></div>
  90. :
  91. <div className="w-full" style={{ overflow: 'hidden' }}>
  92. <div className=" float-right mt-1 mr-5 text-gray-400"><RadioButtonUncheckedIcon /></div></div>
  93. }
  94. {Title !== t("All Team") ?
  95. <div className="mb-2">{Title}</div>
  96. :
  97. <div className="mb-9">{Title}</div>
  98. }
  99. </div>
  100. {Title !== t("All Team") ?
  101. <>
  102. <div onClick={(r) => handleCheckProjectStatusClick(TeamId)} className="bg-lime-100 mb-2 border-b-2 pt-1 pb-1 hover:bg-lime-200" style={{ width: "100%", textAlign: "center", color: "#898d8d" }}>{t("Check Project Status")}</div>
  103. </>
  104. :
  105. <><hr /></>
  106. }
  107. <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}>
  108. {"(a) " + t("Total Active Project")}
  109. </div>
  110. <div className="text-lg font-medium mx-5" style={dataBaseStyle}>
  111. {TotalActiveProjectNumber.toLocaleString()}
  112. </div>
  113. <hr />
  114. <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}>
  115. {"(b) " + t("Total Fees")}
  116. </div>
  117. <div className="text-lg font-medium mx-5" style={dataBaseStyle}>
  118. {TotalFees.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
  119. </div>
  120. <hr />
  121. <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}>
  122. {"(c) " + t("Total Budget")}
  123. </div>
  124. <div className="text-lg font-medium mx-5" style={dataBaseStyle}>
  125. {TotalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
  126. </div>
  127. <div style={{ overflow: 'hidden' }}>
  128. <div className="text-sm font-medium ml-5 border-solid w-fit rounded-md mt-2 float-right mr-2" style={{ color: "#888d8f" }}>
  129. <div className="ml-2 mr-2 ">{"(c) = (b) * 80%"}</div>
  130. </div>
  131. </div>
  132. <hr />
  133. <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}>
  134. {"(d) " + t("Total Cumulative Expenditure")}
  135. </div>
  136. <div className="text-lg font-medium mx-5" style={dataBaseStyle}>
  137. {TotalCumulative.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
  138. </div>
  139. <hr />
  140. <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}>
  141. {"(e) " + t("Total Invoiced Amount")}
  142. </div>
  143. <div className="text-lg font-medium mx-5" style={dataBaseStyle}>
  144. {TotalInvoicedAmount.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
  145. </div>
  146. <hr />
  147. <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}>
  148. {"(f) " + t("Total Un-Invoiced Amount")}
  149. </div>
  150. <div className="text-lg font-medium mx-5" style={dataBaseStyle}>
  151. {TotalUnInvoicedAmount.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
  152. </div>
  153. <div style={{ overflow: 'hidden' }}>
  154. <div className="text-sm font-medium ml-5 border-solid w-fit rounded-md mt-2 float-right mr-2" style={{ color: "#888d8f" }}>
  155. <div className="ml-2 mr-2">{"(f) =(b) - (e)"}</div>
  156. </div>
  157. </div>
  158. <hr />
  159. <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}>
  160. {"(g) " + t("Total Received Amount")}
  161. </div>
  162. <div className="text-lg font-medium mx-5" style={dataBaseStyle}>
  163. {TotalReceivedAmount.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
  164. </div>
  165. <hr />
  166. <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}>
  167. {"(h) " + t("Cash Flow Status")}
  168. </div>
  169. {CashFlowStatus === "Negative" && (
  170. <>
  171. <div
  172. className="text-lg font-medium mx-5"
  173. style={dataNegativeStyle}
  174. >
  175. {t(CashFlowStatus)}
  176. </div>
  177. <div style={{ overflow: 'hidden' }}>
  178. <div className="text-sm font-medium ml-5 border-solid w-fit rounded-md mt-2 float-right mr-2" style={{ color: "#888d8f" }}>
  179. <div className="ml-2 mr-2 ">{t("Positive") + ": (e) > or = (d)"}</div>
  180. <div className="ml-2 mr-2 ">{t("Negative") + ": (e) < (d)"}</div>
  181. </div>
  182. </div>
  183. <hr />
  184. </>
  185. )}
  186. {CashFlowStatus === "Positive" && (
  187. <>
  188. <div
  189. className="text-lg font-medium mx-5"
  190. style={dataPositiveStyle}
  191. >
  192. {t(CashFlowStatus)}
  193. </div>
  194. <div style={{ overflow: 'hidden' }}>
  195. <div className="text-sm font-medium ml-5 border-solid w-fit rounded-md mt-2 float-right mr-2" style={{ color: "#888d8f" }}>
  196. <div className="ml-2 mr-2 ">{t("Positive") + ": (e) > or = (d)"}</div>
  197. <div className="ml-2 mr-2 ">{t("Negative") + ": (e) < (d)"}</div>
  198. </div>
  199. </div>
  200. <hr />
  201. </>
  202. )}
  203. <div
  204. className="text-sm mt-2 font-medium mx-5"
  205. style={{ color: "#898d8d" }}
  206. >
  207. {"(i) " + t("Cost Performance Index") + " (CPI)"}
  208. </div>
  209. { Number(CostPerformanceIndex) < 1 && (
  210. <>
  211. <div
  212. className="text-lg font-medium mx-5 mb-2"
  213. style={dataNegativeStyle}
  214. >
  215. {CostPerformanceIndex}
  216. </div>
  217. <div style={{ overflow: 'hidden' }}>
  218. <div className="text-sm font-medium ml-5 border-solid w-fit rounded-md mt-2 float-right mr-2" style={{ color: "#888d8f" }}>
  219. <div className="ml-2 mr-2 ">{"(i) = (e) / (d)"}</div>
  220. </div>
  221. </div>
  222. <hr />
  223. </>
  224. )}
  225. {Number(CostPerformanceIndex) >= 1 && (
  226. <>
  227. <div
  228. className="text-lg font-medium mx-5 mb-2"
  229. style={dataPositiveStyle}
  230. >
  231. {CostPerformanceIndex}
  232. </div>
  233. <div style={{ overflow: 'hidden' }}>
  234. <div className="text-sm font-medium ml-5 border-solid w-fit rounded-md mt-2 float-right mr-2" style={{ color: "#888d8f" }}>
  235. <div className="ml-2 mr-2 ">{"(i) =(e) / (d)"}</div>
  236. </div>
  237. </div>
  238. <hr />
  239. </>
  240. )}
  241. <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}>
  242. {"(j) " + t("Projected Cash Flow Status")}
  243. </div>
  244. {ProjectedCashFlowStatus === "Negative" && (
  245. <>
  246. <div
  247. className="text-lg font-medium mx-5"
  248. style={dataNegativeStyle}
  249. >
  250. {t(ProjectedCashFlowStatus)}
  251. </div>
  252. <div style={{ overflow: 'hidden' }}>
  253. <div className="text-sm font-medium mr-2 border-solid w-fit rounded-md mt-2 float-right" style={{ color: "#888d8f" }}>
  254. <div className="ml-2 mr-2 ">{t("Positive") + ": (b) > or = (d)"}</div>
  255. <div className="ml-2 mr-2 ">{t("Negative") + ": (b) < (d)"}</div>
  256. </div>
  257. </div>
  258. <hr />
  259. </>
  260. )}
  261. {ProjectedCashFlowStatus === "Positive" && (
  262. <>
  263. <div
  264. className="text-lg font-medium mx-5"
  265. style={dataPositiveStyle}
  266. >
  267. {t(ProjectedCashFlowStatus)}
  268. </div>
  269. <div style={{ overflow: 'hidden' }}>
  270. <div className="text-sm font-medium mr-2 border-solid w-fit rounded-md mt-2 float-right" style={{ color: "#888d8f" }}>
  271. <div className="ml-2 mr-2 ">{t("Positive") + ": (b) > or = (d)"}</div>
  272. <div className="ml-2 mr-2 ">{t("Negative") + ": (b) < (d)"}</div>
  273. </div>
  274. </div>
  275. <hr />
  276. </>
  277. )}
  278. <div
  279. className="text-sm mt-2 font-medium ml-5"
  280. style={{ color: "#898d8d" }}
  281. >
  282. {"(k) " + t("Projected Cost Performance Index") + " (CPI)"}
  283. </div>
  284. {Number(ProjectedCPI) < 1 && (
  285. <>
  286. <div
  287. className="text-lg font-medium mx-5 mb-2"
  288. style={dataNegativeStyle}
  289. >
  290. {ProjectedCPI}
  291. </div>
  292. <div className="text-sm font-medium ml-5 border-solid w-fit rounded-md mb-2 mr-2 float-right" style={{ color: "#888d8f" }}>
  293. <div className="ml-2 mr-2 ">{"(k) = (b) / (d)"}</div>
  294. </div>
  295. </>
  296. )}
  297. {Number(ProjectedCPI) >= 1 && (
  298. <>
  299. <div
  300. className="text-lg font-medium mx-5 mb-2"
  301. style={dataPositiveStyle}
  302. >
  303. {ProjectedCPI}
  304. </div>
  305. <div className="text-sm font-medium ml-5 border-solid w-fit rounded-md mb-2 mr-2 float-right" style={{ color: "#888d8f" }}>
  306. <div className="ml-2 mr-2 ">{"(k) = (b) / (d)"}</div>
  307. </div>
  308. </>
  309. )}
  310. </Card>
  311. );
  312. };
  313. export default ProjectFinancialCard;