import { CustomerGroup } from "@medusajs/medusa"
import { difference } from "lodash"
import {
useAdminAddCustomersToCustomerGroup,
useAdminCustomerGroup,
useAdminCustomerGroupCustomers,
useAdminDeleteCustomerGroup,
useAdminRemoveCustomersFromCustomerGroup,
} from "medusa-react"
import { useEffect, useState } from "react"
import { useTranslation } from "react-i18next"
import { useNavigate, useParams } from "react-router-dom"
import BackButton from "../../../components/atoms/back-button"
import Spinner from "../../../components/atoms/spinner"
import WidgetContainer from "../../../components/extensions/widget-container"
import EditIcon from "../../../components/fundamentals/icons/edit-icon"
import PlusIcon from "../../../components/fundamentals/icons/plus-icon"
import TrashIcon from "../../../components/fundamentals/icons/trash-icon"
import { ActionType } from "../../../components/molecules/actionables"
import BodyCard from "../../../components/organisms/body-card"
import DeletePrompt from "../../../components/organisms/delete-prompt"
import CustomersListTable from "../../../components/templates/customer-group-table/customers-list-table"
import EditCustomersTable from "../../../components/templates/customer-group-table/edit-customers-table"
import useQueryFilters from "../../../hooks/use-query-filters"
import useToggleState from "../../../hooks/use-toggle-state"
import { useWidgets } from "../../../providers/widget-provider"
import { getErrorStatus } from "../../../utils/get-error-status"
import CustomerGroupModal from "./customer-group-modal"
/**
* Default filtering config for querying customer group customers list endpoint.
*/
const defaultQueryProps = {
additionalFilters: { expand: "groups" },
limit: 15,
offset: 0,
}
/*
* Placeholder for the customer groups list.
*/
function CustomersListPlaceholder() {
const { t } = useTranslation()
return (
{t(
"groups-no-customers-in-this-group-yet",
"No customers in this group yet"
)}
)
}
type CustomerGroupCustomersListProps = { group: CustomerGroup }
/*
* Customer groups list container.
*/
function CustomerGroupCustomersList(props: CustomerGroupCustomersListProps) {
const groupId = props.group.id
// toggle to show/hide "edit customers" modal
const [showCustomersModal, setShowCustomersModal] = useState(false)
const { t } = useTranslation()
const { q, queryObject, paginate, setQuery } =
useQueryFilters(defaultQueryProps)
const {
customers = [],
isLoading,
count,
} = useAdminCustomerGroupCustomers(groupId, queryObject, {
keepPreviousData: true,
})
const { mutate: addCustomers } = useAdminAddCustomersToCustomerGroup(groupId)
const { mutate: removeCustomers } =
useAdminRemoveCustomersFromCustomerGroup(groupId)
// list of currently selected customers of a group
const [selectedCustomerIds, setSelectedCustomerIds] = useState(
customers.map((c) => c.id)
)
useEffect(() => {
if (!isLoading) {
setSelectedCustomerIds(customers.map((c) => c.id))
}
}, [isLoading, customers])
const showPlaceholder = !isLoading && !customers.length && !q
const actions = [
{
label: "Edit customers",
onClick: () => setShowCustomersModal(true),
icon: (
),
},
]
/*
* Calculate which customers need to be added/removed.
*/
const calculateDiff = () => {
const initialIds = customers.map((c) => c.id)
return {
toAdd: difference(selectedCustomerIds, initialIds),
toRemove: difference(initialIds, selectedCustomerIds),
}
}
/**
* Handle "edit customers" modal form submit.
*/
const handleSubmit = () => {
const { toAdd, toRemove } = calculateDiff()
if (toAdd.length) {
addCustomers({ customer_ids: toAdd.map((i) => ({ id: i })) })
}
if (toRemove.length) {
removeCustomers({ customer_ids: toRemove.map((i) => ({ id: i })) })
}
setShowCustomersModal(false)
}
return (
{showCustomersModal && (
setShowCustomersModal(false)}
/>
)}
{showPlaceholder ? (
) : (
)}
)
}
type CustomerGroupDetailsHeaderProps = {
customerGroup: CustomerGroup
}
/*
* Customers groups details page header.
*/
function CustomerGroupDetailsHeader(props: CustomerGroupDetailsHeaderProps) {
const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false)
const { t } = useTranslation()
const navigate = useNavigate()
const { mutate: deleteGroup } = useAdminDeleteCustomerGroup(
props.customerGroup.id
)
const { state, close, open } = useToggleState()
const actions: ActionType[] = [
{
label: t("groups-edit", "Edit"),
onClick: open,
icon: ,
},
{
label: t("groups-delete", "Delete"),
onClick: () => {
setShowDeleteConfirmation(true)
},
variant: "danger",
icon: ,
},
]
const onDeleteConfirmed = async () => {
deleteGroup()
navigate("/a/customers/groups")
}
const handleConfirmDialogClose = () => setShowDeleteConfirmation(false)
return (
<>
{showDeleteConfirmation && (
)}
>
)
}
/*
* Customer groups details page
*/
function CustomerGroupDetails() {
const { id } = useParams()
const { t } = useTranslation()
const navigate = useNavigate()
const { customer_group, isLoading, error } = useAdminCustomerGroup(id!)
const { getWidgets } = useWidgets()
if (error) {
const errorStatus = getErrorStatus(error)
if (errorStatus) {
// If the product is not found, redirect to the 404 page
if (errorStatus.status === 404) {
navigate("/404")
return null
}
}
// Let the error boundary handle the error
throw error
}
if (isLoading || !customer_group) {
return (
)
}
return (
{getWidgets("customer_group.details.before").map((w, i) => {
return (
)
})}
{getWidgets("customer_group.details.after").map((w, i) => {
return (
)
})}
)
}
export default CustomerGroupDetails