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.
 
 
 

85 lines
2.7 KiB

  1. import { Criterion } from "@/components/SearchBox/SearchBox";
  2. import { useTranslation } from "react-i18next";
  3. import { useState } from "react";
  4. import { Card, CardContent, Typography, Grid, TextField, Button, Stack } from "@mui/material";
  5. import { RestartAlt, Search } from "@mui/icons-material";
  6. import { Autocomplete } from "@mui/material";
  7. const VerticalSearchBox = ({ criteria, onSearch, onReset }: {
  8. criteria: Criterion<any>[];
  9. onSearch: (inputs: Record<string, any>) => void;
  10. onReset?: () => void;
  11. }) => {
  12. const { t } = useTranslation("common");
  13. const [inputs, setInputs] = useState<Record<string, any>>({});
  14. const handleInputChange = (paramName: string, value: any) => {
  15. setInputs(prev => ({ ...prev, [paramName]: value }));
  16. };
  17. const handleSearch = () => {
  18. onSearch(inputs);
  19. };
  20. const handleReset = () => {
  21. setInputs({});
  22. onReset?.();
  23. };
  24. return (
  25. <Card>
  26. <CardContent sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
  27. <Typography variant="overline">{t("Search Criteria")}</Typography>
  28. <Grid container spacing={2} columns={{ xs: 12, sm: 12 }}>
  29. {criteria.map((c) => {
  30. return (
  31. <Grid key={c.paramName} item xs={12}>
  32. {c.type === "text" && (
  33. <TextField
  34. label={t(c.label)}
  35. fullWidth
  36. onChange={(e) => handleInputChange(c.paramName, e.target.value)}
  37. value={inputs[c.paramName] || ""}
  38. />
  39. )}
  40. {c.type === "autocomplete" && (
  41. <Autocomplete
  42. options={c.options || []}
  43. getOptionLabel={(option: any) => option.label}
  44. onChange={(_, value: any) => handleInputChange(c.paramName, value?.value || "")}
  45. value={c.options?.find(option => option.value === inputs[c.paramName]) || null}
  46. renderInput={(params) => (
  47. <TextField
  48. {...params}
  49. label={t(c.label)}
  50. fullWidth
  51. />
  52. )}
  53. />
  54. )}
  55. </Grid>
  56. );
  57. })}
  58. </Grid>
  59. <Stack direction="row" spacing={2} sx={{ mt: 2 }}>
  60. <Button
  61. variant="text"
  62. startIcon={<RestartAlt />}
  63. onClick={handleReset}
  64. >
  65. {t("Reset")}
  66. </Button>
  67. <Button
  68. variant="outlined"
  69. startIcon={<Search />}
  70. onClick={handleSearch}
  71. >
  72. {t("Search")}
  73. </Button>
  74. </Stack>
  75. </CardContent>
  76. </Card>
  77. );
  78. };
  79. export default VerticalSearchBox;