Untitled

 avatar
unknown
plain_text
5 months ago
10 kB
3
Indexable
import React, { useEffect, useState } from "react"
import { useMutation, useQuery } from "@apollo/client"
import {
  Autocomplete,
  Box,
  Button,
  Grid2,
  Modal,
  TextField,
} from "@mui/material"

import { gql } from "../../__generated__"
import {
  AddCategoryOrTopicInput,
  CategoryTypesEnum,
  UpdateCategoryOrTopicInput,
} from "../../__generated__/graphql"
import { useAlert } from "../atoms/alertContext"
import { Category } from "../pages/master_data_request/categories_page"

// Interfaces to avoid type "any"
interface CategoryModalProps {
  open: boolean
  onClose: () => void
  modalData?: Category | null
}

interface Field {
  categoryName: string
  countryId: number[]
  groupId: number | null
  countryName: string[]
}

/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
const CountryDetails = gql(/* GraphQL */ `
  fragment CountryDetails on Country {
    id
    name
    frmlName
    iso2CntryCd
    iso3CntryCd
    isoNum
  }
`)

const regionCountry_Query = gql(/* GraphQL */ `
  query regionCountry_Query {
    whoami {
      id
      userCountries {
        country {
          ...CountryDetails
        }
      }
      regionUsers {
        region {
          regionCountries {
            country {
              ...CountryDetails
            }
          }
        }
      }
    }
  }
`)

// Mutation for Save
const add_Category_Mutation = gql(/* GraphQL */ `
  mutation add_Category_Mutation($input: [AddCategoryOrTopicInput!]!) {
    addCategoryOrTopic(input: $input) {
      success
      message
    }
  }
`)

// Mutation for Update
const update_Category_Mutation = gql(/* GraphQL */ `
  mutation update_Category_Mutation($input: [UpdateCategoryOrTopicInput!]!) {
    updateCategoryOrTopic(input: $input) {
      success
      message
    }
  }
`)

const CategoryModal: React.FC<CategoryModalProps> = ({
  open,
  onClose,
  modalData,
}) => {
  const [searchTerm, setSearchTerm] = useState("")
  const [fields, setFields] = useState<Field[]>([
    { categoryName: "", countryId: [], groupId: null, countryName: [] },
  ])
  const [selectedCategory, setSelectedCategory] = useState<string>("")
  const { showAlert } = useAlert()

  const { data } = useQuery(regionCountry_Query)

  const [saveCategory] = useMutation(add_Category_Mutation)
  const [updateCategory] = useMutation(update_Category_Mutation)

  // Set the modal data when it changes
  useEffect(() => {
    if (modalData && modalData.groupCountries) {
      setSelectedCategory(modalData.name)
      const modalCountriesId = Number(
        modalData.groupCountries
          .map((country) => country.country.id)
          .join(", "),
      )
      const modalCountriesName = modalData.groupCountries
        .map((country) => country.country.name)
        .join(", ")
      setFields([
        {
          categoryName: modalData.name,
          countryId: [modalCountriesId],
          groupId: parseInt(modalData.id),
          countryName: [modalCountriesName],
        },
      ])
    }
  }, [modalData])

  // Filtered country names based on the search term
  const regionCountriesName =
    data?.whoami?.userCountries
      .flatMap((area: any) => area.country)
      .filter((row: any) =>
        row.name.toLowerCase().includes(searchTerm.toLowerCase()),
      ) ||
    // .map((row: any) => ({ id: row.id, name: row.name }))
    []

  // Function to handle Reset button
  const handleReset = () => {
    if (modalData) {
      setSelectedCategory(modalData.name)
      setFields([
        {
          categoryName: modalData.name,
          countryId: modalData.groupCountries.map(
            (country) => country.country.id,
          ),
          groupId: parseInt(modalData.id),
          countryName: modalData.groupCountries.map(
            (country) => country.country.name,
          ),
        },
      ]) // Reset fields to initial state
      setSearchTerm(searchTerm) // Clear search term
    } else {
      setSelectedCategory("")
      setFields([
        { categoryName: "", countryId: [], groupId: null, countryName: [] },
      ]) // Reset fields to initial state
      setSearchTerm("") // Clear search term
    }
  }

  // Function to handle cancel action
  const handleCancel = () => {
    if (modalData) {
      setSelectedCategory(modalData.name)
      setFields([
        {
          categoryName: modalData.name,
          countryId: modalData.groupCountries.map(
            (country) => country.country.id,
          ),
          groupId: parseInt(modalData.id),
          countryName: modalData.groupCountries.map(
            (country) => country.country.name,
          ),
        },
      ])
      setSearchTerm("") // Clear search term
      onClose() // Close the modal
    } else {
      setSelectedCategory("")
      setFields([
        { categoryName: "", countryId: [], groupId: null, countryName: [] },
      ])
      setSearchTerm("") // Clear search term
      onClose() // Close the modal
    }
  }

  // Handle category name change
  const handleCategoryChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setSelectedCategory(e.target.value)
  }

  // Function to handle form submission
  const handleAddSubmit = async () => {
    try {
      if (modalData) {
        const input: UpdateCategoryOrTopicInput[] = []
        // Construct the input for the mutation
        for (const field of fields) {
          if (field.groupId) {
            // this tells the TypeScript type system that groupId is not null
            input.push({
              name: selectedCategory,
              countryId: field.countryId,
              groupId: field.groupId,
              type: CategoryTypesEnum.Category,
            })
          }
        }
        const response = await updateCategory({
          variables: { input },
        })

        if (response?.data!.updateCategoryOrTopic.success) {
          // Handle success response
          showAlert("Category updated successfully!", "success")
          handleReset() // Reset the form after successful submission
          onClose()
        } else {
          // Handle error response
          showAlert(response?.data!.updateCategoryOrTopic.message, "error")
        }
      } else {
        const input: AddCategoryOrTopicInput[] = []
        // Construct the input for the mutation
        for (const field of fields) {
          input.push({
            name: selectedCategory,
            countryId: field.countryId,
            type: CategoryTypesEnum.Category,
          })
        }
        const response = await saveCategory({
          variables: { input },
        })

        if (response?.data!.addCategoryOrTopic.success) {
          // Handle success response
          showAlert("Category added successfully!", "success")
          handleReset() // Reset the form after successful submission
          onClose()
        } else {
          // Handle error response
          showAlert(response?.data!.addCategoryOrTopic.message, "error")
        }
      }
    } catch {
      // Handle any errors that occur during the mutation
      showAlert("Error in saving the category. Please try again.", "error")
    }
  }

  return (
    <Modal open={open} onClose={onClose}>
      <Box
        sx={{
          position: "absolute",
          top: "50%",
          left: "50%",
          transform: "translate(-50%, -50%)",
          width: {
            xs: "90%",
            sm: 620,
            md: 860,
          },
          height: "auto",
          maxHeight: "95vh",
          bgcolor: "background.paper",
          boxShadow: 24,
          p: 4,
          borderRadius: 2,
          overflowY: "auto",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        {modalData ? <h2>Edit Category</h2> : <h2>Add Category</h2>}
        <Grid2 container spacing={2}>
          <Grid2 size={6}>
            <Box display="flex" alignItems="center">
              <TextField
                label="Category"
                fullWidth
                value={selectedCategory} // Bind to selectedCategory state
                onChange={handleCategoryChange} // Handle the change event
                variant="outlined"
                sx={{ mb: 2 }}
              />
            </Box>
          </Grid2>
          <Grid2 size={6}>
            <Box display="flex" alignItems="center">
              {fields.map((field, index) => (
                <div key={index} style={{ width: "100%" }}>
                  <Autocomplete
                    fullWidth
                    multiple
                    options={regionCountriesName}
                    getOptionLabel={(option) => option.name}
                    value={regionCountriesName.filter((option) =>
                      field.countryId.includes(option.id),
                    )}
                    onChange={(event, newValue) => {
                      const updatedFields = [...fields]
                      updatedFields[index].countryName = newValue.map(
                        (country) => country.name,
                      )
                      updatedFields[index].countryId = newValue.map(
                        (country) => country.id,
                      )
                      setFields(updatedFields)
                    }}
                    renderInput={(params) => (
                      <TextField
                        {...params}
                        variant="outlined"
                        label="Countries"
                        placeholder="Select countries"
                      />
                    )}
                  />
                </div>
              ))}
            </Box>
          </Grid2>
        </Grid2>
        <Box
          sx={{ display: "flex", justifyContent: "flex-end", mt: 2, gap: 1 }}
        >
          <Button variant="contained" onClick={handleAddSubmit}>
            Submit
          </Button>
          <Button variant="contained" onClick={handleReset}>
            Reset
          </Button>
          <Button variant="contained" onClick={handleCancel}>
            Cancel
          </Button>
        </Box>
      </Box>
    </Modal>
  )
}

export default CategoryModal
Editor is loading...
Leave a Comment