recur-tw 0.9.12 → 0.9.13
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/index.cjs +174 -68
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +174 -68
- package/dist/recur.umd.js +183 -117
- package/dist/server.cjs +1 -1
- package/dist/server.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1029,7 +1029,7 @@ var init_payment_form_shadow = __esm({
|
|
|
1029
1029
|
var payment_form_light_default;
|
|
1030
1030
|
var init_payment_form_light = __esm({
|
|
1031
1031
|
"src/components/styles/payment-form-light.css"() {
|
|
1032
|
-
payment_form_light_default = "/**\n * Payment Form - Light DOM Styles\n * These styles are applied to slotted content in the Light DOM\n * Using BEM naming convention with 'recur-' prefix for isolation\n */\n\n/* ============================================\n * Order Summary Styles\n * ============================================ */\n.recur-order-summary {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n}\n\n.recur-order-summary__row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.recur-order-summary__row--total {\n margin-bottom: 0;\n padding-top: 12px;\n border-top: 1px solid #e2e8f0;\n}\n\n.recur-order-summary__label {\n font-size: 14px;\n color: #4a5568;\n}\n\n.recur-order-summary__value {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: #2d3748;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.recur-order-summary__total {\n font-size: 18px;\n line-height: 26px;\n font-weight: 700;\n color: #1a202c;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n/* ============================================\n * Coupon Section Styles\n * ============================================ */\n.recur-coupon {\n padding: 12px 0;\n border-top: 1px solid #e2e8f0;\n margin-top: 12px;\n min-height: 36px;\n display: flex;\n align-items: center;\n}\n\n.recur-coupon__trigger {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n height: 36px;\n background: none;\n border: none;\n padding: 0;\n font-size: 14px;\n line-height: 1;\n color: #718096;\n cursor: pointer;\n transition: color 0.2s;\n}\n\n.recur-coupon__trigger:hover {\n color: #4a5568;\n}\n\n.recur-coupon__trigger-icon {\n width: 16px;\n height: 16px;\n}\n\n.recur-coupon__input-row {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__input {\n flex: 1;\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n text-transform: uppercase;\n background-color: #ffffff;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.recur-coupon__input::placeholder {\n text-transform: none;\n}\n\n.recur-coupon__input:hover:not(:focus) {\n border-color: #9ca3af;\n}\n\n.recur-coupon__input:focus {\n border-color: var(--ring, hsl(215 16% 47%));\n outline: 0;\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring, hsl(215 16% 47%)) 50%, transparent);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.recur-coupon__btn {\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.2s, opacity 0.2s;\n white-space: nowrap;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.recur-coupon__btn--apply {\n background: #18181b;\n color: white;\n border: none;\n min-width: 52px;\n}\n\n.recur-coupon__btn--apply .recur-coupon__spinner {\n width: 14px;\n height: 14px;\n}\n\n.recur-coupon__btn--apply:hover:not(:disabled) {\n background: #27272a;\n}\n\n.recur-coupon__btn--apply:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.recur-
|
|
1032
|
+
payment_form_light_default = "/**\n * Payment Form - Light DOM Styles\n * These styles are applied to slotted content in the Light DOM\n * Using BEM naming convention with 'recur-' prefix for isolation\n */\n\n/* ============================================\n * Order Summary Styles\n * ============================================ */\n.recur-order-summary {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n}\n\n.recur-order-summary__row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.recur-order-summary__row--total {\n margin-bottom: 0;\n padding-top: 12px;\n border-top: 1px solid #e2e8f0;\n}\n\n.recur-order-summary__label {\n font-size: 14px;\n color: #4a5568;\n}\n\n.recur-order-summary__value {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: #2d3748;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.recur-order-summary__total {\n font-size: 18px;\n line-height: 26px;\n font-weight: 700;\n color: #1a202c;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n/* ============================================\n * Coupon Section Styles\n * ============================================ */\n.recur-coupon {\n padding: 12px 0;\n border-top: 1px solid #e2e8f0;\n margin-top: 12px;\n min-height: 36px;\n display: flex;\n align-items: center;\n}\n\n.recur-coupon__trigger {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n height: 36px;\n background: none;\n border: none;\n padding: 0;\n font-size: 14px;\n line-height: 1;\n color: #718096;\n cursor: pointer;\n transition: color 0.2s;\n}\n\n.recur-coupon__trigger:hover {\n color: #4a5568;\n}\n\n.recur-coupon__trigger-icon {\n width: 16px;\n height: 16px;\n}\n\n.recur-coupon__input-row {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__input-wrapper {\n position: relative;\n flex: 1;\n}\n\n.recur-coupon__input {\n width: 100%;\n height: 36px;\n padding: 0 32px 0 12px;\n font-size: 14px;\n text-transform: uppercase;\n background-color: #ffffff;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.recur-coupon__input::placeholder {\n text-transform: none;\n}\n\n.recur-coupon__input:hover:not(:focus) {\n border-color: #9ca3af;\n}\n\n.recur-coupon__input:focus {\n border-color: var(--ring, hsl(215 16% 47%));\n outline: 0;\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring, hsl(215 16% 47%)) 50%, transparent);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.recur-coupon__clear {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: #9ca3af;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: color 0.2s;\n}\n\n.recur-coupon__clear:hover {\n color: #6b7280;\n}\n\n.recur-coupon__clear-icon {\n width: 16px;\n height: 16px;\n}\n\n.recur-coupon__btn {\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.2s, opacity 0.2s;\n white-space: nowrap;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.recur-coupon__btn--apply {\n background: #18181b;\n color: white;\n border: none;\n min-width: 52px;\n}\n\n.recur-coupon__btn--apply .recur-coupon__spinner {\n width: 14px;\n height: 14px;\n}\n\n.recur-coupon__btn--apply:hover:not(:disabled) {\n background: #27272a;\n}\n\n.recur-coupon__btn--apply:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.recur-coupon__error {\n width: 100%;\n margin-top: 8px;\n font-size: 13px;\n color: #dc2626;\n}\n\n.recur-coupon__applied-wrapper {\n width: 100%;\n}\n\n.recur-coupon__description {\n font-size: 12px;\n color: #6b7280;\n margin: 4px 0 0 22px;\n}\n\n.recur-coupon__bonus {\n display: flex;\n align-items: center;\n gap: 6px;\n background: #dcfce7;\n border-radius: 6px;\n padding: 8px 12px;\n margin-top: 8px;\n font-size: 12px;\n color: #15803d;\n}\n\n.recur-coupon__applied {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__applied-info {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n flex: 1;\n}\n\n.recur-coupon__applied-icon {\n width: 16px;\n height: 16px;\n color: #dc2626;\n flex-shrink: 0;\n}\n\n.recur-coupon__applied-name {\n font-size: 14px;\n font-weight: 500;\n color: #dc2626;\n white-space: nowrap;\n}\n\n.recur-coupon__applied-code {\n font-size: 14px;\n color: #9ca3af;\n white-space: nowrap;\n margin-right: 2px;\n}\n\n.recur-coupon__applied-amount {\n font-size: 14px;\n font-weight: 500;\n color: #dc2626;\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n flex-shrink: 0;\n margin-left: auto;\n}\n\n.recur-coupon__remove {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: #9ca3af;\n border-radius: 4px;\n transition: color 0.2s, background-color 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.recur-coupon__remove:hover {\n color: #6b7280;\n background: rgba(0, 0, 0, 0.05);\n}\n\n.recur-coupon__remove-icon {\n width: 14px;\n height: 14px;\n}\n\n.recur-coupon__spinner {\n width: 14px;\n height: 14px;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: recur-spin 0.6s linear infinite;\n}\n\n/* Discount Row */\n.recur-order-summary__row--discount {\n color: #16a34a;\n}\n\n.recur-order-summary__row--discount .recur-order-summary__value {\n color: #16a34a;\n font-weight: 500;\n}\n\n/* ============================================\n * Customer Info Styles\n * ============================================ */\n.recur-info-display {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n padding: 12px;\n margin-bottom: 8px;\n}\n\n.recur-info-row {\n margin-bottom: 12px;\n}\n\n.recur-info-row:last-child {\n margin-bottom: 0;\n}\n\n.recur-info-label {\n display: block;\n font-size: 12px;\n line-height: 16px;\n color: #718096;\n margin-bottom: 2px;\n}\n\n.recur-info-value {\n display: block;\n font-size: 14px;\n line-height: 20px;\n min-height: 20px;\n color: #2d3748;\n font-weight: 500;\n word-break: break-all;\n}\n\n.recur-form-group {\n margin-bottom: 16px;\n}\n\n.recur-form-label {\n display: block;\n font-size: 14px;\n font-weight: 500;\n color: #2d3748;\n margin-bottom: 6px;\n}\n\n.recur-form-input {\n width: 100%;\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n transition: border-color 0.2s;\n box-sizing: border-box;\n}\n\n.recur-form-input:focus {\n border-color: var(--ring, hsl(215 16% 47%));\n outline: 0;\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring, hsl(215 16% 47%)) 50%, transparent);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.recur-form-input:hover:not(:focus) {\n border-color: #9ca3af;\n}\n\n/* ============================================\n * Card Fields Styles\n * ============================================ */\n.recur-card-field {\n margin-bottom: 16px;\n}\n\n.recur-card-field-label {\n display: block;\n font-size: 14px;\n font-weight: 500;\n color: #2d3748;\n margin-bottom: 6px;\n}\n\n.recur-payuni-iframe {\n height: 36px;\n width: 100%;\n max-width: 100%;\n box-sizing: border-box;\n touch-action: manipulation;\n}\n\n.recur-card-row {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n column-gap: 16px;\n max-width: 100%;\n box-sizing: border-box;\n}\n\n.recur-card-field-container {\n position: relative;\n touch-action: manipulation;\n}\n\n.recur-card-skeleton {\n position: absolute;\n top: 0;\n left: 0;\n height: 36px;\n width: 100%;\n background: linear-gradient(90deg, #f0f0f0 0%, #e8e8e8 50%, #f0f0f0 100%);\n background-size: 200% 100%;\n animation: recur-skeleton-loading 1.5s ease-in-out infinite;\n border-radius: 4px;\n z-index: 1;\n pointer-events: none;\n}\n\n.recur-card-skeleton.hidden {\n display: none;\n}\n\n@keyframes recur-skeleton-loading {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* ============================================\n * Submit Button Styles\n * ============================================ */\n.recur-submit-button {\n width: 100%;\n padding: 14px 20px;\n font-size: 16px;\n font-weight: 500;\n color: #ffffff;\n background: #18181b;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n box-sizing: border-box;\n}\n\n.recur-submit-button:hover:not(:disabled) {\n background: #27272a;\n}\n\n.recur-submit-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.recur-submit-button.loading {\n cursor: wait;\n}\n\n.recur-loading-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: recur-spin 0.6s linear infinite;\n}\n\n@keyframes recur-spin {\n to { transform: rotate(360deg); }\n}\n\n/* ============================================\n * Skeleton Loading Styles\n * ============================================ */\n.recur-skeleton {\n display: inline-block;\n background: linear-gradient(90deg, #f0f0f0 0%, #e8e8e8 50%, #f0f0f0 100%);\n background-size: 200% 100%;\n animation: recur-skeleton-loading 1.5s ease-in-out infinite;\n border-radius: 4px;\n}\n";
|
|
1033
1033
|
}
|
|
1034
1034
|
});
|
|
1035
1035
|
|
|
@@ -1063,6 +1063,11 @@ var init_payment_form = __esm({
|
|
|
1063
1063
|
<svg class="recur-coupon__remove-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1064
1064
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
1065
1065
|
</svg>
|
|
1066
|
+
`,
|
|
1067
|
+
clearInput: html`
|
|
1068
|
+
<svg class="recur-coupon__clear-icon" width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1069
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
1070
|
+
</svg>
|
|
1066
1071
|
`,
|
|
1067
1072
|
spinner: html`<span class="recur-coupon__spinner"></span>`
|
|
1068
1073
|
};
|
|
@@ -1275,30 +1280,106 @@ var init_payment_form = __esm({
|
|
|
1275
1280
|
</div>
|
|
1276
1281
|
`;
|
|
1277
1282
|
}
|
|
1283
|
+
// Helper to get interval text in Chinese
|
|
1284
|
+
getIntervalText(interval, count) {
|
|
1285
|
+
if (!interval) return "";
|
|
1286
|
+
const countText = count && count > 1 ? count.toString() : "";
|
|
1287
|
+
switch (interval.toUpperCase()) {
|
|
1288
|
+
case "MONTH":
|
|
1289
|
+
return `${countText}\u6708`;
|
|
1290
|
+
case "YEAR":
|
|
1291
|
+
return `${countText}\u5E74`;
|
|
1292
|
+
case "WEEK":
|
|
1293
|
+
return `${countText}\u9031`;
|
|
1294
|
+
case "DAY":
|
|
1295
|
+
return `${countText}\u5929`;
|
|
1296
|
+
default:
|
|
1297
|
+
return "";
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
// Get discount description based on type and duration
|
|
1301
|
+
getDiscountDescription() {
|
|
1302
|
+
if (!this._appliedCoupon) return null;
|
|
1303
|
+
const { discountType, duration, durationMonths, productPrice, productInterval, productIntervalCount } = this._appliedCoupon;
|
|
1304
|
+
const intervalText = this.getIntervalText(productInterval, productIntervalCount);
|
|
1305
|
+
const originalPriceText = productPrice && intervalText ? `NT$ ${productPrice.toLocaleString()}/${intervalText}` : productPrice ? `NT$ ${productPrice.toLocaleString()}` : "";
|
|
1306
|
+
const amount = parseInt(this.getAttribute("amount") || "0", 10);
|
|
1307
|
+
const finalAmount = amount - this._appliedCoupon.discountAmount;
|
|
1308
|
+
if (discountType === "FIRST_PERIOD_PRICE") {
|
|
1309
|
+
if (originalPriceText) {
|
|
1310
|
+
return `\u9996\u671F\u53EA\u9700 NT$ ${finalAmount.toLocaleString()}\uFF0C\u4E4B\u5F8C ${originalPriceText}`;
|
|
1311
|
+
}
|
|
1312
|
+
return `\u9996\u671F\u53EA\u9700 NT$ ${finalAmount.toLocaleString()}`;
|
|
1313
|
+
}
|
|
1314
|
+
if (duration) {
|
|
1315
|
+
switch (duration) {
|
|
1316
|
+
case "ONCE":
|
|
1317
|
+
if (originalPriceText) {
|
|
1318
|
+
return `\u9996\u671F\u6298\u6263\uFF0C\u4E4B\u5F8C ${originalPriceText}`;
|
|
1319
|
+
}
|
|
1320
|
+
return "\u50C5\u9650\u9996\u671F";
|
|
1321
|
+
case "REPEATING":
|
|
1322
|
+
if (durationMonths) {
|
|
1323
|
+
return `\u524D ${durationMonths} \u671F\u4EAB\u512A\u60E0\uFF0C\u4E4B\u5F8C\u6062\u5FA9\u539F\u50F9`;
|
|
1324
|
+
}
|
|
1325
|
+
return null;
|
|
1326
|
+
case "FOREVER":
|
|
1327
|
+
return "\u7D42\u8EAB\u512A\u60E0";
|
|
1328
|
+
default:
|
|
1329
|
+
return null;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
return null;
|
|
1333
|
+
}
|
|
1334
|
+
// Get bonus description
|
|
1335
|
+
getBonusDescription() {
|
|
1336
|
+
if (!this._appliedCoupon) return null;
|
|
1337
|
+
const parts = [];
|
|
1338
|
+
if (this._appliedCoupon.bonusTrialDays) {
|
|
1339
|
+
parts.push(`\u5EF6\u9577\u8A66\u7528 ${this._appliedCoupon.bonusTrialDays} \u5929`);
|
|
1340
|
+
}
|
|
1341
|
+
if (this._appliedCoupon.bonusMonths) {
|
|
1342
|
+
parts.push(`\u52A0\u9001 ${this._appliedCoupon.bonusMonths} \u500B\u6708`);
|
|
1343
|
+
}
|
|
1344
|
+
return parts.length > 0 ? parts.join("\u3001") : null;
|
|
1345
|
+
}
|
|
1278
1346
|
renderCoupon() {
|
|
1279
1347
|
if (this._appliedCoupon) {
|
|
1348
|
+
const discountDescription = this.getDiscountDescription();
|
|
1349
|
+
const bonusDescription = this.getBonusDescription();
|
|
1280
1350
|
return html`
|
|
1281
|
-
<div class="recur-coupon__applied">
|
|
1282
|
-
<div class="recur-coupon__applied
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1351
|
+
<div class="recur-coupon__applied-wrapper">
|
|
1352
|
+
<div class="recur-coupon__applied">
|
|
1353
|
+
<div class="recur-coupon__applied-info">
|
|
1354
|
+
${icons.tagApplied}
|
|
1355
|
+
${this._appliedCoupon.couponName ? html`
|
|
1356
|
+
<span class="recur-coupon__applied-name">${this._appliedCoupon.couponName}</span>
|
|
1357
|
+
<span class="recur-coupon__applied-code">(${this._appliedCoupon.code})</span>
|
|
1358
|
+
` : html`
|
|
1359
|
+
<span class="recur-coupon__applied-name">${this._appliedCoupon.code}</span>
|
|
1360
|
+
`}
|
|
1361
|
+
<button
|
|
1362
|
+
type="button"
|
|
1363
|
+
class="recur-coupon__remove"
|
|
1364
|
+
?disabled=${this._couponLoading}
|
|
1365
|
+
@click=${() => this.removeCoupon()}
|
|
1366
|
+
>
|
|
1367
|
+
${this._couponLoading ? icons.spinner : icons.close}
|
|
1368
|
+
</button>
|
|
1369
|
+
</div>
|
|
1370
|
+
<span class="recur-coupon__applied-amount">
|
|
1371
|
+
-NT$ ${this._appliedCoupon.discountAmount.toLocaleString()}
|
|
1372
|
+
</span>
|
|
1298
1373
|
</div>
|
|
1299
|
-
|
|
1300
|
-
-
|
|
1301
|
-
|
|
1374
|
+
${discountDescription ? html`
|
|
1375
|
+
<p class="recur-coupon__description">${discountDescription}</p>
|
|
1376
|
+
` : nothing}
|
|
1377
|
+
${bonusDescription ? html`
|
|
1378
|
+
<div class="recur-coupon__bonus">
|
|
1379
|
+
<span>✨</span>
|
|
1380
|
+
<span>${bonusDescription}</span>
|
|
1381
|
+
</div>
|
|
1382
|
+
` : nothing}
|
|
1302
1383
|
</div>
|
|
1303
1384
|
`;
|
|
1304
1385
|
}
|
|
@@ -1306,16 +1387,28 @@ var init_payment_form = __esm({
|
|
|
1306
1387
|
return html`
|
|
1307
1388
|
<div style="width: 100%;">
|
|
1308
1389
|
<div class="recur-coupon__input-row">
|
|
1309
|
-
<
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1390
|
+
<div class="recur-coupon__input-wrapper">
|
|
1391
|
+
<input
|
|
1392
|
+
type="text"
|
|
1393
|
+
class="recur-coupon__input"
|
|
1394
|
+
id="${this.containerId}-coupon-input"
|
|
1395
|
+
placeholder="輸入優惠碼"
|
|
1396
|
+
.value=${this._couponCode}
|
|
1397
|
+
?disabled=${this._couponLoading}
|
|
1398
|
+
@input=${(e) => this.handleCouponInputChange(e)}
|
|
1399
|
+
@keydown=${(e) => this.handleCouponKeydown(e)}
|
|
1400
|
+
/>
|
|
1401
|
+
${this._couponCode && !this._couponLoading ? html`
|
|
1402
|
+
<button
|
|
1403
|
+
type="button"
|
|
1404
|
+
class="recur-coupon__clear"
|
|
1405
|
+
@click=${() => this.clearCouponInput()}
|
|
1406
|
+
aria-label="清除"
|
|
1407
|
+
>
|
|
1408
|
+
${icons.clearInput}
|
|
1409
|
+
</button>
|
|
1410
|
+
` : nothing}
|
|
1411
|
+
</div>
|
|
1319
1412
|
<button
|
|
1320
1413
|
type="button"
|
|
1321
1414
|
class="recur-coupon__btn recur-coupon__btn--apply"
|
|
@@ -1324,14 +1417,6 @@ var init_payment_form = __esm({
|
|
|
1324
1417
|
>
|
|
1325
1418
|
${this._couponLoading ? icons.spinner : "\u5957\u7528"}
|
|
1326
1419
|
</button>
|
|
1327
|
-
<button
|
|
1328
|
-
type="button"
|
|
1329
|
-
class="recur-coupon__btn recur-coupon__btn--cancel"
|
|
1330
|
-
?disabled=${this._couponLoading}
|
|
1331
|
-
@click=${() => this.cancelCouponInput()}
|
|
1332
|
-
>
|
|
1333
|
-
取消
|
|
1334
|
-
</button>
|
|
1335
1420
|
</div>
|
|
1336
1421
|
${this._couponError ? html`
|
|
1337
1422
|
<div class="recur-coupon__error">${this._couponError}</div>
|
|
@@ -1366,6 +1451,15 @@ var init_payment_form = __esm({
|
|
|
1366
1451
|
this._couponError = null;
|
|
1367
1452
|
this.updateCouponSectionDOM();
|
|
1368
1453
|
}
|
|
1454
|
+
clearCouponInput() {
|
|
1455
|
+
this._couponCode = "";
|
|
1456
|
+
this._couponError = null;
|
|
1457
|
+
this.updateCouponSectionDOM();
|
|
1458
|
+
requestAnimationFrame(() => {
|
|
1459
|
+
const input = document.getElementById(`${this.containerId}-coupon-input`);
|
|
1460
|
+
input?.focus();
|
|
1461
|
+
});
|
|
1462
|
+
}
|
|
1369
1463
|
handleCouponInputChange(e) {
|
|
1370
1464
|
this._couponCode = e.target.value.toUpperCase();
|
|
1371
1465
|
this._couponError = null;
|
|
@@ -1413,17 +1507,25 @@ var init_payment_form = __esm({
|
|
|
1413
1507
|
}
|
|
1414
1508
|
getCouponInputHTML() {
|
|
1415
1509
|
const errorHTML = this._couponError ? `<div class="recur-coupon__error">${this._couponError}</div>` : "";
|
|
1510
|
+
const clearBtnHTML = this._couponCode && !this._couponLoading ? `<button type="button" class="recur-coupon__clear" aria-label="\u6E05\u9664">
|
|
1511
|
+
<svg class="recur-coupon__clear-icon" width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1512
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
1513
|
+
</svg>
|
|
1514
|
+
</button>` : "";
|
|
1416
1515
|
return `
|
|
1417
1516
|
<div style="width: 100%;">
|
|
1418
1517
|
<div class="recur-coupon__input-row">
|
|
1419
|
-
<
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1518
|
+
<div class="recur-coupon__input-wrapper">
|
|
1519
|
+
<input
|
|
1520
|
+
type="text"
|
|
1521
|
+
class="recur-coupon__input"
|
|
1522
|
+
id="${this.containerId}-coupon-input"
|
|
1523
|
+
placeholder="\u8F38\u5165\u512A\u60E0\u78BC"
|
|
1524
|
+
value="${this._couponCode}"
|
|
1525
|
+
${this._couponLoading ? "disabled" : ""}
|
|
1526
|
+
/>
|
|
1527
|
+
${clearBtnHTML}
|
|
1528
|
+
</div>
|
|
1427
1529
|
<button
|
|
1428
1530
|
type="button"
|
|
1429
1531
|
class="recur-coupon__btn recur-coupon__btn--apply"
|
|
@@ -1431,13 +1533,6 @@ var init_payment_form = __esm({
|
|
|
1431
1533
|
>
|
|
1432
1534
|
${this._couponLoading ? '<span class="recur-coupon__spinner"></span>' : "\u5957\u7528"}
|
|
1433
1535
|
</button>
|
|
1434
|
-
<button
|
|
1435
|
-
type="button"
|
|
1436
|
-
class="recur-coupon__btn recur-coupon__btn--cancel"
|
|
1437
|
-
${this._couponLoading ? "disabled" : ""}
|
|
1438
|
-
>
|
|
1439
|
-
\u53D6\u6D88
|
|
1440
|
-
</button>
|
|
1441
1536
|
</div>
|
|
1442
1537
|
${errorHTML}
|
|
1443
1538
|
</div>
|
|
@@ -1446,18 +1541,26 @@ var init_payment_form = __esm({
|
|
|
1446
1541
|
getCouponAppliedHTML() {
|
|
1447
1542
|
const coupon = this._appliedCoupon;
|
|
1448
1543
|
const nameHTML = coupon.couponName ? `<span class="recur-coupon__applied-name">${coupon.couponName}</span><span class="recur-coupon__applied-code">(${coupon.code})</span>` : `<span class="recur-coupon__applied-name">${coupon.code}</span>`;
|
|
1544
|
+
const discountDescription = this.getDiscountDescription();
|
|
1545
|
+
const bonusDescription = this.getBonusDescription();
|
|
1546
|
+
const descriptionHTML = discountDescription ? `<p class="recur-coupon__description">${discountDescription}</p>` : "";
|
|
1547
|
+
const bonusHTML = bonusDescription ? `<div class="recur-coupon__bonus"><span>\u2728</span><span>${bonusDescription}</span></div>` : "";
|
|
1449
1548
|
return `
|
|
1450
|
-
<div class="recur-coupon__applied">
|
|
1451
|
-
<div class="recur-coupon__applied
|
|
1452
|
-
<
|
|
1453
|
-
<
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1549
|
+
<div class="recur-coupon__applied-wrapper">
|
|
1550
|
+
<div class="recur-coupon__applied">
|
|
1551
|
+
<div class="recur-coupon__applied-info">
|
|
1552
|
+
<svg class="recur-coupon__applied-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1553
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z" />
|
|
1554
|
+
</svg>
|
|
1555
|
+
${nameHTML}
|
|
1556
|
+
<button type="button" class="recur-coupon__remove" ${this._couponLoading ? "disabled" : ""}>
|
|
1557
|
+
${this._couponLoading ? '<span class="recur-coupon__spinner"></span>' : '<svg class="recur-coupon__remove-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /></svg>'}
|
|
1558
|
+
</button>
|
|
1559
|
+
</div>
|
|
1560
|
+
<span class="recur-coupon__applied-amount">-NT$ ${coupon.discountAmount.toLocaleString()}</span>
|
|
1459
1561
|
</div>
|
|
1460
|
-
|
|
1562
|
+
${descriptionHTML}
|
|
1563
|
+
${bonusHTML}
|
|
1461
1564
|
</div>
|
|
1462
1565
|
`;
|
|
1463
1566
|
}
|
|
@@ -1468,11 +1571,11 @@ var init_payment_form = __esm({
|
|
|
1468
1571
|
bindCouponInputEvents(container) {
|
|
1469
1572
|
const input = container.querySelector(".recur-coupon__input");
|
|
1470
1573
|
const applyBtn = container.querySelector(".recur-coupon__btn--apply");
|
|
1471
|
-
const
|
|
1574
|
+
const clearBtn = container.querySelector(".recur-coupon__clear");
|
|
1472
1575
|
input?.addEventListener("input", (e) => this.handleCouponInputChange(e));
|
|
1473
1576
|
input?.addEventListener("keydown", (e) => this.handleCouponKeydown(e));
|
|
1474
1577
|
applyBtn?.addEventListener("click", () => this.applyCoupon());
|
|
1475
|
-
|
|
1578
|
+
clearBtn?.addEventListener("click", () => this.clearCouponInput());
|
|
1476
1579
|
}
|
|
1477
1580
|
bindCouponAppliedEvents(container) {
|
|
1478
1581
|
const removeBtn = container.querySelector(".recur-coupon__remove");
|
|
@@ -1532,7 +1635,10 @@ var init_payment_form = __esm({
|
|
|
1532
1635
|
duration: data.discount.duration,
|
|
1533
1636
|
durationMonths: data.discount.durationMonths,
|
|
1534
1637
|
bonusTrialDays: data.discount.bonusTrialDays,
|
|
1535
|
-
bonusMonths: data.discount.bonusMonths
|
|
1638
|
+
bonusMonths: data.discount.bonusMonths,
|
|
1639
|
+
productInterval: data.discount.productInterval,
|
|
1640
|
+
productIntervalCount: data.discount.productIntervalCount,
|
|
1641
|
+
productPrice: data.discount.productPrice
|
|
1536
1642
|
};
|
|
1537
1643
|
this._showCouponInput = false;
|
|
1538
1644
|
this._couponCode = "";
|
|
@@ -2540,7 +2646,7 @@ function toCamelCase(obj) {
|
|
|
2540
2646
|
|
|
2541
2647
|
// package.json
|
|
2542
2648
|
var package_default = {
|
|
2543
|
-
version: "0.9.
|
|
2649
|
+
version: "0.9.13"};
|
|
2544
2650
|
var SDK_VERSION = package_default.version;
|
|
2545
2651
|
var SDK_TYPE = "react";
|
|
2546
2652
|
var RecurContext = createContext(null);
|