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.
 
 

162 lines
4.4 KiB

  1. "use client";
  2. import { useCallback, useEffect, useState } from "react";
  3. import { useRouter } from "next/navigation";
  4. import { useTranslation } from "react-i18next";
  5. import { PrinterResult } from "@/app/api/settings/printer";
  6. import { editPrinter, PrinterInputs } from "@/app/api/settings/printer/actions";
  7. import {
  8. Box,
  9. Button,
  10. FormControl,
  11. Grid,
  12. InputLabel,
  13. MenuItem,
  14. Select,
  15. SelectChangeEvent,
  16. Stack,
  17. TextField,
  18. Typography,
  19. } from "@mui/material";
  20. import { Check, ArrowBack } from "@mui/icons-material";
  21. import { successDialog } from "../Swal/CustomAlerts";
  22. type Props = {
  23. printer: PrinterResult;
  24. };
  25. const EditPrinter: React.FC<Props> = ({ printer }) => {
  26. const { t } = useTranslation("common");
  27. const router = useRouter();
  28. const [isSubmitting, setIsSubmitting] = useState(false);
  29. const [formData, setFormData] = useState<PrinterInputs>({
  30. name: printer.name || "",
  31. ip: printer.ip || "",
  32. port: printer.port || undefined,
  33. type: printer.type || "",
  34. dpi: printer.dpi || undefined,
  35. });
  36. useEffect(() => {
  37. if (formData.type !== "Label") {
  38. setFormData((prev) => ({ ...prev, dpi: undefined }));
  39. }
  40. }, [formData.type]);
  41. const handleChange = useCallback((field: keyof PrinterInputs) => {
  42. return (e: React.ChangeEvent<HTMLInputElement>) => {
  43. const value = e.target.value;
  44. setFormData((prev) => ({
  45. ...prev,
  46. [field]: field === "port" || field === "dpi"
  47. ? (value === "" ? undefined : parseInt(value, 10))
  48. : value,
  49. }));
  50. };
  51. }, []);
  52. const handleTypeChange = useCallback((e: SelectChangeEvent) => {
  53. const value = e.target.value;
  54. setFormData((prev) => ({
  55. ...prev,
  56. type: value,
  57. }));
  58. }, []);
  59. const handleSubmit = useCallback(async () => {
  60. setIsSubmitting(true);
  61. try {
  62. await editPrinter(printer.id, formData);
  63. successDialog(t("Save") || "儲存成功", t);
  64. router.push("/settings/printer");
  65. router.refresh();
  66. } catch (error) {
  67. console.error("Failed to update printer:", error);
  68. const errorMessage = error instanceof Error ? error.message : (t("Error saving data") || "儲存失敗");
  69. alert(errorMessage);
  70. } finally {
  71. setIsSubmitting(false);
  72. }
  73. }, [formData, printer.id, router, t]);
  74. return (
  75. <Box sx={{ mt: 3 }}>
  76. <Grid container spacing={3}>
  77. <Grid item xs={12} md={6}>
  78. <TextField
  79. fullWidth
  80. label={t("Name")}
  81. value={formData.name}
  82. onChange={handleChange("name")}
  83. variant="outlined"
  84. />
  85. </Grid>
  86. <Grid item xs={12} md={6}>
  87. <TextField
  88. fullWidth
  89. label="IP"
  90. value={formData.ip}
  91. onChange={handleChange("ip")}
  92. variant="outlined"
  93. />
  94. </Grid>
  95. <Grid item xs={12} md={6}>
  96. <TextField
  97. fullWidth
  98. label="Port"
  99. type="number"
  100. value={formData.port || ""}
  101. onChange={handleChange("port")}
  102. variant="outlined"
  103. />
  104. </Grid>
  105. <Grid item xs={12} md={6}>
  106. <FormControl fullWidth>
  107. <InputLabel>{t("Type")}</InputLabel>
  108. <Select
  109. label={t("Type")}
  110. value={formData.type ?? ""}
  111. onChange={handleTypeChange}
  112. >
  113. <MenuItem value={"A4"}>A4</MenuItem>
  114. <MenuItem value={"Label"}>Label</MenuItem>
  115. </Select>
  116. </FormControl>
  117. </Grid>
  118. <Grid item xs={12} md={6}>
  119. <TextField
  120. fullWidth
  121. label="DPI"
  122. type="number"
  123. value={formData.dpi || ""}
  124. onChange={handleChange("dpi")}
  125. variant="outlined"
  126. disabled={formData.type !== "Label"}
  127. />
  128. </Grid>
  129. <Grid item xs={12}>
  130. <Stack direction="row" spacing={2}>
  131. <Button
  132. variant="outlined"
  133. startIcon={<ArrowBack />}
  134. onClick={() => router.push("/settings/printer")}
  135. >
  136. {t("Back")}
  137. </Button>
  138. <Button
  139. variant="contained"
  140. startIcon={<Check />}
  141. onClick={handleSubmit}
  142. disabled={isSubmitting}
  143. >
  144. {t("Save")}
  145. </Button>
  146. </Stack>
  147. </Grid>
  148. </Grid>
  149. </Box>
  150. );
  151. };
  152. export default EditPrinter;