Feature - Gift Cards (#1366)
* Add deletion to gift cards (#1298) * Add gift cards section to menu and add empty list component * Update messages * Change styling of app wide page header to match design * Add gift cards list table wip * Update prop name for status chip component to make it more consistent with other components * Replace old trash icon with new one * Add Size type based on action dialog sizes to be used app wide * Add delete icon button * Add new sizes option to status chip component * Add / update gift cards list components * Add bulk actions type * Work on gift cards list WIP * Small refactor * Fix styling of gift cards table * Remove temp files * Remove unnecessary type * Add gift cards section to menu and add empty list component * Update schema and types * Add link to gift card update page to gift cards list and add route to gift cards index * Extract order page title with status chip into a separate generic component and use it in order page title * wip * Update money component * Add gift card details card balance section * Refactor gift card details * Add vertical spacer component * Update schema and types * Add gift card tag input component along with necessary queries * Add gift card tag input to gift card update page * Add gift card update details card expiry section WIP * Add time period select field WIP * Post rebase refactor * Add time period select field to gift card update view * Update schema, types and gift cards query * Add getFullName util function and replace existing manual usages * Add text with select field component * Add gift card update info card and refactor * Fixes after review * Fix import * Add displaying order link in gift card update * Refactor * Connect gift card list to api * refactor * Add gift card create dialog * Fix gift card list styles, change location for gift card list query, minor refactor * Fix menu structure data for gift cards * Add channel currencies type to shop * Refactor text with select field * Add gift card expiry select component * Add gift card error type and fragment * Update global types * Add default prop to getFormErrors function * Move gift card details provider to providers dir * Update global utils with mapSingleValueNodeToChoice function * Update gift card tag input * Move and refactor time period field * Update schema * move format money function to other money ulities * Update gift card urls * Add content or skeleton component * Add gift card create util for extracting expiry settings input data * Remove content or skeleton component and move displaying logic to existing skeleton * Move displaying logic of gift card create dialog to list * Refactor * Add hooks for gift card bulk actions and gift card list to be used instead of context directly * Fix types for text with select field + add parsing for number typed field * Add initial currency to gift card create form * Fix gift card create dialog closing animation * Add gift card update info card * Refactor gift card update details card * Add gift card balance dialog * Move gift card update form providers to providers dir * Connect gift card update page to api, add necessary contexts etc. * Refactor * Refactor * Add hooks to use instead of gift card contexts directly * Fix types * Fix text field target name missing in passed event in text with select field * Add minimal value option to text with select field, add to gift card inputs * Fix gift card update balance dialog not changing hasChanged prop after submit * Refactor * Add enable / disable section to gift card update * Refactor * Refactor * Fix update balance dialog crashing the app when enetered wrong amount * Fix gift card list table header styles * Refactor * Add metadata to gift card update * Update messages ids * Refactor * Refactor * Refactor * Refactor * Update schema and types, add gift card delete and bulk delete mutations * Fix url change after gift card delete * Refactor * Update messages * Change gift card list providers order * Refactor/fix after merge * Add gift card resend mutation and update types * Add use dialog form reset hook and make update balance dialog use it, to fix it displaying form errors after modal close and open * Add gift card resend code dialog * Add button to open gift card resend code dialog * Update messages * Add gift card list bulk enable disable section * Add refetching gift card list query after bulk activate / deactivate, refactor * Refactor * Refactor * Update messages * Update schema * Change gift card update expiry settings * Refactor * Add gift card settings view (#1300) * Add gift card settings view * Refactor * Create gift card sttings expiry select * Update test snapshots * Update schema * Update gift card settings page title * Refactor to match rest of the gift cards flow (#1308) Co-authored-by: Magdalena Markusik <magdalena.markusik@mirumee.com> * Refactor * Refactor * Set common error codes in string union Co-authored-by: Magdalena Markusik <magdalena.markusik@mirumee.com> * Add gift card kind to product type (#1307) * Add gift card kind to product type * Fix radio label alignment * Update test snapshots * Refactor * Set default kind in product type create * Change styling of activate / deactivate button in gift card update * Add week option to time period select field * Update messages * Change labels and update messages * Add auto fulfill non shippable gift cards to order settings * Fix fixture * Update messages * Update snapshots * Refactor * Update types * Add gift card used in order money amount in order payment section * Remove unnecessary schema changes * Change types * Update fixtures and messages * Refactor * Add top card to gift card list (#1327) * Add top card to gift card list * Update no gift card products notification messages * Use alert instead of notification * Update prodduct and product type counts * Return null if none of the conditions pass * Update messages * Fix unused product type deletion * Update types * Update imports * Update messages * Update test snapshots * Change gift card dialog expiry settings * Update form of create gift card dialog * Add activation option to create gift card dialog * Update event handling * Update test snapshots * Use date context provider for moment time * Update types * Refactor * Update messages * Update snapshots * Add channel picker to gift card create modal * Fix styling * Add channel picker to gift card resend code dialog * Update schema and types * Refactor * Update messages * Refactor * Update messages and snapshots * Fix order gift card money amount (#1371) * Update messages and snapshots * Fix order gift card money in payment card when multiple gift cards used * Fix missing order id check in gift card events in order gift card money used util * Fix channel selection in gift card create dialog * Fix order number not showing in gift card update view * Add gift card settings to gift card create dialog (#1372) * Fix gift cards number inputs to accept floats * Fix order number showing as null in gift card update info card * Fix channel slug adding in gift card create dialog * Fix gift card list header top card links to display correctly * Remove unused imports Co-authored-by: Dawid Tarasiuk <tarasiukdawid@gmail.com>
This commit is contained in:
parent
9b3d90e9c7
commit
aaa0a9f309
205 changed files with 6354 additions and 1172 deletions
|
@ -3407,6 +3407,22 @@
|
|||
"context": "gift cards section name",
|
||||
"string": "Gift Cards"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardCreateDialog_dot_GiftCardCreateExpirySelect_dot_expiryDateLabel": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection expiry date label",
|
||||
"string": "Exact date"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardCreateDialog_dot_GiftCardCreateExpirySelect_dot_expiryOnLabel": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection expiry on label",
|
||||
"string": "Will expire on:"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardCreateDialog_dot_GiftCardCreateExpirySelect_dot_expiryPeriodLabel": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection expiry period label",
|
||||
"string": "Expires in"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardCreateDialog_dot_GiftCardCreateExpirySelect_dot_expirySelectedLabel": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection expiry selected label",
|
||||
"string": "Set gift card expiry date"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardCreateDialog_dot_amountLabel": {
|
||||
"context": "GiftCardCreateDialog amount label",
|
||||
"string": "Enter amount"
|
||||
|
@ -3431,10 +3447,6 @@
|
|||
"context": "GiftCardCreateDialog customer label",
|
||||
"string": "Customer"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardCreateDialog_dot_customerSubtitle": {
|
||||
"context": "GiftCardCreateDialog customer subtitle",
|
||||
"string": "Selected customer will be sent the generated gift card code. Someone else can redeem the gift card code. Gift card will be assigned to account which redeemed the code."
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardCreateDialog_dot_issueButtonLabel": {
|
||||
"context": "GiftCardCreateDialog issue button label",
|
||||
"string": "Issue"
|
||||
|
@ -3447,10 +3459,57 @@
|
|||
"context": "GiftCardCreateDialog note subtitle",
|
||||
"string": "Why was this gift card issued. This note will not be shown to the customer. Note will be stored in gift card history"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardCreateDialog_dot_requiresActivationCaption": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection requires activation caption",
|
||||
"string": "All issued cards require activation by staff before use."
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardCreateDialog_dot_requiresActivationLabel": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection requires activation label",
|
||||
"string": "Requires activation"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardCreateDialog_dot_title": {
|
||||
"context": "GiftCardCreateDialog title",
|
||||
"string": "Issue gift card"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardSettings_dot_GiftCardExpirySettingsCard_dot_expiryDateSectionDescription": {
|
||||
"string": "You can set gift cards to expire after a certain time after their purchase. Remember that in some countries, gift cards expiry is prohibited by law."
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardSettings_dot_GiftCardExpirySettingsCard_dot_expiryDateTitle": {
|
||||
"context": "section header",
|
||||
"string": "Expiry date"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardSettings_dot_title": {
|
||||
"context": "header",
|
||||
"string": "Gift Cards Settings"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardResendCodeDialog_dot_consentCheckboxLabel": {
|
||||
"context": "GiftCardResendCodeDialog consentCheckboxLabel",
|
||||
"string": "Yes, I want to send gift card to different address"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardResendCodeDialog_dot_description": {
|
||||
"context": "GiftCardResendCodeDialog description",
|
||||
"string": "Gift Card Code will be resent to email provided during checkout. You can provide a different email address if you want to:"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardResendCodeDialog_dot_emailInputPlaceholder": {
|
||||
"context": "GiftCardResendCodeDialog emailInputPlaceholder",
|
||||
"string": "Provided email address"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardResendCodeDialog_dot_sendToChannelSelectLabel": {
|
||||
"context": "ChannelPickerSelectField sendToChannelLabel",
|
||||
"string": "Send to channel"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardResendCodeDialog_dot_submitButtonLabel": {
|
||||
"context": "GiftCardResendCodeDialog submitButtonLabel",
|
||||
"string": "Resend"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardResendCodeDialog_dot_successResendAlertText": {
|
||||
"context": "GiftCardResendCodeDialog successResendAlertText",
|
||||
"string": "Successfully resent code to customer!"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardResendCodeDialog_dot_title": {
|
||||
"context": "GiftCardResendCodeDialog title",
|
||||
"string": "Resend code to customer"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardUpdateBalanceDialog_dot_changeButtonLabel": {
|
||||
"context": "GiftCardUpdateDetailsCard set balance dialog change button label",
|
||||
"string": "Change"
|
||||
|
@ -3479,6 +3538,14 @@
|
|||
"context": "GiftCardUpdateDetailsCard title",
|
||||
"string": "Details"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardUpdateExpirySelect_dot_expiryDateCheckboxLabel": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection expiry date checkbox label",
|
||||
"string": "Gift card expires"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardUpdateExpirySelect_dot_expiryDateLabel": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection expiry date label",
|
||||
"string": "Expiration date"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardUpdateInfoCard_dot_boughtByLabel": {
|
||||
"context": "GiftCardUpdateInfoCard bought by label",
|
||||
"string": "Bought by"
|
||||
|
@ -3511,13 +3578,9 @@
|
|||
"context": "GiftCardUpdateInfoCard used by label",
|
||||
"string": "Used by"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardUpdatePageHeader_dot_disableLabel": {
|
||||
"context": "GiftCardEnableDisableSection enable label",
|
||||
"string": "Disable"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardUpdatePageHeader_dot_enableLabel": {
|
||||
"context": "GiftCardEnableDisableSection enable label",
|
||||
"string": "Enable"
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardUpdatePageHeader_dot_resendButtonLabel": {
|
||||
"context": "giftCardUpdatePageHeader resendButtonLabel",
|
||||
"string": "Resend code"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_GiftCardUpdatePageHeader_dot_successfullyDisabledTitle": {
|
||||
"context": "GiftCardEnableDisableSection disable success",
|
||||
|
@ -3527,10 +3590,38 @@
|
|||
"context": "GiftCardEnableDisableSection enable success",
|
||||
"string": "Successfully enabled gift card"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_notFound": {
|
||||
"context": "giftCardErrorMessages not found",
|
||||
"string": "Couldn't find gift card"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardUpdate_dot_title": {
|
||||
"context": "GiftCardUpdateDetailsCard title",
|
||||
"string": "Details"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_GiftCardsListTable_dot_GiftCardsListTableHeader_dot_disableLabel": {
|
||||
"context": "GiftCardEnableDisableSection enable label",
|
||||
"string": "Deactivate"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_GiftCardsListTable_dot_GiftCardsListTableHeader_dot_enableLabel": {
|
||||
"context": "GiftCardEnableDisableSection enable label",
|
||||
"string": "Activate"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_GiftCardsListTable_dot_GiftCardsListTableHeader_dot_errorActivateAlertText": {
|
||||
"context": "GiftCardEnableDisableSection error activate alert text",
|
||||
"string": "Error activating gift {count,plural,one{card} other{cards}}"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_GiftCardsListTable_dot_GiftCardsListTableHeader_dot_errorDeactivateAlertText": {
|
||||
"context": "GiftCardEnableDisableSection error activate alert text",
|
||||
"string": "Errors deactivating gift {count,plural,one{card} other{cards}}"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_GiftCardsListTable_dot_GiftCardsListTableHeader_dot_successActivateAlertText": {
|
||||
"context": "GiftCardEnableDisableSection success activate alert text",
|
||||
"string": "Successfully activated gift {count,plural,one{card} other{cards}}"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_GiftCardsListTable_dot_GiftCardsListTableHeader_dot_successDeactivateAlertText": {
|
||||
"context": "GiftCardEnableDisableSection success activate alert text",
|
||||
"string": "Successfully deactivated gift {count,plural,one{card} other{cards}}"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_bulkIssue": {
|
||||
"context": "GiftCardsListHeader menu item settings",
|
||||
"string": "Bulk Issue"
|
||||
|
@ -3539,6 +3630,14 @@
|
|||
"context": "GiftCardsListTable code ending with label",
|
||||
"string": "Code ending with {displayCode}"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_createGiftCardProduct": {
|
||||
"context": "GiftCardsListHeader alert",
|
||||
"string": "Create a gift card product"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_createGiftCardProductType": {
|
||||
"context": "GiftCardsListHeader alert",
|
||||
"string": "Create a gift card product type"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_exportCodes": {
|
||||
"context": "GiftCardsListHeader menu item settings",
|
||||
"string": "Export card codes"
|
||||
|
@ -3547,6 +3646,10 @@
|
|||
"context": "GiftCardsListTable disabled label",
|
||||
"string": "Disabled"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_giftCardProduct": {
|
||||
"context": "GiftCardsListHeader alert",
|
||||
"string": "gift card product"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_giftCardsTableColumnBalanceTitle": {
|
||||
"context": "GiftCardsListTable column title balance",
|
||||
"string": "Balance"
|
||||
|
@ -3571,29 +3674,73 @@
|
|||
"context": "GiftCardsListHeader issue button label",
|
||||
"string": "Issue card"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_noGiftCardsAlertTitle": {
|
||||
"context": "GiftCardsListHeader alert",
|
||||
"string": "You haven’t defined a gift card product!"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_noGiftCardsFound": {
|
||||
"context": "GiftCardsListTable no cards found title",
|
||||
"string": "No gift cards found"
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_noGiftCardsProductTypes": {
|
||||
"context": "GiftCardsListHeader alert",
|
||||
"string": "{createGiftCardProductType} to start selling gift cards in your store."
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_noGiftCardsProducts": {
|
||||
"context": "GiftCardsListHeader alert",
|
||||
"string": "{createGiftCardProduct} to start selling gift cards in your store."
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_noGiftCardsProductsAndProductTypes": {
|
||||
"context": "GiftCardsListHeader alert",
|
||||
"string": "{createGiftCardProductType} and {giftCardProduct} to start selling gift cards in your store."
|
||||
},
|
||||
"src_dot_giftCards_dot_GiftCardsList_dot_settings": {
|
||||
"context": "GiftCardsListHeader menu item settings",
|
||||
"string": "Settings"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardExpirySelect_dot_expirationDateLabel": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection expiration date label",
|
||||
"string": "Expiration date"
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardDeleteDialog_dot_consentLabel": {
|
||||
"context": "GiftCardDeleteDialog consent label",
|
||||
"string": "{selectedItemsCount,plural,one{I am aware that I am removing a gift card with balance} other{I am aware that I am removing gift cards with balance}}"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardExpirySelect_dot_expiryDateLabel": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection expiry date label",
|
||||
"string": "Expiration date"
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardDeleteDialog_dot_defaultDescription": {
|
||||
"context": "GiftCardDeleteDialog default description",
|
||||
"string": "{selectedItemsCount,plural,one{Are you sure you want to delete this gift card?} other{Are you sure you want to delete {selectedItemsCount} giftCards?}}"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardExpirySelect_dot_expiryPeriodLabel": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection expiry period label",
|
||||
"string": "Expiry period"
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardDeleteDialog_dot_deleteSuccessAlertText": {
|
||||
"context": "GiftCardDeleteDialog success alert text",
|
||||
"string": "{selectedItemsCount,plural,one{Successfully deleted gift card} other{Successfully deleted gift cards}}"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardExpirySelect_dot_neverExpireLabel": {
|
||||
"context": "GiftCarUpdateDetailsExpirySection never expire label",
|
||||
"string": "Never expire"
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardDeleteDialog_dot_title": {
|
||||
"context": "GiftCardDeleteDialog single title",
|
||||
"string": "{selectedItemsCount,plural,one{Delete Gift Card} other{Delete Gift Cards}}"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardDeleteDialog_dot_withBalanceDescription": {
|
||||
"context": "GiftCardDeleteDialog with balance description",
|
||||
"string": "{selectedItemsCount,plural,one{The gift card you are about to delete has available balance. By deleting this card you may remove balance available to your customer.} other{You are about to delete gift cards with available balance. Are you sure you want to do that?}}"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardSendToCustomer_dot_channelSelectLabel": {
|
||||
"context": "GiftCardCreateDialog channel select label",
|
||||
"string": "Channel"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardSendToCustomer_dot_customerChannelSubtitle": {
|
||||
"context": "GiftCardCreateDialog customer channel subtitle",
|
||||
"string": "Customer will be sent the gift card code via this channels email address"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardSendToCustomer_dot_customerSubtitle": {
|
||||
"context": "GiftCardCreateDialog customer subtitle",
|
||||
"string": "Selected customer will be sent the generated gift card code. Someone else can redeem the gift card code. Gift card will be assigned to account which redeemed the code."
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardSendToCustomer_dot_sendToCustomerSelectedLabel": {
|
||||
"context": "GiftCardSendToCustomer send to customer selected label",
|
||||
"string": "Send gift card to customer"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardSettingsExpirySelect_dot_setExpirationPeriodDescription": {
|
||||
"context": "checkbox label description",
|
||||
"string": "Expiration date will be automatically set, once gift card is issued"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardSettingsExpirySelect_dot_setExpirationPeriodTitle": {
|
||||
"context": "checkbox label",
|
||||
"string": "Set gift card expiration period"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_GiftCardTagInput_dot_label": {
|
||||
"context": "GiftCardTagInput tag label",
|
||||
|
@ -3605,15 +3752,19 @@
|
|||
},
|
||||
"src_dot_giftCards_dot_components_dot_TimePeriodField_dot_dayLabel": {
|
||||
"context": "TimePeriodTextWithSelectField day label",
|
||||
"string": "days after usage"
|
||||
"string": "days after issue"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_TimePeriodField_dot_monthLabel": {
|
||||
"context": "TimePeriodTextWithSelectField month label",
|
||||
"string": "months after usage"
|
||||
"string": "months after issue"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_TimePeriodField_dot_weekLabel": {
|
||||
"context": "TimePeriodTextWithSelectField day label",
|
||||
"string": "weeks after issue"
|
||||
},
|
||||
"src_dot_giftCards_dot_components_dot_TimePeriodField_dot_yearLabel": {
|
||||
"context": "TimePeriodTextWithSelectField year label",
|
||||
"string": "years after usage"
|
||||
"string": "years after issue"
|
||||
},
|
||||
"src_dot_home": {
|
||||
"context": "home section name",
|
||||
|
@ -4411,6 +4562,10 @@
|
|||
"context": "order discount",
|
||||
"string": "Discount"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_372187363": {
|
||||
"context": "order payment",
|
||||
"string": "Paid with Gift Card"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderPayment_dot_3768782744": {
|
||||
"context": "order payment",
|
||||
"string": "Preauthorized amount"
|
||||
|
@ -4752,6 +4907,14 @@
|
|||
"context": "section header",
|
||||
"string": "Settings"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderSettings_dot_2116402092": {
|
||||
"context": "checkbox gift cards label",
|
||||
"string": "Automatically fulfill non shippable gift cards"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderSettings_dot_2879928595": {
|
||||
"context": "checkbox gift cards label description",
|
||||
"string": "when activated non-shippable gift cards will be automatically set as fulfilled and sent to customer"
|
||||
},
|
||||
"src_dot_orders_dot_components_dot_OrderSettings_dot_3281882935": {
|
||||
"context": "checkbox label description",
|
||||
"string": "All orders will be automatically confirmed and all payments will be captured."
|
||||
|
@ -5402,7 +5565,24 @@
|
|||
"context": "switch button",
|
||||
"string": "Product type uses Variant Attributes"
|
||||
},
|
||||
"src_dot_productTypes_dot_components_dot_ProductTypeDetails_dot_1007996279": {
|
||||
"src_dot_productTypes_dot_components_dot_ProductTypeDetails_dot_optionGiftCardDescription": {
|
||||
"context": "option description",
|
||||
"string": "This product type can be used to create voucher/gift card type products that user will be able to pay with during checkout process"
|
||||
},
|
||||
"src_dot_productTypes_dot_components_dot_ProductTypeDetails_dot_optionGiftCardTitle": {
|
||||
"context": "option",
|
||||
"string": "Products of this type can be used as gift card/voucher"
|
||||
},
|
||||
"src_dot_productTypes_dot_components_dot_ProductTypeDetails_dot_optionNormalDescription": {
|
||||
"context": "option description",
|
||||
"string": "This product type can be used to create shipping passes for your customers"
|
||||
},
|
||||
"src_dot_productTypes_dot_components_dot_ProductTypeDetails_dot_optionNormalTitle": {
|
||||
"context": "option",
|
||||
"string": "This is a normal product"
|
||||
},
|
||||
"src_dot_productTypes_dot_components_dot_ProductTypeDetails_dot_productTypeName": {
|
||||
"context": "label",
|
||||
"string": "Product Type Name"
|
||||
},
|
||||
"src_dot_productTypes_dot_components_dot_ProductTypeListPage_dot_1776073799": {
|
||||
|
@ -7594,6 +7774,10 @@
|
|||
"context": "event",
|
||||
"string": "Product Variant out of stock"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2315238863": {
|
||||
"context": "event",
|
||||
"string": "Product variant out of stock"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2454751033": {
|
||||
"context": "event",
|
||||
"string": "All events"
|
||||
|
@ -7690,6 +7874,10 @@
|
|||
"context": "event",
|
||||
"string": "Page created"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_69923590": {
|
||||
"context": "event",
|
||||
"string": "Product variant back in stock"
|
||||
},
|
||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_759562905": {
|
||||
"context": "event",
|
||||
"string": "Authorize payment"
|
||||
|
|
150
schema.graphql
150
schema.graphql
|
@ -1111,6 +1111,7 @@ enum CheckoutErrorCode {
|
|||
TAX_ERROR
|
||||
UNIQUE
|
||||
VOUCHER_NOT_APPLICABLE
|
||||
GIFT_CARD_NOT_APPLICABLE
|
||||
ZERO_QUANTITY
|
||||
MISSING_CHANNEL_SLUG
|
||||
CHANNEL_INACTIVE
|
||||
|
@ -2253,7 +2254,6 @@ type GiftCard implements Node & ObjectWithMetadata {
|
|||
code: String!
|
||||
isActive: Boolean!
|
||||
expiryDate: Date
|
||||
expiryType: GiftCardExpiryTypeEnum!
|
||||
tag: String
|
||||
created: DateTime!
|
||||
lastUsedOn: DateTime
|
||||
|
@ -2268,9 +2268,9 @@ type GiftCard implements Node & ObjectWithMetadata {
|
|||
createdByEmail: String
|
||||
usedByEmail: String
|
||||
app: App
|
||||
expiryPeriod: TimePeriod
|
||||
product: Product
|
||||
events: [GiftCardEvent!]!
|
||||
boughtInChannel: String
|
||||
user: User @deprecated(reason: "This field will be removed in Saleor 4.0. Use `createdBy` field instead.")
|
||||
endDate: DateTime @deprecated(reason: "This field will be removed in Saleor 4.0. Use `expiryDate` field instead.")
|
||||
startDate: DateTime @deprecated(reason: "This field will be removed in Saleor 4.0.")
|
||||
|
@ -2282,6 +2282,31 @@ type GiftCardActivate {
|
|||
errors: [GiftCardError!]!
|
||||
}
|
||||
|
||||
type GiftCardAddNote {
|
||||
giftCard: GiftCard
|
||||
event: GiftCardEvent
|
||||
errors: [GiftCardError!]!
|
||||
}
|
||||
|
||||
input GiftCardAddNoteInput {
|
||||
message: String!
|
||||
}
|
||||
|
||||
type GiftCardBulkActivate {
|
||||
count: Int!
|
||||
errors: [GiftCardError!]!
|
||||
}
|
||||
|
||||
type GiftCardBulkDeactivate {
|
||||
count: Int!
|
||||
errors: [GiftCardError!]!
|
||||
}
|
||||
|
||||
type GiftCardBulkDelete {
|
||||
count: Int!
|
||||
errors: [GiftCardError!]!
|
||||
}
|
||||
|
||||
type GiftCardCountableConnection {
|
||||
pageInfo: PageInfo!
|
||||
edges: [GiftCardCountableEdge!]!
|
||||
|
@ -2301,11 +2326,13 @@ type GiftCardCreate {
|
|||
|
||||
input GiftCardCreateInput {
|
||||
tag: String
|
||||
expiryDate: Date
|
||||
startDate: Date
|
||||
endDate: Date
|
||||
balance: PriceInput!
|
||||
userEmail: String
|
||||
expirySettings: GiftCardExpirySettingsInput!
|
||||
channel: String
|
||||
isActive: Boolean!
|
||||
code: String
|
||||
note: String
|
||||
}
|
||||
|
@ -2350,25 +2377,17 @@ type GiftCardEvent implements Node {
|
|||
tag: String
|
||||
oldTag: String
|
||||
balance: GiftCardEventBalance
|
||||
expiry: GiftCardEventExpiry
|
||||
expiryDate: Date
|
||||
oldExpiryDate: Date
|
||||
}
|
||||
|
||||
type GiftCardEventBalance {
|
||||
initialBalance: Money!
|
||||
initialBalance: Money
|
||||
currentBalance: Money!
|
||||
oldInitialBalance: Money
|
||||
oldCurrentBalance: Money
|
||||
}
|
||||
|
||||
type GiftCardEventExpiry {
|
||||
expiryType: GiftCardExpiryTypeEnum
|
||||
expiryPeriod: TimePeriod
|
||||
expiryDate: Date
|
||||
oldExpiryType: GiftCardExpiryTypeEnum
|
||||
oldExpiryPeriod: TimePeriod
|
||||
oldExpiryDate: Date
|
||||
}
|
||||
|
||||
enum GiftCardEventsEnum {
|
||||
ISSUED
|
||||
BOUGHT
|
||||
|
@ -2376,25 +2395,77 @@ enum GiftCardEventsEnum {
|
|||
ACTIVATED
|
||||
DEACTIVATED
|
||||
BALANCE_RESET
|
||||
EXPIRY_SETTINGS_UPDATED
|
||||
EXPIRY_DATE_UPDATED
|
||||
SENT_TO_CUSTOMER
|
||||
RESENT
|
||||
}
|
||||
|
||||
input GiftCardExpirySettingsInput {
|
||||
expiryType: GiftCardExpiryTypeEnum!
|
||||
expiryDate: Date
|
||||
expiryPeriod: TimePeriodInputType
|
||||
}
|
||||
|
||||
enum GiftCardExpiryTypeEnum {
|
||||
NEVER_EXPIRE
|
||||
EXPIRY_PERIOD
|
||||
EXPIRY_DATE
|
||||
NOTE_ADDED
|
||||
USED_IN_ORDER
|
||||
}
|
||||
|
||||
input GiftCardFilterInput {
|
||||
isActive: Boolean
|
||||
tag: String
|
||||
tags: [String]
|
||||
products: [ID]
|
||||
usedBy: [ID]
|
||||
currency: String
|
||||
currentBalance: PriceRangeInput
|
||||
initialBalance: PriceRangeInput
|
||||
}
|
||||
|
||||
type GiftCardResend {
|
||||
giftCard: GiftCard
|
||||
errors: [GiftCardError!]!
|
||||
}
|
||||
|
||||
input GiftCardResendInput {
|
||||
id: ID!
|
||||
email: String
|
||||
channel: String!
|
||||
}
|
||||
|
||||
type GiftCardSettings {
|
||||
expiryType: GiftCardSettingsExpiryTypeEnum!
|
||||
expiryPeriod: TimePeriod
|
||||
}
|
||||
|
||||
type GiftCardSettingsError {
|
||||
field: String
|
||||
message: String
|
||||
code: GiftCardSettingsErrorCode!
|
||||
}
|
||||
|
||||
enum GiftCardSettingsErrorCode {
|
||||
INVALID
|
||||
REQUIRED
|
||||
GRAPHQL_ERROR
|
||||
}
|
||||
|
||||
enum GiftCardSettingsExpiryTypeEnum {
|
||||
NEVER_EXPIRE
|
||||
EXPIRY_PERIOD
|
||||
}
|
||||
|
||||
type GiftCardSettingsUpdate {
|
||||
giftCardSettings: GiftCardSettings
|
||||
errors: [GiftCardSettingsError!]!
|
||||
}
|
||||
|
||||
input GiftCardSettingsUpdateInput {
|
||||
expiryType: GiftCardSettingsExpiryTypeEnum
|
||||
expiryPeriod: TimePeriodInputType
|
||||
}
|
||||
|
||||
enum GiftCardSortField {
|
||||
TAG
|
||||
PRODUCT
|
||||
USED_BY
|
||||
CURRENT_BALANCE
|
||||
}
|
||||
|
||||
input GiftCardSortingInput {
|
||||
direction: OrderDirection!
|
||||
field: GiftCardSortField!
|
||||
}
|
||||
|
||||
type GiftCardUpdate {
|
||||
|
@ -2405,10 +2476,10 @@ type GiftCardUpdate {
|
|||
|
||||
input GiftCardUpdateInput {
|
||||
tag: String
|
||||
expiryDate: Date
|
||||
startDate: Date
|
||||
endDate: Date
|
||||
balanceAmount: PositiveDecimal
|
||||
expirySettings: GiftCardExpirySettingsInput
|
||||
}
|
||||
|
||||
type Group implements Node {
|
||||
|
@ -3645,6 +3716,7 @@ type Mutation {
|
|||
shopSettingsTranslate(input: ShopSettingsTranslationInput!, languageCode: LanguageCodeEnum!): ShopSettingsTranslate
|
||||
shopAddressUpdate(input: AddressInput): ShopAddressUpdate
|
||||
orderSettingsUpdate(input: OrderSettingsUpdateInput!): OrderSettingsUpdate
|
||||
giftCardSettingsUpdate(input: GiftCardSettingsUpdateInput!): GiftCardSettingsUpdate
|
||||
shippingMethodChannelListingUpdate(id: ID!, input: ShippingMethodChannelListingInput!): ShippingMethodChannelListingUpdate
|
||||
shippingPriceCreate(input: ShippingPriceInput!): ShippingPriceCreate
|
||||
shippingPriceDelete(id: ID!): ShippingPriceDelete
|
||||
|
@ -3783,6 +3855,11 @@ type Mutation {
|
|||
giftCardDelete(id: ID!): GiftCardDelete
|
||||
giftCardDeactivate(id: ID!): GiftCardDeactivate
|
||||
giftCardUpdate(id: ID!, input: GiftCardUpdateInput!): GiftCardUpdate
|
||||
giftCardResend(input: GiftCardResendInput!): GiftCardResend
|
||||
giftCardAddNote(id: ID!, input: GiftCardAddNoteInput!): GiftCardAddNote
|
||||
giftCardBulkDelete(ids: [ID]!): GiftCardBulkDelete
|
||||
giftCardBulkActivate(ids: [ID]!): GiftCardBulkActivate
|
||||
giftCardBulkDeactivate(ids: [ID]!): GiftCardBulkDeactivate
|
||||
pluginUpdate(channelId: ID, id: ID!, input: PluginUpdateInput!): PluginUpdate
|
||||
externalNotificationTrigger(channel: String!, input: ExternalNotificationTriggerInput!, pluginId: String): ExternalNotificationTrigger
|
||||
saleCreate(input: SaleInput!): SaleCreate
|
||||
|
@ -4383,6 +4460,7 @@ input OrderReturnProductsInput {
|
|||
|
||||
type OrderSettings {
|
||||
automaticallyConfirmAllNewOrders: Boolean!
|
||||
automaticallyFulfillNonShippableGiftCard: Boolean!
|
||||
}
|
||||
|
||||
type OrderSettingsError {
|
||||
|
@ -4402,7 +4480,8 @@ type OrderSettingsUpdate {
|
|||
}
|
||||
|
||||
input OrderSettingsUpdateInput {
|
||||
automaticallyConfirmAllNewOrders: Boolean!
|
||||
automaticallyConfirmAllNewOrders: Boolean
|
||||
automaticallyFulfillNonShippableGiftCard: Boolean
|
||||
}
|
||||
|
||||
enum OrderSortField {
|
||||
|
@ -5235,6 +5314,7 @@ input ProductFilterInput {
|
|||
price: PriceRangeInput
|
||||
minimalPrice: PriceRangeInput
|
||||
productTypes: [ID]
|
||||
giftCard: Boolean
|
||||
ids: [ID]
|
||||
channel: String
|
||||
}
|
||||
|
@ -5397,6 +5477,7 @@ type ProductType implements Node & ObjectWithMetadata {
|
|||
weight: Weight
|
||||
privateMetadata: [MetadataItem]!
|
||||
metadata: [MetadataItem]!
|
||||
kind: ProductTypeKindEnum!
|
||||
products(channel: String, before: String, after: String, first: Int, last: Int): ProductCountableConnection @deprecated(reason: "This field will be removed in Saleor 4.0. Use the top-level `products` query with the `productTypes` filter.")
|
||||
taxType: TaxType
|
||||
variantAttributes(variantSelection: VariantAttributeScope): [Attribute]
|
||||
|
@ -5448,12 +5529,14 @@ input ProductTypeFilterInput {
|
|||
configurable: ProductTypeConfigurable
|
||||
productType: ProductTypeEnum
|
||||
metadata: [MetadataFilter]
|
||||
kind: ProductTypeKindEnum
|
||||
ids: [ID]
|
||||
}
|
||||
|
||||
input ProductTypeInput {
|
||||
name: String
|
||||
slug: String
|
||||
kind: ProductTypeKindEnum
|
||||
hasVariants: Boolean
|
||||
productAttributes: [ID]
|
||||
variantAttributes: [ID]
|
||||
|
@ -5463,6 +5546,11 @@ input ProductTypeInput {
|
|||
taxCode: String
|
||||
}
|
||||
|
||||
enum ProductTypeKindEnum {
|
||||
NORMAL
|
||||
GIFT_CARD
|
||||
}
|
||||
|
||||
type ProductTypeReorderAttributes {
|
||||
productType: ProductType
|
||||
productErrors: [ProductError!]! @deprecated(reason: "This field will be removed in Saleor 4.0. Use `errors` field instead.")
|
||||
|
@ -5682,6 +5770,7 @@ type Query {
|
|||
stocks(filter: StockFilterInput, before: String, after: String, first: Int, last: Int): StockCountableConnection
|
||||
shop: Shop!
|
||||
orderSettings: OrderSettings
|
||||
giftCardSettings: GiftCardSettings!
|
||||
shippingZone(id: ID!, channel: String): ShippingZone
|
||||
shippingZones(filter: ShippingZoneFilterInput, channel: String, before: String, after: String, first: Int, last: Int): ShippingZoneCountableConnection
|
||||
digitalContent(id: ID!): DigitalContent
|
||||
|
@ -5714,7 +5803,7 @@ type Query {
|
|||
menuItem(id: ID!, channel: String): MenuItem
|
||||
menuItems(channel: String, sortBy: MenuItemSortingInput, filter: MenuItemFilterInput, before: String, after: String, first: Int, last: Int): MenuItemCountableConnection
|
||||
giftCard(id: ID!): GiftCard
|
||||
giftCards(filter: GiftCardFilterInput, before: String, after: String, first: Int, last: Int): GiftCardCountableConnection
|
||||
giftCards(sortBy: GiftCardSortingInput, filter: GiftCardFilterInput, before: String, after: String, first: Int, last: Int): GiftCardCountableConnection
|
||||
plugin(id: ID!): Plugin
|
||||
plugins(filter: PluginFilterInput, sortBy: PluginSortingInput, before: String, after: String, first: Int, last: Int): PluginCountableConnection
|
||||
sale(id: ID!, channel: String): Sale
|
||||
|
@ -6471,6 +6560,7 @@ input TimePeriodInputType {
|
|||
|
||||
enum TimePeriodTypeEnum {
|
||||
DAY
|
||||
WEEK
|
||||
MONTH
|
||||
YEAR
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { ConfirmButtonTransitionState } from "../ConfirmButton";
|
|||
import DialogButtons from "./DialogButtons";
|
||||
import { ActionDialogVariant, Size } from "./types";
|
||||
|
||||
interface ActionDialogProps extends DialogProps {
|
||||
export interface ActionDialogProps extends DialogProps {
|
||||
children?: React.ReactNode;
|
||||
confirmButtonLabel?: string;
|
||||
confirmButtonState: ConfirmButtonTransitionState;
|
||||
|
|
|
@ -57,8 +57,7 @@ export const AppChannelProvider: React.FC = ({ children }) => {
|
|||
const availableChannels = channelData?.channels || [];
|
||||
|
||||
const channel =
|
||||
channelData &&
|
||||
(availableChannels.find(channel => channel.id === selectedChannel) || null);
|
||||
channelData && (availableChannels.find(getById(selectedChannel)) || null);
|
||||
|
||||
return (
|
||||
<AppChannelContext.Provider
|
||||
|
|
|
@ -3,13 +3,13 @@ import { ChannelData } from "@saleor/channels/utils";
|
|||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||
import Hr from "@saleor/components/Hr";
|
||||
import RadioSwitchField from "@saleor/components/RadioSwitchField";
|
||||
import useCurrentDate from "@saleor/hooks/useCurrentDate";
|
||||
import useDateLocalize from "@saleor/hooks/useDateLocalize";
|
||||
import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors";
|
||||
import classNames from "classnames";
|
||||
import React, { useState } from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { DateContext } from "../../Date/DateContext";
|
||||
import { useStyles } from "../styles";
|
||||
import { ChannelOpts, ChannelsAvailabilityError, Messages } from "../types";
|
||||
export interface ChannelContentProps {
|
||||
|
@ -43,7 +43,7 @@ const ChannelContent: React.FC<ChannelContentProps> = ({
|
|||
publicationDate,
|
||||
...(visibleInListings !== undefined ? { visibleInListings } : {})
|
||||
};
|
||||
const dateNow = React.useContext(DateContext);
|
||||
const dateNow = useCurrentDate();
|
||||
const localizeDate = useDateLocalize();
|
||||
const hasAvailableProps =
|
||||
isAvailable !== undefined && availableForPurchase !== undefined;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { Divider } from "@material-ui/core";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
@ -17,6 +18,9 @@ const useStyles = makeStyles(
|
|||
}
|
||||
}
|
||||
},
|
||||
underline: {
|
||||
marginBottom: theme.spacing(4)
|
||||
},
|
||||
grid: {
|
||||
padding: theme.spacing(2)
|
||||
},
|
||||
|
@ -51,25 +55,34 @@ interface ExtendedPageHeaderProps {
|
|||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
inline?: boolean;
|
||||
underline?: boolean;
|
||||
title?: React.ReactNode;
|
||||
testId?: string;
|
||||
}
|
||||
|
||||
const ExtendedPageHeader: React.FC<ExtendedPageHeaderProps> = props => {
|
||||
const { children, className, inline, title, testId } = props;
|
||||
const { children, className, inline, underline, title, testId } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<div
|
||||
data-test-id={testId}
|
||||
className={classNames(classes.root, className, {
|
||||
[classes.block]: !inline
|
||||
})}
|
||||
>
|
||||
{title}
|
||||
<div className={classes.action}>{children}</div>
|
||||
</div>
|
||||
<>
|
||||
<div
|
||||
data-test-id={testId}
|
||||
className={classNames(classes.root, className, {
|
||||
[classes.block]: !inline,
|
||||
[classes.underline]: underline
|
||||
})}
|
||||
>
|
||||
{title}
|
||||
<div className={classes.action}>{children}</div>
|
||||
</div>
|
||||
{underline && (
|
||||
<div className={classes.underline}>
|
||||
<Divider />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
ExtendedPageHeader.displayName = "ExtendedPageHeader";
|
||||
|
|
|
@ -43,12 +43,13 @@ interface PageHeaderProps {
|
|||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
inline?: boolean;
|
||||
underline?: boolean;
|
||||
limitText?: string;
|
||||
title?: React.ReactNode;
|
||||
}
|
||||
|
||||
const PageHeader: React.FC<PageHeaderProps> = props => {
|
||||
const { children, className, inline, limitText, title } = props;
|
||||
const { children, className, inline, underline, limitText, title } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
|
@ -57,6 +58,7 @@ const PageHeader: React.FC<PageHeaderProps> = props => {
|
|||
testId="page-header"
|
||||
className={className}
|
||||
inline={inline}
|
||||
underline={underline}
|
||||
title={
|
||||
<Typography className={classes.title} variant="h5">
|
||||
{title !== undefined ? title : <Skeleton style={{ width: "10em" }} />}
|
||||
|
|
|
@ -7,47 +7,11 @@ import {
|
|||
Radio,
|
||||
RadioGroup
|
||||
} from "@material-ui/core";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
alignTop: {
|
||||
alignSelf: "baseline",
|
||||
position: "relative",
|
||||
top: -6
|
||||
},
|
||||
formLabel: {
|
||||
marginBottom: theme.spacing(1)
|
||||
},
|
||||
radioGroupInline: {
|
||||
flexDirection: "row"
|
||||
},
|
||||
radioLabel: {
|
||||
marginBottom: theme.spacing(-0.5)
|
||||
},
|
||||
radioLabelInline: {
|
||||
marginRight: theme.spacing(4)
|
||||
},
|
||||
root: {
|
||||
"& $radioLabel": {
|
||||
"&:last-of-type": {
|
||||
marginBottom: 0
|
||||
}
|
||||
},
|
||||
padding: 0,
|
||||
width: "100%"
|
||||
},
|
||||
rootNoLabel: {
|
||||
marginTop: theme.spacing(-1.5)
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "RadioGroupField"
|
||||
}
|
||||
);
|
||||
import { useStyles } from "./styles";
|
||||
|
||||
export interface RadioGroupFieldChoice<
|
||||
T extends string | number = string | number
|
||||
|
@ -119,6 +83,9 @@ export const RadioGroupField: React.FC<RadioGroupFieldProps> = props => {
|
|||
[classes.radioLabel]: variant !== "inline",
|
||||
[classes.radioLabelInline]: variant === "inline"
|
||||
})}
|
||||
classes={{
|
||||
label: classes.label
|
||||
}}
|
||||
control={
|
||||
<Radio
|
||||
className={classNames({
|
||||
|
|
43
src/components/RadioGroupField/styles.ts
Normal file
43
src/components/RadioGroupField/styles.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
|
||||
export const useStyles = makeStyles(
|
||||
theme => ({
|
||||
alignTop: {
|
||||
alignSelf: "baseline",
|
||||
position: "relative",
|
||||
top: -6
|
||||
},
|
||||
formLabel: {
|
||||
marginBottom: theme.spacing(1)
|
||||
},
|
||||
radioGroupInline: {
|
||||
flexDirection: "row"
|
||||
},
|
||||
radioLabel: {
|
||||
alignItems: "start",
|
||||
marginBottom: theme.spacing(-0.5)
|
||||
},
|
||||
radioLabelInline: {
|
||||
alignItems: "start",
|
||||
marginRight: theme.spacing(4)
|
||||
},
|
||||
label: {
|
||||
marginTop: theme.spacing(1.5)
|
||||
},
|
||||
root: {
|
||||
"& $radioLabel": {
|
||||
"&:last-of-type": {
|
||||
marginBottom: 0
|
||||
}
|
||||
},
|
||||
padding: 0,
|
||||
width: "100%"
|
||||
},
|
||||
rootNoLabel: {
|
||||
marginTop: theme.spacing(-1.5)
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "RadioGroupField"
|
||||
}
|
||||
);
|
|
@ -0,0 +1,46 @@
|
|||
import { Typography } from "@material-ui/core";
|
||||
import React, { ChangeEvent } from "react";
|
||||
|
||||
import CardSpacer from "../CardSpacer";
|
||||
import ControlledCheckbox from "../ControlledCheckbox";
|
||||
import { useTypeDeleteWarningDialogStyles as useStyles } from "./styles";
|
||||
|
||||
interface DeleteWarningDialogConsentContentProps {
|
||||
description: string | React.ReactNode[];
|
||||
consentLabel: string;
|
||||
isConsentChecked: boolean;
|
||||
onConsentChange: (value: boolean) => void;
|
||||
}
|
||||
|
||||
const DeleteWarningDialogConsentContent: React.FC<DeleteWarningDialogConsentContentProps> = ({
|
||||
description,
|
||||
consentLabel,
|
||||
isConsentChecked,
|
||||
onConsentChange
|
||||
}) => {
|
||||
const classes = useStyles();
|
||||
|
||||
const handleConsentChange = ({ target }: ChangeEvent<any>) =>
|
||||
onConsentChange(target.value);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography>{description}</Typography>
|
||||
<CardSpacer />
|
||||
{consentLabel && (
|
||||
<ControlledCheckbox
|
||||
name="delete-assigned-items-consent"
|
||||
checked={isConsentChecked}
|
||||
onChange={handleConsentChange}
|
||||
label={
|
||||
<Typography className={classes.consentLabel}>
|
||||
{consentLabel}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DeleteWarningDialogConsentContent;
|
|
@ -1,13 +1,13 @@
|
|||
import { CardContent, Typography } from "@material-ui/core";
|
||||
import { CardContent } from "@material-ui/core";
|
||||
import HorizontalSpacer from "@saleor/apps/components/HorizontalSpacer";
|
||||
import CardSpacer from "@saleor/components/CardSpacer";
|
||||
import ConfirmButton from "@saleor/components/ConfirmButton";
|
||||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||
import DeleteButton from "@saleor/components/DeleteButton";
|
||||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import React, { ChangeEvent, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { MessageDescriptor, useIntl } from "react-intl";
|
||||
|
||||
import DeleteButton from "../DeleteButton";
|
||||
import DeleteWarningDialogConsentContent from "./DeleteWarningDialogConsentContent";
|
||||
import { useTypeDeleteWarningDialogStyles as useStyles } from "./styles";
|
||||
|
||||
interface TypeDeleteWarningDialogContentProps {
|
||||
|
@ -40,9 +40,6 @@ const TypeDeleteWarningDialogContent: React.FC<TypeDeleteWarningDialogContentPro
|
|||
|
||||
const [isConsentChecked, setIsConsentChecked] = useState(false);
|
||||
|
||||
const handleConsentChange = ({ target }: ChangeEvent<any>) =>
|
||||
setIsConsentChecked(target.value);
|
||||
|
||||
const handleViewAssignedItems = () => navigate(viewAssignedItemsUrl);
|
||||
|
||||
const isDisbled = hasAssignedItems ? !isConsentChecked : false;
|
||||
|
@ -52,26 +49,16 @@ const TypeDeleteWarningDialogContent: React.FC<TypeDeleteWarningDialogContentPro
|
|||
|
||||
return (
|
||||
<CardContent>
|
||||
<Typography>
|
||||
{intl.formatMessage(description, {
|
||||
<DeleteWarningDialogConsentContent
|
||||
description={intl.formatMessage(description, {
|
||||
typeName: singleItemSelectedName,
|
||||
assignedItemsCount,
|
||||
b: (...chunks) => <b>{chunks}</b>
|
||||
})}
|
||||
</Typography>
|
||||
<CardSpacer />
|
||||
{consentLabel && (
|
||||
<ControlledCheckbox
|
||||
name="delete-assigned-items-consent"
|
||||
checked={isConsentChecked}
|
||||
onChange={handleConsentChange}
|
||||
label={
|
||||
<Typography className={classes.consentLabel}>
|
||||
{intl.formatMessage(consentLabel)}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
consentLabel={consentLabel && intl.formatMessage(consentLabel)}
|
||||
isConsentChecked={isConsentChecked}
|
||||
onConsentChange={setIsConsentChecked}
|
||||
/>
|
||||
<CardSpacer />
|
||||
<div className={classes.buttonsSection}>
|
||||
{shouldShowViewAssignedItemsButton && (
|
||||
|
|
|
@ -3,6 +3,7 @@ import CardTitle from "@saleor/components/CardTitle";
|
|||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||
import Hr from "@saleor/components/Hr";
|
||||
import RadioSwitchField from "@saleor/components/RadioSwitchField";
|
||||
import useCurrentDate from "@saleor/hooks/useCurrentDate";
|
||||
import useDateLocalize from "@saleor/hooks/useDateLocalize";
|
||||
import { ChangeEvent } from "@saleor/hooks/useForm";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
|
@ -12,7 +13,6 @@ import classNames from "classnames";
|
|||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { DateContext } from "../Date/DateContext";
|
||||
import FormSpacer from "../FormSpacer";
|
||||
import DateVisibilitySelector from "./DateVisibilitySelector";
|
||||
|
||||
|
@ -103,7 +103,7 @@ export const VisibilityCard: React.FC<VisibilityCardProps> = props => {
|
|||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
const localizeDate = useDateLocalize();
|
||||
const dateNow = React.useContext(DateContext);
|
||||
const dateNow = useCurrentDate();
|
||||
const hasAvailableProps =
|
||||
isAvailable !== undefined && availableForPurchase !== undefined;
|
||||
|
||||
|
|
|
@ -222,3 +222,10 @@ export const giftCardErrorFragment = gql`
|
|||
field
|
||||
}
|
||||
`;
|
||||
|
||||
export const giftCardSettingsErrorFragment = gql`
|
||||
fragment GiftCardSettingsErrorFragment on GiftCardSettingsError {
|
||||
code
|
||||
field
|
||||
}
|
||||
`;
|
||||
|
|
11
src/fragments/giftCards.ts
Normal file
11
src/fragments/giftCards.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import gql from "graphql-tag";
|
||||
|
||||
export const fragmentGiftCardsSettings = gql`
|
||||
fragment GiftCardsSettingsFragment on GiftCardSettings {
|
||||
expiryType
|
||||
expiryPeriod {
|
||||
type
|
||||
amount
|
||||
}
|
||||
}
|
||||
`;
|
|
@ -182,6 +182,27 @@ export const fragmentOrderDetails = gql`
|
|||
billingAddress {
|
||||
...AddressFragment
|
||||
}
|
||||
giftCards {
|
||||
events {
|
||||
id
|
||||
type
|
||||
orderId
|
||||
balance {
|
||||
initialBalance {
|
||||
...Money
|
||||
}
|
||||
currentBalance {
|
||||
...Money
|
||||
}
|
||||
oldInitialBalance {
|
||||
...Money
|
||||
}
|
||||
oldCurrentBalance {
|
||||
...Money
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
isShippingRequired
|
||||
canFinalize
|
||||
created
|
||||
|
@ -296,6 +317,7 @@ export const fragmentOrderDetails = gql`
|
|||
export const fragmentOrderSettings = gql`
|
||||
fragment OrderSettingsFragment on OrderSettings {
|
||||
automaticallyConfirmAllNewOrders
|
||||
automaticallyFulfillNonShippableGiftCard
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ export const productTypeFragment = gql`
|
|||
fragment ProductTypeFragment on ProductType {
|
||||
id
|
||||
name
|
||||
kind
|
||||
hasVariants
|
||||
isShippingRequired
|
||||
taxType {
|
||||
|
|
16
src/fragments/types/GiftCardSettingsErrorFragment.ts
Normal file
16
src/fragments/types/GiftCardSettingsErrorFragment.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardSettingsErrorCode } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL fragment: GiftCardSettingsErrorFragment
|
||||
// ====================================================
|
||||
|
||||
export interface GiftCardSettingsErrorFragment {
|
||||
__typename: "GiftCardSettingsError";
|
||||
code: GiftCardSettingsErrorCode;
|
||||
field: string | null;
|
||||
}
|
22
src/fragments/types/GiftCardsSettingsFragment.ts
Normal file
22
src/fragments/types/GiftCardsSettingsFragment.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardSettingsExpiryTypeEnum, TimePeriodTypeEnum } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL fragment: GiftCardsSettingsFragment
|
||||
// ====================================================
|
||||
|
||||
export interface GiftCardsSettingsFragment_expiryPeriod {
|
||||
__typename: "TimePeriod";
|
||||
type: TimePeriodTypeEnum;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export interface GiftCardsSettingsFragment {
|
||||
__typename: "GiftCardSettings";
|
||||
expiryType: GiftCardSettingsExpiryTypeEnum;
|
||||
expiryPeriod: GiftCardsSettingsFragment_expiryPeriod | null;
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { OrderDiscountType, DiscountValueTypeEnum, OrderEventsEmailsEnum, OrderEventsEnum, FulfillmentStatus, PaymentChargeStatusEnum, WarehouseClickAndCollectOptionEnum, OrderStatus, OrderAction, JobStatusEnum } from "./../../types/globalTypes";
|
||||
import { GiftCardEventsEnum, OrderDiscountType, DiscountValueTypeEnum, OrderEventsEmailsEnum, OrderEventsEnum, FulfillmentStatus, PaymentChargeStatusEnum, WarehouseClickAndCollectOptionEnum, OrderStatus, OrderAction, JobStatusEnum } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL fragment: OrderDetailsFragment
|
||||
|
@ -43,6 +43,51 @@ export interface OrderDetailsFragment_billingAddress {
|
|||
streetAddress2: string;
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_giftCards_events_balance_initialBalance {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_giftCards_events_balance_currentBalance {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_giftCards_events_balance_oldInitialBalance {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_giftCards_events_balance_oldCurrentBalance {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_giftCards_events_balance {
|
||||
__typename: "GiftCardEventBalance";
|
||||
initialBalance: OrderDetailsFragment_giftCards_events_balance_initialBalance | null;
|
||||
currentBalance: OrderDetailsFragment_giftCards_events_balance_currentBalance;
|
||||
oldInitialBalance: OrderDetailsFragment_giftCards_events_balance_oldInitialBalance | null;
|
||||
oldCurrentBalance: OrderDetailsFragment_giftCards_events_balance_oldCurrentBalance | null;
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_giftCards_events {
|
||||
__typename: "GiftCardEvent";
|
||||
id: string;
|
||||
type: GiftCardEventsEnum | null;
|
||||
orderId: string | null;
|
||||
balance: OrderDetailsFragment_giftCards_events_balance | null;
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_giftCards {
|
||||
__typename: "GiftCard";
|
||||
events: OrderDetailsFragment_giftCards_events[];
|
||||
}
|
||||
|
||||
export interface OrderDetailsFragment_discounts_amount {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
|
@ -497,6 +542,7 @@ export interface OrderDetailsFragment {
|
|||
metadata: (OrderDetailsFragment_metadata | null)[];
|
||||
privateMetadata: (OrderDetailsFragment_privateMetadata | null)[];
|
||||
billingAddress: OrderDetailsFragment_billingAddress | null;
|
||||
giftCards: (OrderDetailsFragment_giftCards | null)[] | null;
|
||||
isShippingRequired: boolean;
|
||||
canFinalize: boolean;
|
||||
created: any;
|
||||
|
|
|
@ -10,4 +10,5 @@
|
|||
export interface OrderSettingsFragment {
|
||||
__typename: "OrderSettings";
|
||||
automaticallyConfirmAllNewOrders: boolean;
|
||||
automaticallyFulfillNonShippableGiftCard: boolean;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { AttributeTypeEnum, MeasurementUnitsEnum, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||
import { ProductTypeKindEnum, AttributeTypeEnum, MeasurementUnitsEnum, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL fragment: ProductTypeDetailsFragment
|
||||
|
@ -63,6 +63,7 @@ export interface ProductTypeDetailsFragment {
|
|||
__typename: "ProductType";
|
||||
id: string;
|
||||
name: string;
|
||||
kind: ProductTypeKindEnum;
|
||||
hasVariants: boolean;
|
||||
isShippingRequired: boolean;
|
||||
taxType: ProductTypeDetailsFragment_taxType | null;
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { ProductTypeKindEnum } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL fragment: ProductTypeFragment
|
||||
// ====================================================
|
||||
|
@ -17,6 +19,7 @@ export interface ProductTypeFragment {
|
|||
__typename: "ProductType";
|
||||
id: string;
|
||||
name: string;
|
||||
kind: ProductTypeKindEnum;
|
||||
hasVariants: boolean;
|
||||
isShippingRequired: boolean;
|
||||
taxType: ProductTypeFragment_taxType | null;
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import { Dialog, DialogTitle } from "@material-ui/core";
|
||||
import { IMessage } from "@saleor/components/messages";
|
||||
import useCurrentDate from "@saleor/hooks/useCurrentDate";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
import { GiftCardCreateInput } from "@saleor/types/globalTypes";
|
||||
import commonErrorMessages from "@saleor/utils/errors/common";
|
||||
import { DialogActionHandlersProps } from "@saleor/utils/handlers/dialogActionHandlers";
|
||||
import React, { useState } from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { GIFT_CARD_LIST_QUERY } from "../GiftCardsList/types";
|
||||
import ContentWithProgress from "./ContentWithProgress";
|
||||
import GiftCardCreateDialogCodeContent from "./GiftCardCreateDialogCodeContent";
|
||||
import GiftCardCreateDialogForm, {
|
||||
|
@ -15,15 +18,10 @@ import { giftCardCreateDialogMessages as messages } from "./messages";
|
|||
import { useGiftCardCreateMutation } from "./mutations";
|
||||
import { useChannelCurrencies } from "./queries";
|
||||
import { GiftCardCreate } from "./types/GiftCardCreate";
|
||||
import { getGiftCardExpirySettingsInputData } from "./utils";
|
||||
import { getGiftCardExpiryInputData } from "./utils";
|
||||
|
||||
interface GiftCardCreateDialogProps {
|
||||
onClose: () => void;
|
||||
open: boolean;
|
||||
}
|
||||
|
||||
const GiftCardCreateDialog: React.FC<GiftCardCreateDialogProps> = ({
|
||||
onClose,
|
||||
const GiftCardCreateDialog: React.FC<DialogActionHandlersProps> = ({
|
||||
closeDialog,
|
||||
open
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
|
@ -56,6 +54,8 @@ const GiftCardCreateDialog: React.FC<GiftCardCreateDialogProps> = ({
|
|||
}
|
||||
};
|
||||
|
||||
const currentDate = useCurrentDate();
|
||||
|
||||
const getParsedSubmitInputData = (
|
||||
formData: GiftCardCreateFormData
|
||||
): GiftCardCreateInput => {
|
||||
|
@ -64,23 +64,29 @@ const GiftCardCreateDialog: React.FC<GiftCardCreateDialogProps> = ({
|
|||
balanceCurrency,
|
||||
note,
|
||||
tag,
|
||||
selectedCustomer
|
||||
sendToCustomerSelected,
|
||||
selectedCustomer,
|
||||
requiresActivation,
|
||||
channelSlug
|
||||
} = formData;
|
||||
|
||||
return {
|
||||
note: note || null,
|
||||
tag: tag || null,
|
||||
userEmail: selectedCustomer.email || null,
|
||||
userEmail: (sendToCustomerSelected && selectedCustomer.email) || null,
|
||||
channel: (sendToCustomerSelected && channelSlug) || null,
|
||||
balance: {
|
||||
amount: balanceAmount,
|
||||
currency: balanceCurrency
|
||||
},
|
||||
expirySettings: getGiftCardExpirySettingsInputData(formData)
|
||||
expiryDate: getGiftCardExpiryInputData(formData, currentDate),
|
||||
isActive: !requiresActivation
|
||||
};
|
||||
};
|
||||
|
||||
const [createGiftCard, createGiftCardOpts] = useGiftCardCreateMutation({
|
||||
onCompleted
|
||||
onCompleted,
|
||||
refetchQueries: [GIFT_CARD_LIST_QUERY]
|
||||
});
|
||||
|
||||
const handleSubmit = (data: GiftCardCreateFormData) => {
|
||||
|
@ -92,7 +98,7 @@ const GiftCardCreateDialog: React.FC<GiftCardCreateDialogProps> = ({
|
|||
};
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
closeDialog();
|
||||
// dialog closing animation runs slower than prop change
|
||||
// and we don't want to show the form for a split second
|
||||
setTimeout(() => setCardCode(null), 0);
|
||||
|
|
|
@ -1,33 +1,51 @@
|
|||
import { DialogContent, Divider, TextField } from "@material-ui/core";
|
||||
import {
|
||||
DialogContent,
|
||||
Divider,
|
||||
TextField,
|
||||
Typography
|
||||
} from "@material-ui/core";
|
||||
import VerticalSpacer from "@saleor/apps/components/VerticalSpacer";
|
||||
import DialogButtons from "@saleor/components/ActionDialog/DialogButtons";
|
||||
import CardSpacer from "@saleor/components/CardSpacer";
|
||||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||
import TextWithSelectField from "@saleor/components/TextWithSelectField";
|
||||
import { GiftCardError } from "@saleor/fragments/types/GiftCardError";
|
||||
import GiftCardExpirySelect from "@saleor/giftCards/components/GiftCardExpirySelect";
|
||||
import GiftCardTagInput from "@saleor/giftCards/components/GiftCardTagInput";
|
||||
import useForm from "@saleor/hooks/useForm";
|
||||
import { commonMessages } from "@saleor/intl";
|
||||
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
||||
import Label from "@saleor/orders/components/OrderHistory/Label";
|
||||
import {
|
||||
GiftCardExpiryTypeEnum,
|
||||
GiftCardSettingsExpiryTypeEnum,
|
||||
TimePeriodTypeEnum
|
||||
} from "@saleor/types/globalTypes";
|
||||
import { getFormErrors } from "@saleor/utils/errors";
|
||||
import { mapSingleValueNodeToChoice } from "@saleor/utils/maps";
|
||||
import React, { useState } from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
import GiftCardSendToCustomer from "../components/GiftCardSendToCustomer/GiftCardSendToCustomer";
|
||||
import { useGiftCardSettingsQuery } from "../GiftCardSettings/queries";
|
||||
import { getGiftCardErrorMessage } from "../GiftCardUpdate/messages";
|
||||
import GiftCardCustomerSelectField from "./GiftCardCustomerSelectField";
|
||||
import GiftCardCreateExpirySelect from "./GiftCardCreateExpirySelect";
|
||||
import { giftCardCreateDialogMessages as messages } from "./messages";
|
||||
import { useGiftCardCreateDialogFormStyles as useStyles } from "./styles";
|
||||
import { GiftCardCommonFormData, GiftCardCreateFormCustomer } from "./types";
|
||||
import {
|
||||
GiftCardCommonFormData,
|
||||
GiftCardCreateFormCustomer,
|
||||
GiftCardExpiryType
|
||||
} from "./types";
|
||||
|
||||
export interface GiftCardCreateFormData extends GiftCardCommonFormData {
|
||||
note: string;
|
||||
sendToCustomerSelected: boolean;
|
||||
selectedCustomer?: GiftCardCreateFormCustomer;
|
||||
channelSlug?: string;
|
||||
expirySelected: boolean;
|
||||
expiryType: GiftCardExpiryType;
|
||||
expiryPeriodType: TimePeriodTypeEnum;
|
||||
expiryPeriodAmount: number;
|
||||
requiresActivation: boolean;
|
||||
}
|
||||
|
||||
const initialCustomer = { email: "", name: "" };
|
||||
|
@ -37,10 +55,13 @@ export const initialData: GiftCardCreateFormData = {
|
|||
balanceAmount: 1,
|
||||
balanceCurrency: null,
|
||||
note: "",
|
||||
sendToCustomerSelected: false,
|
||||
expirySelected: false,
|
||||
expiryType: "EXPIRY_PERIOD",
|
||||
expiryDate: "",
|
||||
expiryType: GiftCardExpiryTypeEnum.EXPIRY_PERIOD,
|
||||
expiryPeriodType: TimePeriodTypeEnum.YEAR,
|
||||
expiryPeriodAmount: 1
|
||||
expiryPeriodType: TimePeriodTypeEnum.MONTH,
|
||||
expiryPeriodAmount: 12,
|
||||
requiresActivation: true
|
||||
};
|
||||
|
||||
interface GiftCardCreateDialogFormProps {
|
||||
|
@ -63,6 +84,11 @@ const GiftCardCreateDialogForm: React.FC<GiftCardCreateDialogFormProps> = ({
|
|||
|
||||
const initialCurrency = channelCurrencies[0];
|
||||
|
||||
const {
|
||||
data: settingsData,
|
||||
loading: loadingSettings
|
||||
} = useGiftCardSettingsQuery();
|
||||
|
||||
const [selectedCustomer, setSelectedCustomer] = useState<
|
||||
GiftCardCreateFormCustomer
|
||||
>(initialCustomer);
|
||||
|
@ -70,33 +96,65 @@ const GiftCardCreateDialogForm: React.FC<GiftCardCreateDialogFormProps> = ({
|
|||
const handleSubmit = (data: GiftCardCreateFormData) =>
|
||||
onSubmit({ ...data, selectedCustomer });
|
||||
|
||||
const getInitialExpirySettingsData = (): Partial<GiftCardCreateFormData> => {
|
||||
if (loadingSettings) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const { expiryType, expiryPeriod } = settingsData?.giftCardSettings;
|
||||
|
||||
if (expiryType === GiftCardSettingsExpiryTypeEnum.NEVER_EXPIRE) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
expiryType,
|
||||
expiryPeriodType: expiryPeriod?.type,
|
||||
expiryPeriodAmount: expiryPeriod?.amount
|
||||
};
|
||||
};
|
||||
|
||||
const { submit, change, data } = useForm(
|
||||
{ ...initialData, balanceCurrency: initialCurrency },
|
||||
{
|
||||
...initialData,
|
||||
...getInitialExpirySettingsData(),
|
||||
balanceCurrency: initialCurrency,
|
||||
channelSlug: ""
|
||||
},
|
||||
handleSubmit
|
||||
);
|
||||
|
||||
const formErrors = getFormErrors(
|
||||
[
|
||||
"tag",
|
||||
"expiryDate",
|
||||
"expiryPeriod",
|
||||
"customer",
|
||||
"currency",
|
||||
"amount",
|
||||
"balance"
|
||||
],
|
||||
["tag", "expiryDate", "customer", "currency", "amount", "balance"],
|
||||
apiErrors
|
||||
);
|
||||
|
||||
const {
|
||||
tag,
|
||||
sendToCustomerSelected,
|
||||
channelSlug,
|
||||
balanceAmount,
|
||||
balanceCurrency,
|
||||
expirySelected,
|
||||
expiryType,
|
||||
expiryPeriodAmount,
|
||||
expiryPeriodType,
|
||||
expiryType,
|
||||
balanceAmount,
|
||||
balanceCurrency
|
||||
expiryDate,
|
||||
requiresActivation
|
||||
} = data;
|
||||
|
||||
const shouldEnableSubmitButton = () => {
|
||||
if (!balanceAmount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (expirySelected && expiryType === "EXPIRY_DATE") {
|
||||
return !!expiryDate;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DialogContent>
|
||||
|
@ -107,7 +165,7 @@ const GiftCardCreateDialogForm: React.FC<GiftCardCreateDialogFormProps> = ({
|
|||
choices={mapSingleValueNodeToChoice(channelCurrencies)}
|
||||
containerClassName={classes.balanceContainer}
|
||||
textFieldProps={{
|
||||
type: "number",
|
||||
type: "float",
|
||||
label: intl.formatMessage(messages.amountLabel),
|
||||
name: "balanceAmount",
|
||||
value: balanceAmount,
|
||||
|
@ -128,24 +186,25 @@ const GiftCardCreateDialogForm: React.FC<GiftCardCreateDialogFormProps> = ({
|
|||
/>
|
||||
<CardSpacer />
|
||||
<Divider />
|
||||
<CardSpacer />
|
||||
<GiftCardCustomerSelectField
|
||||
<GiftCardSendToCustomer
|
||||
selectedChannelSlug={channelSlug}
|
||||
change={change}
|
||||
sendToCustomerSelected={sendToCustomerSelected}
|
||||
selectedCustomer={selectedCustomer}
|
||||
setSelectedCustomer={setSelectedCustomer}
|
||||
/>
|
||||
<VerticalSpacer />
|
||||
<Label text={intl.formatMessage(messages.customerSubtitle)} />
|
||||
<CardSpacer />
|
||||
<Divider />
|
||||
<CardSpacer />
|
||||
<GiftCardExpirySelect
|
||||
<VerticalSpacer />
|
||||
<GiftCardCreateExpirySelect
|
||||
errors={formErrors}
|
||||
change={change}
|
||||
expirySelected={expirySelected}
|
||||
expiryType={expiryType}
|
||||
expiryPeriodAmount={expiryPeriodAmount}
|
||||
expiryPeriodType={expiryPeriodType}
|
||||
expiryDate={expiryDate}
|
||||
/>
|
||||
<CardSpacer />
|
||||
<VerticalSpacer />
|
||||
<TextField
|
||||
name="note"
|
||||
onChange={change}
|
||||
|
@ -157,8 +216,23 @@ const GiftCardCreateDialogForm: React.FC<GiftCardCreateDialogFormProps> = ({
|
|||
/>
|
||||
<VerticalSpacer />
|
||||
<Label text={intl.formatMessage(messages.noteSubtitle)} />
|
||||
<VerticalSpacer spacing={2} />
|
||||
<ControlledCheckbox
|
||||
name="requiresActivation"
|
||||
label={
|
||||
<>
|
||||
<FormattedMessage {...messages.requiresActivationLabel} />
|
||||
<Typography variant="caption">
|
||||
<FormattedMessage {...messages.requiresActivationCaption} />
|
||||
</Typography>
|
||||
</>
|
||||
}
|
||||
checked={requiresActivation}
|
||||
onChange={change}
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogButtons
|
||||
disabled={!shouldEnableSubmitButton()}
|
||||
onConfirm={submit}
|
||||
confirmButtonLabel={intl.formatMessage(messages.issueButtonLabel)}
|
||||
confirmButtonState={opts?.status}
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
import { TextField, Typography } from "@material-ui/core";
|
||||
import HorizontalSpacer from "@saleor/apps/components/HorizontalSpacer";
|
||||
import VerticalSpacer from "@saleor/apps/components/VerticalSpacer";
|
||||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||
import RadioGroupField from "@saleor/components/RadioGroupField";
|
||||
import { GiftCardError } from "@saleor/fragments/types/GiftCardError";
|
||||
import TimePeriodField from "@saleor/giftCards/components/TimePeriodField";
|
||||
import { GiftCardExpiryType } from "@saleor/giftCards/GiftCardCreateDialog/types";
|
||||
import { getExpiryPeriodTerminationDate } from "@saleor/giftCards/GiftCardCreateDialog/utils";
|
||||
import { getGiftCardErrorMessage } from "@saleor/giftCards/GiftCardUpdate/messages";
|
||||
import useCurrentDate from "@saleor/hooks/useCurrentDate";
|
||||
import { FormChange } from "@saleor/hooks/useForm";
|
||||
import { TimePeriodTypeEnum } from "@saleor/types/globalTypes";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { MessageDescriptor, useIntl } from "react-intl";
|
||||
|
||||
import { giftCardCreateExpirySelectMessages as messages } from "./messages";
|
||||
import { useGiftCardCreateExpirySelectStyles as useStyles } from "./styles";
|
||||
|
||||
interface UntranslatedOption {
|
||||
label: MessageDescriptor;
|
||||
value: GiftCardExpiryType;
|
||||
}
|
||||
|
||||
const options: UntranslatedOption[] = [
|
||||
{
|
||||
label: messages.expiryPeriodLabel,
|
||||
value: "EXPIRY_PERIOD"
|
||||
},
|
||||
{
|
||||
label: messages.expiryDateLabel,
|
||||
value: "EXPIRY_DATE"
|
||||
}
|
||||
];
|
||||
|
||||
interface GiftCardCreateExpirySelectProps {
|
||||
change: FormChange;
|
||||
expirySelected: boolean;
|
||||
expiryPeriodType: TimePeriodTypeEnum;
|
||||
expiryPeriodAmount: number;
|
||||
expiryType: GiftCardExpiryType;
|
||||
customOptions?: UntranslatedOption[];
|
||||
errors?: Record<"expiryDate", GiftCardError>;
|
||||
expiryDate?: string;
|
||||
}
|
||||
|
||||
const GiftCardCreateExpirySelect: React.FC<GiftCardCreateExpirySelectProps> = ({
|
||||
errors,
|
||||
change,
|
||||
expirySelected,
|
||||
expiryPeriodType,
|
||||
expiryPeriodAmount,
|
||||
expiryType,
|
||||
expiryDate
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const classes = useStyles({});
|
||||
|
||||
const translatedOptions = options.map(({ label, value }) => ({
|
||||
value,
|
||||
label: intl.formatMessage(label)
|
||||
}));
|
||||
|
||||
const currentDate = useCurrentDate();
|
||||
|
||||
return (
|
||||
<>
|
||||
<ControlledCheckbox
|
||||
name={"expirySelected"}
|
||||
label={intl.formatMessage(messages.expirySelectedLabel)}
|
||||
checked={expirySelected}
|
||||
onChange={change}
|
||||
/>
|
||||
{expirySelected && (
|
||||
<>
|
||||
<VerticalSpacer spacing={2} />
|
||||
<RadioGroupField
|
||||
innerContainerClassName={classes.radioGroupContainer}
|
||||
choices={translatedOptions}
|
||||
onChange={change}
|
||||
name={"expiryType"}
|
||||
value={expiryType}
|
||||
variant="inline"
|
||||
/>
|
||||
<VerticalSpacer spacing={2} />
|
||||
|
||||
{expiryType === "EXPIRY_DATE" && (
|
||||
<TextField
|
||||
error={!!errors?.expiryDate}
|
||||
helperText={getGiftCardErrorMessage(errors?.expiryDate, intl)}
|
||||
onChange={change}
|
||||
name={"expiryDate"}
|
||||
className={classes.dateField}
|
||||
label={intl.formatMessage(messages.expiryDateLabel)}
|
||||
value={expiryDate}
|
||||
InputLabelProps={{
|
||||
shrink: true
|
||||
}}
|
||||
type="date"
|
||||
/>
|
||||
)}
|
||||
|
||||
{expiryType === "EXPIRY_PERIOD" && (
|
||||
<div className={classes.periodField}>
|
||||
<TimePeriodField
|
||||
isError={!!errors?.expiryDate}
|
||||
helperText={getGiftCardErrorMessage(errors?.expiryDate, intl)}
|
||||
change={change}
|
||||
periodType={expiryPeriodType}
|
||||
periodAmount={expiryPeriodAmount}
|
||||
amountFieldName={"expiryPeriodAmount"}
|
||||
typeFieldName={"expiryPeriodType"}
|
||||
/>
|
||||
<HorizontalSpacer spacing={2} />
|
||||
<div className={classes.dateText}>
|
||||
<Typography variant="caption">
|
||||
<FormattedMessage {...messages.expiryOnLabel} />
|
||||
</Typography>
|
||||
<Typography>
|
||||
{getExpiryPeriodTerminationDate(
|
||||
currentDate,
|
||||
expiryPeriodType,
|
||||
expiryPeriodAmount
|
||||
)?.format("L")}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<VerticalSpacer spacing={2} />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default GiftCardCreateExpirySelect;
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./GiftCardCreateExpirySelect";
|
||||
export { default } from "./GiftCardCreateExpirySelect";
|
|
@ -0,0 +1,20 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const giftCardCreateExpirySelectMessages = defineMessages({
|
||||
expirySelectedLabel: {
|
||||
defaultMessage: "Set gift card expiry date",
|
||||
description: "GiftCarUpdateDetailsExpirySection expiry selected label"
|
||||
},
|
||||
expiryPeriodLabel: {
|
||||
defaultMessage: "Expires in",
|
||||
description: "GiftCarUpdateDetailsExpirySection expiry period label"
|
||||
},
|
||||
expiryDateLabel: {
|
||||
defaultMessage: "Exact date",
|
||||
description: "GiftCarUpdateDetailsExpirySection expiry date label"
|
||||
},
|
||||
expiryOnLabel: {
|
||||
defaultMessage: "Will expire on:",
|
||||
description: "GiftCarUpdateDetailsExpirySection expiry on label"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
|
||||
export const useGiftCardCreateExpirySelectStyles = makeStyles(
|
||||
theme => ({
|
||||
radioGroupContainer: {
|
||||
display: "flex",
|
||||
flexDirection: "row"
|
||||
},
|
||||
dateField: {
|
||||
width: 400
|
||||
},
|
||||
periodField: {
|
||||
display: "flex"
|
||||
},
|
||||
dateText: {
|
||||
marginTop: theme.spacing(0.5)
|
||||
}
|
||||
}),
|
||||
{ name: "GiftCardExpirySelect" }
|
||||
);
|
|
@ -17,11 +17,6 @@ export const giftCardCreateDialogMessages = defineMessages({
|
|||
defaultMessage: "Customer",
|
||||
description: "GiftCardCreateDialog customer label"
|
||||
},
|
||||
customerSubtitle: {
|
||||
defaultMessage:
|
||||
"Selected customer will be sent the generated gift card code. Someone else can redeem the gift card code. Gift card will be assigned to account which redeemed the code.",
|
||||
description: "GiftCardCreateDialog customer subtitle"
|
||||
},
|
||||
noteLabel: {
|
||||
defaultMessage: "Note",
|
||||
description: "GiftCardCreateDialog note label"
|
||||
|
@ -46,5 +41,13 @@ export const giftCardCreateDialogMessages = defineMessages({
|
|||
createdSuccessAlertTitle: {
|
||||
defaultMessage: "Successfully created gift card",
|
||||
description: "GiftCardCreateDialog createdSuccessAlertTitle"
|
||||
},
|
||||
requiresActivationLabel: {
|
||||
defaultMessage: "Requires activation",
|
||||
description: "GiftCarUpdateDetailsExpirySection requires activation label"
|
||||
},
|
||||
requiresActivationCaption: {
|
||||
defaultMessage: "All issued cards require activation by staff before use.",
|
||||
description: "GiftCarUpdateDetailsExpirySection requires activation caption"
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { GiftCardError } from "@saleor/fragments/types/GiftCardError";
|
||||
import { FormChange } from "@saleor/hooks/useForm";
|
||||
import {
|
||||
GiftCardExpiryTypeEnum,
|
||||
TimePeriodTypeEnum
|
||||
} from "@saleor/types/globalTypes";
|
||||
|
||||
import { GiftCardCreateFormData } from "./GiftCardCreateDialogForm";
|
||||
|
||||
export type GiftCardExpiryType = "EXPIRY_DATE" | "EXPIRY_PERIOD";
|
||||
|
||||
export interface GiftCardCreateFormCustomer {
|
||||
name: string;
|
||||
|
@ -15,16 +15,22 @@ export interface GiftCardCommonFormData {
|
|||
balanceAmount: number;
|
||||
balanceCurrency: string;
|
||||
expiryDate: string;
|
||||
expiryType: GiftCardExpiryTypeEnum;
|
||||
expiryPeriodType: TimePeriodTypeEnum;
|
||||
expiryPeriodAmount: number;
|
||||
}
|
||||
|
||||
export type GiftCardCreateFormErrors = Record<
|
||||
"tag" | "expiryDate" | "expiryPeriod" | "customer" | "currency" | "amount",
|
||||
"tag" | "expiryDate" | "customer" | "currency" | "amount",
|
||||
GiftCardError
|
||||
>;
|
||||
|
||||
export type GiftCardCreateInputData = Pick<
|
||||
GiftCardCreateFormData,
|
||||
| "expirySelected"
|
||||
| "expiryDate"
|
||||
| "expiryPeriodAmount"
|
||||
| "expiryPeriodType"
|
||||
| "expiryType"
|
||||
>;
|
||||
|
||||
export interface GiftCardCreateFormCommonProps {
|
||||
change: FormChange;
|
||||
errors: GiftCardCreateFormErrors;
|
||||
|
|
|
@ -1,41 +1,54 @@
|
|||
import {
|
||||
GiftCardExpirySettingsInput,
|
||||
GiftCardExpiryTypeEnum
|
||||
} from "@saleor/types/globalTypes";
|
||||
import { TimePeriodTypeEnum } from "@saleor/types/globalTypes";
|
||||
import moment from "moment-timezone";
|
||||
|
||||
import { GiftCardCommonFormData } from "./types";
|
||||
import { GiftCardCreateFormData } from "./GiftCardCreateDialogForm";
|
||||
|
||||
export const getGiftCardExpirySettingsInputData = ({
|
||||
expiryType,
|
||||
expiryDate,
|
||||
expiryPeriodAmount,
|
||||
expiryPeriodType
|
||||
}: Pick<
|
||||
GiftCardCommonFormData,
|
||||
"expiryDate" | "expiryPeriodAmount" | "expiryPeriodType" | "expiryType"
|
||||
>): GiftCardExpirySettingsInput => {
|
||||
switch (expiryType) {
|
||||
case GiftCardExpiryTypeEnum.EXPIRY_DATE: {
|
||||
return {
|
||||
expiryType,
|
||||
expiryDate
|
||||
};
|
||||
}
|
||||
const addToCurrentDate = (
|
||||
currentDate: number,
|
||||
expiryPeriodAmount: number,
|
||||
unit: moment.unitOfTime.DurationConstructor
|
||||
) => moment(currentDate).add(expiryPeriodAmount, unit);
|
||||
|
||||
case GiftCardExpiryTypeEnum.EXPIRY_PERIOD: {
|
||||
return {
|
||||
expiryType,
|
||||
expiryPeriod: {
|
||||
amount: expiryPeriodAmount,
|
||||
type: expiryPeriodType
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
default: {
|
||||
return {
|
||||
expiryType
|
||||
};
|
||||
}
|
||||
export const getExpiryPeriodTerminationDate = (
|
||||
currentDate: number,
|
||||
expiryPeriodType: TimePeriodTypeEnum,
|
||||
expiryPeriodAmount: number = 0
|
||||
): moment.Moment | null => {
|
||||
switch (expiryPeriodType) {
|
||||
case TimePeriodTypeEnum.DAY:
|
||||
return addToCurrentDate(currentDate, expiryPeriodAmount, "d");
|
||||
case TimePeriodTypeEnum.WEEK:
|
||||
return addToCurrentDate(currentDate, expiryPeriodAmount, "w");
|
||||
case TimePeriodTypeEnum.MONTH:
|
||||
return addToCurrentDate(currentDate, expiryPeriodAmount, "M");
|
||||
case TimePeriodTypeEnum.YEAR:
|
||||
return addToCurrentDate(currentDate, expiryPeriodAmount, "y");
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const getGiftCardExpiryInputData = (
|
||||
{
|
||||
expirySelected,
|
||||
expiryType,
|
||||
expiryDate,
|
||||
expiryPeriodAmount,
|
||||
expiryPeriodType
|
||||
}: GiftCardCreateFormData,
|
||||
currentDate: number
|
||||
): string => {
|
||||
if (!expirySelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (expiryType === "EXPIRY_PERIOD") {
|
||||
return getExpiryPeriodTerminationDate(
|
||||
currentDate,
|
||||
expiryPeriodType,
|
||||
expiryPeriodAmount
|
||||
)?.format("YYYY-MM-DD");
|
||||
}
|
||||
|
||||
return expiryDate;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import { Card, CardContent } from "@material-ui/core";
|
||||
import CardTitle from "@saleor/components/CardTitle";
|
||||
import GiftCardSettingsExpirySelect, {
|
||||
GiftCardSettingsExpirySelectProps
|
||||
} from "@saleor/giftCards/components/GiftCardSettingsExpirySelect";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { GiftCardSettingsFormData } from "../types";
|
||||
import { giftCardExpirySettingsCard as messages } from "./messages";
|
||||
|
||||
export interface GiftCardExpirySettingsCardProps
|
||||
extends Pick<GiftCardSettingsExpirySelectProps, "errors"> {
|
||||
data: GiftCardSettingsFormData;
|
||||
disabled: boolean;
|
||||
onChange: (event: React.ChangeEvent<any>) => void;
|
||||
}
|
||||
|
||||
const GiftCardExpirySettingsCard: React.FC<GiftCardExpirySettingsCardProps> = ({
|
||||
data,
|
||||
disabled,
|
||||
errors,
|
||||
onChange
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<Card data-test="giftCardSettings">
|
||||
<CardTitle title={intl.formatMessage(messages.expiryDateTitle)} />
|
||||
<CardContent>
|
||||
<GiftCardSettingsExpirySelect
|
||||
expiryPeriodActive={data.expiryPeriodActive}
|
||||
expiryPeriodType={data.expiryPeriodType}
|
||||
expiryPeriodAmount={data.expiryPeriodAmount}
|
||||
change={onChange}
|
||||
disabled={disabled}
|
||||
errors={errors}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
GiftCardExpirySettingsCard.displayName = "GiftCardExpirySettingsCard";
|
||||
export default GiftCardExpirySettingsCard;
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./GiftCardExpirySettingsCard";
|
||||
export { default } from "./GiftCardExpirySettingsCard";
|
|
@ -0,0 +1,12 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const giftCardExpirySettingsCard = defineMessages({
|
||||
expiryDateSectionDescription: {
|
||||
defaultMessage:
|
||||
"You can set gift cards to expire after a certain time after their purchase. Remember that in some countries, gift cards expiry is prohibited by law."
|
||||
},
|
||||
expiryDateTitle: {
|
||||
defaultMessage: "Expiry date",
|
||||
description: "section header"
|
||||
}
|
||||
});
|
101
src/giftCards/GiftCardSettings/GiftCardSettingsPage.tsx
Normal file
101
src/giftCards/GiftCardSettings/GiftCardSettingsPage.tsx
Normal file
|
@ -0,0 +1,101 @@
|
|||
import { Typography } from "@material-ui/core";
|
||||
import Container from "@saleor/components/Container";
|
||||
import Form from "@saleor/components/Form";
|
||||
import { Grid } from "@saleor/components/Grid";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import Savebar from "@saleor/components/Savebar";
|
||||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import { sectionNames } from "@saleor/intl";
|
||||
import { Backlink } from "@saleor/macaw-ui";
|
||||
import {
|
||||
GiftCardSettingsExpiryTypeEnum,
|
||||
TimePeriodTypeEnum
|
||||
} from "@saleor/types/globalTypes";
|
||||
import { getFormErrors } from "@saleor/utils/errors";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
import { giftCardsListPath } from "../urls";
|
||||
import GiftCardExpirySettingsCard from "./GiftCardExpirySettingsCard";
|
||||
import { giftCardExpirySettingsCard as expirySettingsMessages } from "./GiftCardExpirySettingsCard/messages";
|
||||
import { giftCardSettingsPageMessages as messages } from "./messages";
|
||||
import { useGiftCardSettingsUpdateMutation } from "./mutations";
|
||||
import { useGiftCardSettingsQuery } from "./queries";
|
||||
import { GiftCardSettingsFormData } from "./types";
|
||||
import { getGiftCardSettingsInputData } from "./utils";
|
||||
|
||||
const GiftCardSettingsPage: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
const navigate = useNavigator();
|
||||
|
||||
const { data, loading } = useGiftCardSettingsQuery();
|
||||
|
||||
const settingsData = data?.giftCardSettings;
|
||||
|
||||
const initialData: GiftCardSettingsFormData = {
|
||||
expiryPeriodActive:
|
||||
settingsData?.expiryType === GiftCardSettingsExpiryTypeEnum.EXPIRY_PERIOD,
|
||||
expiryPeriodType:
|
||||
settingsData?.expiryPeriod?.type || TimePeriodTypeEnum.YEAR,
|
||||
expiryPeriodAmount: settingsData?.expiryPeriod?.amount || 1
|
||||
};
|
||||
|
||||
const [
|
||||
updateGiftCardSettings,
|
||||
updateGiftCardSettingsOpts
|
||||
] = useGiftCardSettingsUpdateMutation({});
|
||||
|
||||
const navigateBack = () => navigate(giftCardsListPath);
|
||||
|
||||
const handleSubmit = (formData: GiftCardSettingsFormData) => {
|
||||
updateGiftCardSettings({
|
||||
variables: {
|
||||
input: getGiftCardSettingsInputData(formData)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const formLoading = loading || updateGiftCardSettingsOpts?.loading;
|
||||
|
||||
const apiErrors =
|
||||
updateGiftCardSettingsOpts?.data?.giftCardSettingsUpdate?.errors;
|
||||
|
||||
const formErrors = getFormErrors(["expiryPeriod"], apiErrors);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Backlink onClick={navigateBack}>
|
||||
{intl.formatMessage(sectionNames.giftCards)}
|
||||
</Backlink>
|
||||
<PageHeader title={intl.formatMessage(messages.title)} underline={true} />
|
||||
<Form initial={initialData} onSubmit={handleSubmit}>
|
||||
{({ data: formData, submit, hasChanged, change }) => (
|
||||
<Grid variant="inverted">
|
||||
<div>
|
||||
<Typography>
|
||||
<FormattedMessage
|
||||
{...expirySettingsMessages.expiryDateSectionDescription}
|
||||
/>
|
||||
</Typography>
|
||||
</div>
|
||||
<GiftCardExpirySettingsCard
|
||||
data={formData}
|
||||
disabled={formLoading}
|
||||
onChange={change}
|
||||
errors={formErrors}
|
||||
/>
|
||||
<Savebar
|
||||
onCancel={navigateBack}
|
||||
onSubmit={submit}
|
||||
disabled={formLoading || !hasChanged}
|
||||
state={updateGiftCardSettingsOpts?.status}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
</Form>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
export default GiftCardSettingsPage;
|
2
src/giftCards/GiftCardSettings/index.tsx
Normal file
2
src/giftCards/GiftCardSettings/index.tsx
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from "./GiftCardSettingsPage";
|
||||
export { default } from "./GiftCardSettingsPage";
|
17
src/giftCards/GiftCardSettings/messages.ts
Normal file
17
src/giftCards/GiftCardSettings/messages.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { GiftCardSettingsErrorFragment } from "@saleor/fragments/types/GiftCardSettingsErrorFragment";
|
||||
import { getCommonFormFieldErrorMessage } from "@saleor/utils/errors/common";
|
||||
import { defineMessages, IntlShape } from "react-intl";
|
||||
|
||||
export const giftCardSettingsPageMessages = defineMessages({
|
||||
title: {
|
||||
defaultMessage: "Gift Cards Settings",
|
||||
description: "header"
|
||||
}
|
||||
});
|
||||
|
||||
export function getGiftCardSettingsErrorMessage(
|
||||
error: Omit<GiftCardSettingsErrorFragment, "__typename"> | undefined,
|
||||
intl: IntlShape
|
||||
): string {
|
||||
return getCommonFormFieldErrorMessage(error, intl);
|
||||
}
|
29
src/giftCards/GiftCardSettings/mutations.ts
Normal file
29
src/giftCards/GiftCardSettings/mutations.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { giftCardSettingsErrorFragment } from "@saleor/fragments/errors";
|
||||
import { fragmentGiftCardsSettings } from "@saleor/fragments/giftCards";
|
||||
import makeMutation from "@saleor/hooks/makeMutation";
|
||||
import gql from "graphql-tag";
|
||||
|
||||
import {
|
||||
GiftCardSettingsUpdate,
|
||||
GiftCardSettingsUpdateVariables
|
||||
} from "./types/GiftCardSettingsUpdate";
|
||||
|
||||
const giftCardSettingsUpdate = gql`
|
||||
${giftCardSettingsErrorFragment}
|
||||
${fragmentGiftCardsSettings}
|
||||
mutation GiftCardSettingsUpdate($input: GiftCardSettingsUpdateInput!) {
|
||||
giftCardSettingsUpdate(input: $input) {
|
||||
errors {
|
||||
...GiftCardSettingsErrorFragment
|
||||
}
|
||||
giftCardSettings {
|
||||
...GiftCardsSettingsFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const useGiftCardSettingsUpdateMutation = makeMutation<
|
||||
GiftCardSettingsUpdate,
|
||||
GiftCardSettingsUpdateVariables
|
||||
>(giftCardSettingsUpdate);
|
18
src/giftCards/GiftCardSettings/queries.ts
Normal file
18
src/giftCards/GiftCardSettings/queries.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { fragmentGiftCardsSettings } from "@saleor/fragments/giftCards";
|
||||
import makeQuery from "@saleor/hooks/makeQuery";
|
||||
import gql from "graphql-tag";
|
||||
|
||||
import { GiftCardSettings } from "./types/GiftCardSettings";
|
||||
|
||||
export const giftCardSettings = gql`
|
||||
${fragmentGiftCardsSettings}
|
||||
query GiftCardSettings {
|
||||
giftCardSettings {
|
||||
...GiftCardsSettingsFragment
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const useGiftCardSettingsQuery = makeQuery<GiftCardSettings, never>(
|
||||
giftCardSettings
|
||||
);
|
7
src/giftCards/GiftCardSettings/types.ts
Normal file
7
src/giftCards/GiftCardSettings/types.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { TimePeriodTypeEnum } from "@saleor/types/globalTypes";
|
||||
|
||||
export interface GiftCardSettingsFormData {
|
||||
expiryPeriodActive: boolean;
|
||||
expiryPeriodType: TimePeriodTypeEnum;
|
||||
expiryPeriodAmount: number;
|
||||
}
|
26
src/giftCards/GiftCardSettings/types/GiftCardSettings.ts
Normal file
26
src/giftCards/GiftCardSettings/types/GiftCardSettings.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardSettingsExpiryTypeEnum, TimePeriodTypeEnum } from "./../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: GiftCardSettings
|
||||
// ====================================================
|
||||
|
||||
export interface GiftCardSettings_giftCardSettings_expiryPeriod {
|
||||
__typename: "TimePeriod";
|
||||
type: TimePeriodTypeEnum;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export interface GiftCardSettings_giftCardSettings {
|
||||
__typename: "GiftCardSettings";
|
||||
expiryType: GiftCardSettingsExpiryTypeEnum;
|
||||
expiryPeriod: GiftCardSettings_giftCardSettings_expiryPeriod | null;
|
||||
}
|
||||
|
||||
export interface GiftCardSettings {
|
||||
giftCardSettings: GiftCardSettings_giftCardSettings;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardSettingsUpdateInput, GiftCardSettingsErrorCode, GiftCardSettingsExpiryTypeEnum, TimePeriodTypeEnum } from "./../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: GiftCardSettingsUpdate
|
||||
// ====================================================
|
||||
|
||||
export interface GiftCardSettingsUpdate_giftCardSettingsUpdate_errors {
|
||||
__typename: "GiftCardSettingsError";
|
||||
code: GiftCardSettingsErrorCode;
|
||||
field: string | null;
|
||||
}
|
||||
|
||||
export interface GiftCardSettingsUpdate_giftCardSettingsUpdate_giftCardSettings_expiryPeriod {
|
||||
__typename: "TimePeriod";
|
||||
type: TimePeriodTypeEnum;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export interface GiftCardSettingsUpdate_giftCardSettingsUpdate_giftCardSettings {
|
||||
__typename: "GiftCardSettings";
|
||||
expiryType: GiftCardSettingsExpiryTypeEnum;
|
||||
expiryPeriod: GiftCardSettingsUpdate_giftCardSettingsUpdate_giftCardSettings_expiryPeriod | null;
|
||||
}
|
||||
|
||||
export interface GiftCardSettingsUpdate_giftCardSettingsUpdate {
|
||||
__typename: "GiftCardSettingsUpdate";
|
||||
errors: GiftCardSettingsUpdate_giftCardSettingsUpdate_errors[];
|
||||
giftCardSettings: GiftCardSettingsUpdate_giftCardSettingsUpdate_giftCardSettings | null;
|
||||
}
|
||||
|
||||
export interface GiftCardSettingsUpdate {
|
||||
giftCardSettingsUpdate: GiftCardSettingsUpdate_giftCardSettingsUpdate | null;
|
||||
}
|
||||
|
||||
export interface GiftCardSettingsUpdateVariables {
|
||||
input: GiftCardSettingsUpdateInput;
|
||||
}
|
32
src/giftCards/GiftCardSettings/utils.ts
Normal file
32
src/giftCards/GiftCardSettings/utils.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
import {
|
||||
GiftCardSettingsExpiryTypeEnum,
|
||||
GiftCardSettingsUpdateInput
|
||||
} from "@saleor/types/globalTypes";
|
||||
|
||||
import { GiftCardSettingsFormData } from "./types";
|
||||
|
||||
export const getGiftCardSettingsInputData = ({
|
||||
expiryPeriodActive,
|
||||
expiryPeriodType,
|
||||
expiryPeriodAmount
|
||||
}: Pick<
|
||||
GiftCardSettingsFormData,
|
||||
"expiryPeriodActive" | "expiryPeriodType" | "expiryPeriodAmount"
|
||||
>): GiftCardSettingsUpdateInput => {
|
||||
const expiryType = expiryPeriodActive
|
||||
? GiftCardSettingsExpiryTypeEnum.EXPIRY_PERIOD
|
||||
: GiftCardSettingsExpiryTypeEnum.NEVER_EXPIRE;
|
||||
|
||||
const expiryPeriod =
|
||||
expiryPeriodActive && expiryPeriodType && expiryPeriodAmount
|
||||
? {
|
||||
type: expiryPeriodType,
|
||||
amount: expiryPeriodAmount
|
||||
}
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
expiryType,
|
||||
expiryPeriod
|
||||
};
|
||||
};
|
|
@ -0,0 +1,179 @@
|
|||
import { CircularProgress, TextField, Typography } from "@material-ui/core";
|
||||
import VerticalSpacer from "@saleor/apps/components/VerticalSpacer";
|
||||
import { useChannelsList } from "@saleor/channels/queries";
|
||||
import ActionDialog from "@saleor/components/ActionDialog";
|
||||
import { useChannelsSearch } from "@saleor/components/ChannelsAvailabilityDialog/utils";
|
||||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||
import { IMessage } from "@saleor/components/messages";
|
||||
import SingleAutocompleteSelectField from "@saleor/components/SingleAutocompleteSelectField";
|
||||
import useForm from "@saleor/hooks/useForm";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
import { getBySlug } from "@saleor/products/components/ProductVariantCreatorPage/utils";
|
||||
import commonErrorMessages from "@saleor/utils/errors/common";
|
||||
import { DialogActionHandlersProps } from "@saleor/utils/handlers/dialogActionHandlers";
|
||||
import { mapSlugNodeToChoice } from "@saleor/utils/maps";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { useGiftCardDeleteDialogContentStyles as useProgressStyles } from "../../components/GiftCardDeleteDialog/styles";
|
||||
import { useUpdateBalanceDialogStyles as useStyles } from "../GiftCardUpdateBalanceDialog/styles";
|
||||
import { getGiftCardErrorMessage } from "../messages";
|
||||
import useGiftCardDetails from "../providers/GiftCardDetailsProvider/hooks/useGiftCardDetails";
|
||||
import { giftCardResendCodeDialogMessages as messages } from "./messages";
|
||||
import { useGiftCardResendCodeMutation } from "./mutations";
|
||||
import { GiftCardResend } from "./types/GiftCardResend";
|
||||
import { useDialogFormReset } from "./utils";
|
||||
|
||||
export interface GiftCardResendCodeFormData {
|
||||
email: string;
|
||||
channelSlug: string;
|
||||
}
|
||||
|
||||
const GiftCardResendCodeDialog: React.FC<DialogActionHandlersProps> = ({
|
||||
open,
|
||||
closeDialog
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const notify = useNotifier();
|
||||
const classes = useStyles();
|
||||
const progressClasses = useProgressStyles();
|
||||
|
||||
const {
|
||||
giftCard: { boughtInChannel: initialChannelSlug }
|
||||
} = useGiftCardDetails();
|
||||
|
||||
const [consentSelected, setConsentSelected] = useState(false);
|
||||
|
||||
const { data: channelsData, loading: loadingChannels } = useChannelsList({});
|
||||
|
||||
const channels = channelsData?.channels;
|
||||
|
||||
const activeChannels = channels?.filter(({ isActive }) => isActive);
|
||||
|
||||
const { onQueryChange, filteredChannels } = useChannelsSearch(activeChannels);
|
||||
|
||||
const initialFormData: GiftCardResendCodeFormData = {
|
||||
email: "",
|
||||
channelSlug: initialChannelSlug || ""
|
||||
};
|
||||
|
||||
const {
|
||||
giftCard: { id }
|
||||
} = useGiftCardDetails();
|
||||
|
||||
const handleSubmit = async ({
|
||||
email,
|
||||
channelSlug
|
||||
}: GiftCardResendCodeFormData) => {
|
||||
const result = await resendGiftCardCode({
|
||||
variables: {
|
||||
input: {
|
||||
id,
|
||||
email: email ? email : null,
|
||||
channel: channelSlug
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return result?.data?.giftCardResend?.errors;
|
||||
};
|
||||
|
||||
const { data, change, submit, reset } = useForm(
|
||||
initialFormData,
|
||||
handleSubmit
|
||||
);
|
||||
|
||||
const onCompleted = (data: GiftCardResend) => {
|
||||
const errors = data?.giftCardResend?.errors;
|
||||
|
||||
const notifierData: IMessage = !!errors?.length
|
||||
? {
|
||||
status: "error",
|
||||
text: intl.formatMessage(commonErrorMessages.unknownError)
|
||||
}
|
||||
: {
|
||||
status: "success",
|
||||
text: intl.formatMessage(messages.successResendAlertText)
|
||||
};
|
||||
|
||||
notify(notifierData);
|
||||
|
||||
if (!errors.length) {
|
||||
closeDialog();
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
const [
|
||||
resendGiftCardCode,
|
||||
resendGiftCardCodeOpts
|
||||
] = useGiftCardResendCodeMutation({
|
||||
onCompleted
|
||||
});
|
||||
|
||||
const { loading, status, data: submitData } = resendGiftCardCodeOpts;
|
||||
|
||||
const { formErrors } = useDialogFormReset({
|
||||
open,
|
||||
reset,
|
||||
apiErrors: submitData?.giftCardResend?.errors,
|
||||
keys: ["email"]
|
||||
});
|
||||
|
||||
useEffect(reset, [consentSelected]);
|
||||
|
||||
return (
|
||||
<ActionDialog
|
||||
maxWidth="sm"
|
||||
open={open}
|
||||
onConfirm={submit}
|
||||
confirmButtonLabel={intl.formatMessage(messages.submitButtonLabel)}
|
||||
onClose={closeDialog}
|
||||
title={intl.formatMessage(messages.title)}
|
||||
confirmButtonState={status}
|
||||
disabled={loading}
|
||||
>
|
||||
{loadingChannels ? (
|
||||
<div className={progressClasses.progressContainer}>
|
||||
<CircularProgress />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<Typography>{intl.formatMessage(messages.description)}</Typography>
|
||||
<VerticalSpacer />
|
||||
<SingleAutocompleteSelectField
|
||||
choices={mapSlugNodeToChoice(filteredChannels)}
|
||||
name="channelSlug"
|
||||
label={intl.formatMessage(messages.sendToChannelSelectLabel)}
|
||||
value={data?.channelSlug}
|
||||
onChange={change}
|
||||
displayValue={channels.find(getBySlug(data?.channelSlug))?.name}
|
||||
fetchChoices={onQueryChange}
|
||||
/>
|
||||
<VerticalSpacer />
|
||||
<ControlledCheckbox
|
||||
name="differentMailConsent"
|
||||
label={intl.formatMessage(messages.consentCheckboxLabel)}
|
||||
checked={consentSelected}
|
||||
onChange={(event: React.ChangeEvent<any>) =>
|
||||
setConsentSelected(event.target.value)
|
||||
}
|
||||
/>
|
||||
<VerticalSpacer />
|
||||
<TextField
|
||||
disabled={!consentSelected}
|
||||
error={!!formErrors?.email}
|
||||
helperText={getGiftCardErrorMessage(formErrors?.email, intl)}
|
||||
name="email"
|
||||
value={data.email}
|
||||
onChange={change}
|
||||
className={classes.inputContainer}
|
||||
label={intl.formatMessage(messages.emailInputPlaceholder)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</ActionDialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default GiftCardResendCodeDialog;
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./GiftCardResendCodeDialog";
|
||||
export { default } from "./GiftCardResendCodeDialog";
|
|
@ -0,0 +1,33 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const giftCardResendCodeDialogMessages = defineMessages({
|
||||
title: {
|
||||
defaultMessage: "Resend code to customer",
|
||||
description: "GiftCardResendCodeDialog title"
|
||||
},
|
||||
description: {
|
||||
defaultMessage:
|
||||
"Gift Card Code will be resent to email provided during checkout. You can provide a different email address if you want to:",
|
||||
description: "GiftCardResendCodeDialog description"
|
||||
},
|
||||
consentCheckboxLabel: {
|
||||
defaultMessage: "Yes, I want to send gift card to different address",
|
||||
description: "GiftCardResendCodeDialog consentCheckboxLabel"
|
||||
},
|
||||
submitButtonLabel: {
|
||||
defaultMessage: "Resend",
|
||||
description: "GiftCardResendCodeDialog submitButtonLabel"
|
||||
},
|
||||
emailInputPlaceholder: {
|
||||
defaultMessage: "Provided email address",
|
||||
description: "GiftCardResendCodeDialog emailInputPlaceholder"
|
||||
},
|
||||
successResendAlertText: {
|
||||
defaultMessage: "Successfully resent code to customer!",
|
||||
description: "GiftCardResendCodeDialog successResendAlertText"
|
||||
},
|
||||
sendToChannelSelectLabel: {
|
||||
defaultMessage: "Send to channel",
|
||||
description: "ChannelPickerSelectField sendToChannelLabel"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
import { giftCardErrorFragment } from "@saleor/fragments/errors";
|
||||
import makeMutation from "@saleor/hooks/makeMutation";
|
||||
import gql from "graphql-tag";
|
||||
|
||||
import { giftCardDataFragment } from "../queries";
|
||||
import {
|
||||
GiftCardResend,
|
||||
GiftCardResendVariables
|
||||
} from "./types/GiftCardResend";
|
||||
|
||||
const giftCardResend = gql`
|
||||
${giftCardDataFragment}
|
||||
${giftCardErrorFragment}
|
||||
mutation GiftCardResend($input: GiftCardResendInput!) {
|
||||
giftCardResend(input: $input) {
|
||||
errors {
|
||||
...GiftCardError
|
||||
}
|
||||
giftCard {
|
||||
...GiftCardData
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const useGiftCardResendCodeMutation = makeMutation<
|
||||
GiftCardResend,
|
||||
GiftCardResendVariables
|
||||
>(giftCardResend);
|
|
@ -0,0 +1,102 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardResendInput, GiftCardErrorCode } from "./../../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: GiftCardResend
|
||||
// ====================================================
|
||||
|
||||
export interface GiftCardResend_giftCardResend_errors {
|
||||
__typename: "GiftCardError";
|
||||
code: GiftCardErrorCode;
|
||||
field: string | null;
|
||||
}
|
||||
|
||||
export interface GiftCardResend_giftCardResend_giftCard_metadata {
|
||||
__typename: "MetadataItem";
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface GiftCardResend_giftCardResend_giftCard_privateMetadata {
|
||||
__typename: "MetadataItem";
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface GiftCardResend_giftCardResend_giftCard_createdBy {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
}
|
||||
|
||||
export interface GiftCardResend_giftCardResend_giftCard_product {
|
||||
__typename: "Product";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface GiftCardResend_giftCardResend_giftCard_usedBy {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
}
|
||||
|
||||
export interface GiftCardResend_giftCardResend_giftCard_app {
|
||||
__typename: "App";
|
||||
id: string;
|
||||
name: string | null;
|
||||
}
|
||||
|
||||
export interface GiftCardResend_giftCardResend_giftCard_initialBalance {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface GiftCardResend_giftCardResend_giftCard_currentBalance {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface GiftCardResend_giftCardResend_giftCard {
|
||||
__typename: "GiftCard";
|
||||
metadata: (GiftCardResend_giftCardResend_giftCard_metadata | null)[];
|
||||
privateMetadata: (GiftCardResend_giftCardResend_giftCard_privateMetadata | null)[];
|
||||
displayCode: string;
|
||||
boughtInChannel: string | null;
|
||||
createdBy: GiftCardResend_giftCardResend_giftCard_createdBy | null;
|
||||
product: GiftCardResend_giftCardResend_giftCard_product | null;
|
||||
usedBy: GiftCardResend_giftCardResend_giftCard_usedBy | null;
|
||||
usedByEmail: string | null;
|
||||
createdByEmail: string | null;
|
||||
app: GiftCardResend_giftCardResend_giftCard_app | null;
|
||||
created: any;
|
||||
expiryDate: any | null;
|
||||
lastUsedOn: any | null;
|
||||
isActive: boolean;
|
||||
initialBalance: GiftCardResend_giftCardResend_giftCard_initialBalance | null;
|
||||
currentBalance: GiftCardResend_giftCardResend_giftCard_currentBalance | null;
|
||||
id: string;
|
||||
tag: string | null;
|
||||
}
|
||||
|
||||
export interface GiftCardResend_giftCardResend {
|
||||
__typename: "GiftCardResend";
|
||||
errors: GiftCardResend_giftCardResend_errors[];
|
||||
giftCard: GiftCardResend_giftCardResend_giftCard | null;
|
||||
}
|
||||
|
||||
export interface GiftCardResend {
|
||||
giftCardResend: GiftCardResend_giftCardResend | null;
|
||||
}
|
||||
|
||||
export interface GiftCardResendVariables {
|
||||
input: GiftCardResendInput;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import { UserError } from "@saleor/types";
|
||||
import { FormErrors, getFormErrors } from "@saleor/utils/errors";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export function useDialogFormReset<
|
||||
TError extends UserError,
|
||||
TKey extends string
|
||||
>({
|
||||
reset,
|
||||
apiErrors,
|
||||
keys,
|
||||
open
|
||||
}: {
|
||||
reset: () => void;
|
||||
apiErrors: TError[];
|
||||
keys: TKey[];
|
||||
open: boolean;
|
||||
}) {
|
||||
const [formErrors, setFormErrors] = useState<FormErrors<TKey, TError>>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
setFormErrors(null);
|
||||
reset();
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
useEffect(() => {
|
||||
const errors = getFormErrors(keys, apiErrors);
|
||||
setFormErrors(errors);
|
||||
}, [apiErrors]);
|
||||
|
||||
return { formErrors };
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
import { TextField, Typography } from "@material-ui/core";
|
||||
import ActionDialog from "@saleor/components/ActionDialog";
|
||||
import CardSpacer from "@saleor/components/CardSpacer";
|
||||
import Form from "@saleor/components/Form";
|
||||
import { IMessage } from "@saleor/components/messages";
|
||||
import useForm from "@saleor/hooks/useForm";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
import { getFormErrors } from "@saleor/utils/errors";
|
||||
import commonErrorMessages from "@saleor/utils/errors/common";
|
||||
import { DialogActionHandlers } from "@saleor/utils/handlers/dialogActionHandlers";
|
||||
import { DialogActionHandlersProps } from "@saleor/utils/handlers/dialogActionHandlers";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { giftCardsListTableMessages as tableMessages } from "../../GiftCardsList/messages";
|
||||
import { useDialogFormReset } from "../GiftCardResendCodeDialog/utils";
|
||||
import { getGiftCardErrorMessage } from "../messages";
|
||||
import { useGiftCardUpdateMutation } from "../mutations";
|
||||
import useGiftCardDetails from "../providers/GiftCardDetailsProvider/hooks/useGiftCardDetails";
|
||||
|
@ -22,9 +22,9 @@ export interface GiftCardBalanceUpdateFormData {
|
|||
balanceAmount: number;
|
||||
}
|
||||
|
||||
const GiftCardUpdateBalanceDialog: React.FC<DialogActionHandlers> = ({
|
||||
const GiftCardUpdateBalanceDialog: React.FC<DialogActionHandlersProps> = ({
|
||||
open,
|
||||
onClose
|
||||
closeDialog
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const classes = useStyles({});
|
||||
|
@ -57,7 +57,7 @@ const GiftCardUpdateBalanceDialog: React.FC<DialogActionHandlers> = ({
|
|||
notify(notifierData);
|
||||
|
||||
if (!errors.length) {
|
||||
onClose();
|
||||
closeDialog();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -83,54 +83,57 @@ const GiftCardUpdateBalanceDialog: React.FC<DialogActionHandlers> = ({
|
|||
return result?.data?.giftCardUpdate?.errors;
|
||||
};
|
||||
|
||||
const { loading, status, data } = updateGiftCardBalanceOpts;
|
||||
|
||||
const formErrors = getFormErrors(
|
||||
["initialBalanceAmount"],
|
||||
data?.giftCardUpdate?.errors
|
||||
const { data, change, submit, reset, hasChanged } = useForm(
|
||||
initialFormData,
|
||||
handleSubmit
|
||||
);
|
||||
|
||||
const { loading, status, data: submitData } = updateGiftCardBalanceOpts;
|
||||
|
||||
const { formErrors } = useDialogFormReset({
|
||||
open,
|
||||
reset,
|
||||
keys: ["initialBalanceAmount"],
|
||||
apiErrors: submitData?.giftCardUpdate?.errors
|
||||
});
|
||||
|
||||
return (
|
||||
<Form initial={initialFormData} onSubmit={handleSubmit}>
|
||||
{({ data, change, submit, hasChanged }) => (
|
||||
<ActionDialog
|
||||
maxWidth="sm"
|
||||
open={open}
|
||||
onConfirm={submit}
|
||||
confirmButtonLabel={intl.formatMessage(messages.changeButtonLabel)}
|
||||
onClose={onClose}
|
||||
title={intl.formatMessage(messages.title)}
|
||||
confirmButtonState={status}
|
||||
disabled={loading || !hasChanged}
|
||||
>
|
||||
<Typography>{intl.formatMessage(messages.subtitle)}</Typography>
|
||||
<CardSpacer />
|
||||
<TextField
|
||||
inputProps={{ min: 0 }}
|
||||
error={!!formErrors?.initialBalanceAmount}
|
||||
helperText={getGiftCardErrorMessage(
|
||||
formErrors?.initialBalanceAmount,
|
||||
intl
|
||||
)}
|
||||
name="balanceAmount"
|
||||
value={data.balanceAmount}
|
||||
onChange={change}
|
||||
className={classes.inputContainer}
|
||||
label={intl.formatMessage(
|
||||
tableMessages.giftCardsTableColumnBalanceTitle
|
||||
)}
|
||||
type="number"
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<div className={classes.currencyCodeContainer}>
|
||||
<Typography variant="caption">{currency}</Typography>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</ActionDialog>
|
||||
)}
|
||||
</Form>
|
||||
<ActionDialog
|
||||
maxWidth="sm"
|
||||
open={open}
|
||||
onConfirm={submit}
|
||||
confirmButtonLabel={intl.formatMessage(messages.changeButtonLabel)}
|
||||
onClose={closeDialog}
|
||||
title={intl.formatMessage(messages.title)}
|
||||
confirmButtonState={status}
|
||||
disabled={loading || !hasChanged}
|
||||
>
|
||||
<Typography>{intl.formatMessage(messages.subtitle)}</Typography>
|
||||
<CardSpacer />
|
||||
<TextField
|
||||
inputProps={{ min: 0 }}
|
||||
error={!!formErrors?.initialBalanceAmount}
|
||||
helperText={getGiftCardErrorMessage(
|
||||
formErrors?.initialBalanceAmount,
|
||||
intl
|
||||
)}
|
||||
name="balanceAmount"
|
||||
value={data.balanceAmount}
|
||||
onChange={change}
|
||||
className={classes.inputContainer}
|
||||
label={intl.formatMessage(
|
||||
tableMessages.giftCardsTableColumnBalanceTitle
|
||||
)}
|
||||
type="float"
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<div className={classes.currencyCodeContainer}>
|
||||
<Typography variant="caption">{currency}</Typography>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</ActionDialog>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@ import { Button, Card, CardContent, Divider } from "@material-ui/core";
|
|||
import CardSpacer from "@saleor/components/CardSpacer";
|
||||
import CardTitle from "@saleor/components/CardTitle";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import GiftCardExpirySelect from "@saleor/giftCards/components/GiftCardExpirySelect";
|
||||
import GiftCardTagInput from "@saleor/giftCards/components/GiftCardTagInput";
|
||||
import GiftCardUpdateExpirySelect from "@saleor/giftCards/GiftCardUpdate/GiftCardUpdateExpirySelect";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
|
@ -21,7 +21,7 @@ const GiftCardUpdateDetailsCard: React.FC = () => {
|
|||
|
||||
const {
|
||||
change,
|
||||
data: { expiryType, expiryPeriodAmount, expiryPeriodType, tag, expiryDate },
|
||||
data: { tag },
|
||||
formErrors
|
||||
} = useGiftCardUpdateForm();
|
||||
|
||||
|
@ -55,14 +55,7 @@ const GiftCardUpdateDetailsCard: React.FC = () => {
|
|||
change={change}
|
||||
/>
|
||||
<CardSpacer />
|
||||
<GiftCardExpirySelect
|
||||
expiryDate={expiryDate}
|
||||
errors={formErrors}
|
||||
change={change}
|
||||
expiryType={expiryType}
|
||||
expiryPeriodAmount={expiryPeriodAmount}
|
||||
expiryPeriodType={expiryPeriodType}
|
||||
/>
|
||||
<GiftCardUpdateExpirySelect />
|
||||
</>
|
||||
)}
|
||||
</Skeleton>
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import { TextField, Typography } from "@material-ui/core";
|
||||
import VerticalSpacer from "@saleor/apps/components/VerticalSpacer";
|
||||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||
import { getGiftCardErrorMessage } from "@saleor/giftCards/GiftCardUpdate/messages";
|
||||
import useGiftCardUpdateForm from "@saleor/giftCards/GiftCardUpdate/providers/GiftCardUpdateFormProvider/hooks/useGiftCardUpdateForm";
|
||||
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
||||
import React, { useEffect } from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { giftCardExpirySelectMessages as messages } from "./messages";
|
||||
import { useGiftCardExpirySelectStyles as useStyles } from "./styles";
|
||||
|
||||
const GiftCardUpdateExpirySelect: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const classes = useStyles({});
|
||||
|
||||
const {
|
||||
change,
|
||||
data: { expiryDate },
|
||||
formErrors
|
||||
} = useGiftCardUpdateForm();
|
||||
|
||||
const [cardExpiresSelected, setCardExpiresSelected] = useStateFromProps(
|
||||
!!expiryDate
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!cardExpiresSelected) {
|
||||
change({
|
||||
target: {
|
||||
name: "expiryDate",
|
||||
value: null
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [cardExpiresSelected]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography>{intl.formatMessage(messages.expiryDateLabel)}</Typography>
|
||||
<VerticalSpacer />
|
||||
<ControlledCheckbox
|
||||
name="cardExpires"
|
||||
label={intl.formatMessage(messages.expiryDateCheckboxLabel)}
|
||||
checked={cardExpiresSelected}
|
||||
onChange={event => setCardExpiresSelected(event.target.value)}
|
||||
/>
|
||||
<VerticalSpacer spacing={2} />
|
||||
|
||||
{cardExpiresSelected && (
|
||||
<TextField
|
||||
error={!!formErrors?.expiryDate}
|
||||
helperText={getGiftCardErrorMessage(formErrors?.expiryDate, intl)}
|
||||
onChange={change}
|
||||
name={"expiryDate"}
|
||||
className={classes.dateField}
|
||||
label={intl.formatMessage(messages.expiryDateLabel)}
|
||||
value={expiryDate}
|
||||
InputLabelProps={{
|
||||
shrink: true
|
||||
}}
|
||||
type="date"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default GiftCardUpdateExpirySelect;
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./GiftCardUpdateExpirySelect";
|
||||
export { default } from "./GiftCardUpdateExpirySelect";
|
|
@ -0,0 +1,12 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const giftCardExpirySelectMessages = defineMessages({
|
||||
expiryDateCheckboxLabel: {
|
||||
defaultMessage: "Gift card expires",
|
||||
description: "GiftCarUpdateDetailsExpirySection expiry date checkbox label"
|
||||
},
|
||||
expiryDateLabel: {
|
||||
defaultMessage: "Expiration date",
|
||||
description: "GiftCarUpdateDetailsExpirySection expiry date label"
|
||||
}
|
||||
});
|
|
@ -1,13 +1,19 @@
|
|||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
|
||||
export const useGiftCardExpirySelectStyles = makeStyles(
|
||||
() => ({
|
||||
theme => ({
|
||||
radioGroupContainer: {
|
||||
display: "flex",
|
||||
flexDirection: "row"
|
||||
},
|
||||
dateField: {
|
||||
width: 400
|
||||
},
|
||||
periodField: {
|
||||
display: "flex"
|
||||
},
|
||||
dateText: {
|
||||
marginTop: theme.spacing(0.5)
|
||||
}
|
||||
}),
|
||||
{ name: "GiftCardUpdateDetailsExpirySection" }
|
|
@ -8,6 +8,7 @@ import useNavigator from "@saleor/hooks/useNavigator";
|
|||
import { getFullName, getStringOrPlaceholder } from "@saleor/misc";
|
||||
import Label from "@saleor/orders/components/OrderHistory/Label";
|
||||
import { getOrderNumberLinkObject } from "@saleor/orders/components/OrderHistory/utils";
|
||||
import { getByType } from "@saleor/orders/components/OrderReturnPage/utils";
|
||||
import { productUrl } from "@saleor/products/urls";
|
||||
import { staffMemberDetailsUrl } from "@saleor/staff/urls";
|
||||
import { GiftCardEventsEnum } from "@saleor/types/globalTypes";
|
||||
|
@ -37,9 +38,8 @@ const GiftCardUpdateInfoCardContent: React.FC = () => {
|
|||
events
|
||||
} = giftCard;
|
||||
|
||||
const cardIssuedEvent = events.find(
|
||||
({ type }) => type === GiftCardEventsEnum.ISSUED
|
||||
);
|
||||
const cardIssuedEvent = events.find(getByType(GiftCardEventsEnum.ISSUED));
|
||||
const cardBoughtEvent = events.find(getByType(GiftCardEventsEnum.BOUGHT));
|
||||
|
||||
const getBuyerFieldData = (): {
|
||||
label: MessageDescriptor;
|
||||
|
@ -80,13 +80,31 @@ const GiftCardUpdateInfoCardContent: React.FC = () => {
|
|||
};
|
||||
};
|
||||
|
||||
const orderData =
|
||||
cardIssuedEvent && cardIssuedEvent.orderId
|
||||
? getOrderNumberLinkObject({
|
||||
id: cardIssuedEvent.orderId,
|
||||
number: cardIssuedEvent.orderNumber
|
||||
})
|
||||
: null;
|
||||
const getOrderData = () => {
|
||||
if (cardIssuedEvent) {
|
||||
const { orderId, orderNumber } = cardIssuedEvent;
|
||||
|
||||
if (!orderId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getOrderNumberLinkObject({
|
||||
id: orderId,
|
||||
number: orderNumber
|
||||
});
|
||||
}
|
||||
|
||||
if (cardBoughtEvent) {
|
||||
const { orderId, orderNumber } = cardBoughtEvent;
|
||||
|
||||
return getOrderNumberLinkObject({
|
||||
id: orderId,
|
||||
number: orderNumber
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const {
|
||||
label: buyerLabelMessage,
|
||||
|
@ -94,6 +112,8 @@ const GiftCardUpdateInfoCardContent: React.FC = () => {
|
|||
url: buyerUrl
|
||||
} = getBuyerFieldData();
|
||||
|
||||
const orderData = getOrderData();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Label text={intl.formatMessage(messages.creationLabel)} />
|
||||
|
|
|
@ -13,7 +13,7 @@ import useGiftCardUpdate from "./providers/GiftCardUpdateFormProvider/hooks/useG
|
|||
import useGiftCardUpdateForm from "./providers/GiftCardUpdateFormProvider/hooks/useGiftCardUpdateForm";
|
||||
|
||||
const GiftCardUpdatePage: React.FC = () => {
|
||||
const { navigateBack } = useGiftCardUpdateDialogs();
|
||||
const { navigateBack, openDeleteDialog } = useGiftCardUpdateDialogs();
|
||||
|
||||
const {
|
||||
hasChanged,
|
||||
|
@ -44,6 +44,7 @@ const GiftCardUpdatePage: React.FC = () => {
|
|||
disabled={loadingUpdate || !hasChanged}
|
||||
onCancel={navigateBack}
|
||||
onSubmit={submit}
|
||||
onDelete={openDeleteDialog}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
|
|
|
@ -2,22 +2,20 @@ import useNotifier from "@saleor/hooks/useNotifier";
|
|||
import { commonMessages } from "@saleor/intl";
|
||||
import { ConfirmButton } from "@saleor/macaw-ui";
|
||||
import commonErrorMessages from "@saleor/utils/errors/common";
|
||||
import classNames from "classnames";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { bulkEnableDisableSectionMessages as buttonMessages } from "../../GiftCardsList/GiftCardsListTable/GiftCardsListTableHeader/messages";
|
||||
import useGiftCardDetails from "../providers/GiftCardDetailsProvider/hooks/useGiftCardDetails";
|
||||
import { giftCardEnableDisableSectionMessages as messages } from "./messages";
|
||||
import {
|
||||
useGiftCardActivateMutation,
|
||||
useGiftCardDeactivateMutation
|
||||
} from "./mutations";
|
||||
import { useGiftCardEnableDisableSectionStyles as useStyles } from "./styles";
|
||||
import { GiftCardActivate } from "./types/GiftCardActivate";
|
||||
import { GiftCardDeactivate } from "./types/GiftCardDeactivate";
|
||||
|
||||
const GiftCardEnableDisableSection: React.FC = () => {
|
||||
const classes = useStyles({});
|
||||
const notify = useNotifier();
|
||||
const intl = useIntl();
|
||||
|
||||
|
@ -25,10 +23,6 @@ const GiftCardEnableDisableSection: React.FC = () => {
|
|||
giftCard: { id, isActive }
|
||||
} = useGiftCardDetails();
|
||||
|
||||
const [showButtonGreen, setShowButtonGreen] = useState(!isActive);
|
||||
|
||||
useEffect(() => setShowButtonGreen(!isActive), [isActive]);
|
||||
|
||||
const onActivateCompleted = (data: GiftCardActivate) => {
|
||||
const errors = data?.giftCardActivate?.errors;
|
||||
|
||||
|
@ -38,8 +32,6 @@ const GiftCardEnableDisableSection: React.FC = () => {
|
|||
text: intl.formatMessage(commonErrorMessages.unknownError)
|
||||
});
|
||||
|
||||
setShowButtonGreen(false);
|
||||
setTimeout(() => setShowButtonGreen(true), 3000);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -82,16 +74,14 @@ const GiftCardEnableDisableSection: React.FC = () => {
|
|||
? giftCardDeactivate({ variables: { id } })
|
||||
: giftCardActivate({ variables: { id } });
|
||||
|
||||
const buttonLabel = isActive ? messages.disableLabel : messages.enableLabel;
|
||||
const buttonLabel = isActive
|
||||
? buttonMessages.disableLabel
|
||||
: buttonMessages.enableLabel;
|
||||
|
||||
const currentOpts = isActive ? giftCardDeactivateOpts : giftCardActivateOpts;
|
||||
|
||||
return (
|
||||
<ConfirmButton
|
||||
className={classNames(classes.button, {
|
||||
[classes.buttonRed]: isActive || currentOpts?.status === "error",
|
||||
[classes.buttonGreen]: showButtonGreen
|
||||
})}
|
||||
onClick={handleClick}
|
||||
transitionState={currentOpts?.status}
|
||||
labels={{
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { Button } from "@material-ui/core";
|
||||
import HorizontalSpacer from "@saleor/apps/components/HorizontalSpacer";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import PageTitleWithStatusChip from "@saleor/components/PageTitleWithStatusChip";
|
||||
import { StatusType } from "@saleor/components/StatusChip/types";
|
||||
|
@ -10,6 +12,7 @@ import { giftCardsListTableMessages as tableMessages } from "../../GiftCardsList
|
|||
import useGiftCardDetails from "../providers/GiftCardDetailsProvider/hooks/useGiftCardDetails";
|
||||
import useGiftCardUpdateDialogs from "../providers/GiftCardUpdateDialogsProvider/hooks/useGiftCardUpdateDialogs";
|
||||
import GiftCardEnableDisableSection from "./GiftCardEnableDisableSection";
|
||||
import { giftCardUpdatePageHeaderMessages as messages } from "./messages";
|
||||
|
||||
const GiftCardUpdatePageHeader: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
|
@ -20,6 +23,8 @@ const GiftCardUpdatePageHeader: React.FC = () => {
|
|||
return null;
|
||||
}
|
||||
|
||||
const { openResendCodeDialog } = useGiftCardUpdateDialogs();
|
||||
|
||||
const { displayCode, isActive } = giftCard;
|
||||
|
||||
const title = intl.formatMessage(tableMessages.codeEndingWithLabel, {
|
||||
|
@ -48,6 +53,14 @@ const GiftCardUpdatePageHeader: React.FC = () => {
|
|||
}
|
||||
>
|
||||
<GiftCardEnableDisableSection />
|
||||
<HorizontalSpacer />
|
||||
<Button
|
||||
color="primary"
|
||||
variant="contained"
|
||||
onClick={openResendCodeDialog}
|
||||
>
|
||||
{intl.formatMessage(messages.resendButtonLabel)}
|
||||
</Button>
|
||||
</PageHeader>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const giftCardEnableDisableSectionMessages = defineMessages({
|
||||
enableLabel: {
|
||||
defaultMessage: "Enable",
|
||||
description: "GiftCardEnableDisableSection enable label"
|
||||
},
|
||||
disableLabel: {
|
||||
defaultMessage: "Disable",
|
||||
description: "GiftCardEnableDisableSection enable label"
|
||||
},
|
||||
successfullyEnabledTitle: {
|
||||
defaultMessage: "Successfully enabled gift card",
|
||||
description: "GiftCardEnableDisableSection enable success"
|
||||
|
@ -18,3 +10,10 @@ export const giftCardEnableDisableSectionMessages = defineMessages({
|
|||
description: "GiftCardEnableDisableSection disable success"
|
||||
}
|
||||
});
|
||||
|
||||
export const giftCardUpdatePageHeaderMessages = defineMessages({
|
||||
resendButtonLabel: {
|
||||
defaultMessage: "Resend code",
|
||||
description: "giftCardUpdatePageHeader resendButtonLabel"
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
import { darken } from "@material-ui/core";
|
||||
import { statusChipStyles } from "@saleor/components/StatusChip/StatusChip";
|
||||
import { makeStyles } from "@saleor/macaw-ui";
|
||||
|
||||
export const useGiftCardEnableDisableSectionStyles = makeStyles(
|
||||
theme => ({
|
||||
button: {
|
||||
transition: "backgroundColor 0ms"
|
||||
},
|
||||
buttonRed: {
|
||||
backgroundColor: theme.palette.error.main,
|
||||
color: "#ffffff",
|
||||
|
||||
"&:hover": {
|
||||
backgroundColor: darken(theme.palette.error.main, 0.1)
|
||||
}
|
||||
},
|
||||
buttonGreen: {
|
||||
backgroundColor: statusChipStyles.successLabel.color,
|
||||
|
||||
"&:hover": {
|
||||
backgroundColor: darken(statusChipStyles.successLabel.color, 0.1)
|
||||
}
|
||||
}
|
||||
}),
|
||||
{ name: "GiftCardEnableDisableSection" }
|
||||
);
|
|
@ -3,7 +3,7 @@
|
|||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardErrorCode, GiftCardExpiryTypeEnum, TimePeriodTypeEnum } from "./../../../../types/globalTypes";
|
||||
import { GiftCardErrorCode } from "./../../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: GiftCardActivate
|
||||
|
@ -40,13 +40,6 @@ export interface GiftCardActivate_giftCardActivate_giftCard_product {
|
|||
name: string;
|
||||
}
|
||||
|
||||
export interface GiftCardActivate_giftCardActivate_giftCard_user {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
}
|
||||
|
||||
export interface GiftCardActivate_giftCardActivate_giftCard_usedBy {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
|
@ -60,12 +53,6 @@ export interface GiftCardActivate_giftCardActivate_giftCard_app {
|
|||
name: string | null;
|
||||
}
|
||||
|
||||
export interface GiftCardActivate_giftCardActivate_giftCard_expiryPeriod {
|
||||
__typename: "TimePeriod";
|
||||
amount: number;
|
||||
type: TimePeriodTypeEnum;
|
||||
}
|
||||
|
||||
export interface GiftCardActivate_giftCardActivate_giftCard_initialBalance {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
|
@ -83,17 +70,15 @@ export interface GiftCardActivate_giftCardActivate_giftCard {
|
|||
metadata: (GiftCardActivate_giftCardActivate_giftCard_metadata | null)[];
|
||||
privateMetadata: (GiftCardActivate_giftCardActivate_giftCard_privateMetadata | null)[];
|
||||
displayCode: string;
|
||||
boughtInChannel: string | null;
|
||||
createdBy: GiftCardActivate_giftCardActivate_giftCard_createdBy | null;
|
||||
product: GiftCardActivate_giftCardActivate_giftCard_product | null;
|
||||
user: GiftCardActivate_giftCardActivate_giftCard_user | null;
|
||||
usedBy: GiftCardActivate_giftCardActivate_giftCard_usedBy | null;
|
||||
usedByEmail: string | null;
|
||||
createdByEmail: string | null;
|
||||
app: GiftCardActivate_giftCardActivate_giftCard_app | null;
|
||||
created: any;
|
||||
expiryDate: any | null;
|
||||
expiryType: GiftCardExpiryTypeEnum;
|
||||
expiryPeriod: GiftCardActivate_giftCardActivate_giftCard_expiryPeriod | null;
|
||||
lastUsedOn: any | null;
|
||||
isActive: boolean;
|
||||
initialBalance: GiftCardActivate_giftCardActivate_giftCard_initialBalance | null;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardErrorCode, GiftCardExpiryTypeEnum, TimePeriodTypeEnum } from "./../../../../types/globalTypes";
|
||||
import { GiftCardErrorCode } from "./../../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: GiftCardDeactivate
|
||||
|
@ -40,13 +40,6 @@ export interface GiftCardDeactivate_giftCardDeactivate_giftCard_product {
|
|||
name: string;
|
||||
}
|
||||
|
||||
export interface GiftCardDeactivate_giftCardDeactivate_giftCard_user {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
}
|
||||
|
||||
export interface GiftCardDeactivate_giftCardDeactivate_giftCard_usedBy {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
|
@ -60,12 +53,6 @@ export interface GiftCardDeactivate_giftCardDeactivate_giftCard_app {
|
|||
name: string | null;
|
||||
}
|
||||
|
||||
export interface GiftCardDeactivate_giftCardDeactivate_giftCard_expiryPeriod {
|
||||
__typename: "TimePeriod";
|
||||
amount: number;
|
||||
type: TimePeriodTypeEnum;
|
||||
}
|
||||
|
||||
export interface GiftCardDeactivate_giftCardDeactivate_giftCard_initialBalance {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
|
@ -83,17 +70,15 @@ export interface GiftCardDeactivate_giftCardDeactivate_giftCard {
|
|||
metadata: (GiftCardDeactivate_giftCardDeactivate_giftCard_metadata | null)[];
|
||||
privateMetadata: (GiftCardDeactivate_giftCardDeactivate_giftCard_privateMetadata | null)[];
|
||||
displayCode: string;
|
||||
boughtInChannel: string | null;
|
||||
createdBy: GiftCardDeactivate_giftCardDeactivate_giftCard_createdBy | null;
|
||||
product: GiftCardDeactivate_giftCardDeactivate_giftCard_product | null;
|
||||
user: GiftCardDeactivate_giftCardDeactivate_giftCard_user | null;
|
||||
usedBy: GiftCardDeactivate_giftCardDeactivate_giftCard_usedBy | null;
|
||||
usedByEmail: string | null;
|
||||
createdByEmail: string | null;
|
||||
app: GiftCardDeactivate_giftCardDeactivate_giftCard_app | null;
|
||||
created: any;
|
||||
expiryDate: any | null;
|
||||
expiryType: GiftCardExpiryTypeEnum;
|
||||
expiryPeriod: GiftCardDeactivate_giftCardDeactivate_giftCard_expiryPeriod | null;
|
||||
lastUsedOn: any | null;
|
||||
isActive: boolean;
|
||||
initialBalance: GiftCardDeactivate_giftCardDeactivate_giftCard_initialBalance | null;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import { commonMessages } from "@saleor/intl";
|
||||
import { GiftCardError } from "@saleor/fragments/types/GiftCardError";
|
||||
import { GiftCardErrorCode } from "@saleor/types/globalTypes";
|
||||
import commonErrorMessages from "@saleor/utils/errors/common";
|
||||
import { getCommonFormFieldErrorMessage } from "@saleor/utils/errors/common";
|
||||
import { defineMessages, IntlShape } from "react-intl";
|
||||
|
||||
import { GiftCardUpdate_giftCardUpdate_errors } from "./types/GiftCardUpdate";
|
||||
|
||||
export const giftCardUpdateDetailsCardMessages = defineMessages({
|
||||
title: {
|
||||
defaultMessage: "Details",
|
||||
|
@ -12,23 +10,23 @@ export const giftCardUpdateDetailsCardMessages = defineMessages({
|
|||
}
|
||||
});
|
||||
|
||||
const giftCardErrorMessages = defineMessages({
|
||||
notFound: {
|
||||
defaultMessage: "Couldn't find gift card",
|
||||
description: "giftCardErrorMessages not found"
|
||||
}
|
||||
});
|
||||
|
||||
export function getGiftCardErrorMessage(
|
||||
error: Omit<GiftCardUpdate_giftCardUpdate_errors, "__typename"> | undefined,
|
||||
error: Omit<GiftCardError, "__typename"> | undefined,
|
||||
intl: IntlShape
|
||||
): string {
|
||||
if (error) {
|
||||
switch (error.code) {
|
||||
case GiftCardErrorCode.GRAPHQL_ERROR:
|
||||
return intl.formatMessage(commonErrorMessages.graphqlError);
|
||||
case GiftCardErrorCode.REQUIRED:
|
||||
return intl.formatMessage(commonMessages.requiredField);
|
||||
case GiftCardErrorCode.INVALID:
|
||||
return intl.formatMessage(commonErrorMessages.invalid);
|
||||
|
||||
default:
|
||||
return intl.formatMessage(commonErrorMessages.unknownError);
|
||||
case GiftCardErrorCode.NOT_FOUND:
|
||||
return intl.formatMessage(giftCardErrorMessages.notFound);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return getCommonFormFieldErrorMessage(error, intl);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import GiftCardUpdatePageDeleteDialog from "@saleor/giftCards/components/GiftCardDeleteDialog/GiftCardUpdatePageDeleteDialog";
|
||||
import { giftCardsListPath, giftCardUrl } from "@saleor/giftCards/urls";
|
||||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||
import React, { createContext } from "react";
|
||||
|
||||
import GiftCardResendCodeDialog from "../../GiftCardResendCodeDialog";
|
||||
import GiftCardUpdateBalanceDialog from "../../GiftCardUpdateBalanceDialog";
|
||||
import {
|
||||
GiftCardUpdatePageActionParamsEnum,
|
||||
|
@ -18,8 +20,10 @@ interface GiftCardUpdateDialogsProviderProps {
|
|||
|
||||
export interface GiftCardUpdateDialogsConsumerProps {
|
||||
navigateBack: () => void;
|
||||
openSetBalanceDialog: () => void;
|
||||
closeDialog: () => void;
|
||||
openSetBalanceDialog: () => void;
|
||||
openDeleteDialog: () => void;
|
||||
openResendCodeDialog: () => void;
|
||||
}
|
||||
|
||||
export const GiftCardUpdateDialogsContext = createContext<
|
||||
|
@ -35,21 +39,26 @@ const GiftCardUpdateDialogsProvider: React.FC<GiftCardUpdateDialogsProviderProps
|
|||
|
||||
const { loading: loadingGiftCard } = useGiftCardDetails();
|
||||
|
||||
const {
|
||||
SET_BALANCE,
|
||||
DELETE,
|
||||
RESEND_CODE
|
||||
} = GiftCardUpdatePageActionParamsEnum;
|
||||
|
||||
const [openDialog, closeDialog] = createDialogActionHandlers<
|
||||
GiftCardUpdatePageActionParamsEnum,
|
||||
GiftCardUpdatePageUrlQueryParams
|
||||
>(navigate, params => giftCardUrl(id, params), params);
|
||||
|
||||
const openSetBalanceDialog = () =>
|
||||
openDialog(GiftCardUpdatePageActionParamsEnum.SET_BALANCE);
|
||||
|
||||
const isSetBalanceDialogOpen =
|
||||
params?.action === GiftCardUpdatePageActionParamsEnum.SET_BALANCE;
|
||||
const isDialogOpen = (action: GiftCardUpdatePageActionParamsEnum) =>
|
||||
params?.action === action;
|
||||
|
||||
const navigateBack = () => navigate(giftCardsListPath);
|
||||
|
||||
const providerValues: GiftCardUpdateDialogsConsumerProps = {
|
||||
openSetBalanceDialog,
|
||||
openSetBalanceDialog: () => openDialog(SET_BALANCE),
|
||||
openDeleteDialog: () => openDialog(DELETE),
|
||||
openResendCodeDialog: () => openDialog(RESEND_CODE),
|
||||
closeDialog,
|
||||
navigateBack
|
||||
};
|
||||
|
@ -58,10 +67,21 @@ const GiftCardUpdateDialogsProvider: React.FC<GiftCardUpdateDialogsProviderProps
|
|||
<GiftCardUpdateDialogsContext.Provider value={providerValues}>
|
||||
{children}
|
||||
{!loadingGiftCard && (
|
||||
<GiftCardUpdateBalanceDialog
|
||||
onClose={closeDialog}
|
||||
open={isSetBalanceDialogOpen}
|
||||
/>
|
||||
<>
|
||||
<GiftCardUpdateBalanceDialog
|
||||
closeDialog={closeDialog}
|
||||
open={isDialogOpen(SET_BALANCE)}
|
||||
/>
|
||||
<GiftCardUpdatePageDeleteDialog
|
||||
closeDialog={closeDialog}
|
||||
open={isDialogOpen(DELETE)}
|
||||
navigateBack={navigateBack}
|
||||
/>
|
||||
<GiftCardResendCodeDialog
|
||||
open={isDialogOpen(RESEND_CODE)}
|
||||
closeDialog={closeDialog}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</GiftCardUpdateDialogsContext.Provider>
|
||||
);
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import { MetadataFormData } from "@saleor/components/Metadata";
|
||||
import { GiftCardError } from "@saleor/fragments/types/GiftCardError";
|
||||
import { GiftCardCommonFormData } from "@saleor/giftCards/GiftCardCreateDialog/types";
|
||||
import { getGiftCardExpirySettingsInputData } from "@saleor/giftCards/GiftCardCreateDialog/utils";
|
||||
import { MutationResultWithOpts } from "@saleor/hooks/makeMutation";
|
||||
import useForm, { FormChange, UseFormResult } from "@saleor/hooks/useForm";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
import { getDefaultNotifierSuccessErrorData } from "@saleor/hooks/useNotifier/utils";
|
||||
import { TimePeriodTypeEnum } from "@saleor/types/globalTypes";
|
||||
import { getFormErrors } from "@saleor/utils/errors";
|
||||
import handleFormSubmit from "@saleor/utils/handlers/handleFormSubmit";
|
||||
import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler";
|
||||
|
@ -38,7 +36,7 @@ export interface GiftCardUpdateFormConsumerData
|
|||
}
|
||||
|
||||
export interface GiftCardUpdateFormErrors {
|
||||
formErrors: Record<"tag" | "expiryDate" | "expiryPeriod", GiftCardError>;
|
||||
formErrors: Record<"tag" | "expiryDate", GiftCardError>;
|
||||
handlers: { changeMetadata: FormChange };
|
||||
}
|
||||
|
||||
|
@ -66,21 +64,11 @@ const GiftCardUpdateFormProvider: React.FC<GiftCardUpdateFormProviderProps> = ({
|
|||
return { ...emptyFormData, metadata: [], privateMetadata: [] };
|
||||
}
|
||||
|
||||
const {
|
||||
tag,
|
||||
expiryDate,
|
||||
expiryType,
|
||||
expiryPeriod,
|
||||
privateMetadata,
|
||||
metadata
|
||||
} = giftCard;
|
||||
const { tag, expiryDate, privateMetadata, metadata } = giftCard;
|
||||
|
||||
return {
|
||||
tag,
|
||||
expiryDate,
|
||||
expiryType,
|
||||
expiryPeriodType: expiryPeriod?.type || TimePeriodTypeEnum.YEAR,
|
||||
expiryPeriodAmount: expiryPeriod?.amount || 1,
|
||||
privateMetadata: privateMetadata?.map(mapMetadataItemToInput),
|
||||
metadata: metadata?.map(mapMetadataItemToInput)
|
||||
};
|
||||
|
@ -96,13 +84,13 @@ const GiftCardUpdateFormProvider: React.FC<GiftCardUpdateFormProviderProps> = ({
|
|||
onCompleted: onSubmit
|
||||
});
|
||||
|
||||
const submit = async (formData: GiftCardUpdateFormData) => {
|
||||
const submit = async ({ tag, expiryDate }: GiftCardUpdateFormData) => {
|
||||
const result = await updateGiftCard({
|
||||
variables: {
|
||||
id: giftCard?.id,
|
||||
input: {
|
||||
tag: formData.tag,
|
||||
expirySettings: getGiftCardExpirySettingsInputData(formData)
|
||||
tag,
|
||||
expiryDate
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -138,7 +126,7 @@ const GiftCardUpdateFormProvider: React.FC<GiftCardUpdateFormProviderProps> = ({
|
|||
handleFormSubmit(submitData, handleSubmit, setChanged);
|
||||
|
||||
const formErrors = getFormErrors(
|
||||
["tag", "expiryDate", "expiryPeriod"],
|
||||
["tag", "expiryDate"],
|
||||
updateGiftCardOpts?.data?.giftCardUpdate?.errors
|
||||
);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { fragmentUserBase } from "@saleor/fragments/auth";
|
||||
import { metadataFragment } from "@saleor/fragments/metadata";
|
||||
import { fragmentMoney } from "@saleor/fragments/products";
|
||||
import { fragmentTimePeriod } from "@saleor/fragments/timePeriod";
|
||||
import makeQuery from "@saleor/hooks/makeQuery";
|
||||
import gql from "graphql-tag";
|
||||
|
||||
|
@ -14,10 +13,10 @@ export const giftCardDataFragment = gql`
|
|||
${fragmentMoney}
|
||||
${metadataFragment}
|
||||
${fragmentUserBase}
|
||||
${fragmentTimePeriod}
|
||||
fragment GiftCardData on GiftCard {
|
||||
...MetadataFragment
|
||||
displayCode
|
||||
boughtInChannel
|
||||
createdBy {
|
||||
...UserBase
|
||||
}
|
||||
|
@ -25,7 +24,7 @@ export const giftCardDataFragment = gql`
|
|||
id
|
||||
name
|
||||
}
|
||||
user {
|
||||
createdBy {
|
||||
...UserBase
|
||||
}
|
||||
usedBy {
|
||||
|
@ -39,10 +38,6 @@ export const giftCardDataFragment = gql`
|
|||
}
|
||||
created
|
||||
expiryDate
|
||||
expiryType
|
||||
expiryPeriod {
|
||||
...TimePeriod
|
||||
}
|
||||
lastUsedOn
|
||||
isActive
|
||||
initialBalance {
|
||||
|
@ -63,18 +58,8 @@ export const giftCardDetails = gql`
|
|||
giftCard(id: $id) {
|
||||
...GiftCardData
|
||||
events {
|
||||
expiry {
|
||||
expiryType
|
||||
expiryPeriod {
|
||||
...TimePeriod
|
||||
}
|
||||
expiryDate
|
||||
oldExpiryType
|
||||
oldExpiryPeriod {
|
||||
...TimePeriod
|
||||
}
|
||||
oldExpiryDate
|
||||
}
|
||||
expiryDate
|
||||
oldExpiryDate
|
||||
id
|
||||
date
|
||||
type
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { Dialog } from "@saleor/types";
|
||||
|
||||
export enum GiftCardUpdatePageActionParamsEnum {
|
||||
SET_BALANCE = "set-balance"
|
||||
SET_BALANCE = "set-balance",
|
||||
DELETE = "delete",
|
||||
RESEND_CODE = "resend-code"
|
||||
}
|
||||
|
||||
export type GiftCardUpdatePageUrlQueryParams = Dialog<
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardExpiryTypeEnum, TimePeriodTypeEnum } from "./../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL fragment: GiftCardData
|
||||
// ====================================================
|
||||
|
@ -34,13 +32,6 @@ export interface GiftCardData_product {
|
|||
name: string;
|
||||
}
|
||||
|
||||
export interface GiftCardData_user {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
}
|
||||
|
||||
export interface GiftCardData_usedBy {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
|
@ -54,12 +45,6 @@ export interface GiftCardData_app {
|
|||
name: string | null;
|
||||
}
|
||||
|
||||
export interface GiftCardData_expiryPeriod {
|
||||
__typename: "TimePeriod";
|
||||
amount: number;
|
||||
type: TimePeriodTypeEnum;
|
||||
}
|
||||
|
||||
export interface GiftCardData_initialBalance {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
|
@ -77,17 +62,15 @@ export interface GiftCardData {
|
|||
metadata: (GiftCardData_metadata | null)[];
|
||||
privateMetadata: (GiftCardData_privateMetadata | null)[];
|
||||
displayCode: string;
|
||||
boughtInChannel: string | null;
|
||||
createdBy: GiftCardData_createdBy | null;
|
||||
product: GiftCardData_product | null;
|
||||
user: GiftCardData_user | null;
|
||||
usedBy: GiftCardData_usedBy | null;
|
||||
usedByEmail: string | null;
|
||||
createdByEmail: string | null;
|
||||
app: GiftCardData_app | null;
|
||||
created: any;
|
||||
expiryDate: any | null;
|
||||
expiryType: GiftCardExpiryTypeEnum;
|
||||
expiryPeriod: GiftCardData_expiryPeriod | null;
|
||||
lastUsedOn: any | null;
|
||||
isActive: boolean;
|
||||
initialBalance: GiftCardData_initialBalance | null;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardExpiryTypeEnum, TimePeriodTypeEnum, GiftCardEventsEnum } from "./../../../types/globalTypes";
|
||||
import { GiftCardEventsEnum } from "./../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: GiftCardDetails
|
||||
|
@ -34,13 +34,6 @@ export interface GiftCardDetails_giftCard_product {
|
|||
name: string;
|
||||
}
|
||||
|
||||
export interface GiftCardDetails_giftCard_user {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
}
|
||||
|
||||
export interface GiftCardDetails_giftCard_usedBy {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
|
@ -54,12 +47,6 @@ export interface GiftCardDetails_giftCard_app {
|
|||
name: string | null;
|
||||
}
|
||||
|
||||
export interface GiftCardDetails_giftCard_expiryPeriod {
|
||||
__typename: "TimePeriod";
|
||||
amount: number;
|
||||
type: TimePeriodTypeEnum;
|
||||
}
|
||||
|
||||
export interface GiftCardDetails_giftCard_initialBalance {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
|
@ -72,28 +59,6 @@ export interface GiftCardDetails_giftCard_currentBalance {
|
|||
currency: string;
|
||||
}
|
||||
|
||||
export interface GiftCardDetails_giftCard_events_expiry_expiryPeriod {
|
||||
__typename: "TimePeriod";
|
||||
amount: number;
|
||||
type: TimePeriodTypeEnum;
|
||||
}
|
||||
|
||||
export interface GiftCardDetails_giftCard_events_expiry_oldExpiryPeriod {
|
||||
__typename: "TimePeriod";
|
||||
amount: number;
|
||||
type: TimePeriodTypeEnum;
|
||||
}
|
||||
|
||||
export interface GiftCardDetails_giftCard_events_expiry {
|
||||
__typename: "GiftCardEventExpiry";
|
||||
expiryType: GiftCardExpiryTypeEnum | null;
|
||||
expiryPeriod: GiftCardDetails_giftCard_events_expiry_expiryPeriod | null;
|
||||
expiryDate: any | null;
|
||||
oldExpiryType: GiftCardExpiryTypeEnum | null;
|
||||
oldExpiryPeriod: GiftCardDetails_giftCard_events_expiry_oldExpiryPeriod | null;
|
||||
oldExpiryDate: any | null;
|
||||
}
|
||||
|
||||
export interface GiftCardDetails_giftCard_events_user {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
|
@ -133,7 +98,7 @@ export interface GiftCardDetails_giftCard_events_balance_oldCurrentBalance {
|
|||
|
||||
export interface GiftCardDetails_giftCard_events_balance {
|
||||
__typename: "GiftCardEventBalance";
|
||||
initialBalance: GiftCardDetails_giftCard_events_balance_initialBalance;
|
||||
initialBalance: GiftCardDetails_giftCard_events_balance_initialBalance | null;
|
||||
currentBalance: GiftCardDetails_giftCard_events_balance_currentBalance;
|
||||
oldInitialBalance: GiftCardDetails_giftCard_events_balance_oldInitialBalance | null;
|
||||
oldCurrentBalance: GiftCardDetails_giftCard_events_balance_oldCurrentBalance | null;
|
||||
|
@ -141,7 +106,8 @@ export interface GiftCardDetails_giftCard_events_balance {
|
|||
|
||||
export interface GiftCardDetails_giftCard_events {
|
||||
__typename: "GiftCardEvent";
|
||||
expiry: GiftCardDetails_giftCard_events_expiry | null;
|
||||
expiryDate: any | null;
|
||||
oldExpiryDate: any | null;
|
||||
id: string;
|
||||
date: any | null;
|
||||
type: GiftCardEventsEnum | null;
|
||||
|
@ -161,17 +127,15 @@ export interface GiftCardDetails_giftCard {
|
|||
metadata: (GiftCardDetails_giftCard_metadata | null)[];
|
||||
privateMetadata: (GiftCardDetails_giftCard_privateMetadata | null)[];
|
||||
displayCode: string;
|
||||
boughtInChannel: string | null;
|
||||
createdBy: GiftCardDetails_giftCard_createdBy | null;
|
||||
product: GiftCardDetails_giftCard_product | null;
|
||||
user: GiftCardDetails_giftCard_user | null;
|
||||
usedBy: GiftCardDetails_giftCard_usedBy | null;
|
||||
usedByEmail: string | null;
|
||||
createdByEmail: string | null;
|
||||
app: GiftCardDetails_giftCard_app | null;
|
||||
created: any;
|
||||
expiryDate: any | null;
|
||||
expiryType: GiftCardExpiryTypeEnum;
|
||||
expiryPeriod: GiftCardDetails_giftCard_expiryPeriod | null;
|
||||
lastUsedOn: any | null;
|
||||
isActive: boolean;
|
||||
initialBalance: GiftCardDetails_giftCard_initialBalance | null;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardUpdateInput, GiftCardErrorCode, GiftCardExpiryTypeEnum, TimePeriodTypeEnum } from "./../../../types/globalTypes";
|
||||
import { GiftCardUpdateInput, GiftCardErrorCode } from "./../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: GiftCardUpdate
|
||||
|
@ -40,13 +40,6 @@ export interface GiftCardUpdate_giftCardUpdate_giftCard_product {
|
|||
name: string;
|
||||
}
|
||||
|
||||
export interface GiftCardUpdate_giftCardUpdate_giftCard_user {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
}
|
||||
|
||||
export interface GiftCardUpdate_giftCardUpdate_giftCard_usedBy {
|
||||
__typename: "User";
|
||||
id: string;
|
||||
|
@ -60,12 +53,6 @@ export interface GiftCardUpdate_giftCardUpdate_giftCard_app {
|
|||
name: string | null;
|
||||
}
|
||||
|
||||
export interface GiftCardUpdate_giftCardUpdate_giftCard_expiryPeriod {
|
||||
__typename: "TimePeriod";
|
||||
amount: number;
|
||||
type: TimePeriodTypeEnum;
|
||||
}
|
||||
|
||||
export interface GiftCardUpdate_giftCardUpdate_giftCard_initialBalance {
|
||||
__typename: "Money";
|
||||
amount: number;
|
||||
|
@ -83,17 +70,15 @@ export interface GiftCardUpdate_giftCardUpdate_giftCard {
|
|||
metadata: (GiftCardUpdate_giftCardUpdate_giftCard_metadata | null)[];
|
||||
privateMetadata: (GiftCardUpdate_giftCardUpdate_giftCard_privateMetadata | null)[];
|
||||
displayCode: string;
|
||||
boughtInChannel: string | null;
|
||||
createdBy: GiftCardUpdate_giftCardUpdate_giftCard_createdBy | null;
|
||||
product: GiftCardUpdate_giftCardUpdate_giftCard_product | null;
|
||||
user: GiftCardUpdate_giftCardUpdate_giftCard_user | null;
|
||||
usedBy: GiftCardUpdate_giftCardUpdate_giftCard_usedBy | null;
|
||||
usedByEmail: string | null;
|
||||
createdByEmail: string | null;
|
||||
app: GiftCardUpdate_giftCardUpdate_giftCard_app | null;
|
||||
created: any;
|
||||
expiryDate: any | null;
|
||||
expiryType: GiftCardExpiryTypeEnum;
|
||||
expiryPeriod: GiftCardUpdate_giftCardUpdate_giftCard_expiryPeriod | null;
|
||||
lastUsedOn: any | null;
|
||||
isActive: boolean;
|
||||
initialBalance: GiftCardUpdate_giftCardUpdate_giftCard_initialBalance | null;
|
||||
|
|
14
src/giftCards/GiftCardsList/GiftCardListPage.tsx
Normal file
14
src/giftCards/GiftCardsList/GiftCardListPage.tsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
import Container from "@saleor/components/Container";
|
||||
import React from "react";
|
||||
|
||||
import GiftCardsListHeader from "./GiftCardsListHeader";
|
||||
import GiftCardsListTable from "./GiftCardsListTable";
|
||||
|
||||
const GiftCardsListPage: React.FC = () => (
|
||||
<Container>
|
||||
<GiftCardsListHeader />
|
||||
<GiftCardsListTable />
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default GiftCardsListPage;
|
|
@ -1,46 +1,20 @@
|
|||
import Container from "@saleor/components/Container";
|
||||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||
import React from "react";
|
||||
|
||||
import GiftCardCreateDialog from "../GiftCardCreateDialog";
|
||||
import { giftCardsListUrl } from "../urls";
|
||||
import GiftCardsListHeader from "./GiftCardsListHeader";
|
||||
import GiftCardsListTable from "./GiftCardsListTable";
|
||||
import { GiftCardsListProvider } from "./providers/GiftCardsListProvider";
|
||||
import {
|
||||
GiftCardListActionParamsEnum,
|
||||
GiftCardListUrlQueryParams
|
||||
} from "./types";
|
||||
import GiftCardListPage from "./GiftCardListPage";
|
||||
import GiftCardListDialogsProvider from "./providers/GiftCardListDialogsProvider";
|
||||
import { GiftCardsListProvider } from "./providers/GiftCardListProvider";
|
||||
import { GiftCardListUrlQueryParams } from "./types";
|
||||
|
||||
interface GiftCardsListProps {
|
||||
params: GiftCardListUrlQueryParams;
|
||||
}
|
||||
|
||||
const GiftCardsList: React.FC<GiftCardsListProps> = ({ params }) => {
|
||||
const navigate = useNavigator();
|
||||
|
||||
const [openModal, closeModal] = createDialogActionHandlers<
|
||||
GiftCardListActionParamsEnum,
|
||||
GiftCardListUrlQueryParams
|
||||
>(navigate, giftCardsListUrl, params);
|
||||
|
||||
const openCreateModal = () => openModal(GiftCardListActionParamsEnum.CREATE);
|
||||
|
||||
return (
|
||||
<>
|
||||
<GiftCardsListProvider params={params}>
|
||||
<Container>
|
||||
<GiftCardsListHeader onIssueButtonClick={openCreateModal} />
|
||||
<GiftCardsListTable />
|
||||
</Container>
|
||||
</GiftCardsListProvider>
|
||||
<GiftCardCreateDialog
|
||||
open={params?.action === GiftCardListActionParamsEnum.CREATE}
|
||||
onClose={closeModal}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
const GiftCardsList: React.FC<GiftCardsListProps> = ({ params }) => (
|
||||
<GiftCardsListProvider params={params}>
|
||||
<GiftCardListDialogsProvider params={params}>
|
||||
<GiftCardListPage />
|
||||
</GiftCardListDialogsProvider>
|
||||
</GiftCardsListProvider>
|
||||
);
|
||||
|
||||
export default GiftCardsList;
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
import { Button } from "@material-ui/core";
|
||||
import HorizontalSpacer from "@saleor/apps/components/HorizontalSpacer";
|
||||
// import CardMenu, { CardMenuItem } from "@saleor/components/CardMenu";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import { sectionNames } from "@saleor/intl";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { giftCardsListHeaderMenuItemsMessages as messages } from "./messages";
|
||||
|
||||
interface GiftCardsListHeaderProps {
|
||||
onIssueButtonClick: () => void;
|
||||
}
|
||||
|
||||
const GiftCardsListHeader: React.FC<GiftCardsListHeaderProps> = ({
|
||||
onIssueButtonClick
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
// const menuItems: CardMenuItem[] = [
|
||||
// {
|
||||
// label: intl.formatMessage(messages.settings),
|
||||
// testId: "settingsMenuItem"
|
||||
// // onSelect:
|
||||
// },
|
||||
// {
|
||||
// label: intl.formatMessage(messages.bulkIssue),
|
||||
// testId: "bulkIssueMenuItem"
|
||||
// // onSelect:
|
||||
// },
|
||||
// {
|
||||
// label: intl.formatMessage(messages.exportCodes),
|
||||
// testId: "exportCodesMenuItem"
|
||||
// // onSelect:
|
||||
// }
|
||||
// ];
|
||||
|
||||
return (
|
||||
<PageHeader title={intl.formatMessage(sectionNames.giftCards)}>
|
||||
{/* <CardMenu menuItems={menuItems} data-test="menu" /> */}
|
||||
<HorizontalSpacer spacing={2} />
|
||||
<Button
|
||||
color="primary"
|
||||
variant="contained"
|
||||
onClick={onIssueButtonClick}
|
||||
data-test-id="issueCardButton"
|
||||
>
|
||||
{intl.formatMessage(messages.issueButtonLabel)}
|
||||
</Button>
|
||||
</PageHeader>
|
||||
);
|
||||
};
|
||||
|
||||
export default GiftCardsListHeader;
|
|
@ -0,0 +1,103 @@
|
|||
import { Button } from "@material-ui/core";
|
||||
import HorizontalSpacer from "@saleor/apps/components/HorizontalSpacer";
|
||||
import VerticalSpacer from "@saleor/apps/components/VerticalSpacer";
|
||||
import CardMenu, { CardMenuItem } from "@saleor/components/CardMenu";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import { sectionNames } from "@saleor/intl";
|
||||
import { Alert } from "@saleor/macaw-ui";
|
||||
import { productAddUrl } from "@saleor/products/urls";
|
||||
import { productTypeAddUrl } from "@saleor/productTypes/urls";
|
||||
import { ProductTypeKindEnum } from "@saleor/types/globalTypes";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { giftCardSettingsUrl } from "../../urls";
|
||||
import { giftCardsListHeaderMenuItemsMessages as messages } from "../messages";
|
||||
import useGiftCardListDialogs from "../providers/GiftCardListDialogsProvider/hooks/useGiftCardListDialogs";
|
||||
import { useGiftCardProductsCountQuery } from "../queries";
|
||||
import GiftCardsListHeaderAlertContent from "./GiftCardsListHeaderAlertContent";
|
||||
|
||||
const GiftCardsListHeader: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const navigate = useNavigator();
|
||||
|
||||
const { openCreateDialog } = useGiftCardListDialogs();
|
||||
|
||||
const {
|
||||
data: giftCardProductsCount,
|
||||
loading: giftCardProductsCountLoading
|
||||
} = useGiftCardProductsCountQuery();
|
||||
|
||||
const openSettings = () => navigate(giftCardSettingsUrl);
|
||||
|
||||
const menuItems: CardMenuItem[] = [
|
||||
{
|
||||
label: intl.formatMessage(messages.settings),
|
||||
testId: "settingsMenuItem",
|
||||
onSelect: openSettings
|
||||
}
|
||||
// {
|
||||
// label: intl.formatMessage(messages.bulkIssue),
|
||||
// testId: "bulkIssueMenuItem"
|
||||
// // onSelect:
|
||||
// },
|
||||
// {
|
||||
// label: intl.formatMessage(messages.exportCodes),
|
||||
// testId: "exportCodesMenuItem"
|
||||
// // onSelect:
|
||||
// }
|
||||
];
|
||||
|
||||
const giftCardProductTypesExist =
|
||||
giftCardProductsCount?.giftCardProductTypes.totalCount > 0;
|
||||
const giftCardProductsExist =
|
||||
giftCardProductsCount?.giftCardProducts.totalCount > 0;
|
||||
|
||||
const showNoGiftCardProductsAlert =
|
||||
!giftCardProductsCountLoading &&
|
||||
(!giftCardProductTypesExist || !giftCardProductsExist);
|
||||
|
||||
const handleCreateGiftCardProductType = () =>
|
||||
navigate(
|
||||
productTypeAddUrl({
|
||||
kind: ProductTypeKindEnum.GIFT_CARD
|
||||
})
|
||||
);
|
||||
|
||||
const handleCreateGiftCardProduct = () => navigate(productAddUrl());
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader title={intl.formatMessage(sectionNames.giftCards)}>
|
||||
<CardMenu menuItems={menuItems} data-test="menu" />
|
||||
<HorizontalSpacer spacing={2} />
|
||||
<Button
|
||||
color="primary"
|
||||
variant="contained"
|
||||
onClick={openCreateDialog}
|
||||
data-test-id="issueCardButton"
|
||||
>
|
||||
{intl.formatMessage(messages.issueButtonLabel)}
|
||||
</Button>
|
||||
</PageHeader>
|
||||
{showNoGiftCardProductsAlert && (
|
||||
<Alert
|
||||
title={intl.formatMessage(messages.noGiftCardsAlertTitle)}
|
||||
variant="warning"
|
||||
close={false}
|
||||
>
|
||||
<GiftCardsListHeaderAlertContent
|
||||
giftCardProductTypesExist={giftCardProductTypesExist}
|
||||
giftCardProductsExist={giftCardProductsExist}
|
||||
handleCreateGiftCardProductType={handleCreateGiftCardProductType}
|
||||
handleCreateGiftCardProduct={handleCreateGiftCardProduct}
|
||||
/>
|
||||
</Alert>
|
||||
)}
|
||||
<VerticalSpacer spacing={2} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default GiftCardsListHeader;
|
|
@ -0,0 +1,62 @@
|
|||
import Link from "@saleor/components/Link";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import { giftCardsListHeaderMenuItemsMessages as messages } from "../messages";
|
||||
import { useHeaderStyles as useStyles } from "../styles";
|
||||
|
||||
interface GiftCardsListHeaderAlertContentProps {
|
||||
giftCardProductTypesExist: boolean;
|
||||
giftCardProductsExist: boolean;
|
||||
handleCreateGiftCardProductType: () => void;
|
||||
handleCreateGiftCardProduct: () => void;
|
||||
}
|
||||
|
||||
const GiftCardsListHeaderAlertContent: React.FC<GiftCardsListHeaderAlertContentProps> = ({
|
||||
giftCardProductTypesExist,
|
||||
giftCardProductsExist,
|
||||
handleCreateGiftCardProductType,
|
||||
handleCreateGiftCardProduct
|
||||
}) => {
|
||||
const classes = useStyles({});
|
||||
|
||||
if (!giftCardProductTypesExist) {
|
||||
return (
|
||||
<FormattedMessage
|
||||
{...messages.noGiftCardsProductTypes}
|
||||
values={{
|
||||
createGiftCardProductType: (
|
||||
<Link
|
||||
onClick={handleCreateGiftCardProductType}
|
||||
className={classes.alertLink}
|
||||
>
|
||||
<FormattedMessage {...messages.createGiftCardProductType} />
|
||||
</Link>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (!giftCardProductsExist) {
|
||||
return (
|
||||
<FormattedMessage
|
||||
{...messages.noGiftCardsProducts}
|
||||
values={{
|
||||
createGiftCardProduct: (
|
||||
<Link
|
||||
onClick={handleCreateGiftCardProduct}
|
||||
className={classes.alertLink}
|
||||
>
|
||||
<FormattedMessage {...messages.createGiftCardProduct} />
|
||||
</Link>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default GiftCardsListHeaderAlertContent;
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./GiftCardsListHeader";
|
||||
export { default } from "./GiftCardsListHeader";
|
|
@ -22,8 +22,9 @@ import React from "react";
|
|||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
import { giftCardsListTableMessages as messages } from "../messages";
|
||||
import useGiftCardList from "../providers/hooks/useGiftCardList";
|
||||
import useGiftCardListBulkActions from "../providers/hooks/useGiftCardListBulkActions";
|
||||
import useGiftCardListDialogs from "../providers/GiftCardListDialogsProvider/hooks/useGiftCardListDialogs";
|
||||
import useGiftCardList from "../providers/GiftCardListProvider/hooks/useGiftCardList";
|
||||
import useGiftCardListBulkActions from "../providers/GiftCardListProvider/hooks/useGiftCardListBulkActions";
|
||||
import { useTableStyles as useStyles } from "../styles";
|
||||
import GiftCardsListTableFooter from "./GiftCardsListTableFooter";
|
||||
import GiftCardsListTableHeader from "./GiftCardsListTableHeader";
|
||||
|
@ -34,8 +35,10 @@ const GiftCardsListTable: React.FC = () => {
|
|||
const intl = useIntl();
|
||||
const classes = useStyles({});
|
||||
const navigate = useNavigator();
|
||||
|
||||
const { giftCards, numberOfColumns, loading } = useGiftCardList();
|
||||
const { toggle, isSelected } = useGiftCardListBulkActions();
|
||||
const { openDeleteDialog } = useGiftCardListDialogs();
|
||||
|
||||
const redirectToGiftCardUpdate = (id: string) => () =>
|
||||
navigate(giftCardUrl(id));
|
||||
|
@ -122,7 +125,12 @@ const GiftCardsListTable: React.FC = () => {
|
|||
</div>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colDelete}>
|
||||
<DeleteIconButton />
|
||||
<DeleteIconButton
|
||||
onClick={event => {
|
||||
event.stopPropagation();
|
||||
openDeleteDialog(id);
|
||||
}}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
),
|
||||
|
|
|
@ -3,7 +3,7 @@ import TablePagination from "@saleor/components/TablePagination";
|
|||
import usePaginator from "@saleor/hooks/usePaginator";
|
||||
import React from "react";
|
||||
|
||||
import useGiftCardList from "../providers/hooks/useGiftCardList";
|
||||
import useGiftCardList from "../providers/GiftCardListProvider/hooks/useGiftCardList";
|
||||
|
||||
const GiftCardsListTableFooter: React.FC = () => {
|
||||
const paginate = usePaginator();
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
import ConfirmButton from "@saleor/components/ConfirmButton";
|
||||
import { IMessage } from "@saleor/components/messages";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
import { getByIds } from "@saleor/orders/components/OrderReturnPage/utils";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import useGiftCardList from "../../providers/GiftCardListProvider/hooks/useGiftCardList";
|
||||
import useGiftCardListBulkActions from "../../providers/GiftCardListProvider/hooks/useGiftCardListBulkActions";
|
||||
import { GIFT_CARD_LIST_QUERY } from "../../types";
|
||||
import { bulkEnableDisableSectionMessages as messages } from "./messages";
|
||||
import {
|
||||
useGiftCardBulkActivateMutation,
|
||||
useGiftCardBulkDeactivateMutation
|
||||
} from "./mutations";
|
||||
import { GiftCardBulkActivate } from "./types/GiftCardBulkActivate";
|
||||
import { GiftCardBulkDeactivate } from "./types/GiftCardBulkDeactivate";
|
||||
|
||||
const BulkEnableDisableSection: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const notify = useNotifier();
|
||||
|
||||
const { listElements: ids, reset } = useGiftCardListBulkActions();
|
||||
const { giftCards } = useGiftCardList();
|
||||
|
||||
const onActivateCompleted = (data: GiftCardBulkActivate) => {
|
||||
const { errors, count } = data?.giftCardBulkActivate;
|
||||
|
||||
const notifierData: IMessage = !!errors?.length
|
||||
? {
|
||||
status: "error",
|
||||
text: intl.formatMessage(messages.errorActivateAlertText, { count })
|
||||
}
|
||||
: {
|
||||
status: "success",
|
||||
text: intl.formatMessage(messages.successActivateAlertText, { count })
|
||||
};
|
||||
|
||||
notify(notifierData);
|
||||
|
||||
if (!errors.length) {
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
const onDeactivateCompleted = (data: GiftCardBulkDeactivate) => {
|
||||
const { errors, count } = data?.giftCardBulkDeactivate;
|
||||
|
||||
const notifierData: IMessage = !!errors?.length
|
||||
? {
|
||||
status: "error",
|
||||
text: intl.formatMessage(messages.errorDeactivateAlertText, { count })
|
||||
}
|
||||
: {
|
||||
status: "success",
|
||||
text: intl.formatMessage(messages.successDeactivateAlertText, {
|
||||
count
|
||||
})
|
||||
};
|
||||
|
||||
notify(notifierData);
|
||||
|
||||
if (!errors.length) {
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
const hasAnyEnabledCardsSelected = giftCards
|
||||
.filter(getByIds(ids))
|
||||
.some(({ isActive }) => isActive);
|
||||
|
||||
const hasAnyDisabledCardsSelected = giftCards
|
||||
.filter(getByIds(ids))
|
||||
.some(({ isActive }) => !isActive);
|
||||
|
||||
const [
|
||||
activateGiftCards,
|
||||
activateGiftCardsOpts
|
||||
] = useGiftCardBulkActivateMutation({
|
||||
onCompleted: onActivateCompleted,
|
||||
refetchQueries: [GIFT_CARD_LIST_QUERY]
|
||||
});
|
||||
|
||||
const [
|
||||
deactivateGiftCards,
|
||||
deactivateGiftCardsOpts
|
||||
] = useGiftCardBulkDeactivateMutation({
|
||||
onCompleted: onDeactivateCompleted,
|
||||
refetchQueries: [GIFT_CARD_LIST_QUERY]
|
||||
});
|
||||
|
||||
const handleActivateGiftCards = () =>
|
||||
activateGiftCards({ variables: { ids } });
|
||||
|
||||
const handleDeactivateGiftCards = () =>
|
||||
deactivateGiftCards({ variables: { ids } });
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConfirmButton
|
||||
disabled={hasAnyEnabledCardsSelected}
|
||||
onClick={handleActivateGiftCards}
|
||||
variant="text"
|
||||
transitionState={activateGiftCardsOpts?.status}
|
||||
>
|
||||
{intl.formatMessage(messages.enableLabel)}
|
||||
</ConfirmButton>
|
||||
<ConfirmButton
|
||||
disabled={hasAnyDisabledCardsSelected}
|
||||
onClick={handleDeactivateGiftCards}
|
||||
variant="text"
|
||||
transitionState={deactivateGiftCardsOpts?.status}
|
||||
>
|
||||
{intl.formatMessage(messages.disableLabel)}
|
||||
</ConfirmButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default BulkEnableDisableSection;
|
|
@ -1,4 +1,5 @@
|
|||
import { TableCell } from "@material-ui/core";
|
||||
import DeleteIconButton from "@saleor/components/DeleteIconButton";
|
||||
import TableCellHeader, {
|
||||
TableCellHeaderProps
|
||||
} from "@saleor/components/TableCellHeader";
|
||||
|
@ -9,10 +10,12 @@ import Label, {
|
|||
import React from "react";
|
||||
import { MessageDescriptor, useIntl } from "react-intl";
|
||||
|
||||
import { giftCardsListTableMessages as messages } from "../messages";
|
||||
import useGiftCardList from "../providers/hooks/useGiftCardList";
|
||||
import useGiftCardListBulkActions from "../providers/hooks/useGiftCardListBulkActions";
|
||||
import { useTableStyles as useStyles } from "../styles";
|
||||
import { giftCardsListTableMessages as messages } from "../../messages";
|
||||
import useGiftCardListDialogs from "../../providers/GiftCardListDialogsProvider/hooks/useGiftCardListDialogs";
|
||||
import useGiftCardList from "../../providers/GiftCardListProvider/hooks/useGiftCardList";
|
||||
import useGiftCardListBulkActions from "../../providers/GiftCardListProvider/hooks/useGiftCardListBulkActions";
|
||||
import { useTableStyles as useStyles } from "../../styles";
|
||||
import BulkEnableDisableSection from "./BulkEnableDisableSection";
|
||||
|
||||
interface HeaderItem {
|
||||
title?: MessageDescriptor;
|
||||
|
@ -22,8 +25,10 @@ interface HeaderItem {
|
|||
const GiftCardsListTableHeader: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const classes = useStyles({});
|
||||
|
||||
const { giftCards, numberOfColumns, loading } = useGiftCardList();
|
||||
const { toggleAll, listElements } = useGiftCardListBulkActions();
|
||||
const { openDeleteDialog } = useGiftCardListDialogs();
|
||||
|
||||
const headerItems: HeaderItem[] = [
|
||||
{
|
||||
|
@ -68,6 +73,12 @@ const GiftCardsListTableHeader: React.FC = () => {
|
|||
selected={listElements.length}
|
||||
items={giftCards}
|
||||
toggleAll={toggleAll}
|
||||
toolbar={
|
||||
<>
|
||||
<BulkEnableDisableSection />
|
||||
<DeleteIconButton onClick={openDeleteDialog} />
|
||||
</>
|
||||
}
|
||||
>
|
||||
{headerItems.map(({ title, options }) => (
|
||||
<TableCellHeader {...options}>
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./GiftCardsListTableHeader";
|
||||
export { default } from "./GiftCardsListTableHeader";
|
|
@ -0,0 +1,32 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
export const bulkEnableDisableSectionMessages = defineMessages({
|
||||
enableLabel: {
|
||||
defaultMessage: "Activate",
|
||||
description: "GiftCardEnableDisableSection enable label"
|
||||
},
|
||||
disableLabel: {
|
||||
defaultMessage: "Deactivate",
|
||||
description: "GiftCardEnableDisableSection enable label"
|
||||
},
|
||||
successActivateAlertText: {
|
||||
defaultMessage:
|
||||
"Successfully activated gift {count,plural,one{card} other{cards}}",
|
||||
description: "GiftCardEnableDisableSection success activate alert text"
|
||||
},
|
||||
successDeactivateAlertText: {
|
||||
defaultMessage:
|
||||
"Successfully deactivated gift {count,plural,one{card} other{cards}}",
|
||||
description: "GiftCardEnableDisableSection success activate alert text"
|
||||
},
|
||||
errorActivateAlertText: {
|
||||
defaultMessage:
|
||||
"Error activating gift {count,plural,one{card} other{cards}}",
|
||||
description: "GiftCardEnableDisableSection error activate alert text"
|
||||
},
|
||||
errorDeactivateAlertText: {
|
||||
defaultMessage:
|
||||
"Errors deactivating gift {count,plural,one{card} other{cards}}",
|
||||
description: "GiftCardEnableDisableSection error activate alert text"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,46 @@
|
|||
import { giftCardErrorFragment } from "@saleor/fragments/errors";
|
||||
import makeMutation from "@saleor/hooks/makeMutation";
|
||||
import gql from "graphql-tag";
|
||||
|
||||
import {
|
||||
GiftCardBulkActivate,
|
||||
GiftCardBulkActivateVariables
|
||||
} from "./types/GiftCardBulkActivate";
|
||||
import {
|
||||
GiftCardBulkDeactivate,
|
||||
GiftCardBulkDeactivateVariables
|
||||
} from "./types/GiftCardBulkDeactivate";
|
||||
|
||||
const giftCardBulkActivate = gql`
|
||||
${giftCardErrorFragment}
|
||||
mutation GiftCardBulkActivate($ids: [ID]!) {
|
||||
giftCardBulkActivate(ids: $ids) {
|
||||
errors {
|
||||
...GiftCardError
|
||||
}
|
||||
count
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const useGiftCardBulkActivateMutation = makeMutation<
|
||||
GiftCardBulkActivate,
|
||||
GiftCardBulkActivateVariables
|
||||
>(giftCardBulkActivate);
|
||||
|
||||
const giftCardBulkDeactivate = gql`
|
||||
${giftCardErrorFragment}
|
||||
mutation GiftCardBulkDeactivate($ids: [ID]!) {
|
||||
giftCardBulkDeactivate(ids: $ids) {
|
||||
errors {
|
||||
...GiftCardError
|
||||
}
|
||||
count
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const useGiftCardBulkDeactivateMutation = makeMutation<
|
||||
GiftCardBulkDeactivate,
|
||||
GiftCardBulkDeactivateVariables
|
||||
>(giftCardBulkDeactivate);
|
|
@ -0,0 +1,30 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardErrorCode } from "./../../../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: GiftCardBulkActivate
|
||||
// ====================================================
|
||||
|
||||
export interface GiftCardBulkActivate_giftCardBulkActivate_errors {
|
||||
__typename: "GiftCardError";
|
||||
code: GiftCardErrorCode;
|
||||
field: string | null;
|
||||
}
|
||||
|
||||
export interface GiftCardBulkActivate_giftCardBulkActivate {
|
||||
__typename: "GiftCardBulkActivate";
|
||||
errors: GiftCardBulkActivate_giftCardBulkActivate_errors[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface GiftCardBulkActivate {
|
||||
giftCardBulkActivate: GiftCardBulkActivate_giftCardBulkActivate | null;
|
||||
}
|
||||
|
||||
export interface GiftCardBulkActivateVariables {
|
||||
ids: (string | null)[];
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardErrorCode } from "./../../../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: GiftCardBulkDeactivate
|
||||
// ====================================================
|
||||
|
||||
export interface GiftCardBulkDeactivate_giftCardBulkDeactivate_errors {
|
||||
__typename: "GiftCardError";
|
||||
code: GiftCardErrorCode;
|
||||
field: string | null;
|
||||
}
|
||||
|
||||
export interface GiftCardBulkDeactivate_giftCardBulkDeactivate {
|
||||
__typename: "GiftCardBulkDeactivate";
|
||||
errors: GiftCardBulkDeactivate_giftCardBulkDeactivate_errors[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface GiftCardBulkDeactivate {
|
||||
giftCardBulkDeactivate: GiftCardBulkDeactivate_giftCardBulkDeactivate | null;
|
||||
}
|
||||
|
||||
export interface GiftCardBulkDeactivateVariables {
|
||||
ids: (string | null)[];
|
||||
}
|
|
@ -16,6 +16,37 @@ export const giftCardsListHeaderMenuItemsMessages = defineMessages({
|
|||
issueButtonLabel: {
|
||||
defaultMessage: "Issue card",
|
||||
description: "GiftCardsListHeader issue button label"
|
||||
},
|
||||
noGiftCardsAlertTitle: {
|
||||
defaultMessage: "You haven’t defined a gift card product!",
|
||||
description: "GiftCardsListHeader alert"
|
||||
},
|
||||
noGiftCardsProductsAndProductTypes: {
|
||||
defaultMessage:
|
||||
"{createGiftCardProductType} and {giftCardProduct} to start selling gift cards in your store.",
|
||||
description: "GiftCardsListHeader alert"
|
||||
},
|
||||
noGiftCardsProductTypes: {
|
||||
defaultMessage:
|
||||
"{createGiftCardProductType} to start selling gift cards in your store.",
|
||||
description: "GiftCardsListHeader alert"
|
||||
},
|
||||
noGiftCardsProducts: {
|
||||
defaultMessage:
|
||||
"{createGiftCardProduct} to start selling gift cards in your store.",
|
||||
description: "GiftCardsListHeader alert"
|
||||
},
|
||||
createGiftCardProductType: {
|
||||
defaultMessage: "Create a gift card product type",
|
||||
description: "GiftCardsListHeader alert"
|
||||
},
|
||||
createGiftCardProduct: {
|
||||
defaultMessage: "Create a gift card product",
|
||||
description: "GiftCardsListHeader alert"
|
||||
},
|
||||
giftCardProduct: {
|
||||
defaultMessage: "gift card product",
|
||||
description: "GiftCardsListHeader alert"
|
||||
}
|
||||
});
|
||||
|
||||
|
|
44
src/giftCards/GiftCardsList/mutations.ts
Normal file
44
src/giftCards/GiftCardsList/mutations.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { giftCardErrorFragment } from "@saleor/fragments/errors";
|
||||
import makeMutation from "@saleor/hooks/makeMutation";
|
||||
import gql from "graphql-tag";
|
||||
|
||||
import {
|
||||
BulkDeleteGiftCard,
|
||||
BulkDeleteGiftCardVariables
|
||||
} from "./types/BulkDeleteGiftCard";
|
||||
import {
|
||||
DeleteGiftCard,
|
||||
DeleteGiftCardVariables
|
||||
} from "./types/DeleteGiftCard";
|
||||
|
||||
const deleteGiftCard = gql`
|
||||
${giftCardErrorFragment}
|
||||
mutation DeleteGiftCard($id: ID!) {
|
||||
giftCardDelete(id: $id) {
|
||||
errors {
|
||||
...GiftCardError
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const useGiftCardDeleteMutation = makeMutation<
|
||||
DeleteGiftCard,
|
||||
DeleteGiftCardVariables
|
||||
>(deleteGiftCard);
|
||||
|
||||
const bulkDeleteGiftCard = gql`
|
||||
${giftCardErrorFragment}
|
||||
mutation BulkDeleteGiftCard($ids: [ID]!) {
|
||||
giftCardBulkDelete(ids: $ids) {
|
||||
errors {
|
||||
...GiftCardError
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const useGiftCardBulkDeleteMutation = makeMutation<
|
||||
BulkDeleteGiftCard,
|
||||
BulkDeleteGiftCardVariables
|
||||
>(bulkDeleteGiftCard);
|
|
@ -0,0 +1,80 @@
|
|||
import GiftCardListPageDeleteDialog from "@saleor/giftCards/components/GiftCardDeleteDialog/GiftCardListPageDeleteDialog";
|
||||
import GiftCardCreateDialog from "@saleor/giftCards/GiftCardCreateDialog";
|
||||
import { giftCardsListUrl } from "@saleor/giftCards/urls";
|
||||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||
import React, { createContext } from "react";
|
||||
|
||||
import {
|
||||
GiftCardListActionParamsEnum,
|
||||
GiftCardListUrlQueryParams
|
||||
} from "../../types";
|
||||
|
||||
interface GiftCardListDialogsProviderProps {
|
||||
children: React.ReactNode;
|
||||
params: GiftCardListUrlQueryParams;
|
||||
}
|
||||
|
||||
export interface GiftCardListDialogsConsumerProps {
|
||||
openCreateDialog: () => void;
|
||||
openDeleteDialog: (id?: string | React.MouseEvent) => void;
|
||||
closeDialog: () => void;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export const GiftCardListDialogsContext = createContext<
|
||||
GiftCardListDialogsConsumerProps
|
||||
>(null);
|
||||
|
||||
const GiftCardListDialogsProvider: React.FC<GiftCardListDialogsProviderProps> = ({
|
||||
children,
|
||||
params
|
||||
}) => {
|
||||
const navigate = useNavigator();
|
||||
|
||||
const id = params?.id;
|
||||
|
||||
const [openDialog, closeDialog] = createDialogActionHandlers<
|
||||
GiftCardListActionParamsEnum,
|
||||
GiftCardListUrlQueryParams
|
||||
>(navigate, giftCardsListUrl, params);
|
||||
|
||||
const openCreateDialog = () =>
|
||||
openDialog(GiftCardListActionParamsEnum.CREATE);
|
||||
|
||||
const isCreateDialogOpen =
|
||||
params?.action === GiftCardListActionParamsEnum.CREATE;
|
||||
|
||||
const isDeleteDialogOpen =
|
||||
params?.action === GiftCardListActionParamsEnum.DELETE;
|
||||
|
||||
const handleDeleteDialogOpen = (id?: string) => {
|
||||
openDialog(
|
||||
GiftCardListActionParamsEnum.DELETE,
|
||||
typeof id === "string" ? { id } : undefined
|
||||
);
|
||||
};
|
||||
|
||||
const providerValues: GiftCardListDialogsConsumerProps = {
|
||||
openCreateDialog,
|
||||
openDeleteDialog: handleDeleteDialogOpen,
|
||||
closeDialog,
|
||||
id
|
||||
};
|
||||
|
||||
return (
|
||||
<GiftCardListDialogsContext.Provider value={providerValues}>
|
||||
{children}
|
||||
<GiftCardCreateDialog
|
||||
open={isCreateDialogOpen}
|
||||
closeDialog={closeDialog}
|
||||
/>
|
||||
<GiftCardListPageDeleteDialog
|
||||
open={isDeleteDialogOpen}
|
||||
closeDialog={closeDialog}
|
||||
/>
|
||||
</GiftCardListDialogsContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default GiftCardListDialogsProvider;
|
|
@ -0,0 +1,14 @@
|
|||
import { useContext } from "react";
|
||||
|
||||
import {
|
||||
GiftCardListDialogsConsumerProps,
|
||||
GiftCardListDialogsContext
|
||||
} from "../GiftCardListDialogsProvider";
|
||||
|
||||
const useGiftCardListDialogs = (): GiftCardListDialogsConsumerProps => {
|
||||
const giftCardListDialogsProps = useContext(GiftCardListDialogsContext);
|
||||
|
||||
return giftCardListDialogsProps;
|
||||
};
|
||||
|
||||
export default useGiftCardListDialogs;
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./GiftCardListDialogsProvider";
|
||||
export { default } from "./GiftCardListDialogsProvider";
|
|
@ -0,0 +1,98 @@
|
|||
import useBulkActions, {
|
||||
UseBulkActionsProps
|
||||
} from "@saleor/hooks/useBulkActions";
|
||||
import useListSettings, {
|
||||
UseListSettings
|
||||
} from "@saleor/hooks/useListSettings";
|
||||
import {
|
||||
createPaginationState,
|
||||
PageInfo,
|
||||
PaginationState
|
||||
} from "@saleor/hooks/usePaginator";
|
||||
import { ListViews } from "@saleor/types";
|
||||
import { mapEdgesToItems } from "@saleor/utils/maps";
|
||||
import React, { createContext } from "react";
|
||||
|
||||
import { useGiftCardListQuery } from "../../queries";
|
||||
import { GiftCardListColummns, GiftCardListUrlQueryParams } from "../../types";
|
||||
import {
|
||||
GiftCardList_giftCards_edges_node,
|
||||
GiftCardListVariables
|
||||
} from "../../types/GiftCardList";
|
||||
|
||||
const numberOfColumns = 7;
|
||||
|
||||
interface GiftCardsListProviderProps {
|
||||
children: React.ReactNode;
|
||||
params: GiftCardListUrlQueryParams;
|
||||
}
|
||||
|
||||
export interface GiftCardListDataProps {
|
||||
giftCards: GiftCardList_giftCards_edges_node[];
|
||||
pageInfo: PageInfo;
|
||||
loading: boolean;
|
||||
params: GiftCardListUrlQueryParams;
|
||||
paginationState: PaginationState;
|
||||
numberOfColumns: number;
|
||||
}
|
||||
|
||||
export interface GiftCardsListConsumerProps
|
||||
extends UseBulkActionsProps,
|
||||
GiftCardListDataProps,
|
||||
UseListSettings<GiftCardListColummns> {
|
||||
selectedItemsCount: number;
|
||||
}
|
||||
|
||||
export const GiftCardsListContext = createContext<GiftCardsListConsumerProps>(
|
||||
null
|
||||
);
|
||||
|
||||
export const GiftCardsListProvider: React.FC<GiftCardsListProviderProps> = ({
|
||||
children,
|
||||
params
|
||||
}) => {
|
||||
const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(
|
||||
[]
|
||||
);
|
||||
|
||||
const { updateListSettings, settings } = useListSettings<
|
||||
GiftCardListColummns
|
||||
>(ListViews.GIFT_CARD_LIST);
|
||||
|
||||
const paginationState = createPaginationState(settings.rowNumber, params);
|
||||
|
||||
const queryVariables = React.useMemo<GiftCardListVariables>(
|
||||
() => ({
|
||||
...paginationState
|
||||
}),
|
||||
[params]
|
||||
);
|
||||
|
||||
const { data, loading } = useGiftCardListQuery({
|
||||
displayLoader: true,
|
||||
variables: queryVariables
|
||||
});
|
||||
|
||||
const providerValues: GiftCardsListConsumerProps = {
|
||||
giftCards: mapEdgesToItems(data?.giftCards) || [],
|
||||
loading,
|
||||
isSelected,
|
||||
listElements,
|
||||
reset,
|
||||
toggleAll,
|
||||
toggle,
|
||||
selectedItemsCount: listElements.length,
|
||||
pageInfo: data?.giftCards?.pageInfo,
|
||||
paginationState,
|
||||
params,
|
||||
settings,
|
||||
updateListSettings,
|
||||
numberOfColumns
|
||||
};
|
||||
|
||||
return (
|
||||
<GiftCardsListContext.Provider value={providerValues}>
|
||||
{children}
|
||||
</GiftCardsListContext.Provider>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,37 @@
|
|||
import { UseListSettings } from "@saleor/hooks/useListSettings";
|
||||
import { useContext } from "react";
|
||||
|
||||
import { GiftCardListColummns } from "../../../types";
|
||||
import {
|
||||
GiftCardListDataProps,
|
||||
GiftCardsListContext
|
||||
} from "../GiftCardListProvider";
|
||||
|
||||
export type UseGiftCardListProps = GiftCardListDataProps &
|
||||
UseListSettings<GiftCardListColummns>;
|
||||
|
||||
const useGiftCardList = (): UseGiftCardListProps => {
|
||||
const {
|
||||
giftCards,
|
||||
loading,
|
||||
pageInfo,
|
||||
paginationState,
|
||||
params,
|
||||
settings,
|
||||
updateListSettings,
|
||||
numberOfColumns
|
||||
} = useContext(GiftCardsListContext);
|
||||
|
||||
return {
|
||||
giftCards,
|
||||
loading,
|
||||
pageInfo,
|
||||
paginationState,
|
||||
params,
|
||||
settings,
|
||||
updateListSettings,
|
||||
numberOfColumns
|
||||
};
|
||||
};
|
||||
|
||||
export default useGiftCardList;
|
|
@ -0,0 +1,32 @@
|
|||
import { UseBulkActionsProps } from "@saleor/hooks/useBulkActions";
|
||||
import { useContext } from "react";
|
||||
|
||||
import {
|
||||
GiftCardsListConsumerProps,
|
||||
GiftCardsListContext
|
||||
} from "../GiftCardListProvider";
|
||||
|
||||
export type UseGiftCardListBulkActionsProps = UseBulkActionsProps &
|
||||
Pick<GiftCardsListConsumerProps, "selectedItemsCount">;
|
||||
|
||||
const useGiftCardListBulkActions = (): UseGiftCardListBulkActionsProps => {
|
||||
const {
|
||||
isSelected,
|
||||
listElements,
|
||||
reset,
|
||||
toggleAll,
|
||||
toggle,
|
||||
selectedItemsCount
|
||||
} = useContext(GiftCardsListContext);
|
||||
|
||||
return {
|
||||
isSelected,
|
||||
listElements,
|
||||
reset,
|
||||
toggleAll,
|
||||
toggle,
|
||||
selectedItemsCount
|
||||
};
|
||||
};
|
||||
|
||||
export default useGiftCardListBulkActions;
|
|
@ -0,0 +1 @@
|
|||
export * from "./GiftCardListProvider";
|
|
@ -59,7 +59,7 @@ export const GiftCardsListProvider: React.FC<GiftCardsListProviderProps> = ({
|
|||
GiftCardListColummns
|
||||
>(ListViews.GIFT_CARD_LIST);
|
||||
|
||||
const paginationState = createPaginationState(settings.rowNumber, params);
|
||||
const paginationState = createPaginationState(settings?.rowNumber, params);
|
||||
|
||||
const queryVariables = React.useMemo<GiftCardListVariables>(
|
||||
() => ({
|
||||
|
|
|
@ -5,6 +5,7 @@ import gql from "graphql-tag";
|
|||
|
||||
import { giftCardDataFragment } from "../GiftCardUpdate/queries";
|
||||
import { GiftCardList, GiftCardListVariables } from "./types/GiftCardList";
|
||||
import { GiftCardProductsCount } from "./types/GiftCardProductsCount";
|
||||
|
||||
export const giftCardList = gql`
|
||||
${fragmentUserBase}
|
||||
|
@ -26,8 +27,22 @@ export const giftCardList = gql`
|
|||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const useGiftCardListQuery = makeQuery<
|
||||
GiftCardList,
|
||||
GiftCardListVariables
|
||||
>(giftCardList);
|
||||
|
||||
export const giftCardProductsCount = gql`
|
||||
query GiftCardProductsCount {
|
||||
giftCardProductTypes: productTypes(filter: { kind: GIFT_CARD }) {
|
||||
totalCount
|
||||
}
|
||||
giftCardProducts: products(filter: { giftCard: true }) {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const useGiftCardProductsCountQuery = makeQuery<
|
||||
GiftCardProductsCount,
|
||||
never
|
||||
>(giftCardProductsCount);
|
||||
|
|
|
@ -34,3 +34,12 @@ export const useTableStyles = makeStyles(
|
|||
}),
|
||||
{ name: "GiftCardsListTable" }
|
||||
);
|
||||
|
||||
export const useHeaderStyles = makeStyles(
|
||||
theme => ({
|
||||
alertLink: {
|
||||
fontSize: theme.typography.body2.fontSize
|
||||
}
|
||||
}),
|
||||
{ name: "GiftCardsListHeader" }
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Dialog, Pagination } from "@saleor/types";
|
||||
import { Dialog, Pagination, SingleAction } from "@saleor/types";
|
||||
|
||||
export type GiftCardListColummns =
|
||||
| "giftCardCode"
|
||||
|
@ -8,8 +8,12 @@ export type GiftCardListColummns =
|
|||
| "product";
|
||||
|
||||
export enum GiftCardListActionParamsEnum {
|
||||
CREATE = "gift-card-create"
|
||||
CREATE = "gift-card-create",
|
||||
DELETE = "gift-card-delete"
|
||||
}
|
||||
|
||||
export type GiftCardListUrlQueryParams = Pagination &
|
||||
Dialog<GiftCardListActionParamsEnum>;
|
||||
Dialog<GiftCardListActionParamsEnum> &
|
||||
SingleAction;
|
||||
|
||||
export const GIFT_CARD_LIST_QUERY = "GiftCardList";
|
||||
|
|
29
src/giftCards/GiftCardsList/types/BulkDeleteGiftCard.ts
Normal file
29
src/giftCards/GiftCardsList/types/BulkDeleteGiftCard.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { GiftCardErrorCode } from "./../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: BulkDeleteGiftCard
|
||||
// ====================================================
|
||||
|
||||
export interface BulkDeleteGiftCard_giftCardBulkDelete_errors {
|
||||
__typename: "GiftCardError";
|
||||
code: GiftCardErrorCode;
|
||||
field: string | null;
|
||||
}
|
||||
|
||||
export interface BulkDeleteGiftCard_giftCardBulkDelete {
|
||||
__typename: "GiftCardBulkDelete";
|
||||
errors: BulkDeleteGiftCard_giftCardBulkDelete_errors[];
|
||||
}
|
||||
|
||||
export interface BulkDeleteGiftCard {
|
||||
giftCardBulkDelete: BulkDeleteGiftCard_giftCardBulkDelete | null;
|
||||
}
|
||||
|
||||
export interface BulkDeleteGiftCardVariables {
|
||||
ids: (string | null)[];
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue