index.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import React, { useState, useEffect, FC, useContext } from "react";
  2. import { generalTable } from "../../../api/tables";
  3. import { UserStateContext } from "../../../context/auth/AuthProvider";
  4. import { StateContext } from "../../../context/dashboard/Provider";
  5. import { Summary } from "../../../types/summary";
  6. import { TableHeader as Header, TdGroup } from "../shared";
  7. import * as classes from "../tables.module.css";
  8. import {
  9. redScale,
  10. orangeScale,
  11. blueScale,
  12. greenScale,
  13. yellowScale,
  14. grayScale,
  15. } from "../../../utils";
  16. const GeneralPerSector: FC = () => {
  17. const [data, setData] = useState<Summary[] | null>(null);
  18. const { userToken } = useContext(UserStateContext);
  19. const { from, to, sector } = useContext(StateContext);
  20. useEffect(() => {
  21. if (!userToken) return;
  22. generalTable(from, to, userToken).then(setData);
  23. }, [from, to, userToken]);
  24. // Formato de los summaries(filas)
  25. const rows = data?.map((x) => (
  26. <tr key={x.station.station_code}>
  27. <th
  28. className={classes.cell}
  29. style={{
  30. color: x.station.station_code === sector ? "#0d6efd" : undefined,
  31. }}
  32. >
  33. {x.station.title}
  34. </th>
  35. <TdGroup>
  36. <td
  37. style={{ backgroundColor: blueScale([0, 50])(x.lt10).css() as any }}
  38. >
  39. {x.lt10 ?? "-"}%
  40. </td>
  41. <td
  42. style={{ backgroundColor: orangeScale([0, 50])(x.gt33).css() as any }}
  43. >
  44. {x.gt30 ?? "-"}%
  45. </td>
  46. <td style={{ backgroundColor: redScale([0, 50])(x.gt33).css() as any }}>
  47. {x.gt33 ?? "-"}%
  48. </td>
  49. </TdGroup>
  50. <td
  51. className={classes.cell}
  52. style={{
  53. backgroundColor: greenScale([0, 3000])(x.grados_acumulados).css(),
  54. }}
  55. >
  56. {x.grados_acumulados ?? "-"}
  57. </td>
  58. <td className={classes.cell}>{x.grados_acumulados_promedio ?? "-"}</td>
  59. <td
  60. className={classes.cell}
  61. style={{
  62. backgroundColor: yellowScale([0, 50])(x.amplitud_termica).css(),
  63. }}
  64. >
  65. {x.amplitud_termica ?? "-"}
  66. </td>
  67. <td
  68. className={classes.cell}
  69. style={{
  70. backgroundColor: grayScale([0, 300])(x.precip_acumulada).css(),
  71. }}
  72. >
  73. {x.precip_acumulada ?? "-"}
  74. </td>
  75. <td className={classes.cell}>
  76. {x.data_percentage ? `${x.data_percentage}%` : "-"}
  77. </td>
  78. </tr>
  79. ));
  80. // Tabla
  81. return (
  82. <>
  83. <table className={`${classes.table}`}>
  84. <Header averageAccumulated />
  85. {/* Mostrar las filas si hay data */}
  86. <tbody>{data && rows}</tbody>
  87. </table>
  88. {/* Si no hay data, mostrar una spinner abajo de la tabla */}
  89. {!data && (
  90. <div className="d-flex py-3 justify-content-center">
  91. <div className="spinner-border" role="status">
  92. <span className="visually-hidden">Loading...</span>
  93. </div>
  94. </div>
  95. )}
  96. {data && data.length === 0 && (
  97. <div className="d-flex py-3 justify-content-center">
  98. <div className="spinner-border" role="status">
  99. <p>Sin datos</p>
  100. </div>
  101. </div>
  102. )}
  103. </>
  104. );
  105. };
  106. export default GeneralPerSector;