import { ChannelShippingData } from "@dashboard/channels/utils"; import { Backlink } from "@dashboard/components/Backlink"; import CardSpacer from "@dashboard/components/CardSpacer"; import ChannelsAvailabilityCard from "@dashboard/components/ChannelsAvailabilityCard"; import Container from "@dashboard/components/Container"; import { WithFormId } from "@dashboard/components/Form"; import Grid from "@dashboard/components/Grid"; import Metadata from "@dashboard/components/Metadata/Metadata"; import PageHeader from "@dashboard/components/PageHeader"; import Savebar from "@dashboard/components/Savebar"; import { PermissionEnum, PostalCodeRuleInclusionTypeEnum, ShippingChannelsErrorFragment, ShippingErrorFragment, ShippingMethodTypeEnum, ShippingMethodTypeFragment, ShippingZoneQuery, TaxClassBaseFragment, } from "@dashboard/graphql"; import useForm, { SubmitPromise } from "@dashboard/hooks/useForm"; import useHandleFormSubmit from "@dashboard/hooks/useHandleFormSubmit"; import useNavigator from "@dashboard/hooks/useNavigator"; import { useStateUpdate } from "@dashboard/hooks/useStateUpdate"; import { validatePrice } from "@dashboard/products/utils/validation"; import { handleTaxClassChange } from "@dashboard/productTypes/handlers"; import OrderValue from "@dashboard/shipping/components/OrderValue"; import OrderWeight from "@dashboard/shipping/components/OrderWeight"; import PricingCard from "@dashboard/shipping/components/PricingCard"; import ShippingMethodProducts from "@dashboard/shipping/components/ShippingMethodProducts"; import ShippingRateInfo from "@dashboard/shipping/components/ShippingRateInfo"; import { createChannelsChangeHandler } from "@dashboard/shipping/handlers"; import { FetchMoreProps, ListActions, ListProps } from "@dashboard/types"; import { mapEdgesToItems, mapMetadataItemToInput } from "@dashboard/utils/maps"; import useMetadataChangeTrigger from "@dashboard/utils/metadata/useMetadataChangeTrigger"; import { RichTextContext } from "@dashboard/utils/richText/context"; import useRichText from "@dashboard/utils/richText/useRichText"; import { ConfirmButtonTransitionState } from "@saleor/macaw-ui"; import React, { FormEventHandler } from "react"; import { FormattedMessage } from "react-intl"; import ShippingMethodTaxes from "../ShippingMethodTaxes"; import ShippingZonePostalCodes from "../ShippingZonePostalCodes"; import { ShippingZoneRateUpdateFormData } from "./types"; export interface ShippingZoneRatesPageProps extends Pick>, ListActions, WithFormId { allChannelsCount?: number; shippingChannels: ChannelShippingData[]; disabled: boolean; rate: ShippingZoneQuery["shippingZone"]["shippingMethods"][0]; channelErrors: ShippingChannelsErrorFragment[]; errors: ShippingErrorFragment[]; saveButtonBarState: ConfirmButtonTransitionState; postalCodeRules: ShippingZoneQuery["shippingZone"]["shippingMethods"][0]["postalCodeRules"]; backHref: string; onDelete?: () => void; onSubmit: (data: ShippingZoneRateUpdateFormData) => SubmitPromise; onPostalCodeInclusionChange: ( inclusion: PostalCodeRuleInclusionTypeEnum, ) => void; onPostalCodeAssign: () => void; onPostalCodeUnassign: ( code: ShippingMethodTypeFragment["postalCodeRules"][0], ) => void; onChannelsChange: (data: ChannelShippingData[]) => void; openChannelsModal: () => void; onProductAssign: () => void; onProductUnassign: (ids: string[]) => void; variant: ShippingMethodTypeEnum; taxClasses: TaxClassBaseFragment[]; fetchMoreTaxClasses: FetchMoreProps; } export const ShippingZoneRatesPage: React.FC = ({ allChannelsCount, shippingChannels, channelErrors, disabled, errors, backHref, onDelete, onSubmit, onPostalCodeInclusionChange, onChannelsChange, onPostalCodeAssign, onPostalCodeUnassign, onProductAssign, onProductUnassign, openChannelsModal, rate, saveButtonBarState, postalCodeRules, variant, formId, taxClasses, fetchMoreTaxClasses, ...listProps }) => { const navigate = useNavigator(); const isPriceVariant = variant === ShippingMethodTypeEnum.PRICE; const initialForm: Omit< ShippingZoneRateUpdateFormData, "description" > = React.useMemo( () => ({ channelListings: shippingChannels, maxDays: rate?.maximumDeliveryDays?.toString() || "", maxValue: rate?.maximumOrderWeight?.value.toString() || "", metadata: rate?.metadata.map(mapMetadataItemToInput), minDays: rate?.minimumDeliveryDays?.toString() || "", minValue: rate?.minimumOrderWeight?.value.toString() || "", name: rate?.name || "", orderValueRestricted: !!rate?.channelListings.length, privateMetadata: rate?.privateMetadata.map(mapMetadataItemToInput), type: rate?.type || null, taxClassId: rate?.taxClass?.id || "", }), [shippingChannels, rate], ); const { change, data: formData, setIsSubmitDisabled, triggerChange, } = useForm(initialForm, undefined, { confirmLeave: true, formId }); const [taxClassDisplayName, setTaxClassDisplayName] = useStateUpdate( rate?.taxClass?.name ?? "", ); const handleFormSubmit = useHandleFormSubmit({ formId, onSubmit, }); const richText = useRichText({ initial: rate?.description, loading: !rate, triggerChange, }); const { makeChangeHandler: makeMetadataChangeHandler, } = useMetadataChangeTrigger(); const data: ShippingZoneRateUpdateFormData = { ...formData, description: null, }; // Prevents closing ref in submit functions const getData = async (): Promise => ({ ...data, description: await richText.getValue(), }); const handleFormElementSubmit: FormEventHandler = async event => { event.preventDefault(); handleFormSubmit(await getData()); }; const handleSubmit = async () => handleFormSubmit(await getData()); const handleChannelsChange = createChannelsChangeHandler( shippingChannels, onChannelsChange, triggerChange, ); const isValid = !formData.channelListings?.some(channel => validatePrice(channel.price), ); const changeMetadata = makeMetadataChangeHandler(change); const isSaveDisabled = disabled || !isValid; setIsSubmitDisabled(isSaveDisabled); return (
{isPriceVariant ? ( ) : ( )}
({ id: channel.id, name: channel.name, }))} openModal={openChannelsModal} /> handleTaxClassChange( event, taxClasses, change, setTaxClassDisplayName, ) } onFetchMore={fetchMoreTaxClasses} />
navigate(backHref)} onDelete={onDelete} onSubmit={handleSubmit} state={saveButtonBarState} />
); }; export default ShippingZoneRatesPage;