diff --git a/src/components/CompanyAddressInput/CompanyAddressForm.tsx b/src/components/CompanyAddressInput/CompanyAddressForm.tsx new file mode 100644 index 000000000..b94b87aac --- /dev/null +++ b/src/components/CompanyAddressInput/CompanyAddressForm.tsx @@ -0,0 +1,190 @@ +import { makeStyles } from "@material-ui/core/styles"; +import TextField from "@material-ui/core/TextField"; +import React from "react"; +import { useIntl, IntlShape } from "react-intl"; + +import FormSpacer from "@saleor/components/FormSpacer"; +import Grid from "@saleor/components/Grid"; +import SingleAutocompleteSelectField, { + SingleAutocompleteChoiceType +} from "@saleor/components/SingleAutocompleteSelectField"; +import { AddressTypeInput } from "@saleor/customers/types"; +import { ChangeEvent } from "@saleor/hooks/useForm"; +import getShopErrorMessage from "@saleor/utils/errors/shop"; +import { getFormErrors } from "@saleor/utils/errors"; +import { ShopErrorFragment } from "@saleor/siteSettings/types/ShopErrorFragment"; +import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment"; +import getAccountErrorMessage from "@saleor/utils/errors/account"; + +export interface CompanyAddressFormProps { + countries: SingleAutocompleteChoiceType[]; + data: AddressTypeInput; + displayCountry: string; + errors: Array; + disabled: boolean; + onChange: (event: ChangeEvent) => void; + onCountryChange: (event: ChangeEvent) => void; +} + +const useStyles = makeStyles( + { + root: {} + }, + { name: "CompanyAddressForm" } +); + +function getErrorMessage( + err: AccountErrorFragment | ShopErrorFragment, + intl: IntlShape +): string { + if (err?.__typename === "AccountError") { + return getAccountErrorMessage(err, intl); + } + + return getShopErrorMessage(err, intl); +} + +const CompanyAddressForm: React.FC = props => { + const { + countries, + data, + disabled, + displayCountry, + errors, + onChange, + onCountryChange + } = props; + + const classes = useStyles(props); + const intl = useIntl(); + + const formFields = [ + "companyName", + "streetAddress1", + "streetAddress2", + "city", + "postalCode", + "country", + "companyArea", + "phone" + ]; + const formErrors = getFormErrors(formFields, errors); + + return ( +
+ + + + + + + + + + + + + + + + + +
+ ); +}; +CompanyAddressForm.displayName = "CompanyAddressForm"; +export default CompanyAddressForm; diff --git a/src/components/CompanyAddressInput/CompanyAddressInput.tsx b/src/components/CompanyAddressInput/CompanyAddressInput.tsx index bdd2374a4..a064b4c25 100644 --- a/src/components/CompanyAddressInput/CompanyAddressInput.tsx +++ b/src/components/CompanyAddressInput/CompanyAddressInput.tsx @@ -1,33 +1,17 @@ import Card from "@material-ui/core/Card"; import CardContent from "@material-ui/core/CardContent"; import { makeStyles } from "@material-ui/core/styles"; -import TextField from "@material-ui/core/TextField"; import React from "react"; -import { useIntl, IntlShape } from "react-intl"; +import classNames from "classnames"; -import CardTitle from "@saleor/components/CardTitle"; -import FormSpacer from "@saleor/components/FormSpacer"; -import Grid from "@saleor/components/Grid"; -import SingleAutocompleteSelectField, { - SingleAutocompleteChoiceType -} from "@saleor/components/SingleAutocompleteSelectField"; -import { ChangeEvent } from "@saleor/hooks/useForm"; -import { getFormErrors } from "@saleor/utils/errors"; -import { ShopErrorFragment } from "@saleor/siteSettings/types/ShopErrorFragment"; -import getShopErrorMessage from "@saleor/utils/errors/shop"; -import { AccountErrorFragment } from "@saleor/customers/types/AccountErrorFragment"; -import getAccountErrorMessage from "@saleor/utils/errors/account"; -import { AddressTypeInput } from "@saleor/customers/types"; +import CardTitle from "../CardTitle"; +import CompanyAddressForm, { + CompanyAddressFormProps +} from "./CompanyAddressForm"; -interface CompanyAddressInputProps { - countries: SingleAutocompleteChoiceType[]; - data: AddressTypeInput; - displayCountry: string; - errors: Array; - disabled: boolean; +interface CompanyAddressInputProps extends CompanyAddressFormProps { + className: string; header: string; - onChange: (event: ChangeEvent) => void; - onCountryChange: (event: ChangeEvent) => void; } const useStyles = makeStyles( @@ -39,159 +23,15 @@ const useStyles = makeStyles( { name: "CompanyAddressInput" } ); -function getErrorMessage( - err: AccountErrorFragment | ShopErrorFragment, - intl: IntlShape -): string { - if (err?.__typename === "AccountError") { - return getAccountErrorMessage(err, intl); - } - - return getShopErrorMessage(err, intl); -} - const CompanyAddressInput: React.FC = props => { - const { - countries, - data, - disabled, - displayCountry, - errors, - header, - onChange, - onCountryChange - } = props; - + const { className, header, ...formProps } = props; const classes = useStyles(props); - const intl = useIntl(); - - const formFields = [ - "companyName", - "streetAddress1", - "streetAddress2", - "city", - "postalCode", - "country", - "companyArea", - "phone" - ]; - const formErrors = getFormErrors(formFields, errors); return ( - + - - - - - - - - - - - - - - - - - + ); diff --git a/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectField.tsx b/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectField.tsx index 4df5b02e6..f140d4c05 100644 --- a/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectField.tsx +++ b/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectField.tsx @@ -26,7 +26,7 @@ const useStyles = makeStyles( export interface SingleAutocompleteSelectFieldProps extends Partial { - add: SingleAutocompleteActionType; + add?: SingleAutocompleteActionType; error?: boolean; name: string; displayValue: string; @@ -147,13 +147,15 @@ const SingleAutocompleteSelectFieldComponent: React.FC {isOpen && (!!inputValue || !!choices.length) && ( { - add.onClick(); - closeMenu(); + add={ + !!add && { + ...add, + onClick: () => { + add.onClick(); + closeMenu(); + } } - }} + } choices={choices} displayCustomValue={displayCustomValue} emptyOption={emptyOption} diff --git a/src/shipping/components/ShippingZoneAddWarehouseDialog/ShippingZoneAddWarehouseDialog.tsx b/src/shipping/components/ShippingZoneAddWarehouseDialog/ShippingZoneAddWarehouseDialog.tsx new file mode 100644 index 000000000..4e2f3e806 --- /dev/null +++ b/src/shipping/components/ShippingZoneAddWarehouseDialog/ShippingZoneAddWarehouseDialog.tsx @@ -0,0 +1,162 @@ +import Button from "@material-ui/core/Button"; +import Dialog from "@material-ui/core/Dialog"; +import DialogActions from "@material-ui/core/DialogActions"; +import DialogContent from "@material-ui/core/DialogContent"; +import DialogTitle from "@material-ui/core/DialogTitle"; +import TextField from "@material-ui/core/TextField"; +import React from "react"; +import { FormattedMessage, useIntl } from "react-intl"; +import makeStyles from "@material-ui/core/styles/makeStyles"; + +import ConfirmButton, { + ConfirmButtonTransitionState +} from "@saleor/components/ConfirmButton"; +import { DialogProps, UserError } from "@saleor/types"; +import { AddressTypeInput } from "@saleor/customers/types"; +import useModalDialogOpen from "@saleor/hooks/useModalDialogOpen"; +import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors"; +import CompanyAddressForm from "@saleor/components/CompanyAddressInput/CompanyAddressForm"; +import { buttonMessages } from "@saleor/intl"; +import Hr from "@saleor/components/Hr"; +import Form from "@saleor/components/Form"; +import useAddressValidation from "@saleor/hooks/useAddressValidation"; +import useStateFromProps from "@saleor/hooks/useStateFromProps"; +import { ShopInfo_shop_countries } from "@saleor/components/Shop/types/ShopInfo"; +import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler"; +import FormSpacer from "@saleor/components/FormSpacer"; + +export interface ShippingZoneAddWarehouseDialogSubmitData + extends AddressTypeInput { + name: string; +} +export interface ShippingZoneAddWarehouseDialogProps extends DialogProps { + confirmButtonState: ConfirmButtonTransitionState; + countries: ShopInfo_shop_countries[]; + disabled: boolean; + errors: UserError[]; + onSubmit: (data: ShippingZoneAddWarehouseDialogSubmitData) => void; +} + +const initialForm: ShippingZoneAddWarehouseDialogSubmitData = { + city: "", + cityArea: "", + companyName: "", + country: "", + countryArea: "", + firstName: "", + lastName: "", + name: "", + phone: "", + postalCode: "", + streetAddress1: "", + streetAddress2: "" +}; + +const useStyles = makeStyles( + { + overflow: { + overflowY: "visible" + } + }, + { + name: "ShippingZoneAddWarehouseDialog" + } +); + +const ShippingZoneAddWarehouseDialog: React.FC = ({ + confirmButtonState, + countries, + disabled, + errors: apiErrors, + open, + onClose, + onSubmit +}) => { + const classes = useStyles({}); + const [countryDisplayName, setCountryDisplayName] = useStateFromProps(""); + const { + errors: validationErrors, + submit: handleSubmit + } = useAddressValidation(onSubmit); + const errors = useModalDialogErrors( + [...apiErrors, ...validationErrors], + open + ); + useModalDialogOpen(open, {}); + const intl = useIntl(); + + const countryChoices = countries.map(country => ({ + label: country.country, + value: country.code + })); + + return ( + + + + +
+ {({ change, data, errors: formErrors, submit }) => { + const handleCountrySelect = createSingleAutocompleteSelectHandler( + change, + setCountryDisplayName, + countryChoices + ); + + return ( + <> + + + +
+ + +
+ + + + + + + + ); + }} +
+
+ ); +}; + +ShippingZoneAddWarehouseDialog.displayName = "ShippingZoneAddWarehouseDialog"; +export default ShippingZoneAddWarehouseDialog; diff --git a/src/shipping/components/ShippingZoneAddWarehouseDialog/index.ts b/src/shipping/components/ShippingZoneAddWarehouseDialog/index.ts new file mode 100644 index 000000000..3d5129332 --- /dev/null +++ b/src/shipping/components/ShippingZoneAddWarehouseDialog/index.ts @@ -0,0 +1,2 @@ +export { default } from "./ShippingZoneAddWarehouseDialog"; +export * from "./ShippingZoneAddWarehouseDialog"; diff --git a/src/shipping/views/ShippingZoneDetails/index.tsx b/src/shipping/views/ShippingZoneDetails/index.tsx index 9350e8165..ea22654e4 100644 --- a/src/shipping/views/ShippingZoneDetails/index.tsx +++ b/src/shipping/views/ShippingZoneDetails/index.tsx @@ -21,8 +21,13 @@ import ShippingZoneRateDialog from "@saleor/shipping/components/ShippingZoneRate import useShop from "@saleor/hooks/useShop"; import ShippingZoneCountriesAssignDialog from "@saleor/shipping/components/ShippingZoneCountriesAssignDialog"; import NotFoundPage from "@saleor/components/NotFoundPage"; -import { getStringOrPlaceholder } from "../../../misc"; -import { ShippingMethodTypeEnum } from "../../../types/globalTypes"; +import ShippingZoneAddWarehouseDialog from "@saleor/shipping/components/ShippingZoneAddWarehouseDialog"; +import { useWarehouseCreate } from "@saleor/warehouses/mutations"; +import { getStringOrPlaceholder, findValueInEnum } from "../../../misc"; +import { + ShippingMethodTypeEnum, + CountryCode +} from "../../../types/globalTypes"; import ShippingZoneDetailsPage, { FormData } from "../../components/ShippingZoneDetailsPage"; @@ -126,6 +131,17 @@ const ShippingZoneDetails: React.FC = ({ } }); + const [createWarehouse, createWarehouseOpts] = useWarehouseCreate({ + onCompleted: data => { + if (data.createWarehouse.errors.length === 0) { + notify({ + text: intl.formatMessage(commonMessages.savedChanges) + }); + closeModal(); + } + } + }); + const handleSubmit = (data: FormData) => { updateShippingZone({ variables: { @@ -138,7 +154,7 @@ const ShippingZoneDetails: React.FC = ({ assignToWarehouse({ variables: { shippingZoneId: id, - warehouseId: data.warehouse + warehouseId: data.warehouses[0] } }); }; @@ -346,6 +362,34 @@ const ShippingZoneDetails: React.FC = ({ /> + + createWarehouse({ + variables: { + input: { + address: { + city: data.city, + cityArea: data.cityArea, + country: findValueInEnum(data.country, CountryCode), + countryArea: data.countryArea, + phone: data.phone, + postalCode: data.postalCode, + streetAddress1: data.streetAddress1, + streetAddress2: data.streetAddress2 + }, + companyName: data.companyName, + name: data.name + } + } + }) + } + /> ); };