diff --git a/packages/mint-components/CHANGELOG.md b/packages/mint-components/CHANGELOG.md index ea3fa71402..873af0aac5 100644 --- a/packages/mint-components/CHANGELOG.md +++ b/packages/mint-components/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.1.0] - 2026-02-19 + +### Updated + +- \ +- \ + - Added new reward status based on state of payouts + - Payment Processing + ## [2.0.10] - 2026-01-27 ### Fixed @@ -1446,7 +1455,8 @@ This major release represents a significant advancement in the theming capabilit - \ - \ -[unreleased]: https://github.com/saasquatch/program-tools/compare/mint-components@2.0.10...HEAD +[unreleased]: https://github.com/saasquatch/program-tools/compare/mint-components@2.1.0...HEAD +[2.1.0]: https://github.com/saasquatch/program-tools/releases/tag/%40saasquatch%2Fmint-components%402.1.0 [2.0.10]: https://github.com/saasquatch/program-tools/releases/tag/%40saasquatch%2Fmint-components%402.0.10 [2.0.9]: https://github.com/saasquatch/program-tools/releases/tag/%40saasquatch%2Fmint-components%402.0.9 [2.0.8]: https://github.com/saasquatch/program-tools/releases/tag/%40saasquatch%2Fmint-components%402.0.8 diff --git a/packages/mint-components/package-lock.json b/packages/mint-components/package-lock.json index ffae2b693d..90b75a8123 100644 --- a/packages/mint-components/package-lock.json +++ b/packages/mint-components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@saasquatch/mint-components", - "version": "2.0.10", + "version": "2.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@saasquatch/mint-components", - "version": "2.0.10", + "version": "2.1.0", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/packages/mint-components/package.json b/packages/mint-components/package.json index 4b986067f9..f1436ade44 100644 --- a/packages/mint-components/package.json +++ b/packages/mint-components/package.json @@ -1,7 +1,7 @@ { "name": "@saasquatch/mint-components", "title": "Mint Components", - "version": "2.0.10", + "version": "2.1.0", "description": "A minimal design library with components for referral and loyalty experiences. Built with Shoelace components by Saasquatch.", "icon": "https://res.cloudinary.com/saasquatch/image/upload/v1652219900/squatch-assets/For_Mint.svg", "raisins": "docs/raisins.json", @@ -107,4 +107,4 @@ }, "homepage": "https://github.com/saasquatch/program-tools", "license": "MIT" -} +} \ No newline at end of file diff --git a/packages/mint-components/src/components.d.ts b/packages/mint-components/src/components.d.ts index daccc2ce2e..75da42fab4 100644 --- a/packages/mint-components/src/components.d.ts +++ b/packages/mint-components/src/components.d.ts @@ -4487,6 +4487,7 @@ export namespace Components { "payoutApproved": string; "payoutCancelled": string; "payoutFailed": string; + "payoutProcessing": string; "pendingNewTaxForm": string; "pendingPartnerCreation": string; "pendingReviewText": string; @@ -4529,6 +4530,11 @@ export namespace Components { * @uiName Payout failed text */ "payoutFailed": string; + /** + * Displayed when a reward payout is processing. + * @uiName Payout processing text + */ + "payoutProcessing": string; /** * Displayed when pending due to requiring a new tax document * @uiName Pending new tax form text @@ -12339,6 +12345,7 @@ declare namespace LocalJSX { "payoutApproved"?: string; "payoutCancelled"?: string; "payoutFailed"?: string; + "payoutProcessing"?: string; "pendingNewTaxForm"?: string; "pendingPartnerCreation"?: string; "pendingReviewText"?: string; @@ -12381,6 +12388,11 @@ declare namespace LocalJSX { * @uiName Payout failed text */ "payoutFailed"?: string; + /** + * Displayed when a reward payout is processing. + * @uiName Payout processing text + */ + "payoutProcessing"?: string; /** * Displayed when pending due to requiring a new tax document * @uiName Pending new tax form text diff --git a/packages/mint-components/src/components/sqm-referral-table/TaxAndCashReferralTable.stories.tsx b/packages/mint-components/src/components/sqm-referral-table/TaxAndCashReferralTable.stories.tsx new file mode 100644 index 0000000000..02468d93df --- /dev/null +++ b/packages/mint-components/src/components/sqm-referral-table/TaxAndCashReferralTable.stories.tsx @@ -0,0 +1,118 @@ +import { h } from "@stencil/core"; +import { GenericTableView } from "../../tables/GenericTableView"; +import { + Converted as ConvertedStatus, + DateCell, +} from "./ReferralTableCell.stories"; +import { + PayoutApproved, + PayoutProcessing, + PayoutFailed, + PayoutCancelled, + PendingTaxReview, + PendingNewTaxForm, + PendingTaxSubmission, + PendingPartnerCreation, + PendingW9, + CashReward, +} from "./TaxAndCashReferralTableRewardsCell.stories"; + +export default { + title: "Components/Tax And Cash Referral Table", +}; + +const taxAndCashTableProps = { + states: { + hasPrev: false, + hasNext: true, + show: "rows" as const, + namespace: "sqm-referral-table", + }, + data: { + textOverrides: { + showLabels: true, + prevLabel: "Prev", + moreLabel: "View More", + }, + hiddenColumns: "", + mdBreakpoint: 799, + smBreakpoint: 599, + }, + callbacks: { + prevPage: () => console.log("Prev"), + nextPage: () => console.log("Next"), + }, + + elements: { + columns: ["Customer", "Status", "Date converted", "Rewards"], + rows: [ + [ + , + , + , + , + ], + + [ + , + , + , + , + ], + [ + , + , + , + , + ], + + [ + , + , + , + , + ], + [ + , + , + , + , + ], + [ + , + , + , + , + ], + [ + , + , + , + , + ], + [ + , + , + , + , + ], + [ + , + , + , + , + ], + + [ + , + , + , + , + ], + ], + }, +}; + +export const TaxAndCashReferralTable = () => { + return ; +}; diff --git a/packages/mint-components/src/components/sqm-referral-table/TaxAndCashReferralTableRewardsCell.stories.tsx b/packages/mint-components/src/components/sqm-referral-table/TaxAndCashReferralTableRewardsCell.stories.tsx new file mode 100644 index 0000000000..1aac4f4307 --- /dev/null +++ b/packages/mint-components/src/components/sqm-referral-table/TaxAndCashReferralTableRewardsCell.stories.tsx @@ -0,0 +1,270 @@ +import { h } from "@stencil/core"; +import { DateTime } from "luxon"; +import { Reward, ImpactConnection } from "../../saasquatch"; + +export default { + title: "Components/Tax And Cash Referral Table Rewards Cell", +}; + +function getDays() { + return DateTime.now().toMillis() + 600000000; +} + +function getMonths() { + return DateTime.now().toMillis() + 10000000000; +} + +const cashReward: Reward = { + id: "1234", + type: "CREDIT", + value: 50, + unit: "USD", + name: "test", + dateScheduledFor: getDays(), + dateExpires: getMonths(), + dateCancelled: 134400, + dateRedeemed: 0, + fuelTankCode: null, + fuelTankType: null, + currency: "USD", + prettyValue: "$50.00", + statuses: ["AVAILABLE"], + globalRewardKey: "Key", + rewardRedemptionTransactions: null, + partnerFundsTransfer: null, +}; + +const taxConnection: ImpactConnection = { + connected: true, + taxHandlingEnabled: true, + publisher: { + requiredTaxDocumentType: "W9", + withdrawalSettings: { paymentMethod: "BANK_TRANSFER" }, + payoutsAccount: null, + currentTaxDocument: { + status: "ACTIVE", + type: "W9", + dateCreated: 1627427794891, + }, + }, +}; + +const defaultPFT: Reward["partnerFundsTransfer"] = { + id: "ID1234", + status: null, + dateCreated: null, + dateScheduled: null, + dateTransferred: null, +}; + +const defaultTaxDocument: ImpactConnection["publisher"]["currentTaxDocument"] = + { + status: "NOT_VERIFIED", + type: "W9", + dateCreated: DateTime.now().toMillis() - 1000000, + }; + +const defaultProps = { + statusText: + "{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PROCESSING {Payment Processing} PAYOUT_FAILED {Payout Failed} PAYOUT_CANCELLED {Payout Cancelled} PENDING_TAX_REVIEW {Pending} PENDING_NEW_TAX_FORM {Pending} PENDING_TAX_SUBMISSION {Pending} PENDING_PARTNER_CREATION {Pending} DENIED {Denied} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }", + statusLongText: + "{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} PENDING_REVIEW {Pending since} PAYOUT_APPROVED {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PAYOUT_FAILED {Payout failed due to a fulfillment issue and is currently being retried.} PAYOUT_CANCELLED {If you think this is a mistake, contact our Support team.} PENDING_TAX_REVIEW {Awaiting tax form review} PENDING_NEW_TAX_FORM {Invalid tax form. Submit a new form to receive your rewards.} PROCESSING {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PENDING_TAX_SUBMISSION {Submit your tax documents to receive your rewards} PENDING_PARTNER_CREATION {Complete your tax and cash payout setup to receive your rewards} DENIED {Denied on} EXPIRED {Reward expired on} other {Not available} }", + rewardReceivedText: "Reward received on", + hideDetails: false, +}; + +export const CashReward = () => { + return ( + + ); +}; + +export const PayoutApproved = () => { + return ( + + ); +}; + +export const PayoutProcessing = () => { + return ( + + ); +}; + +export const PayoutFailed = () => { + return ( + + ); +}; + +export const PayoutCancelled = () => { + return ( + + ); +}; + +export const PendingTaxReview = () => { + return ( + + ); +}; + +export const PendingNewTaxForm = () => { + return ( + + ); +}; + +export const PendingTaxSubmission = () => { + return ( + + ); +}; + +export const PendingPartnerCreation = () => { + return ( + + ); +}; + +export const PendingW9 = () => { + return ( + + ); +}; diff --git a/packages/mint-components/src/components/sqm-referral-table/cells/sqm-referral-table-rewards-cell.tsx b/packages/mint-components/src/components/sqm-referral-table/cells/sqm-referral-table-rewards-cell.tsx index 7f044a5108..45478a51a7 100644 --- a/packages/mint-components/src/components/sqm-referral-table/cells/sqm-referral-table-rewards-cell.tsx +++ b/packages/mint-components/src/components/sqm-referral-table/cells/sqm-referral-table-rewards-cell.tsx @@ -15,13 +15,13 @@ export class ReferralTableRewardsCell { @Prop() taxConnection: ImpactConnection; @Prop() hideDetails: boolean; @Prop() statusText: string = - "{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PAYOUT_FAILED {Payout Failed} PAYOUT_CANCELLED {Payout Cancelled} PENDING_TAX_REVIEW {Pending} PENDING_NEW_TAX_FORM {Pending} PENDING_TAX_SUBMISSION {Pending} PENDING_PARTNER_CREATION {Pending} DENIED {Denied} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }"; + "{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PROCESSING {Payment Processing} PAYOUT_FAILED {Payout Failed} PAYOUT_CANCELLED {Payout Cancelled} PENDING_TAX_REVIEW {Pending} PENDING_NEW_TAX_FORM {Pending} PENDING_TAX_SUBMISSION {Pending} PENDING_PARTNER_CREATION {Pending} DENIED {Denied} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }"; @Prop() statusLongText: string = - "{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} PENDING_REVIEW {Pending since} PAYOUT_APPROVED {Reward was scheduled for payment based on your settings, barring any account holds.} PAYOUT_FAILED {Payout failed due to a fulfillment issue and is currently being retried.} PAYOUT_CANCELLED {If you think this is a mistake, contact our Support team.} PENDING_TAX_REVIEW {Awaiting tax form review} PENDING_NEW_TAX_FORM {Invalid tax form. Submit a new form to receive your rewards.} PENDING_TAX_SUBMISSION {Submit your tax documents to receive your rewards} PENDING_PARTNER_CREATION {Complete your tax and cash payout setup to receive your rewards} DENIED {Denied on} EXPIRED {Reward expired on} other {Not available} }"; + "{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} PENDING_REVIEW {Pending since} PAYOUT_APPROVED {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PAYOUT_FAILED {Payout failed due to a fulfillment issue and is currently being retried.} PAYOUT_CANCELLED {If you think this is a mistake, contact our Support team.} PENDING_TAX_REVIEW {Awaiting tax form review} PENDING_NEW_TAX_FORM {Invalid tax form. Submit a new form to receive your rewards.} PROCESSING {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PENDING_TAX_SUBMISSION {Submit your tax documents to receive your rewards} PENDING_PARTNER_CREATION {Complete your tax and cash payout setup to receive your rewards} DENIED {Denied on} EXPIRED {Reward expired on} other {Not available} }"; @Prop() fuelTankText: string; @Prop() rewardReceivedText: string; @Prop() expiringText: string; - @Prop() pendingForText: string; + @Prop() pendingForText: string = "{status} for {date}"; @Prop() deniedHelpText: string; @Prop() locale: string = "en"; render() { @@ -144,7 +144,7 @@ export class ReferralTableRewardsCell { const getState = ( reward: Reward, - taxConnection: ImpactConnection + taxConnection: ImpactConnection, ): string => { const possibleStates = [ "REDEEMED", @@ -161,6 +161,7 @@ export class ReferralTableRewardsCell { "PENDING_NEW_TAX_FORM", "PENDING_TAX_SUBMISSION", "PENDING_PARTNER_CREATION", + "PROCESSING", ]; if (reward.referral?.fraudData?.moderationStatus !== "APPROVED") { @@ -171,13 +172,27 @@ export class ReferralTableRewardsCell { } const partnerFundsStatus = reward.partnerFundsTransfer?.status; - if ( - partnerFundsStatus === "NOT_YET_DUE" || - partnerFundsStatus === "TRANSFERRED" - ) { - return "PAYOUT_APPROVED"; - } else if (partnerFundsStatus === "OVERDUE") return "PAYOUT_FAILED"; - else if (partnerFundsStatus === "REVERSED") return "PAYOUT_CANCELLED"; + + if (reward.partnerFundsTransfer) { + if (partnerFundsStatus === "REVERSED") return "PAYOUT_CANCELLED"; + if (partnerFundsStatus === "OVERDUE") return "PAYOUT_FAILED"; + + if ( + reward.partnerFundsTransfer.dateScheduled && + reward.partnerFundsTransfer.dateScheduled > Date.now() + ) { + return "PROCESSING"; + } + if ( + partnerFundsStatus === "TRANSFERRED" || + partnerFundsStatus === "NOT_YET_DUE" || + (reward.partnerFundsTransfer.dateScheduled && + reward.partnerFundsTransfer.dateScheduled < Date.now() && + partnerFundsStatus !== "OVERDUE" && + partnerFundsStatus !== "REVERSED") + ) + return "PAYOUT_APPROVED"; + } if (reward?.pendingReasons?.includes("US_TAX")) { if (!taxConnection?.taxHandlingEnabled) return "PENDING"; @@ -205,7 +220,7 @@ export class ReferralTableRewardsCell { if (reward.statuses.length === 1) return reward.statuses[0]; return possibleStates.find( - (state) => reward.statuses.includes(state) && state + (state) => reward.statuses.includes(state) && state, ); }; @@ -226,6 +241,7 @@ export class ReferralTableRewardsCell { case "PENDING_NEW_TAX_FORM": case "PENDING_TAX_SUBMISSION": case "PENDING_PARTNER_CREATION": + case "PROCESSING": return "warning"; case "AVAILABLE": return "success"; @@ -248,8 +264,9 @@ export class ReferralTableRewardsCell { { id: "statusShortMessage", defaultMessage: this.statusText }, { status: state, - } + }, ); + const statusText = intl.formatMessage( { id: "statusLongMessage", @@ -257,7 +274,12 @@ export class ReferralTableRewardsCell { }, { status: state, - } + scheduledPayoutDate: reward.partnerFundsTransfer?.dateScheduled + ? DateTime.fromMillis(reward.partnerFundsTransfer.dateScheduled) + ?.setLocale(luxonLocale(this.locale)) + .toLocaleString(DateTime.DATE_MED) + : null, + }, ); return ( @@ -288,7 +310,7 @@ export class ReferralTableRewardsCell { { status: badgeText, date: getTimeDiff(reward.dateScheduledFor), - } + }, )} ) : ( @@ -330,6 +352,11 @@ export class ReferralTableRewardsCell { {statusText} )} + {state === "PROCESSING" && ( +
+ {statusText} +
+ )} {state === "PAYOUT_FAILED" && (
{statusText} diff --git a/packages/mint-components/src/components/sqm-referral-table/columns/referral-table-rewards-column.feature b/packages/mint-components/src/components/sqm-referral-table/columns/referral-table-rewards-column.feature index 42b8949b06..982a5d960f 100644 --- a/packages/mint-components/src/components/sqm-referral-table/columns/referral-table-rewards-column.feature +++ b/packages/mint-components/src/components/sqm-referral-table/columns/referral-table-rewards-column.feature @@ -6,69 +6,117 @@ Feature: Referral Table Reward Column Given the status column is included in the referral table And at least one referral exists + + @motivating @ui - Scenario Outline: The referral reward and it's status are shown for each referral + Scenario Outline: The referral reward and its status are shown for each referral Then for each referral reward there exists a reward cell And the reward type and value is displayed in the cell And the status of each reward is displayed as a pill in the cell And rewards of have a pill with the text Examples: - | status | pillColour | statusText | - | Available | green | Available | - | Pending | orange | Pending | - | Pending Tax Review | orange | Pending | - | Pending New Tax Form | orange | Pending | - | Pending Tax Submission | orange | Pending | - | Pending Partner Creation | orange | Pending | - | Cancelled | red | Cancelled | - | Payout Overdue | red | Payout Failed | - | Payout Reversed | red | Payout Cancelled | - | Expired | red | Expired | - | Redeemed | blue | Redeemed | - | Payout Transferred | blue | Payout Approved | - | Payout Not Yet Due | blue | Payout Approved | - | Pending Review | orange | Pending Review | - | Denied | red | Denied | + | status | pillColour | statusText | + | Available | success | Available | + | Pending | warning | Pending | + | Pending Fraud Review | warning | Pending | + | Pending Tax Review | warning | Pending | + | Pending New Tax Form | warning | Pending | + | Pending Tax Submission | warning | Pending | + | Pending Partner Creation | warning | Pending | + | Cancelled | danger | Cancelled | + | Payout Overdue | danger | Payout Failed | + | Payout Reversed | danger | Payout Cancelled | + | Expired | danger | Expired | + | Denied | danger | Denied | + | Redeemed | primary | Redeemed | + | Payout Transferred | primary | Payout Approved | + | Payout Not Yet Due | primary | Payout Approved | + | Payout Processing | primary | Payment Processing | @motivating - Scenario: The pending period of a referral reward is shown if it exists + Scenario: The pending period of a referral reward is shown inside the pill if scheduled Given a reward that is pending - And the reward has a set pending period - Then the status pill of the reward will instead have the text "Pending for " - And all dates are localized to the users locale + And the reward has a scheduled date in the future + Then the status pill of the reward will contain the text "Pending for " + And the date is localized to the user's locale Examples: | relativeTime | - | 2 days | - | 1 week | - | 3 months | - | 2 years | + | 2 days | + | 1 week | + | 3 months | @motivating - Scenario: The expiry date of a reward is shown if it exists + Scenario: The expiry date of a reward is shown in a secondary pill Given a reward that is available And the reward has a set expiry date - Then an additional grey pill will appear next to the status pill with the text "Expiring in " - And all dates are localized to the users locale + Then an additional info pill will appear next to the status pill with the text "Expiring in " + And the date is localized to the user's locale Examples: | relativeTime | - | 2 days | - | 1 week | - | 3 months | - | 2 years | + | 2 days | + | 1 week | - @motivating - Scenario: Each reward can be expanded to show additional details about the reward + @motivating @ui + Scenario Outline: Expanding the reward cell shows specific detailed status messages When a reward cell is clicked - Then it expands to show the following additional information (if it's available): - | Date the reward was received | - | Date the reward was cancelled | - | Date the reward expires | - | Date the reward is pending until | - | Payout process start date | - | Payout retry date on failure | - | Description for tax pending reason | - | Coupon code | - And all dates are localized to a users locale + Then it expands to show the detail view + And if the reward status is + Then the detail text displays + + Examples: Payout States + | status | detailMessage | + | Payout Approved | Processing until {date}. Payout is then scheduled based on your settings. | + | Payout Failed | Payout failed due to a fulfillment issue and is currently being retried. | + | Payout Cancelled | If you think this is a mistake, contact our Support team. | + | Processing | Processing until {date}. Payout is then scheduled based on your settings. | + + Examples: Tax Compliance States + | status | detailMessage | + | Pending Tax Review | Awaiting tax form review | + | Pending New Tax Form | Invalid tax form. Submit a new form to receive your rewards. | + | Pending Tax Submission | Submit your tax documents to receive your rewards | + | Pending Partner Creation | Complete your tax and cash payout setup to receive your rewards | + + Examples: Standard States + | status | detailMessage | + | Available | Reward expiring on | + | Cancelled | Reward cancelled on | + | Pending | Available on | + | Pending Review | Pending since | + | Denied | Denied on | + | Expired | Reward expired on | + | Redeemed | Redeemed | + + @motivating + Scenario: Fuel Tank codes are displayed in the expanded view + Given a reward has a Fuel Tank code + When the reward cell is clicked + Then the expanded details display the text "Your code is" + And the code is displayed in bold + + @motivating + Scenario: Fraud denial help text is displayed + Given a reward has been denied due to fraud + And the component has "deniedHelpText" configured + When the reward cell is clicked + Then the expanded details display the denied help text next to the denial date + + @minutia + Scenario: Payout-related reward statuses are determined by the state of the Paid Funds Transfer + Given a reward exists + And the reward has a connected Paid Funds Transfer (PFT) + When the PFT is in + Then the reward's status is + And the status text displays + And the status is displayed in a pill + + Examples: + | pftState | status | text | pillColour | + | transfer date is in the future | PROCESSING | Payment Processing | primary | + | successfully transferred to payment provider | PAYOUT_TRANSFERRED | Payout Approved | primary | + | approved but payout scheduled date not yet arrived | PAYOUT_NOT_YET_DUE | Payout Approved | primary | + | failed due to fulfillment issue and retrying | PAYOUT_OVERDUE | Payout Failed | danger | + | reversed or cancelled after being processed | PAYOUT_REVERSED | Payout Cancelled | danger | diff --git a/packages/mint-components/src/components/sqm-referral-table/columns/sqm-referral-table-rewards-column.tsx b/packages/mint-components/src/components/sqm-referral-table/columns/sqm-referral-table-rewards-column.tsx index ce582c2277..6b0b2b592f 100644 --- a/packages/mint-components/src/components/sqm-referral-table/columns/sqm-referral-table-rewards-column.tsx +++ b/packages/mint-components/src/components/sqm-referral-table/columns/sqm-referral-table-rewards-column.tsx @@ -8,7 +8,7 @@ import { ReferralTableColumn } from "./ReferralTableColumn"; * @uiName Referral Table Rewards Column * @validParents ["sqm-referral-table"] * @exampleGroup Referrals - * @example Referral Table Rewards Column - + * @example Referral Table Rewards Column - */ @Component({ tag: "sqm-referral-table-rewards-column", @@ -27,8 +27,7 @@ export class ReferralTableRewardsColumn implements ReferralTableColumn { * @uiWidget textArea */ @Prop() statusText: string = - "{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PAYOUT_FAILED {Payout Failed} PAYOUT_CANCELLED {Payout Cancelled} PENDING_TAX_REVIEW {Pending} PENDING_NEW_TAX_FORM {Pending} PENDING_TAX_SUBMISSION {Pending} PENDING_PARTNER_CREATION {Pending} DENIED {Denied} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }"; - + "{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PROCESSING {Payment Processing} PAYOUT_FAILED {Payout Failed} PAYOUT_CANCELLED {Payout Cancelled} PENDING_TAX_REVIEW {Pending} PENDING_NEW_TAX_FORM {Pending} PENDING_TAX_SUBMISSION {Pending} PENDING_PARTNER_CREATION {Pending} DENIED {Denied} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }"; /** * Additional status text shown in the details drop down. * @@ -36,8 +35,7 @@ export class ReferralTableRewardsColumn implements ReferralTableColumn { * @uiWidget textArea */ @Prop() statusLongText: string = - "{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} PENDING_REVIEW {Pending since} PAYOUT_APPROVED {Reward was scheduled for payment based on your settings, barring any account holds.} PAYOUT_FAILED {Payout failed due to a fulfillment issue and is currently being retried.} PAYOUT_CANCELLED {If you think this is a mistake, contact our Support team.} PENDING_TAX_REVIEW {Awaiting tax form review} PENDING_NEW_TAX_FORM {Invalid tax form. Submit a new form to receive your rewards.} PENDING_TAX_SUBMISSION {Submit your tax documents to receive your rewards} PENDING_PARTNER_CREATION {Complete your tax and cash payout setup to receive your rewards} DENIED {Denied on} EXPIRED {Reward expired on} other {Not available} }"; - + "{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} PENDING_REVIEW {Pending since} PAYOUT_APPROVED {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PAYOUT_FAILED {Payout failed due to a fulfillment issue and is currently being retried.} PAYOUT_CANCELLED {If you think this is a mistake, contact our Support team.} PENDING_TAX_REVIEW {Awaiting tax form review} PENDING_NEW_TAX_FORM {Invalid tax form. Submit a new form to receive your rewards.} PROCESSING {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PENDING_TAX_SUBMISSION {Submit your tax documents to receive your rewards} PENDING_PARTNER_CREATION {Complete your tax and cash payout setup to receive your rewards} DENIED {Denied on} EXPIRED {Reward expired on} other {Not available} }"; /** * Shown in the dropdown details when a reward has an associated fuel tank code. * @@ -88,7 +86,7 @@ export class ReferralTableRewardsColumn implements ReferralTableColumn { @Method() async renderCell( data: Referral, - options?: { locale: string; taxConnection: ImpactConnection } + options?: { locale: string; taxConnection: ImpactConnection }, ) { return ( + * @example Referral Table - */ @Component({ tag: "sqm-referral-table", @@ -146,7 +146,7 @@ function LoadingRow() { function useReferralTableDemo( props: ReferralTable, emptyElement: VNode, - loadingElement: VNode + loadingElement: VNode, ): GenericTableViewProps { const [content, setContent] = useReducer< GenericTableViewProps["elements"], @@ -161,14 +161,14 @@ function useReferralTableDemo( rows: [], loading: false, page: 0, - } + }, ); const tick = useRerenderListener(); const mockData = useMemo( () => props.demoData?.mockData || mockReferralData(props.perPage), - [props.perPage] + [props.perPage], ); const components = useChildElements(); @@ -193,7 +193,7 @@ function useReferralTableDemo( component.slot !== "loading" && component.slot !== "empty" && component?.firstElementChild?.getAttribute("slot") !== "loading" && - component?.firstElementChild?.getAttribute("slot") !== "empty" + component?.firstElementChild?.getAttribute("slot") !== "empty", ); // get the column titles (renderLabel is asynchronous) const columnsPromise = columnComponents?.map( @@ -214,7 +214,7 @@ function useReferralTableDemo( return tryMethod(c, () => c.renderLabel(idx)); } return tryMethod(c, () => c.renderLabel()); - } + }, ); // show the referrer row before any other rows (renderReferrerCell is asynchronous) @@ -223,7 +223,7 @@ function useReferralTableDemo( const referrerPromise = columnComponents?.map(async (c: any) => tryMethod(c, function renderCell() { return c.renderCell(referrerData, c); - }) + }), ); referrerRow = await Promise.all(referrerPromise); } @@ -231,7 +231,7 @@ function useReferralTableDemo( // get the column cells (renderCell is asynchronous) const cellsPromise = componentData?.map(async (r) => { const cellPromise = columnComponents?.map(async (c: any) => - tryMethod(c, () => c.renderCell(r, undefined)) + tryMethod(c, () => c.renderCell(r, undefined)), ); const cells = (await Promise.all(cellPromise)) as VNode[][]; return cells; @@ -240,7 +240,7 @@ function useReferralTableDemo( const rows = cellsPromise && [referrerRow, ...(await Promise.all(cellsPromise))].filter( - (value) => value + (value) => value, ); setContent({ rows }); @@ -286,7 +286,7 @@ function useReferralTableDemo( }, }, props.demoData || {}, - { arrayMerge: (_, a) => a } + { arrayMerge: (_, a) => a }, ); return demoProps; diff --git a/packages/mint-components/src/components/sqm-referral-table/useReferralTable.tsx b/packages/mint-components/src/components/sqm-referral-table/useReferralTable.tsx index 1a414aff1c..140bedf311 100644 --- a/packages/mint-components/src/components/sqm-referral-table/useReferralTable.tsx +++ b/packages/mint-components/src/components/sqm-referral-table/useReferralTable.tsx @@ -60,6 +60,9 @@ const GET_REFERRER_DATA = gql` partnerFundsTransfer { id status + dateScheduled + dateCreated + dateTransferred } meta { status @@ -168,6 +171,9 @@ const GET_REFERRAL_DATA = gql` partnerFundsTransfer { id status + dateScheduled + dateCreated + dateTransferred } referral { dateModerated @@ -275,7 +281,7 @@ export type ReferralDates = export function useReferralTable( props: ReferralTable, emptyElement: VNode, - loadingElement: VNode + loadingElement: VNode, ): GenericTableViewProps { const user = useUserIdentity(); const programIdContext = useProgramId(); @@ -306,7 +312,7 @@ export function useReferralTable( rows: [], loading: false, page: 0, - } + }, ); const locale = useLocale(); @@ -322,7 +328,7 @@ export function useReferralTable( rewardFilter, locale, }, - !props.showReferrer || !user?.jwt + !props.showReferrer || !user?.jwt, ); const referrerData = referrerResponse?.viewer?.referredByReferral; @@ -332,7 +338,7 @@ export function useReferralTable( const { data: taxResponse, loading: taxLoading } = useQuery( GET_IMPACT_TAX, {}, - !user?.jwt + !user?.jwt, ); const taxConnection = taxResponse?.viewer?.impactConnection; @@ -353,7 +359,7 @@ export function useReferralTable( rewardFilter, locale, }, - (props.showReferrer && referrerLoading && !referrerResponse) || !user?.jwt + (props.showReferrer && referrerLoading && !referrerResponse) || !user?.jwt, ); useEffect(() => { @@ -380,18 +386,18 @@ export function useReferralTable( async function getComponentData(components: Element[]) { // filter out loading and empty states from columns array const columnComponents = components.filter( - (component) => component.slot !== "loading" && component.slot !== "empty" + (component) => component.slot !== "loading" && component.slot !== "empty", ); // get the column titles (renderLabel is asynchronous) const columnsPromise = columnComponents?.map(async (c: any) => - tryMethod(c, () => c.renderLabel()) + tryMethod(c, () => c.renderLabel()), ); // show the referrer row before any other rows let referrerRow; if (showReferrerRow && states.currentPage === 0) { const referrerPromise = columnComponents?.map(async (c: any) => - tryMethod(c, () => c.renderReferrerCell(referrerData, locale, h)) + tryMethod(c, () => c.renderReferrerCell(referrerData, locale, h)), ); referrerRow = await Promise.all(referrerPromise); } @@ -399,7 +405,7 @@ export function useReferralTable( // get the column cells (renderCell is asynchronous) const cellsPromise = data?.map(async (r) => { const cellPromise = columnComponents?.map(async (c: any) => - tryMethod(c, () => c.renderCell(r, { locale, taxConnection }, h)) + tryMethod(c, () => c.renderCell(r, { locale, taxConnection }, h)), ); const cells = (await Promise.all(cellPromise)) as VNode[][]; return cells; @@ -408,7 +414,7 @@ export function useReferralTable( const rows = cellsPromise && [referrerRow, ...(await Promise.all(cellsPromise))].filter( - (value) => value + (value) => value, ); setContent({ rows }); @@ -430,10 +436,10 @@ export function useReferralTable( states.loading || content.loading || taxLoading ? "loading" : // 2 - Empty if empty - isEmpty - ? "empty" - : // 3 - Then show rows - "rows"; + isEmpty + ? "empty" + : // 3 - Then show rows + "rows"; return { states: { @@ -484,7 +490,7 @@ export function generateUserError(e: any) { export async function tryMethod( c: HTMLElement, - callback: () => Promise + callback: () => Promise, ): Promise { const tag = c.tagName.toLowerCase(); await customElements.whenDefined(tag); diff --git a/packages/mint-components/src/components/sqm-rewards-table/RewardsTable.stories.tsx b/packages/mint-components/src/components/sqm-rewards-table/RewardsTable.stories.tsx index 026c7685a4..dea3029f7f 100644 --- a/packages/mint-components/src/components/sqm-rewards-table/RewardsTable.stories.tsx +++ b/packages/mint-components/src/components/sqm-rewards-table/RewardsTable.stories.tsx @@ -22,13 +22,8 @@ import { StatusCellRedeemed, StatusCellDenied, StatusCellPendingReview, - StatusCellPayoutSent, - StatusCellPayoutFailed, - StatusCellPendingNewTaxForm, - StatusCellPendingPartnerCreation, - StatusCellPendingTaxReview, - StatusCellPendingTaxSubmission, } from "./RewardsTableCell.stories"; + import scenario from "./rewards-table.feature"; export default { @@ -187,44 +182,6 @@ const r_fueltank_long = [ , ]; -const r_payout_sent = [ - , - , - , - , -]; -const r_payout_failed = [ - , - , - , - , -]; -const r_pending_new_tax_form = [ - , - , - , - , -]; -const r_pending_partner_creation = [ - , - , - , - , -]; -const r_pending_tax_review = [ - , - , - , - , -]; - -const r_pending_tax_submission = [ - , - , - , - , -]; - export const RewardsTable = () => { return ( { r_expired, r_denied, r_pending_review, - r_payout_sent, - r_payout_failed, - r_pending_new_tax_form, - r_pending_partner_creation, - r_pending_tax_submission, - r_pending_tax_review, ])} > ); diff --git a/packages/mint-components/src/components/sqm-rewards-table/RewardsTableCell.stories.tsx b/packages/mint-components/src/components/sqm-rewards-table/RewardsTableCell.stories.tsx index 0077b11907..451d0927f5 100644 --- a/packages/mint-components/src/components/sqm-rewards-table/RewardsTableCell.stories.tsx +++ b/packages/mint-components/src/components/sqm-rewards-table/RewardsTableCell.stories.tsx @@ -45,6 +45,99 @@ const rewardsData: Reward = { rewardRedemptionTransactions: { data: null, }, + partnerFundsTransfer: null, +}; + +const cashReward = { + id: "68c34fd98a6cb4f5f8394084", + type: "CREDIT", + value: 59900, + prettyValue: "$599.00", + availableValue: 0, + prettyAvailableValue: "$0.00", + prettyAssignedCredit: "$599.00", + prettyRedeemedCredit: "$599.00", + prettyValueNumber: "599", + prettyAvailableNumber: "0", + prettyRedeemedNumber: "599", + unit: "CASH/USD", + baseUnit: "CASH", + rewardUnit: { + key: "CASH/USD", + name: "Cash", + }, + name: null, + dateCreated: 1757630425085, + dateScheduledFor: 1757631025115, + dateGiven: 1757630737115, + dateExpires: null, + dateCancelled: null, + dateRedeemed: 1757630737115, + dateModified: 1757630737115, + rewardSource: "MANUAL" as const, + fuelTankCode: null, + fuelTankType: null, + fuelTankSyncSetting: null, + currency: "USD", + meta: null, + programId: "40444", + programRewardKey: null, + globalRewardKey: "cash", + program: { + id: "40444", + name: "Make Money Program", + template: { + id: "2qdmAx1fi31deo3P9O36sQ", + name: "Referral Program With Objectives", + }, + }, + partnerFundsTransfer: { + id: "693503" as const, + status: "TRANSFERRED" as const, + dateScheduled: 1768583958000, + dateTransferred: 1768583958000, + dateCreated: 1767979159000, + }, + user: { + id: "8da2c67e05e3e56de7ea638c2705017945211621c80e1cd4b4aac0e423d1cdb2", + accountId: + "8da2c67e05e3e56de7ea638c2705017945211621c80e1cd4b4aac0e423d1cdb2", + firstName: "Billy", + lastName: "Jean", + email: "billy.jean@impact.com", + impactConnection: { + connected: true, + taxHandlingEnabled: true, + publisher: null, + }, + }, + referral: null, + description: null, + statuses: ["REDEEMED"], + // rewardRedemptionTransactions: { + // data: [ + // { + // exchangedRewards: { + // data: [], + // }, + // redeemedRewards: { + // data: [ + // { + // prettyValue: "$599.00", + // }, + // ], + // }, + // creditRedeemed: 59900, + // prettyRedeemedCredit: "$599.00", + // dateRedeemed: 1757630737115, + // }, + // ], + // }, + rewardRedemptionTransactions: { + data: null, + }, + exchangedRewardRedemptionTransaction: null, + pendingReasons: [], }; const taxConnection: ImpactConnection = { @@ -433,16 +526,7 @@ export const StatusCellExpired = () => { const pending = { statuses: ["PENDING"], }; -const payoutSent = { - statuses: ["PAYOUT_SENT"], -}; -const payoutFailed = { - statuses: ["PAYOUT_FAILED"], -}; -const payoutCancelled = { - statuses: ["PAYOUT_CANCELLED"], - dateCancelled: 1355612521321, -}; + const us_tax = { pendingReasons: ["US_TAX"], }; @@ -463,103 +547,6 @@ export const StatusCellPending = () => { ); }; -export const StatusCellPendingTaxReview = () => { - return ( - - ); -}; - -export const StatusCellPendingNewTaxForm = () => { - return ( - - ); -}; - -export const StatusCellPendingTaxSubmission = () => { - return ( - - ); -}; - -export const StatusCellPendingPartnerCreation = () => { - return ( - - ); -}; - -export const StatusCellPayoutSent = () => { - return ( - - ); -}; - -export const StatusCellPayoutFailed = () => { - return ( - - ); -}; - -export const StatusCellPayoutCancelled = () => { - return ( - - ); -}; - export const StatusCellPendingWithLongText = () => { return (
diff --git a/packages/mint-components/src/components/sqm-rewards-table/TaxAndCashRewardsTable.stories.tsx b/packages/mint-components/src/components/sqm-rewards-table/TaxAndCashRewardsTable.stories.tsx new file mode 100644 index 0000000000..b90c7b5af8 --- /dev/null +++ b/packages/mint-components/src/components/sqm-rewards-table/TaxAndCashRewardsTable.stories.tsx @@ -0,0 +1,151 @@ +import { h } from "@stencil/core"; +import { GenericTableView } from "../../tables/GenericTableView"; +import { SourceCellReferral, DateCell } from "./RewardsTableCell.stories"; +import { + StatusCellPayoutSent, + StatusCellPayoutFailed, + StatusCellPendingNewTaxForm, + StatusCellPendingPartnerCreation, + StatusCellPendingTaxReview, + StatusCellPendingTaxSubmission, + StatusCellPayoutProcessing, + CashReward, + StatusCellPendingW9, + StatusCellPayoutCancelled, +} from "./TaxAndCashRewardsTableCell.stories"; + +export default { + title: "Components/Tax And Cash Rewards Table", +}; + +const rewardsTableProps = ( + rows, + empty = false, + loading = false, + prev = "Prev", + next = "Next", + hidden = "", +) => ({ + states: { + hasPrev: false, + hasNext: true, + show: empty + ? ("empty" as const) + : loading + ? ("loading" as const) + : ("rows" as const), + namespace: "sqm-rewards-table", + }, + data: { + textOverrides: { + showLabels: true, + prevLabel: prev, + moreLabel: next, + }, + hiddenColumns: hidden, + mdBreakpoint: 799, + smBreakpoint: 599, + }, + callbacks: { + prevPage: () => console.log("Prev"), + nextPage: () => console.log("Next"), + }, + + elements: { + columns: ["Rewards", "Status", "Source", "Date received"], + rows: rows, + }, +}); + +/* -------------------------------------------------------------------------- */ +/* PENDING ROWS */ +/* -------------------------------------------------------------------------- */ + +const r_pending_new_tax_form = [ + , + , + , + , +]; + +const r_pending_tax_submission = [ + , + , + , + , +]; + +const r_pending_tax_review = [ + , + , + , + , +]; + +const r_pending_partner_creation = [ + , + , + , + , +]; + +const r_pending_w9 = [ + , + , + , + , +]; + +/* -------------------------------------------------------------------------- */ +/* SUCCESS / PROCESSING ROWS */ +/* -------------------------------------------------------------------------- */ + +const r_payout_sent = [ + , + , + , + , +]; + +const r_payout_processing = [ + , + , + , + , +]; + +/* -------------------------------------------------------------------------- */ +/* ERROR / CANCELLED ROWS */ +/* -------------------------------------------------------------------------- */ + +const r_payout_failed = [ + , + , + , + , +]; + +const r_payout_cancelled = [ + , + , + , + , +]; + +export const RewardsTable = () => { + return ( + + ); +}; diff --git a/packages/mint-components/src/components/sqm-rewards-table/TaxAndCashRewardsTableCell.stories.tsx b/packages/mint-components/src/components/sqm-rewards-table/TaxAndCashRewardsTableCell.stories.tsx new file mode 100644 index 0000000000..994442ef8f --- /dev/null +++ b/packages/mint-components/src/components/sqm-rewards-table/TaxAndCashRewardsTableCell.stories.tsx @@ -0,0 +1,289 @@ +import { h } from "@stencil/core"; +import { ImpactConnection } from "../../saasquatch"; + +export default { + title: "Components/Tax And Cash Rewards Table Cell", +}; + +const cashReward = { + id: "68c34fd98a6cb4f5f8394084", + type: "CREDIT", + value: 59900, + prettyValue: "$599.00", + availableValue: 0, + prettyAvailableValue: "$0.00", + prettyAssignedCredit: "$599.00", + prettyRedeemedCredit: "$599.00", + prettyValueNumber: "599", + prettyAvailableNumber: "0", + prettyRedeemedNumber: "599", + unit: "CASH/USD", + baseUnit: "CASH", + rewardUnit: { + key: "CASH/USD", + name: "Cash", + }, + name: null, + dateCreated: 1757630425085, + dateScheduledFor: 1757631025115, + dateGiven: 1757630737115, + dateExpires: null, + dateCancelled: null, + dateRedeemed: 1757630737115, + dateModified: 1757630737115, + rewardSource: "MANUAL" as const, + fuelTankCode: null, + fuelTankType: null, + fuelTankSyncSetting: null, + currency: "USD", + meta: null, + programId: "40444", + programRewardKey: null, + globalRewardKey: "cash", + program: { + id: "40444", + name: "Make Money Program", + template: { + id: "2qdmAx1fi31deo3P9O36sQ", + name: "Referral Program With Objectives", + }, + }, + partnerFundsTransfer: null, + + user: { + id: "8da2c67e05e3e56de7ea638c2705017945211621c80e1cd4b4aac0e423d1cdb2", + accountId: + "8da2c67e05e3e56de7ea638c2705017945211621c80e1cd4b4aac0e423d1cdb2", + firstName: "Billy", + lastName: "Jean", + email: "billy.jean@impact.com", + impactConnection: { + connected: true, + taxHandlingEnabled: true, + publisher: null, + }, + }, + referral: null, + description: null, + statuses: ["REDEEMED"], + + rewardRedemptionTransactions: { + data: null, + }, + exchangedRewardRedemptionTransaction: null, + pendingReasons: [], +}; + +const pending = { + statuses: ["PENDING"], +}; + +const payoutSent = { + statuses: ["PAYOUT_APPROVED"], +}; +const payoutFailed = { + statuses: ["PAYOUT_FAILED"], +}; +const payoutCancelled = { + statuses: ["PAYOUT_CANCELLED"], + dateCancelled: 1355612521321, +}; + +const processingPFT = { + partnerFundsTransfer: { + id: "123", + status: null, + dateCreated: 1355612521321, + dateScheduled: 2779257600000, + dateTransferred: null, + }, +}; + +const taxConnection: ImpactConnection = { + connected: true, + taxHandlingEnabled: true, + publisher: { + requiredTaxDocumentType: "W8BEN", + currentTaxDocument: { + status: "NOT_VERIFIED", + type: "W8BEN", + dateCreated: 321321487, + }, + withdrawalSettings: { + paymentMethod: "BANK_TRANSFER", + }, + payoutsAccount: null, + }, +}; + +export const CashReward = () => { + return ( + + ); +}; + +export const StatusCellPendingTaxReview = () => { + return ( + + ); +}; + +export const StatusCellPendingNewTaxForm = () => { + return ( + + ); +}; + +export const StatusCellPendingTaxSubmission = () => { + return ( + + ); +}; + +export const StatusCellPendingPartnerCreation = () => { + return ( + + ); +}; + +export const StatusCellPendingW9 = () => { + return ( + + ); +}; + +export const StatusCellPayoutSent = () => { + return ( + + ); +}; + +export const StatusCellPayoutFailed = () => { + return ( + + ); +}; + +export const StatusCellPayoutProcessing = () => { + return ( + + ); +}; + +export const StatusCellPayoutCancelled = () => { + return ( + + ); +}; diff --git a/packages/mint-components/src/components/sqm-rewards-table/cells/readme.md b/packages/mint-components/src/components/sqm-rewards-table/cells/readme.md index e05f97f003..7a516afdd9 100644 --- a/packages/mint-components/src/components/sqm-rewards-table/cells/readme.md +++ b/packages/mint-components/src/components/sqm-rewards-table/cells/readme.md @@ -7,25 +7,26 @@ ## Properties -| Property | Attribute | Description | Type | Default | -| ------------------------ | -------------------------- | ----------- | ------------------ | --------------------------------------------------------------------------------------- | -| `deniedText` | `denied-text` | | `string` | `"Detected self-referral"` | -| `expiryText` | `expiry-text` | | `string` | `"Expires"` | -| `locale` | `locale` | | `string` | `"en"` | -| `payoutApproved` | `payout-approved` | | `string` | `"Reward was scheduled for payment based on your settings, barring any account holds."` | -| `payoutCancelled` | `payout-cancelled` | | `string` | `"If you think this is a mistake, contact our Support team."` | -| `payoutFailed` | `payout-failed` | | `string` | `"Payout failed due to a fulfillment issue and is current being retried."` | -| `pendingNewTaxForm` | `pending-new-tax-form` | | `string` | `"Invalid tax form. Submit a new form to receive your rewards."` | -| `pendingPartnerCreation` | `pending-partner-creation` | | `string` | `"Complete your tax and cash payout setup to receive your rewards."` | -| `pendingReviewText` | `pending-review-text` | | `string` | `"Awaiting review"` | -| `pendingScheduled` | `pending-scheduled` | | `string` | `"Until"` | -| `pendingTaxReview` | `pending-tax-review` | | `string` | `"Awaiting tax form review."` | -| `pendingTaxSubmission` | `pending-tax-submission` | | `string` | `"Submit your tax documents to receive your rewards."` | -| `pendingUnhandled` | `pending-unhandled` | | `string` | `"Fulfillment error"` | -| `pendingUsTax` | `pending-us-tax` | | `string` | `"W-9 required"` | -| `reward` | -- | | `Reward` | `undefined` | -| `statusText` | `status-text` | | `string` | `undefined` | -| `taxConnection` | -- | | `ImpactConnection` | `undefined` | +| Property | Attribute | Description | Type | Default | +| ------------------------ | -------------------------- | ----------- | ------------------ | ----------------------------------------------------------------------------- | +| `deniedText` | `denied-text` | | `string` | `"Detected self-referral"` | +| `expiryText` | `expiry-text` | | `string` | `"Expires"` | +| `locale` | `locale` | | `string` | `"en"` | +| `payoutApproved` | `payout-approved` | | `string` | `"Payout approved and scheduled for payment based on your settings."` | +| `payoutCancelled` | `payout-cancelled` | | `string` | `"If you think this is a mistake, contact our Support team."` | +| `payoutFailed` | `payout-failed` | | `string` | `"Payout failed due to a fulfillment issue and is currently being retried."` | +| `payoutProcessing` | `payout-processing` | | `string` | `"Processing until {date}. Payout is then scheduled based on your settings."` | +| `pendingNewTaxForm` | `pending-new-tax-form` | | `string` | `"Invalid tax form. Submit a new form to receive your rewards."` | +| `pendingPartnerCreation` | `pending-partner-creation` | | `string` | `"Complete your tax and cash payout setup to receive your rewards."` | +| `pendingReviewText` | `pending-review-text` | | `string` | `"Awaiting review"` | +| `pendingScheduled` | `pending-scheduled` | | `string` | `"Until"` | +| `pendingTaxReview` | `pending-tax-review` | | `string` | `"Awaiting tax form review."` | +| `pendingTaxSubmission` | `pending-tax-submission` | | `string` | `"Submit your tax documents to receive your rewards."` | +| `pendingUnhandled` | `pending-unhandled` | | `string` | `"Fulfillment error"` | +| `pendingUsTax` | `pending-us-tax` | | `string` | `"W-9 required"` | +| `reward` | -- | | `Reward` | `undefined` | +| `statusText` | `status-text` | | `string` | `undefined` | +| `taxConnection` | -- | | `ImpactConnection` | `undefined` | ## Dependencies diff --git a/packages/mint-components/src/components/sqm-rewards-table/cells/sqm-rewards-table-status-cell.tsx b/packages/mint-components/src/components/sqm-rewards-table/cells/sqm-rewards-table-status-cell.tsx index dcb353dc03..7f2c42ca67 100644 --- a/packages/mint-components/src/components/sqm-rewards-table/cells/sqm-rewards-table-status-cell.tsx +++ b/packages/mint-components/src/components/sqm-rewards-table/cells/sqm-rewards-table-status-cell.tsx @@ -87,11 +87,13 @@ export class RewardTableStatusCell { @Prop() pendingReviewText: string = "Awaiting review"; @Prop() deniedText: string = "Detected self-referral"; @Prop() payoutFailed: string = - "Payout failed due to a fulfillment issue and is current being retried."; + "Payout failed due to a fulfillment issue and is currently being retried."; @Prop() payoutApproved: string = - "Reward was scheduled for payment based on your settings, barring any account holds."; + "Payout approved and scheduled for payment based on your settings."; @Prop() payoutCancelled: string = "If you think this is a mistake, contact our Support team."; + @Prop() payoutProcessing: string = + "Processing until {date}. Payout is then scheduled based on your settings."; rewardStatus(reward: Reward): string { const hasExpired = reward.statuses?.includes("EXPIRED"); @@ -104,13 +106,28 @@ export class RewardTableStatusCell { if (fraudStatus === "PENDING") return "PENDING_REVIEW"; const partnerTransferStatus = reward.partnerFundsTransfer?.status; - if ( - partnerTransferStatus === "TRANSFERRED" || - partnerTransferStatus === "NOT_YET_DUE" - ) - return "PAYOUT_APPROVED"; - if (partnerTransferStatus === "OVERDUE") return "PAYOUT_FAILED"; - if (partnerTransferStatus === "REVERSED") return "PAYOUT_CANCELLED"; + + if (reward.partnerFundsTransfer) { + if (partnerTransferStatus === "REVERSED") return "PAYOUT_CANCELLED"; + if (partnerTransferStatus === "OVERDUE") return "PAYOUT_FAILED"; + + if ( + reward.partnerFundsTransfer.dateScheduled && + reward.partnerFundsTransfer.dateScheduled > Date.now() + ) { + return "PROCESSING"; + } + + if ( + partnerTransferStatus === "TRANSFERRED" || + partnerTransferStatus === "NOT_YET_DUE" || + (reward.partnerFundsTransfer.dateScheduled && + reward.partnerFundsTransfer.dateScheduled < Date.now() && + partnerTransferStatus !== "OVERDUE" && + partnerTransferStatus !== "REVERSED") + ) + return "PAYOUT_APPROVED"; + } if (reward.dateCancelled) return "CANCELLED"; if (hasExpired) return "EXPIRED"; @@ -173,6 +190,7 @@ export class RewardTableStatusCell { return "primary"; case "PENDING": case "PENDING_REVIEW": + case "PROCESSING": return "warning"; default: return "danger"; @@ -197,6 +215,20 @@ export class RewardTableStatusCell { return this.pendingTaxSubmission; case "PENDING_PARTNER_CREATION": return this.pendingPartnerCreation; + case "PROCESSING": + return intl.formatMessage( + { + id: "payoutProcessingText", + defaultMessage: this.payoutProcessing, + }, + { + date: DateTime.fromMillis( + this.reward.partnerFundsTransfer.dateScheduled, + ) + ?.setLocale(luxonLocale(this.locale)) + .toLocaleString(DateTime.DATE_MED), + }, + ); } } @@ -208,7 +240,7 @@ export class RewardTableStatusCell { { id: "statusMessage", defaultMessage: this.statusText }, { status: rewardStatus, - } + }, ); const badgeType = this.getBadgeType(rewardStatus); @@ -239,8 +271,8 @@ export class RewardTableStatusCell { rewardStatus === "PENDING_REVIEW" ? this.pendingReviewText : rewardStatus === "DENIED" - ? this.deniedText - : null; + ? this.deniedText + : null; const getBadgeCSSClass = () => { switch (rewardStatus) { @@ -251,6 +283,7 @@ export class RewardTableStatusCell { return sheet.classes.RedeemBadge; case "PENDING": case "PENDING_REVIEW": + case "PROCESSING": return sheet.classes.WarningBadge; default: return sheet.classes.DangerBadge; @@ -289,7 +322,7 @@ export class RewardTableStatusCell { const taxReason = prop.getTaxPendingReasons( prop.reward, - prop.taxConnection + prop.taxConnection, ); return [ diff --git a/packages/mint-components/src/components/sqm-rewards-table/columns/readme.md b/packages/mint-components/src/components/sqm-rewards-table/columns/readme.md index 4458ce82ad..89610e2b8e 100644 --- a/packages/mint-components/src/components/sqm-rewards-table/columns/readme.md +++ b/packages/mint-components/src/components/sqm-rewards-table/columns/readme.md @@ -7,23 +7,24 @@ ## Properties -| Property | Attribute | Description | Type | Default | -| ------------------------ | -------------------------- | -------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `columnTitle` | `column-title` | | `string` | `"Status"` | -| `deniedText` | `denied-text` | Displayed when denied for fraud. | `string` | `"Detected self-referral"` | -| `expiryText` | `expiry-text` | Text shown before the date of an expiring reward. | `string` | `"Expires on "` | -| `payoutApproved` | `payout-approved` | Displayed when reward payout is approved (based on Impact cash payout configuration). | `string` | `"Reward was scheduled for payment based on your settings, barring any account holds."` | -| `payoutCancelled` | `payout-cancelled` | Displayed when reward payout was reversed (based on Impact cash payout configuration). | `string` | `"If you think this is a mistake, contact our Support team."` | -| `payoutFailed` | `payout-failed` | Displayed when reward payout has failed (based on Impact cash payout configuration). | `string` | `"Payout failed due to a fulfillment issue and is current being retried."` | -| `pendingNewTaxForm` | `pending-new-tax-form` | Displayed when pending due to requiring a new tax document | `string` | `"Invalid tax form. Submit a new form to receive your rewards."` | -| `pendingPartnerCreation` | `pending-partner-creation` | Displayed when pending due to need to connect to an Impact partner | `string` | `"Complete your tax and cash payout setup to receive your rewards."` | -| `pendingReviewText` | `pending-review-text` | Displayed when flagged for fraud. | `string` | `"Awaiting review"` | -| `pendingScheduled` | `pending-scheduled` | Text shown before the available date of a pending reward. | `string` | `"Until"` | -| `pendingTaxReview` | `pending-tax-review` | Displayed when pending due to tax document review. | `string` | `"Awaiting tax form review."` | -| `pendingTaxSubmission` | `pending-tax-submission` | Displayed when pending due to lack of tax document submission. | `string` | `"Submit your tax documents to receive your rewards."` | -| `pendingUnhandled` | `pending-unhandled` | Displayed when fulfillment error occured when creating a reward. | `string` | `"Fulfillment error"` | -| `pendingUsTax` | `pending-us-tax` | Displayed when a reward is pending due to W-9 compliance. | `string` | `"W-9 required"` | -| `statusText` | `status-text` | | `string` | `"{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PAYOUT_CANCELLED {Payout Cancelled} PAYOUT_FAILED {Payout Failed} EXPIRED {Expired} REDEEMED {Redeemed} DENIED {Denied} other {Not available} }"` | +| Property | Attribute | Description | Type | Default | +| ------------------------ | -------------------------- | -------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `columnTitle` | `column-title` | | `string` | `"Status"` | +| `deniedText` | `denied-text` | Displayed when denied for fraud. | `string` | `"Detected self-referral"` | +| `expiryText` | `expiry-text` | Text shown before the date of an expiring reward. | `string` | `"Expires on "` | +| `payoutApproved` | `payout-approved` | Displayed when reward payout is approved (based on Impact cash payout configuration). | `string` | `"Reward was scheduled for payment based on your settings, barring any account holds."` | +| `payoutCancelled` | `payout-cancelled` | Displayed when reward payout was reversed (based on Impact cash payout configuration). | `string` | `"If you think this is a mistake, contact our Support team."` | +| `payoutFailed` | `payout-failed` | Displayed when reward payout has failed (based on Impact cash payout configuration). | `string` | `"Payout failed due to a fulfillment issue and is currently being retried."` | +| `payoutProcessing` | `payout-processing` | Displayed when a reward payout is processing. | `string` | `"Processing until {date}. Payout is then scheduled based on your settings."` | +| `pendingNewTaxForm` | `pending-new-tax-form` | Displayed when pending due to requiring a new tax document | `string` | `"Invalid tax form. Submit a new form to receive your rewards."` | +| `pendingPartnerCreation` | `pending-partner-creation` | Displayed when pending due to need to connect to an Impact partner | `string` | `"Complete your tax and cash payout setup to receive your rewards."` | +| `pendingReviewText` | `pending-review-text` | Displayed when flagged for fraud. | `string` | `"Awaiting review"` | +| `pendingScheduled` | `pending-scheduled` | Text shown before the available date of a pending reward. | `string` | `"Until"` | +| `pendingTaxReview` | `pending-tax-review` | Displayed when pending due to tax document review. | `string` | `"Awaiting tax form review."` | +| `pendingTaxSubmission` | `pending-tax-submission` | Displayed when pending due to lack of tax document submission. | `string` | `"Submit your tax documents to receive your rewards."` | +| `pendingUnhandled` | `pending-unhandled` | Displayed when fulfillment error occured when creating a reward. | `string` | `"Fulfillment error"` | +| `pendingUsTax` | `pending-us-tax` | Displayed when a reward is pending due to W-9 compliance. | `string` | `"W-9 required"` | +| `statusText` | `status-text` | | `string` | `"{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PROCESSING {Payment Processing} PAYOUT_CANCELLED {Payout Cancelled} PAYOUT_FAILED {Payout Failed} EXPIRED {Expired} REDEEMED {Redeemed} DENIED {Denied} other {Not available} }"` | ## Methods diff --git a/packages/mint-components/src/components/sqm-rewards-table/columns/sqm-rewards-table-status-column.feature b/packages/mint-components/src/components/sqm-rewards-table/columns/sqm-rewards-table-status-column.feature index 7eb0d5f10e..af4cbd3b08 100644 --- a/packages/mint-components/src/components/sqm-rewards-table/columns/sqm-rewards-table-status-column.feature +++ b/packages/mint-components/src/components/sqm-rewards-table/columns/sqm-rewards-table-status-column.feature @@ -24,21 +24,22 @@ Feature: Reward Table Status Column Examples: | status | text | pillColour | - | AVAILABLE | Available | Green | - | CANCELLED | Cancelled | Red | - | PENDING | Pending | Orange | - | EXPIRED | Expired | Red | - | REDEEMED | Redeemed | Blue | - | PENDING_REVIEW | Pending | Orange | - | PAYOUT_TRANSFERRED | Payout Approved | blue | - | PAYOUT_NOT_YET_DUE | Payout Approved | blue | - | PAYOUT_OVERDUE | Payout Failed | Red | - | PAYOUT_REVERSED | Payout Cancelled | Red | - | PENDING_TAX_REVIEW | Pending | Orange | - | PENDING_NEW_TAX_FORM | Pending | Orange | - | PENDING_TAX_SUBMISSION | Pending | Orange | - | PENDING_PARTNER_CREATION | Pending | Orange | - | DENIED | Denied | Red | + | AVAILABLE | Available | success | + | CANCELLED | Cancelled | danger | + | PENDING | Pending | warning | + | EXPIRED | Expired | danger | + | REDEEMED | Redeemed | primary | + | PENDING_REVIEW | Pending | warning | + | PAYOUT_TRANSFERRED | Payout Approved | primary | + | PAYOUT_NOT_YET_DUE | Payout Approved | primary | + | PAYOUT_OVERDUE | Payout Failed | danger | + | PAYOUT_REVERSED | Payout Cancelled | danger | + | PROCESSING | Processing | warning | + | PENDING_TAX_REVIEW | Pending | warning | + | PENDING_NEW_TAX_FORM | Pending | warning | + | PENDING_TAX_SUBMISSION | Pending | warning | + | PENDING_PARTNER_CREATION | Pending | warning | + | DENIED | Denied | danger | @motivating Scenario Outline: Reward status related information is displayed under status pills @@ -50,24 +51,28 @@ Feature: Reward Table Status Column And under the pill is And the date is localized to the users locale - Examples: - | reward | text | - | available reward with an expiry date | localized expiry date in format "Month-Day-Year" | - | redeemed reward | localized redemption date in format "Month-Day-Year" | - | expired reward | localized expired date in format "Month-Day-Year" | - | cancelled reward | localized cancelled date in format "Month-Day-Year" | - | pending reward with a end date | localized pending for date in format "Month-Day-Year" | - | pending reward due to W9 | W-9 required | - | pending reward due to fufillment error | Fulfillment error | - | reward pending review of referral | Pending review | - | pending reward due to no connected Impact partner | Complete your tax and cash payout setup to receive your rewards. | - | pending reward due to an invalid tax document | Invalid tax form. Submit a new form to receive your rewards. | - | pending reward due to user required to submit a tax document | Submit your tax documents to receive your rewards. | - | pending reward due to tax document being in review | Awaiting tax form review. | - | reward whose payout failed | Payout failed due to a fulfillment issue and is currently being retried. | - | reward whose payout was approved | Reward approved for payout and was scheduled for payment based on your settings. | - | reward whose payout was cancelled | If you think this is a mistake, contact our Support team. | - | cancelled reward from denied referral | Flagged as fraud | + Examples: Standard Rewards + | reward | text | + | available reward with an expiry date | Expires | + | redeemed reward | | + | expired reward | | + | cancelled reward | | + | pending reward with a scheduled date | Until | + + Examples: Tax & Payout Rewards + | reward | text | + | pending reward due to W9 | W-9 required | + | pending reward due to fulfillment error | Fulfillment error | + | reward pending review of referral | Awaiting review | + | pending reward due to no connected Impact partner | Complete your tax and cash payout setup to receive your rewards. | + | pending reward due to an invalid tax document | Invalid tax form. Submit a new form to receive your rewards. | + | pending reward due to user required to submit a tax document | Submit your tax documents to receive your rewards. | + | pending reward due to tax document being in review | Awaiting tax form review. | + | reward whose payout is processing | Processing until . Payout is then scheduled based on your settings. | + | reward whose payout failed | Payout failed due to a fulfillment issue and is currently being retried. | + | reward whose payout was approved | Payout approved and scheduled for payment based on your settings. | + | reward whose payout was cancelled | If you think this is a mistake, contact our Support team. | + | cancelled reward from denied referral | Detected self-referral | @minutia Scenario Outline: Tax-related reward statuses are based on the user's Impact tax connection @@ -81,7 +86,7 @@ Feature: Reward Table Status Column """ @motivating - Scenario Outline: Statuses can be customized + Scenario Outline: Statuses can be customized via ICU format Given the "status-text" prop is "{status, select, AVAILABLE {Redeem me!} CANCELLED {Unavailable} PENDING {Coming soon!} EXPIRED {Past due} REDEEMED {Spent} PENDING_REVIEW {Pending Review!} PAYOUT_SENT {Payout Sent!} PAYOUT_FAILED {Payout Failed!} PENDING_TAX_REVIEW {Pending Tax Review!} PENDING_NEW_TAX_FORM {Pending new tax form!} PENDING_TAX_SUBMISSION {Pending tax submission!} PENDING_PARTNER_CREATION {Pending partner creation!} DENIED {Unlucky!}}" And a user And they have a reward @@ -90,26 +95,42 @@ Feature: Reward Table Status Column Examples: | status | text | pillColour | - | AVAILABLE | Redeem me! | Green | - | CANCELLED | Unavailable | Red | - | PENDING | Coming soon! | Orange | - | EXPIRED | Past due | Red | - | REDEEMED | Spent | Blue | - | PENDING_REVIEW | Pending Review! | Orange | - | PAYOUT_TRANSFERRED | Payout Approved! | Blue | - | PAYOUT_NOT_YET_DUE | Payout Approved! | Blue | - | PAYOUT_OVERDUE | Payout Failed! | Red | - | PAYOUT_REVERSED | Payout Cancelled! | Red | - | DENIED | Unlucky! | Red | + | AVAILABLE | Redeem me! | success | + | CANCELLED | Unavailable | danger | + | PENDING | Coming soon! | warning | + | EXPIRED | Past due | danger | + | REDEEMED | Spent | primary | + | PENDING_REVIEW | Pending Review! | warning | + | PAYOUT_TRANSFERRED | Payout Approved! | primary | + | PAYOUT_NOT_YET_DUE | Payout Approved! | primary | + | PAYOUT_OVERDUE | Payout Failed! | danger | + | PAYOUT_REVERSED | Payout Cancelled! | danger | + | DENIED | Unlucky! | danger | @minutia @ui - Scenario: Expiry status date text can be configured + Scenario Outline: Expiry status date text can be configured Given the "expiry-text" prop has And a user with an available reward with an expiry date When they view the reward table Then they see under the Available Status pill Examples: - | value | text | - | | Expires on | - | Redeem before | Redeem before | + | value | text | + | Expires | Expires | + | Redeem before | Redeem before | + + @motivating + Scenario: Payout-related reward statuses are determined by the state of the Paid Funds Transfer + Given a user has a reward with a connected Paid Funds Transfer (PFT) + When the PFT is in + Then the reward's status is + And the status is displayed in a pill with + And under the pill is + + Examples: + | pftState | status | text | pillColour | description | + | transfer date is in the future | PROCESSING | Processing | warning | Processing until . Payout is then scheduled based on your settings. | + | successfully transferred to payment provider | PAYOUT_TRANSFERRED | Payout Approved | primary | Payout approved and scheduled for payment based on your settings. | + | approved but payout scheduled date not yet arrived | PAYOUT_NOT_YET_DUE | Payout Approved | primary | Payout approved and scheduled for payment based on your settings. | + | failed due to fulfillment issue and retrying | PAYOUT_OVERDUE | Payout Failed | danger | Payout failed due to a fulfillment issue and is currently being retried. | + | reversed or cancelled after being processed | PAYOUT_REVERSED | Payout Cancelled | danger | If you think this is a mistake, contact our Support team. | \ No newline at end of file diff --git a/packages/mint-components/src/components/sqm-rewards-table/columns/sqm-rewards-table-status-column.tsx b/packages/mint-components/src/components/sqm-rewards-table/columns/sqm-rewards-table-status-column.tsx index f4a4a71bab..5026aba7bd 100644 --- a/packages/mint-components/src/components/sqm-rewards-table/columns/sqm-rewards-table-status-column.tsx +++ b/packages/mint-components/src/components/sqm-rewards-table/columns/sqm-rewards-table-status-column.tsx @@ -8,7 +8,7 @@ import { RewardTableColumn } from "./RewardTableColumn"; * @uiName Reward Table Status Column * @validParents ["sqm-rewards-table"] * @exampleGroup Rewards - * @example Reward Table Status Column - + * @example Reward Table Status Column - */ @Component({ tag: "sqm-rewards-table-status-column", @@ -25,7 +25,7 @@ export class RewardTableStatusColumn implements RewardTableColumn { * @uiWidget textArea */ @Prop() statusText: string = - "{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PAYOUT_CANCELLED {Payout Cancelled} PAYOUT_FAILED {Payout Failed} EXPIRED {Expired} REDEEMED {Redeemed} DENIED {Denied} other {Not available} }"; + "{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PROCESSING {Payment Processing} PAYOUT_CANCELLED {Payout Cancelled} PAYOUT_FAILED {Payout Failed} EXPIRED {Expired} REDEEMED {Redeemed} DENIED {Denied} other {Not available} }"; /** * Text shown before the date of an expiring reward. @@ -106,7 +106,15 @@ export class RewardTableStatusColumn implements RewardTableColumn { * @uiName Payout failed text */ @Prop() payoutFailed: string = - "Payout failed due to a fulfillment issue and is current being retried."; + "Payout failed due to a fulfillment issue and is currently being retried."; + + /** + * Displayed when a reward payout is processing. + * + * @uiName Payout processing text + */ + @Prop() payoutProcessing: string = + "Processing until {date}. Payout is then scheduled based on your settings."; /** * Displayed when reward payout was reversed (based on Impact cash payout configuration). @@ -132,7 +140,7 @@ export class RewardTableStatusColumn implements RewardTableColumn { @Method() async renderCell( data: Reward, - options?: { locale: string; taxConnection: ImpactConnection } + options?: { locale: string; taxConnection: ImpactConnection }, ) { return ( + * @example Reward Table - */ @Component({ tag: "sqm-rewards-table", diff --git a/packages/mint-components/src/components/sqm-rewards-table/useRewardsTable.tsx b/packages/mint-components/src/components/sqm-rewards-table/useRewardsTable.tsx index b000379212..12e942862e 100644 --- a/packages/mint-components/src/components/sqm-rewards-table/useRewardsTable.tsx +++ b/packages/mint-components/src/components/sqm-rewards-table/useRewardsTable.tsx @@ -80,6 +80,9 @@ const GET_REWARDS = gql` partnerFundsTransfer { id status + dateScheduled + dateCreated + dateTransferred } statuses pendingReasons @@ -175,7 +178,7 @@ const GET_IMPACT_TAX = gql` export function useRewardsTable( props: RewardsTable, emptyElement: VNode, - loadingElement: VNode + loadingElement: VNode, ): GenericTableViewProps { const user = useUserIdentity(); const programIdContext = useProgramId(); @@ -207,13 +210,13 @@ export function useRewardsTable( rows: [], loading: false, page: 0, - } + }, ); const { data: impactTaxData, loading: taxLoading } = useQuery( GET_IMPACT_TAX, {}, - !user?.jwt + !user?.jwt, ); const { @@ -231,7 +234,7 @@ export function useRewardsTable( rewardFilter, locale, }, - !user?.jwt + !user?.jwt, ); const tick = useRerenderListener(); @@ -243,17 +246,17 @@ export function useRewardsTable( async function getComponentData(components: Element[]) { // filter out loading and empty states from columns array const columnComponents = components.filter( - (component) => component.slot !== "loading" && component.slot !== "empty" + (component) => component.slot !== "loading" && component.slot !== "empty", ); // get the column titles (renderLabel is asynchronous) const columnsPromise = columnComponents?.map(async (c: any) => - tryMethod(c, () => c.renderLabel()) + tryMethod(c, () => c.renderLabel()), ); // get the column cells (renderCell is asynchronous) const cellsPromise = data?.map(async (r: Reward) => { const cellPromise = columnComponents?.map(async (c: any) => - tryMethod(c, () => c.renderCell(r, { locale, taxConnection }, h)) + tryMethod(c, () => c.renderCell(r, { locale, taxConnection }, h)), ); const cells = (await Promise.all(cellPromise)) as VNode[]; return cells; @@ -281,10 +284,10 @@ export function useRewardsTable( states.loading || content.loading || taxLoading ? "loading" : // 2 - Empty if empty - isEmpty - ? "empty" - : // 3 - Then show rows - "rows"; + isEmpty + ? "empty" + : // 3 - Then show rows + "rows"; return { states: { @@ -321,7 +324,7 @@ export function useRewardsTable( } export async function tryMethod( c: HTMLElement, - callback: () => Promise + callback: () => Promise, ): Promise { const tag = c.tagName.toLowerCase(); await customElements.whenDefined(tag); diff --git a/packages/mint-components/src/components/sqm-stencilbook/sqm-stencilbook.tsx b/packages/mint-components/src/components/sqm-stencilbook/sqm-stencilbook.tsx index d2c2f0f677..c793521e42 100644 --- a/packages/mint-components/src/components/sqm-stencilbook/sqm-stencilbook.tsx +++ b/packages/mint-components/src/components/sqm-stencilbook/sqm-stencilbook.tsx @@ -67,13 +67,17 @@ import * as ReferralCode from "../sqm-referral-code/ReferralCode.stories"; import * as ReferralCodes from "../sqm-referral-codes/ReferralCodes.stories"; import * as ReferralIframe from "../sqm-referral-iframe/ReferralIframe.stories"; import * as ReferralTable from "../sqm-referral-table/ReferralTable.stories"; +import * as TaxAndCashReferralTable from "../sqm-referral-table/TaxAndCashReferralTable.stories"; +import * as TaxAndCashReferralTableRewardsCell from "../sqm-referral-table/TaxAndCashReferralTableRewardsCell.stories"; import * as ReferralTableCell from "../sqm-referral-table/ReferralTableCell.stories"; import * as ReferralTableRewardsCell from "../sqm-referral-table/ReferralTableRewardsCell.stories"; import * as UseReferralTable from "../sqm-referral-table/UseReferralTable.stories"; import * as RewardExchangeList from "../sqm-reward-exchange-list/RewardExchangeList.stories"; import * as UseRewardExchangeList from "../sqm-reward-exchange-list/UseRewardExchangeList.stories"; import * as RewardsTable from "../sqm-rewards-table/RewardsTable.stories"; +import * as TaxAndCashRewardsTable from "../sqm-rewards-table/TaxAndCashRewardsTable.stories"; import * as RewardsTableCell from "../sqm-rewards-table/RewardsTableCell.stories"; +import * as TaxAndCashRewardsTableCell from "../sqm-rewards-table/TaxAndCashRewardsTableCell.stories"; import * as UseRewardsTable from "../sqm-rewards-table/UseRewardsTable.stories"; import * as Router from "../sqm-router/Router.stories"; import * as Scroll from "../sqm-scroll/Scroll.stories"; @@ -211,6 +215,10 @@ const stories = [ LeadInputField, LeadFormDropdownField, LeadCheckboxField, + TaxAndCashRewardsTableCell, + TaxAndCashRewardsTable, + TaxAndCashReferralTableRewardsCell, + TaxAndCashReferralTable, ]; /** diff --git a/packages/mint-components/src/components/tax-and-cash/data.ts b/packages/mint-components/src/components/tax-and-cash/data.ts index 6142e4ff6f..3f3b78e9e5 100644 --- a/packages/mint-components/src/components/tax-and-cash/data.ts +++ b/packages/mint-components/src/components/tax-and-cash/data.ts @@ -58,6 +58,9 @@ export const GET_USER = gql` partnerFundsTransfer { id status + dateScheduled + dateCreated + dateTransferred } } } diff --git a/packages/mint-components/src/components/tax-and-cash/sqm-payout-status-alert/usePayoutStatus.ts b/packages/mint-components/src/components/tax-and-cash/sqm-payout-status-alert/usePayoutStatus.ts index 36d6b65fad..221494b1ef 100644 --- a/packages/mint-components/src/components/tax-and-cash/sqm-payout-status-alert/usePayoutStatus.ts +++ b/packages/mint-components/src/components/tax-and-cash/sqm-payout-status-alert/usePayoutStatus.ts @@ -58,6 +58,9 @@ const GET_USER_STATUS = gql` partnerFundsTransfer { id status + dateScheduled + dateCreated + dateTransferred } } } @@ -80,7 +83,7 @@ export function getStatus(data: UserQuery): PayoutStatus { const hasTransferredReward = data?.user?.rewards?.data?.find( (reward) => reward.statuses.includes("REDEEMED") && - reward.partnerFundsTransfer.status === "TRANSFERRED" + reward.partnerFundsTransfer?.status === "TRANSFERRED", ); if (!data.user?.impactConnection?.connected || !account) @@ -123,11 +126,11 @@ export function usePayoutStatus(props: PayoutStatusAlert) { const { type } = getEnvironmentSDK(); const { loading, data, errors, refetch } = useQuery( GET_USER_STATUS, - {} + {}, ); const { data: taxSettingRes } = useQuery( GET_TAX_SETTING, - {} + {}, ); const { render, diff --git a/packages/mint-components/src/components/tax-and-cash/sqm-user-info-form/useUserInfoForm.tsx b/packages/mint-components/src/components/tax-and-cash/sqm-user-info-form/useUserInfoForm.tsx index 87df5f2010..35f398a025 100644 --- a/packages/mint-components/src/components/tax-and-cash/sqm-user-info-form/useUserInfoForm.tsx +++ b/packages/mint-components/src/components/tax-and-cash/sqm-user-info-form/useUserInfoForm.tsx @@ -84,7 +84,7 @@ export function useUserInfoForm(props: TaxForm) { const countries = useParentValue(SORTED_COUNTRIES_NAMESPACE); const [step, setStep] = useParent(TAX_CONTEXT_NAMESPACE); const [userFormContext, setUserFormContext] = useParent( - USER_FORM_CONTEXT_NAMESPACE + USER_FORM_CONTEXT_NAMESPACE, ); const user = useUserIdentity(); @@ -107,20 +107,20 @@ export function useUserInfoForm(props: TaxForm) { const currencies = useMemo( () => [...(_currencies || [])].sort((a, b) => - a.displayName.localeCompare(b.displayName) + a.displayName.localeCompare(b.displayName), ), - [_currencies] + [_currencies], ); const [countrySearch, setCountrySearch] = useState(""); const [phoneCountrySearch, setPhoneCountrySearch] = useState(""); const [filteredCountries, setFilteredCountries] = useState(countries || []); const [filteredPhoneCountries, setFilteredPhoneCountries] = useState( - countries || [] + countries || [], ); const [currencySearch, setCurrencySearch] = useState(""); const [filteredCurrencies, setFilteredCurrencies] = useState( - currencies || [] + currencies || [], ); const [formErrors, setErrors] = useState({}); @@ -161,8 +161,8 @@ export function useUserInfoForm(props: TaxForm) { // Initialise with user information setUserFormContext({ email, - firstName: user.firstName, - lastName: user.lastName, + firstName: user.impactConnection?.user?.firstName || user.firstName, + lastName: user.impactConnection?.user?.lastName || user.lastName, countryCode: user.countryCode || "US", currency: user.customFields?.currency, phoneNumberCountryCode: @@ -197,8 +197,8 @@ export function useUserInfoForm(props: TaxForm) { } else { setFilteredCountries( countries.filter((c) => - c.displayName.toLowerCase().includes(countrySearch.toLowerCase()) - ) || [] + c.displayName.toLowerCase().includes(countrySearch.toLowerCase()), + ) || [], ); } }, [countrySearch, countries]); @@ -210,8 +210,10 @@ export function useUserInfoForm(props: TaxForm) { } else { setFilteredPhoneCountries( countries.filter((c) => - c.displayName.toLowerCase().includes(phoneCountrySearch.toLowerCase()) - ) || [] + c.displayName + .toLowerCase() + .includes(phoneCountrySearch.toLowerCase()), + ) || [], ); } }, [phoneCountrySearch, countries]); @@ -223,8 +225,8 @@ export function useUserInfoForm(props: TaxForm) { } else { setFilteredCurrencies( currencies.filter((c) => - c.currencyCode.toLowerCase().includes(currencySearch.toLowerCase()) - ) || [] + c.currencyCode.toLowerCase().includes(currencySearch.toLowerCase()), + ) || [], ); } }, [currencySearch, currencies]); @@ -256,7 +258,8 @@ export function useUserInfoForm(props: TaxForm) { // Output backend errors to console for now console.error( "Failed to create Impact connection: ", - (result as ConnectPartnerResult).createImpactConnection.validationErrors + (result as ConnectPartnerResult).createImpactConnection + .validationErrors, ); throw new Error(); @@ -376,7 +379,7 @@ export function useUserInfoForm(props: TaxForm) { } const hasStates = ["ES", "AU", "US", "CA"].includes( - userFormContext.countryCode + userFormContext.countryCode, ); const regionObj = hasStates ? ADDRESS_REGIONS[userFormContext?.countryCode] diff --git a/packages/mint-components/src/global/global.ts b/packages/mint-components/src/global/global.ts index 00b59d7e37..d7881902ee 100644 --- a/packages/mint-components/src/global/global.ts +++ b/packages/mint-components/src/global/global.ts @@ -19,7 +19,7 @@ export const intl = createIntl( { locale: "en", }, - cache + cache, ); import { diff --git a/packages/mint-components/src/templates/CashPayoutsReferralWidget.html b/packages/mint-components/src/templates/CashPayoutsReferralWidget.html index 7c19f5c499..4265bf44fa 100644 --- a/packages/mint-components/src/templates/CashPayoutsReferralWidget.html +++ b/packages/mint-components/src/templates/CashPayoutsReferralWidget.html @@ -79,8 +79,8 @@

diff --git a/packages/mint-components/src/templates/MonoWidget.html b/packages/mint-components/src/templates/MonoWidget.html index e0991f7382..e902af5083 100644 --- a/packages/mint-components/src/templates/MonoWidget.html +++ b/packages/mint-components/src/templates/MonoWidget.html @@ -271,8 +271,8 @@

Earn more rewards

fuel-tank-text="Your code is" pending-for-text="{status} for {date}" reward-received-text="Reward received on" - status-long-text="{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} EXPIRED {Reward expired on} other {Not available} }" - status-text="{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }" + status-text="{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PROCESSING {Payment Processing} PAYOUT_FAILED {Payout Failed} PAYOUT_CANCELLED {Payout Cancelled} PENDING_TAX_REVIEW {Pending} PENDING_NEW_TAX_FORM {Pending} PENDING_TAX_SUBMISSION {Pending} PENDING_PARTNER_CREATION {Pending} DENIED {Denied} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }" + status-long-text="{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} PENDING_REVIEW {Pending since} PAYOUT_APPROVED {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PAYOUT_FAILED {Payout failed due to a fulfillment issue and is currently being retried.} PAYOUT_CANCELLED {If you think this is a mistake, contact our Support team.} PENDING_TAX_REVIEW {Awaiting tax form review} PENDING_NEW_TAX_FORM {Invalid tax form. Submit a new form to receive your rewards.} PROCESSING {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PENDING_TAX_SUBMISSION {Submit your tax documents to receive your rewards} PENDING_PARTNER_CREATION {Complete your tax and cash payout setup to receive your rewards} DENIED {Denied on} EXPIRED {Reward expired on} other {Not available} }" > Earn more rewards reward-returned-text="The email you provided does not link to an existing PayPal account. Payout expired on {date}." reward-reversed-text="Payout reversed on {date}." reward-unclaimed-text="The email you provided does not link to an existing PayPal account. Payout expires on {date}." - status-long-text="{status, select, INPROGRESS {In Progress} TRANSFERRED {Transferred} AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} REDEEMED {Redeemed on} PENDING {Available on} EXPIRED {Reward expired on} SUCCESS {Paid out on} FAILED {This payout will be retried up to 3 times. If it still fails it will be retried in the next payout cycle. Last attempted on} PAYPAL_PENDING {Payout process started on} UNCLAIMED {The email you provided does not link to an existing PayPal account. Payout expires on} ONHOLD {Payout on hold and in review since} REFUNDED {Payout refunded on} RETURNED {Payout returned on} REVERSED {Payout reversed on} BLOCKED {Payout blocked on} other {Not available} }" - status-text="{status, select, AVAILABLE {Available} CANCELLED {Cancelled} EXPIRED {Expired} REDEEMED {Redeemed} PENDING {Pending} SUCCESS {Paid Out} FAILED {Failed} PAYPAL_PENDING {In progress} UNCLAIMED {Unclaimed} ONHOLD {In progress} REFUNDED {Refunded} RETURNED {Returned} REVERSED {Reversed} BLOCKED {Blocked} other {Not available} }" + status-text="{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PROCESSING {Payment Processing} PAYOUT_FAILED {Payout Failed} PAYOUT_CANCELLED {Payout Cancelled} PENDING_TAX_REVIEW {Pending} PENDING_NEW_TAX_FORM {Pending} PENDING_TAX_SUBMISSION {Pending} PENDING_PARTNER_CREATION {Pending} DENIED {Denied} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }" + status-long-text="{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} PENDING_REVIEW {Pending since} PAYOUT_APPROVED {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PAYOUT_FAILED {Payout failed due to a fulfillment issue and is currently being retried.} PAYOUT_CANCELLED {If you think this is a mistake, contact our Support team.} PENDING_TAX_REVIEW {Awaiting tax form review} PENDING_NEW_TAX_FORM {Invalid tax form. Submit a new form to receive your rewards.} PROCESSING {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PENDING_TAX_SUBMISSION {Submit your tax documents to receive your rewards} PENDING_PARTNER_CREATION {Complete your tax and cash payout setup to receive your rewards} DENIED {Denied on} EXPIRED {Reward expired on} other {Not available} }" > Referral History reward-returned-text="The email you provided does not link to an existing PayPal account. Payout expired on {date}." reward-reversed-text="Payout reversed on {date}." reward-unclaimed-text="The email you provided does not link to an existing PayPal account. Payout expires on {date}." - status-long-text="{status, select, INPROGRESS {In Progress} TRANSFERRED {Transferred} AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} REDEEMED {Redeemed on} PENDING {Available on} EXPIRED {Reward expired on} SUCCESS {Paid out on} FAILED {This payout will be retried up to 3 times. If it still fails it will be retried in the next payout cycle. Last attempted on} PAYPAL_PENDING {Payout process started on} UNCLAIMED {The email you provided does not link to an existing PayPal account. Payout expires on} ONHOLD {Payout on hold and in review since} REFUNDED {Payout refunded on} RETURNED {Payout returned on} REVERSED {Payout reversed on} BLOCKED {Payout blocked on} other {Not available} }" - status-text="{status, select, AVAILABLE {Available} CANCELLED {Cancelled} EXPIRED {Expired} REDEEMED {Redeemed} PENDING {Pending} SUCCESS {Paid Out} FAILED {Failed} PAYPAL_PENDING {In progress} UNCLAIMED {Unclaimed} ONHOLD {In progress} REFUNDED {Refunded} RETURNED {Returned} REVERSED {Reversed} BLOCKED {Blocked} other {Not available} }" + status-text="{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PROCESSING {Payment Processing} PAYOUT_FAILED {Payout Failed} PAYOUT_CANCELLED {Payout Cancelled} PENDING_TAX_REVIEW {Pending} PENDING_NEW_TAX_FORM {Pending} PENDING_TAX_SUBMISSION {Pending} PENDING_PARTNER_CREATION {Pending} DENIED {Denied} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }" + status-long-text="{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} PENDING_REVIEW {Pending since} PAYOUT_APPROVED {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PAYOUT_FAILED {Payout failed due to a fulfillment issue and is currently being retried.} PAYOUT_CANCELLED {If you think this is a mistake, contact our Support team.} PENDING_TAX_REVIEW {Awaiting tax form review} PENDING_NEW_TAX_FORM {Invalid tax form. Submit a new form to receive your rewards.} PROCESSING {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PENDING_TAX_SUBMISSION {Submit your tax documents to receive your rewards} PENDING_PARTNER_CREATION {Complete your tax and cash payout setup to receive your rewards} DENIED {Denied on} EXPIRED {Reward expired on} other {Not available} }" > Referral History fuel-tank-text="Your code is" pending-for-text="{status} for {date}" reward-received-text="Reward received on" - status-long-text="{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} EXPIRED {Reward expired on} other {Not available} }" - status-text="{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }" + status-text="{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PROCESSING {Payment Processing} PAYOUT_FAILED {Payout Failed} PAYOUT_CANCELLED {Payout Cancelled} PENDING_TAX_REVIEW {Pending} PENDING_NEW_TAX_FORM {Pending} PENDING_TAX_SUBMISSION {Pending} PENDING_PARTNER_CREATION {Pending} DENIED {Denied} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }" + status-long-text="{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} PENDING_REVIEW {Pending since} PAYOUT_APPROVED {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PAYOUT_FAILED {Payout failed due to a fulfillment issue and is currently being retried.} PAYOUT_CANCELLED {If you think this is a mistake, contact our Support team.} PENDING_TAX_REVIEW {Awaiting tax form review} PENDING_NEW_TAX_FORM {Invalid tax form. Submit a new form to receive your rewards.} PROCESSING {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PENDING_TAX_SUBMISSION {Submit your tax documents to receive your rewards} PENDING_PARTNER_CREATION {Complete your tax and cash payout setup to receive your rewards} DENIED {Denied on} EXPIRED {Reward expired on} other {Not available} }" > Referral History fuel-tank-text="Your code is" pending-for-text="{status} for {date}" reward-received-text="Reward received on" - status-long-text="{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} EXPIRED {Reward expired on} other {Not available} }" - status-text="{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }" + status-text="{status, select, AVAILABLE {Available} CANCELLED {Cancelled} PENDING {Pending} PENDING_REVIEW {Pending} PAYOUT_APPROVED {Payout Approved} PROCESSING {Payment Processing} PAYOUT_FAILED {Payout Failed} PAYOUT_CANCELLED {Payout Cancelled} PENDING_TAX_REVIEW {Pending} PENDING_NEW_TAX_FORM {Pending} PENDING_TAX_SUBMISSION {Pending} PENDING_PARTNER_CREATION {Pending} DENIED {Denied} EXPIRED {Expired} REDEEMED {Redeemed} other {Not available} }" + status-long-text="{status, select, AVAILABLE {Reward expiring on} CANCELLED {Reward cancelled on} PENDING {Available on} PENDING_REVIEW {Pending since} PAYOUT_APPROVED {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PAYOUT_FAILED {Payout failed due to a fulfillment issue and is currently being retried.} PAYOUT_CANCELLED {If you think this is a mistake, contact our Support team.} PENDING_TAX_REVIEW {Awaiting tax form review} PENDING_NEW_TAX_FORM {Invalid tax form. Submit a new form to receive your rewards.} PROCESSING {Processing until {scheduledPayoutDate}. Payout is then scheduled based on your settings.} PENDING_TAX_SUBMISSION {Submit your tax documents to receive your rewards} PENDING_PARTNER_CREATION {Complete your tax and cash payout setup to receive your rewards} DENIED {Denied on} EXPIRED {Reward expired on} other {Not available} }" >