@internetarchive/donation-monthly-portal 6.0.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/edit-plan-form.d.ts +3 -2
- package/dist/src/edit-plan-form.js +25 -4
- package/dist/src/edit-plan-form.js.map +1 -1
- package/dist/src/form-sections/amount.js +2 -0
- package/dist/src/form-sections/amount.js.map +1 -1
- package/dist/src/form-sections/date.d.ts +38 -0
- package/dist/src/form-sections/date.js +370 -0
- package/dist/src/form-sections/date.js.map +1 -0
- package/dist/src/models/plan.d.ts +9 -1
- package/dist/src/models/plan.js +18 -4
- package/dist/src/models/plan.js.map +1 -1
- package/dist/src/monthly-giving-circle.d.ts +1 -1
- package/dist/src/monthly-giving-circle.js +14 -4
- package/dist/src/monthly-giving-circle.js.map +1 -1
- package/dist/src/plans.js +1 -1
- package/dist/src/plans.js.map +1 -1
- package/dist/test/edit-plan-form.test.js +12 -6
- package/dist/test/edit-plan-form.test.js.map +1 -1
- package/dist/test/form-sections/amount.test.js +5 -0
- package/dist/test/form-sections/amount.test.js.map +1 -1
- package/dist/test/form-sections/date.test.d.ts +1 -0
- package/dist/test/form-sections/date.test.js +136 -0
- package/dist/test/form-sections/date.test.js.map +1 -0
- package/dist/test/monthly-giving-circle.test.js +5 -0
- package/dist/test/monthly-giving-circle.test.js.map +1 -1
- package/package.json +1 -1
- package/src/edit-plan-form.ts +29 -3
- package/src/form-sections/amount.ts +2 -0
- package/src/form-sections/date.ts +401 -0
- package/src/models/plan.ts +30 -4
- package/src/monthly-giving-circle.ts +18 -6
- package/src/plans.ts +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
import type { MonthlyPlan } from './models/plan';
|
|
3
|
-
import './form-sections/cancel';
|
|
4
3
|
import './form-sections/amount';
|
|
4
|
+
import './form-sections/date';
|
|
5
|
+
import './form-sections/cancel';
|
|
5
6
|
export declare class IauxEditPlanForm extends LitElement {
|
|
6
7
|
plan?: MonthlyPlan;
|
|
7
|
-
cancelPlanHandler?: (plan: MonthlyPlan) => void;
|
|
8
8
|
updateAmountHandler?: (plan: MonthlyPlan, amountUpdates: {
|
|
9
9
|
amount: number;
|
|
10
10
|
baseAmount: number;
|
|
@@ -13,6 +13,7 @@ export declare class IauxEditPlanForm extends LitElement {
|
|
|
13
13
|
}) => void;
|
|
14
14
|
createRenderRoot(): this;
|
|
15
15
|
amountUpdates(status: 'success' | 'fail'): void;
|
|
16
|
+
dateUpdates(status: 'success' | 'fail'): void;
|
|
16
17
|
render(): import("lit").TemplateResult<1>;
|
|
17
18
|
mailToText(): string;
|
|
18
19
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { LitElement, html } from 'lit';
|
|
3
3
|
import { customElement, property } from 'lit/decorators.js';
|
|
4
|
-
import './form-sections/cancel';
|
|
5
4
|
import './form-sections/amount';
|
|
5
|
+
import './form-sections/date';
|
|
6
|
+
import './form-sections/cancel';
|
|
6
7
|
let IauxEditPlanForm = class IauxEditPlanForm extends LitElement {
|
|
7
8
|
createRenderRoot() {
|
|
8
9
|
return this;
|
|
@@ -11,6 +12,10 @@ let IauxEditPlanForm = class IauxEditPlanForm extends LitElement {
|
|
|
11
12
|
const amountForm = this.querySelector('ia-mgc-edit-plan-amount');
|
|
12
13
|
amountForm.amountUpdated(status);
|
|
13
14
|
}
|
|
15
|
+
dateUpdates(status) {
|
|
16
|
+
const dateForm = this.querySelector('ia-mgc-edit-date');
|
|
17
|
+
dateForm.dateUpdated(status);
|
|
18
|
+
}
|
|
14
19
|
render() {
|
|
15
20
|
return html `
|
|
16
21
|
<section class="mgc-edit-plan">
|
|
@@ -30,6 +35,25 @@ let IauxEditPlanForm = class IauxEditPlanForm extends LitElement {
|
|
|
30
35
|
}}
|
|
31
36
|
></ia-mgc-edit-plan-amount>
|
|
32
37
|
<hr />
|
|
38
|
+
<ia-mgc-edit-date
|
|
39
|
+
@updateDate=${(e) => {
|
|
40
|
+
const { newDate } = e.detail;
|
|
41
|
+
if (this.plan) {
|
|
42
|
+
this.dispatchEvent(new CustomEvent('updateDate', {
|
|
43
|
+
detail: { plan: this.plan, newDate },
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
}}
|
|
47
|
+
.plan=${this.plan}
|
|
48
|
+
></ia-mgc-edit-date>
|
|
49
|
+
<hr />
|
|
50
|
+
<ia-mgc-cancel-plan
|
|
51
|
+
.plan=${this.plan}
|
|
52
|
+
@cancelPlan=${() => {
|
|
53
|
+
this.dispatchEvent(new Event('cancelPlan'));
|
|
54
|
+
}}
|
|
55
|
+
></ia-mgc-cancel-plan>
|
|
56
|
+
<hr />
|
|
33
57
|
<p class="email-edit-plan">
|
|
34
58
|
Need to update your plan further? Please email us at
|
|
35
59
|
<a href=${this.mailToText}>donations@archive.org</a>.
|
|
@@ -44,9 +68,6 @@ let IauxEditPlanForm = class IauxEditPlanForm extends LitElement {
|
|
|
44
68
|
__decorate([
|
|
45
69
|
property({ type: Object })
|
|
46
70
|
], IauxEditPlanForm.prototype, "plan", void 0);
|
|
47
|
-
__decorate([
|
|
48
|
-
property({ type: Object })
|
|
49
|
-
], IauxEditPlanForm.prototype, "cancelPlanHandler", void 0);
|
|
50
71
|
__decorate([
|
|
51
72
|
property({ type: Object })
|
|
52
73
|
], IauxEditPlanForm.prototype, "updateAmountHandler", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit-plan-form.js","sourceRoot":"","sources":["../../src/edit-plan-form.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG5D,OAAO,wBAAwB,CAAC;AAChC,OAAO,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"edit-plan-form.js","sourceRoot":"","sources":["../../src/edit-plan-form.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG5D,OAAO,wBAAwB,CAAC;AAChC,OAAO,sBAAsB,CAAC;AAC9B,OAAO,wBAAwB,CAAC;AAKhC,IAAa,gBAAgB,GAA7B,MAAa,gBAAiB,SAAQ,UAAU;IAa9C,gBAAgB;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,aAAa,CAAC,MAA0B;QACtC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CACnC,yBAAyB,CACL,CAAC;QACvB,UAAW,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,WAAW,CAAC,MAA0B;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAoB,CAAC;QAC3E,QAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;;kBAGG,IAAI,CAAC,IAAI;0BACD,CAAC,CAAc,EAAE,EAAE;;YACjC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC;YAC/D,IAAI,IAAI,CAAC,IAAI,EAAE;gBACb,MAAA,IAAI,CAAC,mBAAmB,qDAAG,IAAI,CAAC,IAAI,EAAE;oBACpC,MAAM;oBACN,UAAU;oBACV,SAAS;oBACT,UAAU;iBACX,CAAC,CAAC;aACJ;QACH,CAAC;;;;wBAIa,CAAC,CAAc,EAAE,EAAE;YAC/B,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC;YAC7B,IAAI,IAAI,CAAC,IAAI,EAAE;gBACb,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,YAAY,EAAE;oBAC5B,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE;iBACrC,CAAC,CACH,CAAC;aACH;QACH,CAAC;kBACO,IAAI,CAAC,IAAI;;;;kBAIT,IAAI,CAAC,IAAI;wBACH,GAAG,EAAE;YACjB,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;QAC9C,CAAC;;;;;oBAKS,IAAI,CAAC,UAAU;;;KAG9B,CAAC;IACJ,CAAC;IAED,UAAU;QACR,OAAO,6EAA6E,CAAC;IACvF,CAAC;CACF,CAAA;AA9E6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CAAoB;AAEnB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6DAQjB;AAXC,gBAAgB;IAD5B,aAAa,CAAC,kBAAkB,CAAC;GACrB,gBAAgB,CA+E5B;SA/EY,gBAAgB","sourcesContent":["import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport type { MonthlyPlan } from './models/plan';\nimport './form-sections/amount';\nimport './form-sections/date';\nimport './form-sections/cancel';\nimport type { MGCEditPlanAmount } from './form-sections/amount';\nimport type { MGCEditPlanDate } from './form-sections/date';\n\n@customElement('ia-mgc-edit-plan')\nexport class IauxEditPlanForm extends LitElement {\n @property({ type: Object }) plan?: MonthlyPlan;\n\n @property({ type: Object }) updateAmountHandler?: (\n plan: MonthlyPlan,\n amountUpdates: {\n amount: number;\n baseAmount: number;\n coverFees: boolean;\n feeCovered: number;\n }\n ) => void;\n\n createRenderRoot() {\n return this;\n }\n\n amountUpdates(status: 'success' | 'fail') {\n const amountForm = this.querySelector(\n 'ia-mgc-edit-plan-amount'\n ) as MGCEditPlanAmount;\n amountForm!.amountUpdated(status);\n }\n\n dateUpdates(status: 'success' | 'fail') {\n const dateForm = this.querySelector('ia-mgc-edit-date') as MGCEditPlanDate;\n dateForm!.dateUpdated(status);\n }\n\n render() {\n return html`\n <section class=\"mgc-edit-plan\">\n <ia-mgc-edit-plan-amount\n .plan=${this.plan}\n @updateAmount=${(e: CustomEvent) => {\n const { amount, baseAmount, coverFees, feeCovered } = e.detail;\n if (this.plan) {\n this.updateAmountHandler?.(this.plan, {\n amount,\n baseAmount,\n coverFees,\n feeCovered,\n });\n }\n }}\n ></ia-mgc-edit-plan-amount>\n <hr />\n <ia-mgc-edit-date\n @updateDate=${(e: CustomEvent) => {\n const { newDate } = e.detail;\n if (this.plan) {\n this.dispatchEvent(\n new CustomEvent('updateDate', {\n detail: { plan: this.plan, newDate },\n })\n );\n }\n }}\n .plan=${this.plan}\n ></ia-mgc-edit-date>\n <hr />\n <ia-mgc-cancel-plan\n .plan=${this.plan}\n @cancelPlan=${() => {\n this.dispatchEvent(new Event('cancelPlan'));\n }}\n ></ia-mgc-cancel-plan>\n <hr />\n <p class=\"email-edit-plan\">\n Need to update your plan further? Please email us at\n <a href=${this.mailToText}>donations@archive.org</a>.\n </p>\n </section>\n `;\n }\n\n mailToText(): string {\n return `mailto:donations@archive.org?subject=I'd like to update my monthly donation`;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"amount.js","sourceRoot":"","sources":["../../../src/form-sections/amount.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n LitElement,\n html,\n PropertyValues,\n nothing,\n css,\n TemplateResult,\n} from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport '@internetarchive/donation-form-section';\nimport {\n DonationPaymentInfo,\n DonationType,\n} from '@internetarchive/donation-form-data-models';\n\nimport type { MonthlyPlan } from '../models/plan';\nimport '../presentational/ia-button';\nimport type { IauxButton } from '../presentational/ia-button';\nimport '../presentational/mgc-update-status';\n\n@customElement('ia-mgc-edit-plan-amount')\nexport class MGCEditPlanAmount extends LitElement {\n @property({ type: Object }) plan?: MonthlyPlan;\n\n // captures the changes made to the amount && calculates the total amount with fees\n @property({ type: Object }) donationPaymentInfo?: DonationPaymentInfo;\n\n @property({ type: Number }) newAmount: number = 0;\n\n @property({ type: Boolean, reflect: true }) currentlyEditing: boolean = false;\n\n @property({ type: Boolean }) coverFees: boolean = false;\n\n @property({ type: String }) updateMessage: string = '';\n\n @property({ type: String }) errorMessage: string = '';\n\n @property({ type: String }) updateStatus: 'success' | 'fail' | '' = '';\n\n @query('form') form!: HTMLFormElement;\n\n updated(changed: PropertyValues) {\n if (changed.has('plan') && this.plan) {\n this.captureAmountChanges();\n }\n if (changed.has('coverFees')) {\n this.captureAmountChanges();\n }\n if (changed.has('currentlyEditing') && this.currentlyEditing) {\n this.form.focus();\n }\n\n if (changed.has('donationPaymentInfo') && !this.donationPaymentInfo) {\n this.captureAmountChanges();\n }\n }\n\n protected render() {\n return html`\n <section>\n <donation-form-section badgemode=\"hidebadge\" headline=\"Amount\">\n ${!this.currentlyEditing\n ? html` <p class=\"current-amount\">\n USD $${this.plan?.amount}\n <ia-mgc-update-status .status=${this.updateStatus}\n >${this.updateMessage}</ia-mgc-update-status\n >\n </p>\n <ia-button\n id=\"edit-amount\"\n class=\"ia-button link\"\n .clickHandler=${() => {\n this.currentlyEditing = true;\n this.clearStatusMessaging();\n }}\n >\n Edit...\n </ia-button>`\n : nothing}\n ${this.currentlyEditing ? this.editAmountForm : nothing}\n </donation-form-section>\n </section>\n `;\n }\n\n /* External Function that is called by consumer to tell the form there has been data update */\n async amountUpdated(status: 'success' | 'fail') {\n this.clearInputField();\n\n this.updateStatus = status;\n this.updateMessage =\n status === 'success' ? 'Amount updated' : 'Failed. Try again.';\n\n if (status === 'success') {\n this.closeForm();\n await this.updateComplete;\n\n this.updateStatus = status;\n this.updateMessage = 'Amount updated';\n\n return;\n }\n\n (\n this.form.querySelector('ia-button#update-amount') as IauxButton\n ).isDisabled = false;\n\n this.captureAmountChanges();\n\n await this.updateComplete;\n }\n\n /* Dispatches amount change request */\n requestAmountUpdate(e: Event): void {\n e.preventDefault();\n\n const input = this.form.querySelector(\n 'input[name=\"amount\"]'\n ) as HTMLInputElement;\n this.newAmount = Number(input.value);\n\n this.captureAmountChanges(this.newAmount);\n\n console.log('<plan-amount> - update amount', {\n newValue: this.newAmount,\n oldValue: this.plan?.plan.amount,\n display: this.donationPaymentInfo?.amount,\n });\n const newAmount = Number(\n DonationPaymentInfo.calculateTotal(\n Number(this.donationPaymentInfo?.amount),\n this.coverFees\n )\n );\n this.dispatchEvent(\n new CustomEvent('updateAmount', {\n detail: {\n plan: this.plan,\n amount: newAmount,\n baseAmount: this.donationPaymentInfo?.amount,\n coverFees: this.coverFees,\n feeCovered: this.donationPaymentInfo?.feeAmountCovered,\n },\n })\n );\n }\n\n /* captures form changes */\n captureAmountChanges(newAmount?: number) {\n if (!this.donationPaymentInfo && this.plan) {\n this.donationPaymentInfo = new DonationPaymentInfo({\n donationType: DonationType.Monthly,\n amount: 0,\n coverFees: true,\n });\n return;\n }\n\n let newPlan;\n if (newAmount) {\n newPlan = new DonationPaymentInfo({\n donationType: DonationType.Monthly,\n amount: newAmount,\n coverFees: true,\n });\n } else {\n const amount = this.donationPaymentInfo\n ? this.donationPaymentInfo.amount\n : this.plan!.amount;\n\n newPlan = new DonationPaymentInfo({\n donationType: DonationType.Monthly,\n amount,\n coverFees: true,\n });\n }\n\n this.donationPaymentInfo = newPlan;\n }\n\n closeForm() {\n this.clearInputField();\n this.clearStatusMessaging();\n this.currentlyEditing = false;\n this.coverFees = false;\n this.errorMessage = '';\n }\n\n clearInputField() {\n const input = this.form.querySelector(\n 'input[name=\"amount\"]'\n ) as HTMLInputElement;\n input.value = '';\n this.newAmount = 0;\n this.donationPaymentInfo = undefined;\n }\n\n async clearStatusMessaging() {\n this.errorMessage = '';\n this.updateMessage = '';\n this.updateStatus = '';\n await this.updateComplete;\n }\n\n /* DISPLAY */\n totalAmountWithFees(): number {\n if (this.newAmount === 0) {\n return 0;\n }\n\n return DonationPaymentInfo.calculateTotal(this.newAmount, this.coverFees);\n }\n\n get coveredFeesText() {\n return `I'll generously add $${this.donationPaymentInfo?.feeAmountCovered} to cover fees.`;\n }\n\n get editAmountForm(): TemplateResult {\n return html`\n <section>\n <form id=\"edit-plan-amount\">\n <p>Current donation amount: $${this.plan?.amount}</p>\n <div>\n $\n <input\n type=\"number\"\n id=\"amount\"\n name=\"amount\"\n required=\"true\"\n @focus=${() => this.clearStatusMessaging()}\n @input=${(e: Event) => {\n const newAmount = Number((e.target as HTMLInputElement).value);\n this.captureAmountChanges(newAmount);\n this.newAmount = newAmount;\n }}\n />\n / month\n </div>\n <div>\n <div class=\"checkbox-option-container\">\n <input\n type=\"checkbox\"\n id=\"cover-fees\"\n tabindex=\"0\"\n @change=${(e: Event) => {\n const input = e.target as HTMLInputElement;\n const coverFees = input.checked;\n this.coverFees = coverFees;\n this.captureAmountChanges();\n }}\n />\n <label for=\"cover-fees\">${this.coveredFeesText}</label>\n </div>\n <p>Total: USD $${this.totalAmountWithFees()}</p>\n <div class=\"cta-container\">\n <ia-button\n class=\"ia-button secondary\"\n .clickHandler=${(e: Event) => {\n e.preventDefault();\n this.closeForm();\n }}\n >\n Cancel\n </ia-button>\n <ia-button\n id=\"update-amount\"\n class=\"ia-button primary\"\n type=\"submit\"\n .clickHandler=${async (e: Event, iaButton: IauxButton) => {\n this.clearStatusMessaging();\n\n if (!this.newAmount) {\n this.errorMessage = 'Please enter a new amount';\n return;\n }\n\n // eslint-disable-next-line no-param-reassign\n (iaButton as IauxButton).isDisabled = true;\n await iaButton.updateComplete;\n\n // check if request is in range\n const input = this.form.querySelector(\n 'input[name=\"amount\"]'\n ) as HTMLInputElement;\n const requestedAmount = Number(input.value) ?? 0;\n const amountTooLow = requestedAmount < 1;\n const amountTooHigh = requestedAmount >= 9999;\n if (amountTooLow) {\n this.errorMessage = 'Please enter a valid amount';\n }\n if (amountTooHigh) {\n this.errorMessage =\n 'Amount must be less than $9,999. Would you like to donate more? Please contact us at donations@archive.org';\n }\n if (amountTooHigh || amountTooLow) {\n // eslint-disable-next-line no-param-reassign\n (iaButton as IauxButton).isDisabled = false;\n await iaButton.updateComplete;\n return;\n }\n\n this.requestAmountUpdate(e);\n }}\n >\n Update\n </ia-button>\n <ia-mgc-update-status .status=${this.updateStatus}\n >${this.updateMessage}</ia-mgc-update-status\n >\n </div>\n </div>\n <p class=\"error\">${this.errorMessage}</p>\n </form>\n </section>\n `;\n }\n\n static styles = css`\n input#amount {\n width: 50px;\n }\n\n .cta-container {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-content: center;\n justify-content: flex-start;\n align-items: center;\n gap: 10px;\n }\n\n p.error {\n color: var(--mgc-warning-color-dark, #bb0505);\n }\n\n ia-mgc-update-status {\n display: inline-block;\n margin-left: 1rem;\n }\n\n .checkbox-option-container {\n margin: 10px 0;\n display: flex;\n }\n `;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"amount.js","sourceRoot":"","sources":["../../../src/form-sections/amount.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n LitElement,\n html,\n PropertyValues,\n nothing,\n css,\n TemplateResult,\n} from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport '@internetarchive/donation-form-section';\nimport {\n DonationPaymentInfo,\n DonationType,\n} from '@internetarchive/donation-form-data-models';\n\nimport type { MonthlyPlan } from '../models/plan';\nimport '../presentational/ia-button';\nimport type { IauxButton } from '../presentational/ia-button';\nimport '../presentational/mgc-update-status';\n\n@customElement('ia-mgc-edit-plan-amount')\nexport class MGCEditPlanAmount extends LitElement {\n @property({ type: Object }) plan?: MonthlyPlan;\n\n // captures the changes made to the amount && calculates the total amount with fees\n @property({ type: Object }) donationPaymentInfo?: DonationPaymentInfo;\n\n @property({ type: Number }) newAmount: number = 0;\n\n @property({ type: Boolean, reflect: true }) currentlyEditing: boolean = false;\n\n @property({ type: Boolean }) coverFees: boolean = false;\n\n @property({ type: String }) updateMessage: string = '';\n\n @property({ type: String }) errorMessage: string = '';\n\n @property({ type: String }) updateStatus: 'success' | 'fail' | '' = '';\n\n @query('form') form!: HTMLFormElement;\n\n updated(changed: PropertyValues) {\n if (changed.has('plan') && this.plan) {\n this.captureAmountChanges();\n }\n if (changed.has('coverFees')) {\n this.captureAmountChanges();\n }\n if (changed.has('currentlyEditing') && this.currentlyEditing) {\n this.form.focus();\n }\n\n if (changed.has('donationPaymentInfo') && !this.donationPaymentInfo) {\n this.captureAmountChanges();\n }\n }\n\n protected render() {\n return html`\n <section>\n <donation-form-section badgemode=\"hidebadge\" headline=\"Amount\">\n ${!this.currentlyEditing\n ? html` <p class=\"current-amount\">\n USD $${this.plan?.amount}\n <ia-mgc-update-status .status=${this.updateStatus}\n >${this.updateMessage}</ia-mgc-update-status\n >\n </p>\n <ia-button\n id=\"edit-amount\"\n class=\"ia-button link\"\n .clickHandler=${() => {\n this.currentlyEditing = true;\n this.clearStatusMessaging();\n }}\n >\n Edit...\n </ia-button>`\n : nothing}\n ${this.currentlyEditing ? this.editAmountForm : nothing}\n </donation-form-section>\n </section>\n `;\n }\n\n /* External Function that is called by consumer to tell the form there has been data update */\n async amountUpdated(status: 'success' | 'fail') {\n this.clearInputField();\n\n this.updateStatus = status;\n this.updateMessage =\n status === 'success' ? 'Amount updated' : 'Failed. Try again.';\n\n if (status === 'success') {\n this.closeForm();\n await this.updateComplete;\n\n this.updateStatus = status;\n this.updateMessage = 'Amount updated';\n\n return;\n }\n\n (\n this.form.querySelector('ia-button#update-amount') as IauxButton\n ).isDisabled = false;\n\n this.captureAmountChanges();\n\n await this.updateComplete;\n }\n\n /* Dispatches amount change request */\n requestAmountUpdate(e: Event): void {\n e.preventDefault();\n\n const input = this.form.querySelector(\n 'input[name=\"amount\"]'\n ) as HTMLInputElement;\n this.newAmount = Number(input.value);\n\n this.captureAmountChanges(this.newAmount);\n\n console.log('<plan-amount> - update amount', {\n newValue: this.newAmount,\n oldValue: this.plan?.plan.amount,\n display: this.donationPaymentInfo?.amount,\n });\n const newAmount = Number(\n DonationPaymentInfo.calculateTotal(\n Number(this.donationPaymentInfo?.amount),\n this.coverFees\n )\n );\n this.dispatchEvent(\n new CustomEvent('updateAmount', {\n detail: {\n plan: this.plan,\n amount: newAmount,\n baseAmount: this.donationPaymentInfo?.amount,\n coverFees: this.coverFees,\n feeCovered: this.donationPaymentInfo?.feeAmountCovered,\n },\n })\n );\n }\n\n /* captures form changes */\n captureAmountChanges(newAmount?: number) {\n if (!this.donationPaymentInfo && this.plan) {\n this.donationPaymentInfo = new DonationPaymentInfo({\n donationType: DonationType.Monthly,\n amount: 0,\n coverFees: true,\n });\n return;\n }\n\n let newPlan;\n if (newAmount) {\n newPlan = new DonationPaymentInfo({\n donationType: DonationType.Monthly,\n amount: newAmount,\n coverFees: true,\n });\n } else {\n const amount = this.donationPaymentInfo\n ? this.donationPaymentInfo.amount\n : this.plan!.amount;\n\n newPlan = new DonationPaymentInfo({\n donationType: DonationType.Monthly,\n amount,\n coverFees: true,\n });\n }\n\n this.donationPaymentInfo = newPlan;\n }\n\n closeForm() {\n this.clearInputField();\n this.clearStatusMessaging();\n this.currentlyEditing = false;\n this.coverFees = false;\n this.errorMessage = '';\n }\n\n clearInputField() {\n const input = this.form.querySelector(\n 'input[name=\"amount\"]'\n ) as HTMLInputElement;\n input.value = '';\n this.newAmount = 0;\n this.donationPaymentInfo = undefined;\n }\n\n async clearStatusMessaging() {\n this.errorMessage = '';\n this.updateMessage = '';\n this.updateStatus = '';\n await this.updateComplete;\n }\n\n /* DISPLAY */\n totalAmountWithFees(): number {\n if (this.newAmount === 0) {\n return 0;\n }\n\n return DonationPaymentInfo.calculateTotal(this.newAmount, this.coverFees);\n }\n\n get coveredFeesText() {\n return `I'll generously add $${this.donationPaymentInfo?.feeAmountCovered} to cover fees.`;\n }\n\n get editAmountForm(): TemplateResult {\n return html`\n <section>\n <form id=\"edit-plan-amount\">\n <p>Current donation amount: $${this.plan?.amount}</p>\n <div>\n $\n <input\n min=\"1\"\n max=\"9999\"\n type=\"number\"\n id=\"amount\"\n name=\"amount\"\n required=\"true\"\n @focus=${() => this.clearStatusMessaging()}\n @input=${(e: Event) => {\n const newAmount = Number((e.target as HTMLInputElement).value);\n this.captureAmountChanges(newAmount);\n this.newAmount = newAmount;\n }}\n />\n / month\n </div>\n <div>\n <div class=\"checkbox-option-container\">\n <input\n type=\"checkbox\"\n id=\"cover-fees\"\n tabindex=\"0\"\n @change=${(e: Event) => {\n const input = e.target as HTMLInputElement;\n const coverFees = input.checked;\n this.coverFees = coverFees;\n this.captureAmountChanges();\n }}\n />\n <label for=\"cover-fees\">${this.coveredFeesText}</label>\n </div>\n <p>Total: USD $${this.totalAmountWithFees()}</p>\n <div class=\"cta-container\">\n <ia-button\n class=\"ia-button secondary\"\n .clickHandler=${(e: Event) => {\n e.preventDefault();\n this.closeForm();\n }}\n >\n Cancel\n </ia-button>\n <ia-button\n id=\"update-amount\"\n class=\"ia-button primary\"\n type=\"submit\"\n .clickHandler=${async (e: Event, iaButton: IauxButton) => {\n this.clearStatusMessaging();\n\n if (!this.newAmount) {\n this.errorMessage = 'Please enter a new amount';\n return;\n }\n\n // eslint-disable-next-line no-param-reassign\n (iaButton as IauxButton).isDisabled = true;\n await iaButton.updateComplete;\n\n // check if request is in range\n const input = this.form.querySelector(\n 'input[name=\"amount\"]'\n ) as HTMLInputElement;\n const requestedAmount = Number(input.value) ?? 0;\n const amountTooLow = requestedAmount < 1;\n const amountTooHigh = requestedAmount >= 9999;\n if (amountTooLow) {\n this.errorMessage = 'Please enter a valid amount';\n }\n if (amountTooHigh) {\n this.errorMessage =\n 'Amount must be less than $9,999. Would you like to donate more? Please contact us at donations@archive.org';\n }\n if (amountTooHigh || amountTooLow) {\n // eslint-disable-next-line no-param-reassign\n (iaButton as IauxButton).isDisabled = false;\n await iaButton.updateComplete;\n return;\n }\n\n this.requestAmountUpdate(e);\n }}\n >\n Update\n </ia-button>\n <ia-mgc-update-status .status=${this.updateStatus}\n >${this.updateMessage}</ia-mgc-update-status\n >\n </div>\n </div>\n <p class=\"error\">${this.errorMessage}</p>\n </form>\n </section>\n `;\n }\n\n static styles = css`\n input#amount {\n width: 50px;\n }\n\n .cta-container {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-content: center;\n justify-content: flex-start;\n align-items: center;\n gap: 10px;\n }\n\n p.error {\n color: var(--mgc-warning-color-dark, #bb0505);\n }\n\n ia-mgc-update-status {\n display: inline-block;\n margin-left: 1rem;\n }\n\n .checkbox-option-container {\n margin: 10px 0;\n display: flex;\n }\n `;\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LitElement, PropertyValues, TemplateResult } from 'lit';
|
|
2
|
+
import '@internetarchive/donation-form-section';
|
|
3
|
+
import type { MonthlyPlan } from '../models/plan';
|
|
4
|
+
import '../presentational/ia-button';
|
|
5
|
+
import type { IauxButton } from '../presentational/ia-button';
|
|
6
|
+
import '../presentational/mgc-update-status';
|
|
7
|
+
declare type InvalidDateErrorCode = 'invalid_date' | 'date_too_early' | 'second_donation_this_month' | 'date_out_of_range' | 'same_next_billing_date' | '';
|
|
8
|
+
export declare class MGCEditPlanDate extends LitElement {
|
|
9
|
+
plan?: MonthlyPlan;
|
|
10
|
+
newDate?: string;
|
|
11
|
+
currentlyEditing: boolean;
|
|
12
|
+
allowEditing: boolean;
|
|
13
|
+
updateMessage: string;
|
|
14
|
+
errorMessage: string;
|
|
15
|
+
warningMessage: string;
|
|
16
|
+
updateStatus: 'success' | 'fail' | '';
|
|
17
|
+
form: HTMLFormElement;
|
|
18
|
+
formSubmitButton: IauxButton;
|
|
19
|
+
dateInput: HTMLInputElement;
|
|
20
|
+
willUpdate(changed: PropertyValues): void;
|
|
21
|
+
updated(changed: PropertyValues): void;
|
|
22
|
+
protected render(): TemplateResult<1>;
|
|
23
|
+
dateUpdated(status: 'success' | 'fail'): Promise<void>;
|
|
24
|
+
requestDateUpdate(e: Event): void;
|
|
25
|
+
closeForm(): void;
|
|
26
|
+
clearInputField(): void;
|
|
27
|
+
formatDateToYYYYMMDD(date: Date): string;
|
|
28
|
+
clearStatusMessaging(): Promise<void>;
|
|
29
|
+
validateChosenDate(dateString: string): {
|
|
30
|
+
valid: boolean;
|
|
31
|
+
errorCode: InvalidDateErrorCode | '';
|
|
32
|
+
};
|
|
33
|
+
get minDate(): string;
|
|
34
|
+
get maxDate(): string;
|
|
35
|
+
get editDateForm(): TemplateResult;
|
|
36
|
+
static styles: import("lit").CSSResult;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { LitElement, html, nothing, css, } from 'lit';
|
|
3
|
+
import { customElement, property, query } from 'lit/decorators.js';
|
|
4
|
+
import '@internetarchive/donation-form-section';
|
|
5
|
+
import '../presentational/ia-button';
|
|
6
|
+
import '../presentational/mgc-update-status';
|
|
7
|
+
var InvalidDateErrorMessages;
|
|
8
|
+
(function (InvalidDateErrorMessages) {
|
|
9
|
+
InvalidDateErrorMessages["invalid_date"] = "Please enter a valid date format (YYYY-MM-DD)";
|
|
10
|
+
InvalidDateErrorMessages["date_too_early"] = "Date must be at least tomorrow.";
|
|
11
|
+
InvalidDateErrorMessages["second_donation_this_month"] = "The date you selected will result in an additional donation for this month.";
|
|
12
|
+
InvalidDateErrorMessages["date_out_of_range"] = "New donation date must be within the next 12 months.";
|
|
13
|
+
InvalidDateErrorMessages["same_next_billing_date"] = "";
|
|
14
|
+
})(InvalidDateErrorMessages || (InvalidDateErrorMessages = {}));
|
|
15
|
+
let MGCEditPlanDate = class MGCEditPlanDate extends LitElement {
|
|
16
|
+
constructor() {
|
|
17
|
+
super(...arguments);
|
|
18
|
+
this.currentlyEditing = false;
|
|
19
|
+
this.allowEditing = false;
|
|
20
|
+
this.updateMessage = '';
|
|
21
|
+
this.errorMessage = '';
|
|
22
|
+
this.warningMessage = '';
|
|
23
|
+
this.updateStatus = '';
|
|
24
|
+
}
|
|
25
|
+
willUpdate(changed) {
|
|
26
|
+
if (this.dateInput && changed.has('plan') && this.plan) {
|
|
27
|
+
this.dateInput.setAttribute('min', this.minDate);
|
|
28
|
+
this.dateInput.setAttribute('max', this.maxDate);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
updated(changed) {
|
|
32
|
+
if (changed.has('currentlyEditing') && this.currentlyEditing) {
|
|
33
|
+
this.dateInput.focus();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
render() {
|
|
37
|
+
var _a;
|
|
38
|
+
return html `
|
|
39
|
+
<section>
|
|
40
|
+
<donation-form-section
|
|
41
|
+
badgemode="hidebadge"
|
|
42
|
+
headline="Change next donation date"
|
|
43
|
+
>
|
|
44
|
+
${!this.currentlyEditing
|
|
45
|
+
? html ` <p class="current-date">
|
|
46
|
+
${(_a = this.plan) === null || _a === void 0 ? void 0 : _a.nextBillingDateLocale}
|
|
47
|
+
<ia-mgc-update-status .status=${this.updateStatus}
|
|
48
|
+
>${this.updateMessage}</ia-mgc-update-status
|
|
49
|
+
>
|
|
50
|
+
</p>
|
|
51
|
+
<ia-button
|
|
52
|
+
id="open-edit-date-form"
|
|
53
|
+
class="ia-button link"
|
|
54
|
+
.clickHandler=${() => {
|
|
55
|
+
this.currentlyEditing = true;
|
|
56
|
+
this.clearStatusMessaging();
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
59
|
+
Edit...
|
|
60
|
+
</ia-button>`
|
|
61
|
+
: nothing}
|
|
62
|
+
${this.currentlyEditing ? this.editDateForm : nothing}
|
|
63
|
+
</donation-form-section>
|
|
64
|
+
</section>
|
|
65
|
+
`;
|
|
66
|
+
}
|
|
67
|
+
/* External Function that is called by consumer to tell the form there has been data update */
|
|
68
|
+
async dateUpdated(status) {
|
|
69
|
+
this.clearInputField();
|
|
70
|
+
this.updateStatus = status;
|
|
71
|
+
this.updateMessage =
|
|
72
|
+
status === 'success'
|
|
73
|
+
? 'Date updated'
|
|
74
|
+
: 'Failed to update date, please try again';
|
|
75
|
+
if (status === 'success') {
|
|
76
|
+
this.closeForm();
|
|
77
|
+
await this.updateComplete;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.allowEditing = false;
|
|
81
|
+
await this.updateComplete;
|
|
82
|
+
}
|
|
83
|
+
/* Dispatches edit-date change request */
|
|
84
|
+
requestDateUpdate(e) {
|
|
85
|
+
e.preventDefault();
|
|
86
|
+
this.dispatchEvent(new CustomEvent('updateDate', {
|
|
87
|
+
detail: {
|
|
88
|
+
plan: this.plan,
|
|
89
|
+
newDate: this.newDate,
|
|
90
|
+
},
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
closeForm() {
|
|
94
|
+
this.clearInputField();
|
|
95
|
+
this.clearStatusMessaging();
|
|
96
|
+
this.currentlyEditing = false;
|
|
97
|
+
this.allowEditing = false;
|
|
98
|
+
}
|
|
99
|
+
clearInputField() {
|
|
100
|
+
this.dateInput.value = '';
|
|
101
|
+
this.newDate = undefined;
|
|
102
|
+
}
|
|
103
|
+
formatDateToYYYYMMDD(date) {
|
|
104
|
+
const year = date.getFullYear();
|
|
105
|
+
const month = String(date.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed
|
|
106
|
+
const dateNum = String(date.getDate()).padStart(2, '0');
|
|
107
|
+
return `${year}-${month}-${dateNum}`;
|
|
108
|
+
}
|
|
109
|
+
async clearStatusMessaging() {
|
|
110
|
+
this.errorMessage = '';
|
|
111
|
+
this.warningMessage = '';
|
|
112
|
+
this.updateMessage = '';
|
|
113
|
+
this.updateStatus = '';
|
|
114
|
+
await this.updateComplete;
|
|
115
|
+
}
|
|
116
|
+
/* @param string dateString - YYYYY-MM-DD */
|
|
117
|
+
validateChosenDate(dateString) {
|
|
118
|
+
var _a, _b, _c;
|
|
119
|
+
if (!dateString) {
|
|
120
|
+
return {
|
|
121
|
+
valid: false,
|
|
122
|
+
errorCode: 'invalid_date',
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
let validDate;
|
|
126
|
+
try {
|
|
127
|
+
validDate = new Date(`${dateString}T00:00:00`);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
return {
|
|
131
|
+
valid: false,
|
|
132
|
+
errorCode: 'invalid_date',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
// Check if minimum date is at least tomorrow
|
|
136
|
+
const today = new Date();
|
|
137
|
+
today.setHours(0, 0, 0, 0);
|
|
138
|
+
const tomorrow = new Date(today);
|
|
139
|
+
tomorrow.setDate(today.getDate() + 1); // Set to tomorrow
|
|
140
|
+
const chosenDate = new Date(validDate);
|
|
141
|
+
chosenDate.setHours(0, 0, 0, 0);
|
|
142
|
+
// check input value against next billing date
|
|
143
|
+
const isNextBillingDate = ((_a = this.plan) === null || _a === void 0 ? void 0 : _a.nextBillingDate)
|
|
144
|
+
? this.formatDateToYYYYMMDD(new Date(this.plan.nextBillingDate)) ===
|
|
145
|
+
this.formatDateToYYYYMMDD(chosenDate)
|
|
146
|
+
: false;
|
|
147
|
+
if (isNextBillingDate) {
|
|
148
|
+
return {
|
|
149
|
+
valid: false,
|
|
150
|
+
errorCode: 'same_next_billing_date',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (chosenDate < today) {
|
|
154
|
+
return {
|
|
155
|
+
valid: false,
|
|
156
|
+
errorCode: 'date_too_early',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// Check if the new date is within the next 12 months
|
|
160
|
+
const twelveMonthsFromNow = new Date(today);
|
|
161
|
+
twelveMonthsFromNow.setFullYear(twelveMonthsFromNow.getFullYear() + 1);
|
|
162
|
+
if (chosenDate > twelveMonthsFromNow) {
|
|
163
|
+
return {
|
|
164
|
+
valid: false,
|
|
165
|
+
errorCode: 'date_out_of_range',
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
// Check if there has been a donation in the last month
|
|
169
|
+
const lastDonationDate = ((_b = this.plan) === null || _b === void 0 ? void 0 : _b.payment.lastBillingDate.date)
|
|
170
|
+
? new Date((_c = this.plan) === null || _c === void 0 ? void 0 : _c.payment.lastBillingDate.date)
|
|
171
|
+
: null;
|
|
172
|
+
if (lastDonationDate) {
|
|
173
|
+
const lastDonationMonth = lastDonationDate.getMonth();
|
|
174
|
+
const lastDonationYear = lastDonationDate.getFullYear();
|
|
175
|
+
const thisYear = validDate.getFullYear();
|
|
176
|
+
const thisMonth = validDate.getMonth();
|
|
177
|
+
const isInLastMonth = thisYear === lastDonationYear && thisMonth === lastDonationMonth;
|
|
178
|
+
if (isInLastMonth) {
|
|
179
|
+
return {
|
|
180
|
+
valid: true,
|
|
181
|
+
errorCode: 'second_donation_this_month',
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
valid: true,
|
|
187
|
+
errorCode: '',
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/* DISPLAY */
|
|
191
|
+
get minDate() {
|
|
192
|
+
const today = new Date();
|
|
193
|
+
const tomorrow = new Date(today);
|
|
194
|
+
tomorrow.setDate(today.getDate() + 1); // Set to tomorrow
|
|
195
|
+
const year = tomorrow.getFullYear();
|
|
196
|
+
const month = String(tomorrow.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed
|
|
197
|
+
const dateString = String(tomorrow.getDate()).padStart(2, '0');
|
|
198
|
+
return `${year}-${month}-${dateString}`;
|
|
199
|
+
}
|
|
200
|
+
get maxDate() {
|
|
201
|
+
const today = new Date();
|
|
202
|
+
const year = today.getFullYear() + 1; // Allow up to one year in the future
|
|
203
|
+
const month = String(today.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed
|
|
204
|
+
const dateString = String(today.getDate()).padStart(2, '0');
|
|
205
|
+
return `${year}-${month}-${dateString}`;
|
|
206
|
+
}
|
|
207
|
+
get editDateForm() {
|
|
208
|
+
var _a, _b, _c, _d, _e;
|
|
209
|
+
const nextBillingDateYYYYMMDD = ((_a = this.plan) === null || _a === void 0 ? void 0 : _a.nextBillingDate)
|
|
210
|
+
? this.formatDateToYYYYMMDD(new Date(this.plan.nextBillingDate))
|
|
211
|
+
: '';
|
|
212
|
+
const inputValueToUse = (_c = (_b = this.dateInput) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : nextBillingDateYYYYMMDD;
|
|
213
|
+
return html `
|
|
214
|
+
<section>
|
|
215
|
+
<form id="edit-date">
|
|
216
|
+
<p id="form-info-last-donation-date">
|
|
217
|
+
Last donation date: ${(_d = this.plan) === null || _d === void 0 ? void 0 : _d.lastBillingDateLocale}
|
|
218
|
+
</p>
|
|
219
|
+
|
|
220
|
+
<p id="form-info-next-donation-date">
|
|
221
|
+
Next donation date: ${(_e = this.plan) === null || _e === void 0 ? void 0 : _e.nextBillingDateLocale}
|
|
222
|
+
</p>
|
|
223
|
+
<div class="date-holder">
|
|
224
|
+
<input
|
|
225
|
+
required
|
|
226
|
+
type="date"
|
|
227
|
+
id="edit-date"
|
|
228
|
+
name="edit-date"
|
|
229
|
+
min=${this.minDate}
|
|
230
|
+
max=${this.maxDate}
|
|
231
|
+
.value=${inputValueToUse}
|
|
232
|
+
@focus=${() => this.clearStatusMessaging()}
|
|
233
|
+
@change=${async () => {
|
|
234
|
+
this.clearStatusMessaging();
|
|
235
|
+
await this.updateComplete;
|
|
236
|
+
const inputValue = this.dateInput.value;
|
|
237
|
+
const { valid, errorCode } = this.validateChosenDate(inputValue);
|
|
238
|
+
this.allowEditing = valid;
|
|
239
|
+
if (errorCode) {
|
|
240
|
+
if (errorCode === 'second_donation_this_month') {
|
|
241
|
+
this.errorMessage = InvalidDateErrorMessages[errorCode];
|
|
242
|
+
this.warningMessage =
|
|
243
|
+
'You have already made a donation this month.';
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
this.errorMessage = InvalidDateErrorMessages[errorCode];
|
|
247
|
+
this.newDate = undefined;
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const chosenDate = new Date(`${inputValue}T00:00:00`);
|
|
252
|
+
const newDate = new Date(chosenDate).toISOString();
|
|
253
|
+
this.newDate = newDate;
|
|
254
|
+
}}
|
|
255
|
+
/>
|
|
256
|
+
</div>
|
|
257
|
+
<div>
|
|
258
|
+
<div class="cta-container">
|
|
259
|
+
<ia-button
|
|
260
|
+
class="ia-button secondary"
|
|
261
|
+
.clickHandler=${(e) => {
|
|
262
|
+
e.preventDefault();
|
|
263
|
+
this.closeForm();
|
|
264
|
+
}}
|
|
265
|
+
>
|
|
266
|
+
Cancel
|
|
267
|
+
</ia-button>
|
|
268
|
+
<ia-button
|
|
269
|
+
id="edit-date"
|
|
270
|
+
class="ia-button primary"
|
|
271
|
+
type="submit"
|
|
272
|
+
.isDisabled=${!this.allowEditing}
|
|
273
|
+
.clickHandler=${async (e, iaButton) => {
|
|
274
|
+
this.clearStatusMessaging();
|
|
275
|
+
if (!this.newDate) {
|
|
276
|
+
this.errorMessage = 'Please enter a valid date';
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
// eslint-disable-next-line no-param-reassign
|
|
280
|
+
iaButton.isDisabled = true;
|
|
281
|
+
await iaButton.updateComplete;
|
|
282
|
+
this.requestDateUpdate(e);
|
|
283
|
+
}}
|
|
284
|
+
>
|
|
285
|
+
Update
|
|
286
|
+
</ia-button>
|
|
287
|
+
<ia-mgc-update-status .status=${this.updateStatus}
|
|
288
|
+
>${this.updateMessage}</ia-mgc-update-status
|
|
289
|
+
>
|
|
290
|
+
</div>
|
|
291
|
+
</div>
|
|
292
|
+
<p class="error error-msg">
|
|
293
|
+
${this.warningMessage
|
|
294
|
+
? html `<span>${this.warningMessage}</span><br />`
|
|
295
|
+
: ''}
|
|
296
|
+
${this.errorMessage}
|
|
297
|
+
</p>
|
|
298
|
+
</form>
|
|
299
|
+
</section>
|
|
300
|
+
`;
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
MGCEditPlanDate.styles = css `
|
|
304
|
+
input[name='edit-date'] {
|
|
305
|
+
margin: 10px 0;
|
|
306
|
+
min-width: 140px;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.cta-container {
|
|
310
|
+
display: flex;
|
|
311
|
+
flex-direction: row;
|
|
312
|
+
flex-wrap: wrap;
|
|
313
|
+
align-content: center;
|
|
314
|
+
justify-content: flex-start;
|
|
315
|
+
align-items: center;
|
|
316
|
+
gap: 10px;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
p.error {
|
|
320
|
+
color: var(--mgc-warning-color-dark, #bb0505);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
ia-mgc-update-status {
|
|
324
|
+
display: inline-block;
|
|
325
|
+
margin-left: 1rem;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.checkbox-option-container {
|
|
329
|
+
margin: 10px 0;
|
|
330
|
+
display: flex;
|
|
331
|
+
}
|
|
332
|
+
`;
|
|
333
|
+
__decorate([
|
|
334
|
+
property({ type: Object })
|
|
335
|
+
], MGCEditPlanDate.prototype, "plan", void 0);
|
|
336
|
+
__decorate([
|
|
337
|
+
property({ type: String })
|
|
338
|
+
], MGCEditPlanDate.prototype, "newDate", void 0);
|
|
339
|
+
__decorate([
|
|
340
|
+
property({ type: Boolean, reflect: true })
|
|
341
|
+
], MGCEditPlanDate.prototype, "currentlyEditing", void 0);
|
|
342
|
+
__decorate([
|
|
343
|
+
property({ type: Boolean })
|
|
344
|
+
], MGCEditPlanDate.prototype, "allowEditing", void 0);
|
|
345
|
+
__decorate([
|
|
346
|
+
property({ type: String })
|
|
347
|
+
], MGCEditPlanDate.prototype, "updateMessage", void 0);
|
|
348
|
+
__decorate([
|
|
349
|
+
property({ type: String })
|
|
350
|
+
], MGCEditPlanDate.prototype, "errorMessage", void 0);
|
|
351
|
+
__decorate([
|
|
352
|
+
property({ type: String })
|
|
353
|
+
], MGCEditPlanDate.prototype, "warningMessage", void 0);
|
|
354
|
+
__decorate([
|
|
355
|
+
property({ type: String })
|
|
356
|
+
], MGCEditPlanDate.prototype, "updateStatus", void 0);
|
|
357
|
+
__decorate([
|
|
358
|
+
query('form')
|
|
359
|
+
], MGCEditPlanDate.prototype, "form", void 0);
|
|
360
|
+
__decorate([
|
|
361
|
+
query('form ia-button#edit-date')
|
|
362
|
+
], MGCEditPlanDate.prototype, "formSubmitButton", void 0);
|
|
363
|
+
__decorate([
|
|
364
|
+
query('form input[name="edit-date"]')
|
|
365
|
+
], MGCEditPlanDate.prototype, "dateInput", void 0);
|
|
366
|
+
MGCEditPlanDate = __decorate([
|
|
367
|
+
customElement('ia-mgc-edit-date')
|
|
368
|
+
], MGCEditPlanDate);
|
|
369
|
+
export { MGCEditPlanDate };
|
|
370
|
+
//# sourceMappingURL=date.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date.js","sourceRoot":"","sources":["../../../src/form-sections/date.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n LitElement,\n html,\n PropertyValues,\n nothing,\n css,\n TemplateResult,\n} from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport '@internetarchive/donation-form-section';\n\nimport type { MonthlyPlan } from '../models/plan';\nimport '../presentational/ia-button';\nimport type { IauxButton } from '../presentational/ia-button';\nimport '../presentational/mgc-update-status';\n\ntype InvalidDateErrorCode =\n | 'invalid_date'\n | 'date_too_early'\n | 'second_donation_this_month'\n | 'date_out_of_range'\n | 'same_next_billing_date'\n | '';\n\nenum InvalidDateErrorMessages {\n invalid_date = 'Please enter a valid date format (YYYY-MM-DD)',\n date_too_early = 'Date must be at least tomorrow.',\n second_donation_this_month = 'The date you selected will result in an additional donation for this month.',\n date_out_of_range = 'New donation date must be within the next 12 months.',\n same_next_billing_date = '',\n}\n@customElement('ia-mgc-edit-date')\nexport class MGCEditPlanDate extends LitElement {\n @property({ type: Object }) plan?: MonthlyPlan;\n\n @property({ type: String }) newDate?: string;\n\n @property({ type: Boolean, reflect: true }) currentlyEditing: boolean = false;\n\n @property({ type: Boolean }) allowEditing: boolean = false;\n\n @property({ type: String }) updateMessage: string = '';\n\n @property({ type: String }) errorMessage: string = '';\n\n @property({ type: String }) warningMessage: string = '';\n\n @property({ type: String }) updateStatus: 'success' | 'fail' | '' = '';\n\n @query('form') form!: HTMLFormElement;\n\n @query('form ia-button#edit-date') formSubmitButton!: IauxButton;\n\n @query('form input[name=\"edit-date\"]')\n dateInput!: HTMLInputElement;\n\n willUpdate(changed: PropertyValues) {\n if (this.dateInput && changed.has('plan') && this.plan) {\n this.dateInput.setAttribute('min', this.minDate);\n this.dateInput.setAttribute('max', this.maxDate);\n }\n }\n\n updated(changed: PropertyValues) {\n if (changed.has('currentlyEditing') && this.currentlyEditing) {\n this.dateInput.focus();\n }\n }\n\n protected render() {\n return html`\n <section>\n <donation-form-section\n badgemode=\"hidebadge\"\n headline=\"Change next donation date\"\n >\n ${!this.currentlyEditing\n ? html` <p class=\"current-date\">\n ${this.plan?.nextBillingDateLocale}\n <ia-mgc-update-status .status=${this.updateStatus}\n >${this.updateMessage}</ia-mgc-update-status\n >\n </p>\n <ia-button\n id=\"open-edit-date-form\"\n class=\"ia-button link\"\n .clickHandler=${() => {\n this.currentlyEditing = true;\n this.clearStatusMessaging();\n }}\n >\n Edit...\n </ia-button>`\n : nothing}\n ${this.currentlyEditing ? this.editDateForm : nothing}\n </donation-form-section>\n </section>\n `;\n }\n\n /* External Function that is called by consumer to tell the form there has been data update */\n async dateUpdated(status: 'success' | 'fail') {\n this.clearInputField();\n\n this.updateStatus = status;\n this.updateMessage =\n status === 'success'\n ? 'Date updated'\n : 'Failed to update date, please try again';\n\n if (status === 'success') {\n this.closeForm();\n await this.updateComplete;\n return;\n }\n\n this.allowEditing = false;\n await this.updateComplete;\n }\n\n /* Dispatches edit-date change request */\n requestDateUpdate(e: Event): void {\n e.preventDefault();\n this.dispatchEvent(\n new CustomEvent('updateDate', {\n detail: {\n plan: this.plan,\n newDate: this.newDate,\n },\n })\n );\n }\n\n closeForm() {\n this.clearInputField();\n this.clearStatusMessaging();\n this.currentlyEditing = false;\n this.allowEditing = false;\n }\n\n clearInputField() {\n this.dateInput.value = '';\n this.newDate = undefined;\n }\n\n formatDateToYYYYMMDD(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed\n const dateNum = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${dateNum}`;\n }\n\n async clearStatusMessaging() {\n this.errorMessage = '';\n this.warningMessage = '';\n this.updateMessage = '';\n this.updateStatus = '';\n await this.updateComplete;\n }\n\n /* @param string dateString - YYYYY-MM-DD */\n validateChosenDate(dateString: string): {\n valid: boolean;\n errorCode: InvalidDateErrorCode | '';\n } {\n if (!dateString) {\n return {\n valid: false,\n errorCode: 'invalid_date',\n };\n }\n\n let validDate;\n try {\n validDate = new Date(`${dateString}T00:00:00`);\n } catch (error) {\n return {\n valid: false,\n errorCode: 'invalid_date',\n };\n }\n\n // Check if minimum date is at least tomorrow\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n const tomorrow = new Date(today);\n tomorrow.setDate(today.getDate() + 1); // Set to tomorrow\n\n const chosenDate = new Date(validDate);\n chosenDate.setHours(0, 0, 0, 0);\n\n // check input value against next billing date\n const isNextBillingDate = this.plan?.nextBillingDate\n ? this.formatDateToYYYYMMDD(new Date(this.plan.nextBillingDate)) ===\n this.formatDateToYYYYMMDD(chosenDate)\n : false;\n if (isNextBillingDate) {\n return {\n valid: false,\n errorCode: 'same_next_billing_date',\n };\n }\n\n if (chosenDate < today) {\n return {\n valid: false,\n errorCode: 'date_too_early',\n };\n }\n\n // Check if the new date is within the next 12 months\n const twelveMonthsFromNow = new Date(today);\n twelveMonthsFromNow.setFullYear(twelveMonthsFromNow.getFullYear() + 1);\n\n if (chosenDate > twelveMonthsFromNow) {\n return {\n valid: false,\n errorCode: 'date_out_of_range',\n };\n }\n\n // Check if there has been a donation in the last month\n const lastDonationDate = this.plan?.payment.lastBillingDate.date\n ? new Date(this.plan?.payment.lastBillingDate.date)\n : null;\n\n if (lastDonationDate) {\n const lastDonationMonth = lastDonationDate.getMonth();\n const lastDonationYear = lastDonationDate.getFullYear();\n\n const thisYear = validDate.getFullYear();\n const thisMonth = validDate.getMonth();\n const isInLastMonth =\n thisYear === lastDonationYear && thisMonth === lastDonationMonth;\n\n if (isInLastMonth) {\n return {\n valid: true,\n errorCode: 'second_donation_this_month',\n };\n }\n }\n\n return {\n valid: true,\n errorCode: '',\n };\n }\n\n /* DISPLAY */\n get minDate(): string {\n const today = new Date();\n const tomorrow = new Date(today);\n tomorrow.setDate(today.getDate() + 1); // Set to tomorrow\n const year = tomorrow.getFullYear();\n const month = String(tomorrow.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed\n const dateString = String(tomorrow.getDate()).padStart(2, '0');\n return `${year}-${month}-${dateString}`;\n }\n\n get maxDate(): string {\n const today = new Date();\n const year = today.getFullYear() + 1; // Allow up to one year in the future\n const month = String(today.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed\n const dateString = String(today.getDate()).padStart(2, '0');\n return `${year}-${month}-${dateString}`;\n }\n\n get editDateForm(): TemplateResult {\n const nextBillingDateYYYYMMDD = this.plan?.nextBillingDate\n ? this.formatDateToYYYYMMDD(new Date(this.plan.nextBillingDate))\n : '';\n const inputValueToUse = this.dateInput?.value ?? nextBillingDateYYYYMMDD;\n return html`\n <section>\n <form id=\"edit-date\">\n <p id=\"form-info-last-donation-date\">\n Last donation date: ${this.plan?.lastBillingDateLocale}\n </p>\n\n <p id=\"form-info-next-donation-date\">\n Next donation date: ${this.plan?.nextBillingDateLocale}\n </p>\n <div class=\"date-holder\">\n <input\n required\n type=\"date\"\n id=\"edit-date\"\n name=\"edit-date\"\n min=${this.minDate}\n max=${this.maxDate}\n .value=${inputValueToUse}\n @focus=${() => this.clearStatusMessaging()}\n @change=${async () => {\n this.clearStatusMessaging();\n await this.updateComplete;\n\n const inputValue = this.dateInput.value;\n const { valid, errorCode } =\n this.validateChosenDate(inputValue);\n\n this.allowEditing = valid;\n\n if (errorCode) {\n if (errorCode === 'second_donation_this_month') {\n this.errorMessage = InvalidDateErrorMessages[errorCode];\n this.warningMessage =\n 'You have already made a donation this month.';\n } else {\n this.errorMessage = InvalidDateErrorMessages[errorCode];\n this.newDate = undefined;\n return;\n }\n }\n\n const chosenDate = new Date(`${inputValue}T00:00:00`);\n const newDate = new Date(chosenDate).toISOString();\n this.newDate = newDate;\n }}\n />\n </div>\n <div>\n <div class=\"cta-container\">\n <ia-button\n class=\"ia-button secondary\"\n .clickHandler=${(e: Event) => {\n e.preventDefault();\n this.closeForm();\n }}\n >\n Cancel\n </ia-button>\n <ia-button\n id=\"edit-date\"\n class=\"ia-button primary\"\n type=\"submit\"\n .isDisabled=${!this.allowEditing}\n .clickHandler=${async (e: Event, iaButton: IauxButton) => {\n this.clearStatusMessaging();\n\n if (!this.newDate) {\n this.errorMessage = 'Please enter a valid date';\n return;\n }\n\n // eslint-disable-next-line no-param-reassign\n (iaButton as IauxButton).isDisabled = true;\n await iaButton.updateComplete;\n\n this.requestDateUpdate(e);\n }}\n >\n Update\n </ia-button>\n <ia-mgc-update-status .status=${this.updateStatus}\n >${this.updateMessage}</ia-mgc-update-status\n >\n </div>\n </div>\n <p class=\"error error-msg\">\n ${this.warningMessage\n ? html`<span>${this.warningMessage}</span><br />`\n : ''}\n ${this.errorMessage}\n </p>\n </form>\n </section>\n `;\n }\n\n static styles = css`\n input[name='edit-date'] {\n margin: 10px 0;\n min-width: 140px;\n }\n\n .cta-container {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-content: center;\n justify-content: flex-start;\n align-items: center;\n gap: 10px;\n }\n\n p.error {\n color: var(--mgc-warning-color-dark, #bb0505);\n }\n\n ia-mgc-update-status {\n display: inline-block;\n margin-left: 1rem;\n }\n\n .checkbox-option-container {\n margin: 10px 0;\n display: flex;\n }\n `;\n}\n"]}
|