import { AdminPostStockLocationsReq, SalesChannel } from "@medusajs/medusa" import { useTranslation } from "react-i18next" import GeneralForm, { GeneralFormType } from "../components/general-form" import MetadataForm, { MetadataFormType, getSubmittableMetadata, } from "../../../../components/forms/general/metadata-form" import { StockLocationAddressDTO, StockLocationAddressInput, } from "@medusajs/types" import { useAdminAddLocationToSalesChannel, useAdminCreateStockLocation, } from "medusa-react" import Accordion from "../../../../components/organisms/accordion" import AddressForm from "../components/address-form" import Button from "../../../../components/fundamentals/button" import CrossIcon from "../../../../components/fundamentals/icons/cross-icon" import DeletePrompt from "../../../../components/organisms/delete-prompt" import FocusModal from "../../../../components/molecules/modal/focus-modal" import React from "react" import SalesChannelsForm from "../components/sales-channels-form" import { getErrorMessage } from "../../../../utils/error-messages" import { nestedForm } from "../../../../utils/nested-form" import { useFeatureFlag } from "../../../../providers/feature-flag-provider" import { useForm } from "react-hook-form" import useNotification from "../../../../hooks/use-notification" import useToggleState from "../../../../hooks/use-toggle-state" type NewLocationForm = { general: GeneralFormType address: StockLocationAddressDTO metadata: MetadataFormType salesChannels: { channels: Omit[] } } const NewLocation = ({ onClose }: { onClose: () => void }) => { const { t } = useTranslation() const [accordionValue, setAccordionValue] = React.useState("general") const form = useForm({ defaultValues: { general: { name: "", }, address: undefined, salesChannels: { channels: [], }, }, reValidateMode: "onBlur", mode: "onBlur", }) const { handleSubmit, formState: { isDirty }, } = form const { state: isShowingClosePrompt, open: showClosePrompt, close: closeClosePrompt, } = useToggleState() const notification = useNotification() const { isFeatureEnabled } = useFeatureFlag() const { mutateAsync: createStockLocation } = useAdminCreateStockLocation() const { mutateAsync: associateSalesChannel } = useAdminAddLocationToSalesChannel() const createSalesChannelAssociationPromise = ( salesChannelId: string, locationId: string ) => associateSalesChannel({ sales_channel_id: salesChannelId, location_id: locationId, }) const handleClose = () => { if (!isDirty) { onClose() } else { showClosePrompt() } } const onSubmit = async (data) => { if (!data.general.name) { setAccordionValue("general") return } const addressFields = [data.address.address_1, data.address.country_code] if (addressFields.some(Boolean) && !addressFields.every(Boolean)) { setAccordionValue("general") return } const { locationPayload, salesChannelsPayload } = createPayload(data) try { const { stock_location } = await createStockLocation(locationPayload) Promise.all( salesChannelsPayload.map((salesChannel) => createSalesChannelAssociationPromise( salesChannel.id, stock_location.id ) ) ) .then(() => { notification( t("new-success", "Success"), t("new-location-added-successfully", "Location added successfully"), "success" ) }) .catch(() => { notification( t("new-error", "Error"), t( "new-location-created", "Location was created successfully, but there was an error associating sales channels" ), "error" ) }) .finally(() => { onClose() }) } catch (err) { notification(t("new-error", "Error"), getErrorMessage(err), "error") } } return (
{isShowingClosePrompt && ( onClose()} /> )}

{t("new-add-new-location", "Add new location")}

{t( "new-location-details", "Specify the details about this location" )}

{t("new-metadata", "Metadata")}

{isFeatureEnabled("sales_channels") && (

{t( "new-select-location-channel", "Specify which Sales Channels this location's items can be purchased through." )}

)}
) } const createPayload = ( data ): { locationPayload: AdminPostStockLocationsReq salesChannelsPayload: SalesChannel[] } => { const { general, address, metadata } = data let addressInput if (address.address_1) { addressInput = address as StockLocationAddressInput addressInput.country_code = address.country_code.value } return { locationPayload: { name: general.name, address: addressInput, metadata: getSubmittableMetadata(metadata), }, salesChannelsPayload: data.salesChannels.channels, } } export default NewLocation