|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- import { BomCombo } from "@/app/api/bom";
- import { JoDetail } from "@/app/api/jo";
- import { SaveJo, manualCreateJo } from "@/app/api/jo/actions";
- import { OUTPUT_DATE_FORMAT, OUTPUT_TIME_FORMAT, dateStringToDayjs, dayjsToDateString, dayjsToInputDateString, dayjsToInputDateTimeString } from "@/app/utils/formatUtil";
- import { Check } from "@mui/icons-material";
- import { Autocomplete, Box, Button, Card, Grid, Modal, Stack, TextField, Typography } from "@mui/material";
- import { DatePicker, DateTimePicker, LocalizationProvider } from "@mui/x-date-pickers";
- import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
- import dayjs, { Dayjs } from "dayjs";
- import { isFinite } from "lodash";
- import React, { SetStateAction, SyntheticEvent, useCallback, useEffect } from "react";
- import { Controller, FormProvider, SubmitErrorHandler, SubmitHandler, useForm, useFormContext } from "react-hook-form";
- import { useTranslation } from "react-i18next";
- import { msg } from "../Swal/CustomAlerts";
-
- interface Props {
- open: boolean;
- bomCombo: BomCombo[];
- onClose: () => void;
- onSearch: () => void;
- }
-
- const JoCreateFormModal: React.FC<Props> = ({
- open,
- bomCombo,
- onClose,
- onSearch,
- }) => {
- const { t } = useTranslation("jo");
- const formProps = useForm<SaveJo>({
- mode: "onChange",
- });
- const { reset, trigger, watch, control, register, formState: { errors } } = formProps
-
- const onModalClose = useCallback(() => {
- reset()
- onClose()
- }, [])
-
- const handleAutoCompleteChange = useCallback((event: SyntheticEvent<Element, Event>, value: BomCombo, onChange: (...event: any[]) => void) => {
- onChange(value.id)
- }, [])
-
- const handleDateTimePickerChange = useCallback((value: Dayjs | null, onChange: (...event: any[]) => void) => {
- if (value != null) {
- const updatedValue = dayjsToInputDateTimeString(value)
- onChange(updatedValue)
- } else {
- onChange(value)
- }
- }, [])
-
- const onSubmit = useCallback<SubmitHandler<SaveJo>>(async (data) => {
- data.type = "manual"
- const response = await manualCreateJo(data)
- if (response) {
- onSearch();
- msg(t("update success"));
- onModalClose();
- }
- }, [])
-
- const onSubmitError = useCallback<SubmitErrorHandler<SaveJo>>((error) => {
- console.log(error)
- }, [])
-
- const planStart = watch("planStart")
- const planEnd = watch("planEnd")
- useEffect(() => {
- trigger(['planStart', 'planEnd']);
- }, [trigger, planStart, planEnd])
-
- return (
- <Modal
- open={open}
- onClose={onModalClose}
- >
- <Card
- style={{
- flex: 10,
- marginBottom: "20px",
- width: "90%",
- // height: "80%",
- position: "fixed",
- top: "50%",
- left: "50%",
- transform: "translate(-50%, -50%)",
- }}
- >
- <Box
- sx={{
- display: "flex",
- "flex-direction": "column",
- padding: "20px",
- height: "100%", //'30rem',
- width: "100%",
- "& .actions": {
- color: "text.secondary",
- },
- "& .header": {
- // border: 1,
- // 'border-width': '1px',
- // 'border-color': 'grey',
- },
- "& .textPrimary": {
- color: "text.primary",
- },
- }}
- >
- <FormProvider {...formProps}>
- <Stack
- // spacing={2}
- component="form"
- onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
- >
- <LocalizationProvider
- dateAdapter={AdapterDayjs}
- // TODO: Should maybe use a custom adapterLocale here to support YYYY-MM-DD
- adapterLocale="zh-hk"
- >
- <Grid container spacing={2}>
- <Grid item xs={12} sm={12} md={12}>
- <Typography variant="h6">{t("Create Job Order")}</Typography>
- </Grid>
- <Grid item xs={12} sm={12} md={6}>
- <Controller
- control={control}
- name="bomId"
- rules={{
- required: "Bom required!",
- validate: (value) => isFinite(value)
- }}
- render={({ field, fieldState: { error } }) => (
- <Autocomplete
- disableClearable
- options={bomCombo}
- onChange={(event, value) => {
- handleAutoCompleteChange(event, value, field.onChange)
- }}
- onBlur={field.onBlur}
- renderInput={(params) => (
- <TextField
- {...params}
- error={Boolean(error)}
- variant="outlined"
- label={t("Bom")}
- />
- )}
- />
- )}
- />
- </Grid>
- <Grid item xs={12} sm={12} md={6}>
- <TextField
- {...register("reqQty", {
- required: "Req. Qty. required!",
- validate: (value) => value > 0
- })}
- label={t("Req. Qty")}
- fullWidth
- error={Boolean(errors.reqQty)}
- variant="outlined"
- type="number"
- />
- </Grid>
- {/* <Grid item xs={12} sm={12} md={6}>
- <Controller
- control={control}
- name="planStart"
- rules={{
- required: "Plan start required!",
- validate: {
- isValid: (value) => dateStringToDayjs(value).isValid(),
- isBeforePlanEnd: (value) => {
- const planStartDayjs = dateStringToDayjs(value)
- const planEndDayjs = dateStringToDayjs(planEnd)
- return planStartDayjs.isBefore(planEndDayjs) || planStartDayjs.isSame(planEndDayjs)
- }
- }
- }}
- render={({ field, fieldState: { error } }) => (
- <DateTimePicker
- label={t("Plan Start")}
- format={`${OUTPUT_DATE_FORMAT} ${OUTPUT_TIME_FORMAT}`}
- onChange={(newValue: Dayjs | null) => {
- handleDateTimePickerChange(newValue, field.onChange)
- }}
- slotProps={{ textField: { fullWidth: true, error: Boolean(error) } }}
- />
- )}
- />
- </Grid>
- <Grid item xs={12} sm={12} md={6}>
- <Controller
- control={control}
- name="planEnd"
- rules={{
- required: "Plan end required!",
- validate: {
- isValid: (value) => dateStringToDayjs(value).isValid(),
- isBeforePlanEnd: (value) => {
- const planStartDayjs = dateStringToDayjs(planStart)
- const planEndDayjs = dateStringToDayjs(value)
- return planEndDayjs.isAfter(planStartDayjs) || planEndDayjs.isSame(planStartDayjs)
- }
- }
- }}
- render={({ field, fieldState: { error } }) => (
- <DateTimePicker
- label={t("Plan End")}
- format={`${OUTPUT_DATE_FORMAT} ${OUTPUT_TIME_FORMAT}`}
- onChange={(newValue: Dayjs | null) => {
- handleDateTimePickerChange(newValue, field.onChange)
- }}
- slotProps={{ textField: { fullWidth: true } }}
- />
- )}
- />
- </Grid> */}
- </Grid>
- <Stack
- direction="row"
- justifyContent="flex-end"
- spacing={2}
- sx={{ mt: 2 }}
- >
- <Button
- name="submit"
- variant="contained"
- startIcon={<Check />}
- type="submit"
- >
- {t("Create")}
- </Button>
- </Stack>
- </LocalizationProvider>
- </Stack>
- </FormProvider>
- </Box>
- </Card>
- </Modal>
- )
- }
-
- export default JoCreateFormModal;
|