2019-06-19 14:40:52 +00:00
import Button from "@material-ui/core/Button" ;
import DialogContentText from "@material-ui/core/DialogContentText" ;
import ActionDialog from "@saleor/components/ActionDialog" ;
import AssignCategoriesDialog from "@saleor/components/AssignCategoryDialog" ;
import AssignCollectionDialog from "@saleor/components/AssignCollectionDialog" ;
import AssignProductDialog from "@saleor/components/AssignProductDialog" ;
import { WindowTitle } from "@saleor/components/WindowTitle" ;
2019-11-21 14:59:06 +00:00
import { DEFAULT_INITIAL_SEARCH_DATA , PAGINATE_BY } from "@saleor/config" ;
2019-06-19 14:40:52 +00:00
import useBulkActions from "@saleor/hooks/useBulkActions" ;
import useNavigator from "@saleor/hooks/useNavigator" ;
import useNotifier from "@saleor/hooks/useNotifier" ;
import usePaginator , {
createPaginationState
} from "@saleor/hooks/usePaginator" ;
import useShop from "@saleor/hooks/useShop" ;
2019-08-26 13:59:32 +00:00
import { commonMessages , sectionNames } from "@saleor/intl" ;
2019-11-19 15:47:12 +00:00
import useCategorySearch from "@saleor/searches/useCategorySearch" ;
2019-11-19 16:04:53 +00:00
import useCollectionSearch from "@saleor/searches/useCollectionSearch" ;
2019-11-19 16:50:40 +00:00
import useProductSearch from "@saleor/searches/useProductSearch" ;
2019-12-06 14:58:28 +00:00
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers" ;
2020-05-14 09:30:32 +00:00
import React from "react" ;
import { FormattedMessage , useIntl } from "react-intl" ;
2019-06-19 14:40:52 +00:00
import { categoryUrl } from "../../categories/urls" ;
import { collectionUrl } from "../../collections/urls" ;
2019-12-06 17:11:46 +00:00
import { decimal , joinDateTime , maybe } from "../../misc" ;
2019-06-19 14:40:52 +00:00
import { productUrl } from "../../products/urls" ;
import {
DiscountValueTypeEnum ,
2019-08-09 11:14:35 +00:00
VoucherTypeEnum
2019-06-19 14:40:52 +00:00
} from "../../types/globalTypes" ;
import DiscountCountrySelectDialog from "../components/DiscountCountrySelectDialog" ;
import VoucherDetailsPage , {
VoucherDetailsPageTab
} from "../components/VoucherDetailsPage" ;
import {
TypedVoucherCataloguesAdd ,
TypedVoucherCataloguesRemove ,
TypedVoucherDelete ,
TypedVoucherUpdate
} from "../mutations" ;
import { TypedVoucherDetails } from "../queries" ;
2019-08-09 11:14:35 +00:00
import { RequirementsPicker } from "../types" ;
2019-06-19 14:40:52 +00:00
import { VoucherCataloguesAdd } from "../types/VoucherCataloguesAdd" ;
import { VoucherCataloguesRemove } from "../types/VoucherCataloguesRemove" ;
import { VoucherDelete } from "../types/VoucherDelete" ;
import { VoucherUpdate } from "../types/VoucherUpdate" ;
import {
voucherListUrl ,
voucherUrl ,
2020-05-14 09:30:32 +00:00
VoucherUrlDialog ,
VoucherUrlQueryParams
2019-06-19 14:40:52 +00:00
} from "../urls" ;
interface VoucherDetailsProps {
id : string ;
params : VoucherUrlQueryParams ;
}
2019-11-07 11:34:54 +00:00
export const VoucherDetails : React.FC < VoucherDetailsProps > = ( {
2019-06-19 14:40:52 +00:00
id ,
params
} ) = > {
const navigate = useNavigator ( ) ;
const paginate = usePaginator ( ) ;
const notify = useNotifier ( ) ;
const shop = useShop ( ) ;
const { isSelected , listElements , reset , toggle , toggleAll } = useBulkActions (
params . ids
) ;
2019-08-26 13:59:32 +00:00
const intl = useIntl ( ) ;
2019-11-19 15:47:12 +00:00
const {
search : searchCategories ,
result : searchCategoriesOpts
} = useCategorySearch ( {
variables : DEFAULT_INITIAL_SEARCH_DATA
} ) ;
2019-11-19 16:04:53 +00:00
const {
search : searchCollections ,
result : searchCollectionsOpts
} = useCollectionSearch ( {
variables : DEFAULT_INITIAL_SEARCH_DATA
} ) ;
2019-11-19 16:50:40 +00:00
const {
2020-10-26 10:29:41 +00:00
loadMore : loadMoreProducts ,
2019-11-19 16:50:40 +00:00
search : searchProducts ,
result : searchProductsOpts
} = useProductSearch ( {
variables : DEFAULT_INITIAL_SEARCH_DATA
} ) ;
2019-06-19 14:40:52 +00:00
const paginationState = createPaginationState ( PAGINATE_BY , params ) ;
const changeTab = ( tab : VoucherDetailsPageTab ) = > {
reset ( ) ;
navigate (
voucherUrl ( id , {
activeTab : tab
} )
) ;
} ;
const handleVoucherDelete = ( data : VoucherDelete ) = > {
if ( data . voucherDelete . errors . length === 0 ) {
notify ( {
2020-07-01 09:39:36 +00:00
status : "success" ,
2019-08-26 13:59:32 +00:00
text : intl.formatMessage ( {
defaultMessage : "Deleted voucher"
2019-06-19 14:40:52 +00:00
} )
} ) ;
navigate ( voucherListUrl ( ) , true ) ;
}
} ;
const handleVoucherUpdate = ( data : VoucherUpdate ) = > {
if ( data . voucherUpdate . errors . length === 0 ) {
closeModal ( ) ;
notify ( {
2020-07-01 09:39:36 +00:00
status : "success" ,
2019-08-26 13:59:32 +00:00
text : intl.formatMessage ( commonMessages . savedChanges )
2019-06-19 14:40:52 +00:00
} ) ;
}
} ;
2019-12-06 14:58:28 +00:00
const [ openModal , closeModal ] = createDialogActionHandlers <
VoucherUrlDialog ,
VoucherUrlQueryParams
> ( navigate , params = > voucherUrl ( id , params ) , params ) ;
2019-06-19 14:40:52 +00:00
const handleCatalogueAdd = ( data : VoucherCataloguesAdd ) = > {
if ( data . voucherCataloguesAdd . errors . length === 0 ) {
closeModal ( ) ;
}
} ;
const handleCatalogueRemove = ( data : VoucherCataloguesRemove ) = > {
if ( data . voucherCataloguesRemove . errors . length === 0 ) {
closeModal ( ) ;
reset ( ) ;
}
} ;
2019-08-26 13:59:32 +00:00
const canOpenBulkActionDialog = maybe ( ( ) = > params . ids . length > 0 ) ;
2019-06-19 14:40:52 +00:00
return (
< TypedVoucherCataloguesRemove onCompleted = { handleCatalogueRemove } >
{ ( voucherCataloguesRemove , voucherCataloguesRemoveOpts ) = > (
< TypedVoucherCataloguesAdd onCompleted = { handleCatalogueAdd } >
{ ( voucherCataloguesAdd , voucherCataloguesAddOpts ) = > (
< TypedVoucherUpdate onCompleted = { handleVoucherUpdate } >
{ ( voucherUpdate , voucherUpdateOpts ) = > (
< TypedVoucherDelete onCompleted = { handleVoucherDelete } >
{ ( voucherDelete , voucherDeleteOpts ) = > (
< TypedVoucherDetails
displayLoader
variables = { { id , . . . paginationState } }
>
{ ( { data , loading } ) = > {
const tabPageInfo =
params . activeTab === VoucherDetailsPageTab . categories
? maybe ( ( ) = > data . voucher . categories . pageInfo )
: params . activeTab ===
VoucherDetailsPageTab . collections
? maybe ( ( ) = > data . voucher . collections . pageInfo )
: maybe ( ( ) = > data . voucher . products . pageInfo ) ;
const handleCategoriesUnassign = ( ids : string [ ] ) = >
voucherCataloguesRemove ( {
variables : {
. . . paginationState ,
id ,
input : {
categories : ids
}
}
} ) ;
const handleCollectionsUnassign = ( ids : string [ ] ) = >
voucherCataloguesRemove ( {
variables : {
. . . paginationState ,
id ,
input : {
collections : ids
}
}
} ) ;
const handleProductsUnassign = ( ids : string [ ] ) = >
voucherCataloguesRemove ( {
variables : {
. . . paginationState ,
id ,
input : {
products : ids
}
}
} ) ;
const {
loadNextPage ,
loadPreviousPage ,
pageInfo
} = paginate ( tabPageInfo , paginationState , params ) ;
return (
< >
2019-08-26 13:59:32 +00:00
< WindowTitle
title = { intl . formatMessage ( sectionNames . vouchers ) }
/ >
2019-06-19 14:40:52 +00:00
< VoucherDetailsPage
defaultCurrency = { maybe (
( ) = > shop . defaultCurrency
) }
voucher = { maybe ( ( ) = > data . voucher ) }
disabled = {
loading || voucherCataloguesRemoveOpts . loading
}
2020-03-03 11:20:39 +00:00
errors = {
voucherUpdateOpts . data ? . voucherUpdate . errors ||
[ ]
}
2019-06-19 14:40:52 +00:00
pageInfo = { pageInfo }
onNextPage = { loadNextPage }
onPreviousPage = { loadPreviousPage }
onCategoryAssign = { ( ) = >
openModal ( "assign-category" )
}
onCategoryClick = { id = > ( ) = >
navigate ( categoryUrl ( id ) ) }
onCollectionAssign = { ( ) = >
openModal ( "assign-collection" )
}
onCollectionUnassign = { collectionId = >
voucherCataloguesRemove ( {
variables : {
. . . paginationState ,
id ,
input : {
collections : [ collectionId ]
}
}
} )
}
onCountryAssign = { ( ) = >
openModal ( "assign-country" )
}
onCountryUnassign = { countryCode = >
voucherUpdate ( {
variables : {
. . . paginationState ,
id ,
input : {
countries : data.voucher.countries
. filter (
country = >
country . code !== countryCode
)
. map ( country = > country . code )
}
}
} )
}
onCategoryUnassign = { categoryId = >
voucherCataloguesRemove ( {
variables : {
. . . paginationState ,
id ,
input : {
categories : [ categoryId ]
}
}
} )
}
onCollectionClick = { id = > ( ) = >
navigate ( collectionUrl ( id ) ) }
onProductAssign = { ( ) = >
openModal ( "assign-product" )
}
onProductUnassign = { productId = >
voucherCataloguesRemove ( {
variables : {
. . . paginationState ,
id ,
input : {
products : [ productId ]
}
}
} )
}
onProductClick = { id = > ( ) = >
navigate ( productUrl ( id ) ) }
activeTab = { params . activeTab }
onBack = { ( ) = > navigate ( voucherListUrl ( ) ) }
onTabClick = { changeTab }
onSubmit = { formData = >
voucherUpdate ( {
variables : {
id ,
input : {
2019-08-09 11:14:35 +00:00
applyOncePerCustomer :
formData . applyOncePerCustomer ,
applyOncePerOrder :
formData . applyOncePerOrder ,
discountValue :
formData . discountType . toString ( ) ===
"SHIPPING"
? 100
: decimal ( formData . value ) ,
discountValueType :
formData . discountType . toString ( ) ===
"SHIPPING"
? DiscountValueTypeEnum . PERCENTAGE
: formData . discountType ,
endDate : formData.hasEndDate
? joinDateTime (
formData . endDate ,
formData . endTime
)
: null ,
minAmountSpent :
formData . requirementsPicker !==
RequirementsPicker . ORDER
? 0
2020-01-09 11:13:24 +00:00
: parseFloat ( formData . minSpent ) ,
2019-08-09 11:14:35 +00:00
minCheckoutItemsQuantity :
formData . requirementsPicker !==
RequirementsPicker . ITEM
? 0
: parseFloat (
formData . minCheckoutItemsQuantity
) ,
startDate : joinDateTime (
formData . startDate ,
formData . startTime
2019-06-19 14:40:52 +00:00
) ,
2019-08-09 11:14:35 +00:00
type :
formData . discountType . toString ( ) ===
"SHIPPING"
? VoucherTypeEnum . SHIPPING
: formData . type ,
2019-09-10 16:51:38 +00:00
usageLimit : formData.hasUsageLimit
? parseInt ( formData . usageLimit , 10 )
2019-11-26 14:44:02 +00:00
: null
2019-06-19 14:40:52 +00:00
}
}
} )
}
onRemove = { ( ) = > openModal ( "remove" ) }
2019-12-06 17:17:44 +00:00
saveButtonBarState = { voucherUpdateOpts . status }
2019-06-19 14:40:52 +00:00
categoryListToolbar = {
< Button
color = "primary"
onClick = { ( ) = >
2019-12-06 14:58:28 +00:00
openModal ( "unassign-category" , {
ids : listElements
} )
2019-06-19 14:40:52 +00:00
}
>
2019-08-26 13:59:32 +00:00
< FormattedMessage
defaultMessage = "Unassign"
description = "unassign category from voucher, button"
id = "voucherDetailsUnassignCategory"
/ >
2019-06-19 14:40:52 +00:00
< / Button >
}
collectionListToolbar = {
< Button
color = "primary"
onClick = { ( ) = >
2019-12-06 14:58:28 +00:00
openModal ( "unassign-collection" , {
ids : listElements
} )
2019-06-19 14:40:52 +00:00
}
>
2019-08-26 13:59:32 +00:00
< FormattedMessage
defaultMessage = "Unassign"
description = "unassign collection from voucher, button"
id = "voucherDetailsUnassignCollection"
/ >
2019-06-19 14:40:52 +00:00
< / Button >
}
productListToolbar = {
< Button
color = "primary"
onClick = { ( ) = >
2019-12-06 14:58:28 +00:00
openModal ( "unassign-product" , {
ids : listElements
} )
2019-06-19 14:40:52 +00:00
}
>
2019-08-26 13:59:32 +00:00
< FormattedMessage
defaultMessage = "Unassign"
description = "unassign product from voucher, button"
id = "voucherDetailsUnassignProduct"
/ >
2019-06-19 14:40:52 +00:00
< / Button >
}
isChecked = { isSelected }
selected = { listElements . length }
toggle = { toggle }
toggleAll = { toggleAll }
/ >
2019-11-19 15:47:12 +00:00
< AssignCategoriesDialog
categories = { maybe ( ( ) = >
searchCategoriesOpts . data . search . edges
. map ( edge = > edge . node )
. filter (
suggestedCategory = > suggestedCategory . id
)
) }
2019-12-06 17:11:46 +00:00
confirmButtonState = {
2019-12-06 17:17:44 +00:00
voucherCataloguesAddOpts . status
2019-12-06 17:11:46 +00:00
}
2019-11-19 15:47:12 +00:00
open = { params . action === "assign-category" }
onFetch = { searchCategories }
loading = { searchCategoriesOpts . loading }
onClose = { closeModal }
onSubmit = { categories = >
voucherCataloguesAdd ( {
variables : {
. . . paginationState ,
id ,
input : {
categories : categories.map (
product = > product . id
2019-06-19 14:40:52 +00:00
)
2019-11-19 15:47:12 +00:00
}
2019-06-19 14:40:52 +00:00
}
2019-11-19 15:47:12 +00:00
} )
}
/ >
2019-11-19 16:04:53 +00:00
< AssignCollectionDialog
collections = { maybe ( ( ) = >
searchCollectionsOpts . data . search . edges
. map ( edge = > edge . node )
. filter (
suggestedCategory = > suggestedCategory . id
)
) }
2019-12-06 17:11:46 +00:00
confirmButtonState = {
2019-12-06 17:17:44 +00:00
voucherCataloguesAddOpts . status
2019-12-06 17:11:46 +00:00
}
2019-11-19 16:04:53 +00:00
open = { params . action === "assign-collection" }
onFetch = { searchCollections }
loading = { searchCollectionsOpts . loading }
onClose = { closeModal }
onSubmit = { collections = >
voucherCataloguesAdd ( {
variables : {
. . . paginationState ,
id ,
input : {
collections : collections.map (
product = > product . id
2019-06-19 14:40:52 +00:00
)
2019-11-19 16:04:53 +00:00
}
2019-06-19 14:40:52 +00:00
}
2019-11-19 16:04:53 +00:00
} )
}
/ >
2019-06-19 14:40:52 +00:00
< DiscountCountrySelectDialog
2019-12-06 17:17:44 +00:00
confirmButtonState = { voucherUpdateOpts . status }
2019-06-19 14:40:52 +00:00
countries = { maybe ( ( ) = > shop . countries , [ ] ) }
onClose = { ( ) = > navigate ( voucherUrl ( id ) ) }
onConfirm = { formData = >
voucherUpdate ( {
variables : {
id ,
input : {
countries : formData.countries
}
}
} )
}
open = { params . action === "assign-country" }
initial = { maybe (
( ) = >
data . voucher . countries . map (
country = > country . code
) ,
[ ]
) }
/ >
2019-11-19 16:50:40 +00:00
< AssignProductDialog
2019-12-06 17:11:46 +00:00
confirmButtonState = {
2019-12-06 17:17:44 +00:00
voucherCataloguesAddOpts . status
2019-12-06 17:11:46 +00:00
}
2020-10-26 10:29:41 +00:00
hasMore = {
searchProductsOpts . data ? . search . pageInfo
. hasNextPage
}
2019-11-19 16:50:40 +00:00
open = { params . action === "assign-product" }
onFetch = { searchProducts }
2020-10-26 10:29:41 +00:00
onFetchMore = { loadMoreProducts }
2019-11-19 16:50:40 +00:00
loading = { searchProductsOpts . loading }
onClose = { closeModal }
onSubmit = { products = >
voucherCataloguesAdd ( {
variables : {
. . . paginationState ,
id ,
input : {
products : products.map (
product = > product . id
2019-06-19 14:40:52 +00:00
)
2019-11-19 16:50:40 +00:00
}
}
} )
}
products = { maybe ( ( ) = >
searchProductsOpts . data . search . edges
. map ( edge = > edge . node )
. filter (
suggestedProduct = > suggestedProduct . id
)
2019-06-19 14:40:52 +00:00
) }
2019-11-19 16:50:40 +00:00
/ >
2019-06-19 14:40:52 +00:00
< ActionDialog
2019-08-26 13:59:32 +00:00
open = {
params . action === "unassign-category" &&
canOpenBulkActionDialog
}
title = { intl . formatMessage ( {
defaultMessage :
"Unassign Categories From Voucher" ,
description : "dialog header"
} ) }
2019-12-06 17:11:46 +00:00
confirmButtonState = {
2019-12-06 17:17:44 +00:00
voucherCataloguesRemoveOpts . status
2019-12-06 17:11:46 +00:00
}
2019-06-19 14:40:52 +00:00
onClose = { closeModal }
onConfirm = { ( ) = >
handleCategoriesUnassign ( params . ids )
}
>
2019-08-26 13:59:32 +00:00
{ canOpenBulkActionDialog && (
< DialogContentText >
< FormattedMessage
2020-02-13 11:14:16 +00:00
defaultMessage = "{counter,plural,one{Are you sure you want to unassign this category?} other{Are you sure you want to unassign {displayQuantity} categories?}}"
2019-08-26 13:59:32 +00:00
description = "dialog content"
values = { {
counter : params.ids.length ,
displayQuantity : (
< strong > { params . ids . length } < / strong >
2019-06-19 14:40:52 +00:00
)
2019-08-26 13:59:32 +00:00
} }
/ >
< / DialogContentText >
) }
2019-06-19 14:40:52 +00:00
< / ActionDialog >
< ActionDialog
2019-08-26 13:59:32 +00:00
open = {
params . action === "unassign-collection" &&
canOpenBulkActionDialog
}
title = { intl . formatMessage ( {
defaultMessage :
"Unassign Collections From Voucher" ,
description : "dialog header"
} ) }
2019-12-06 17:11:46 +00:00
confirmButtonState = {
2019-12-06 17:17:44 +00:00
voucherCataloguesRemoveOpts . status
2019-12-06 17:11:46 +00:00
}
2019-06-19 14:40:52 +00:00
onClose = { closeModal }
onConfirm = { ( ) = >
handleCollectionsUnassign ( params . ids )
}
>
2019-08-26 13:59:32 +00:00
{ canOpenBulkActionDialog && (
< DialogContentText >
< FormattedMessage
2020-02-13 11:14:16 +00:00
defaultMessage = "{counter,plural,one{Are you sure you want to unassign this collection?} other{Are you sure you want to unassign {displayQuantity} collections?}}"
2019-08-26 13:59:32 +00:00
description = "dialog content"
values = { {
counter : params.ids.length ,
displayQuantity : (
< strong > { params . ids . length } < / strong >
2019-06-19 14:40:52 +00:00
)
2019-08-26 13:59:32 +00:00
} }
/ >
< / DialogContentText >
) }
2019-06-19 14:40:52 +00:00
< / ActionDialog >
< ActionDialog
2019-08-26 13:59:32 +00:00
open = {
params . action === "unassign-product" &&
canOpenBulkActionDialog
}
title = { intl . formatMessage ( {
defaultMessage :
"Unassign Products From Voucher" ,
description : "dialog header"
} ) }
2019-12-06 17:11:46 +00:00
confirmButtonState = {
2019-12-06 17:17:44 +00:00
voucherCataloguesRemoveOpts . status
2019-12-06 17:11:46 +00:00
}
2019-06-19 14:40:52 +00:00
onClose = { closeModal }
onConfirm = { ( ) = >
handleProductsUnassign ( params . ids )
}
>
2019-08-26 13:59:32 +00:00
{ canOpenBulkActionDialog && (
< DialogContentText >
< FormattedMessage
2020-02-13 11:14:16 +00:00
defaultMessage = "{counter,plural,one{Are you sure you want to unassign this product?} other{Are you sure you want to unassign {displayQuantity} products?}}"
2019-08-26 13:59:32 +00:00
description = "dialog content"
values = { {
counter : params.ids.length ,
displayQuantity : (
< strong > { params . ids . length } < / strong >
2019-06-19 14:40:52 +00:00
)
2019-08-26 13:59:32 +00:00
} }
/ >
< / DialogContentText >
) }
2019-06-19 14:40:52 +00:00
< / ActionDialog >
< ActionDialog
open = { params . action === "remove" }
2019-08-26 13:59:32 +00:00
title = { intl . formatMessage ( {
defaultMessage : "Delete Voucher" ,
description : "dialog header"
} ) }
2019-12-06 17:17:44 +00:00
confirmButtonState = { voucherDeleteOpts . status }
2019-06-19 14:40:52 +00:00
onClose = { closeModal }
variant = "delete"
onConfirm = { ( ) = >
voucherDelete ( {
variables : { id }
} )
}
>
2019-08-26 13:59:32 +00:00
< DialogContentText >
< FormattedMessage
defaultMessage = "Are you sure you want to delete {voucherCode}?"
description = "dialog content"
values = { {
voucherCode : (
< strong >
{ maybe ( ( ) = > data . voucher . code , "..." ) }
< / strong >
)
} }
/ >
< / DialogContentText >
2019-06-19 14:40:52 +00:00
< / ActionDialog >
< / >
) ;
} }
< / TypedVoucherDetails >
) }
< / TypedVoucherDelete >
) }
< / TypedVoucherUpdate >
) }
< / TypedVoucherCataloguesAdd >
) }
< / TypedVoucherCataloguesRemove >
) ;
} ;
export default VoucherDetails ;