Untitled
unknown
plain_text
8 months ago
10 kB
4
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