payment-kit 1.13.45 → 1.13.47
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/api/dev.ts +1 -1
- package/api/src/libs/session.ts +1 -1
- package/api/src/routes/prices.ts +21 -18
- package/api/src/routes/pricing-table.ts +3 -1
- package/blocklet.yml +1 -1
- package/package.json +20 -20
- package/src/components/checkout/form/index.tsx +17 -14
- package/src/components/checkout/form/user-buttons.tsx +24 -0
- package/src/components/checkout/header.tsx +22 -5
- package/src/components/checkout/pay.tsx +50 -11
- package/src/components/checkout/product-item.tsx +7 -7
- package/src/components/checkout/summary.tsx +17 -4
- package/src/components/livemode.tsx +1 -1
- package/src/components/portal/invoice/list.tsx +16 -6
- package/src/components/portal/subscription/list.tsx +9 -1
- package/src/components/product/cross-sell-select.tsx +2 -2
- package/src/components/product/cross-sell.tsx +2 -1
- package/src/components/section/header.tsx +2 -0
- package/src/components/status.tsx +1 -1
- package/src/libs/util.ts +52 -31
- package/src/locales/en.tsx +36 -11
- package/src/locales/index.tsx +25 -0
- package/src/locales/zh.tsx +33 -9
- package/src/pages/admin/payments/links/detail.tsx +2 -1
- package/src/pages/admin/products/prices/detail.tsx +11 -3
- package/src/pages/admin/products/prices/list.tsx +4 -2
- package/src/pages/admin/products/pricing-tables/detail.tsx +2 -1
- package/src/pages/admin/products/products/create.tsx +2 -2
- package/src/pages/admin/products/products/detail.tsx +2 -2
- package/src/pages/admin/products/products/index.tsx +2 -2
- package/src/pages/checkout/pricing-table.tsx +66 -16
|
@@ -14,6 +14,8 @@ export default function SectionHeader(props: Props) {
|
|
|
14
14
|
direction="row"
|
|
15
15
|
justifyContent="space-between"
|
|
16
16
|
alignItems="center"
|
|
17
|
+
flexWrap="wrap"
|
|
18
|
+
gap={1}
|
|
17
19
|
sx={{ mb: props.mb, pb: 1, width: 1, borderBottom: '1px solid #eee' }}>
|
|
18
20
|
<Typography variant="h6" sx={{ fontWeight: 600 }}>
|
|
19
21
|
{props.title}
|
|
@@ -6,7 +6,7 @@ export default function Status(props: ChipProps) {
|
|
|
6
6
|
size="small"
|
|
7
7
|
variant="outlined"
|
|
8
8
|
{...props}
|
|
9
|
-
sx={{ ...(props.sx || {}), borderRadius: '4px', height: 20, lineHeight:
|
|
9
|
+
sx={{ ...(props.sx || {}), borderRadius: '4px', height: 20, lineHeight: 1, textTransform: 'capitalize' }}
|
|
10
10
|
/>
|
|
11
11
|
);
|
|
12
12
|
}
|
package/src/libs/util.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-nested-ternary */
|
|
1
2
|
/* eslint-disable @typescript-eslint/indent */
|
|
2
3
|
import type {
|
|
3
4
|
LineItem,
|
|
@@ -17,6 +18,7 @@ import cloneDeep from 'lodash/cloneDeep';
|
|
|
17
18
|
import isEqual from 'lodash/isEqual';
|
|
18
19
|
import { defaultCountries } from 'react-international-phone';
|
|
19
20
|
|
|
21
|
+
import { t } from '../locales/index';
|
|
20
22
|
import dayjs from './dayjs';
|
|
21
23
|
|
|
22
24
|
export function getExplorerLink(chainHost: string, did: string, type: string) {
|
|
@@ -119,17 +121,18 @@ export const formatError = (err: any) => {
|
|
|
119
121
|
|
|
120
122
|
export const formatProductPrice = (
|
|
121
123
|
{ prices, unit_label }: { prices: TPrice[]; unit_label: string },
|
|
122
|
-
currency: TPaymentCurrency
|
|
124
|
+
currency: TPaymentCurrency,
|
|
125
|
+
locale: string = 'en'
|
|
123
126
|
): string => {
|
|
124
127
|
if (prices.length > 1) {
|
|
125
|
-
return
|
|
128
|
+
return t('admin.price.count', locale, { count: prices.length });
|
|
126
129
|
}
|
|
127
130
|
|
|
128
131
|
if (prices.length === 1) {
|
|
129
|
-
return formatPrice(prices[0] as TPrice, currency, unit_label);
|
|
132
|
+
return formatPrice(prices[0] as TPrice, currency, unit_label, 1, true, locale);
|
|
130
133
|
}
|
|
131
134
|
|
|
132
|
-
return '
|
|
135
|
+
return t('admin.price.empty', locale);
|
|
133
136
|
};
|
|
134
137
|
|
|
135
138
|
export const formatPrice = (
|
|
@@ -137,14 +140,15 @@ export const formatPrice = (
|
|
|
137
140
|
currency: TPaymentCurrency,
|
|
138
141
|
unit_label?: string,
|
|
139
142
|
quantity: number = 1,
|
|
140
|
-
bn: boolean = true
|
|
143
|
+
bn: boolean = true,
|
|
144
|
+
locale: string = 'en'
|
|
141
145
|
) => {
|
|
142
146
|
const unit = getPriceUintAmountByCurrency(price, currency);
|
|
143
147
|
const amount = bn
|
|
144
148
|
? fromUnitToToken(new BN(unit).mul(new BN(quantity)), currency.decimal).toString()
|
|
145
149
|
: +unit * quantity;
|
|
146
150
|
if (price?.type === 'recurring' && price.recurring) {
|
|
147
|
-
const recurring = formatRecurring(price.recurring, false, '
|
|
151
|
+
const recurring = formatRecurring(price.recurring, false, 'slash', locale);
|
|
148
152
|
|
|
149
153
|
if (unit_label) {
|
|
150
154
|
return `${amount} ${currency.symbol} / ${unit_label} ${recurring}`;
|
|
@@ -219,7 +223,12 @@ export function getStatementDescriptor(items: any[]) {
|
|
|
219
223
|
return window.blocklet.appName;
|
|
220
224
|
}
|
|
221
225
|
|
|
222
|
-
export function formatRecurring(
|
|
226
|
+
export function formatRecurring(
|
|
227
|
+
recurring: PriceRecurring,
|
|
228
|
+
translate: boolean = true,
|
|
229
|
+
separator: string = 'per',
|
|
230
|
+
locale: string = 'en'
|
|
231
|
+
) {
|
|
223
232
|
const intervals = {
|
|
224
233
|
hour: 'hourly',
|
|
225
234
|
day: 'daily',
|
|
@@ -229,11 +238,15 @@ export function formatRecurring(recurring: PriceRecurring, translate: boolean =
|
|
|
229
238
|
};
|
|
230
239
|
|
|
231
240
|
if (+recurring.interval_count === 1) {
|
|
241
|
+
const interval = t(`common.${recurring.interval}`, locale);
|
|
232
242
|
// @ts-ignore
|
|
233
|
-
return translate ? intervals[recurring.interval] :
|
|
243
|
+
return translate ? t(`common.${intervals[recurring.interval]}`, locale) : separator ? t(`common.${separator}`, locale, { interval }) : interval; // prettier-ignore
|
|
234
244
|
}
|
|
235
245
|
|
|
236
|
-
return
|
|
246
|
+
return t('common.recurring', locale, {
|
|
247
|
+
count: recurring.interval_count,
|
|
248
|
+
interval: t(`common.${recurring.interval}s`, locale),
|
|
249
|
+
});
|
|
237
250
|
}
|
|
238
251
|
|
|
239
252
|
export function getPriceUintAmountByCurrency(price: TPrice, currency: TPaymentCurrency) {
|
|
@@ -257,11 +270,12 @@ export function getPriceCurrencyOptions(price: TPrice): PriceCurrency[] {
|
|
|
257
270
|
export function formatLineItemPricing(
|
|
258
271
|
item: TLineItemExpanded,
|
|
259
272
|
currency: TPaymentCurrency,
|
|
260
|
-
trial: number
|
|
273
|
+
trial: number,
|
|
274
|
+
locale: string = 'en'
|
|
261
275
|
): { primary: string; secondary?: string; quantity: string } {
|
|
262
276
|
const price = item.upsell_price || item.price;
|
|
263
277
|
|
|
264
|
-
let quantity =
|
|
278
|
+
let quantity = t('common.qty', locale, { count: item.quantity });
|
|
265
279
|
if (price.recurring?.usage_type === 'metered' || +item.quantity === 1) {
|
|
266
280
|
quantity = '';
|
|
267
281
|
}
|
|
@@ -274,20 +288,20 @@ export function formatLineItemPricing(
|
|
|
274
288
|
|
|
275
289
|
const appendUnit = (v: string, alt: string) => {
|
|
276
290
|
if (price.product.unit_label) {
|
|
277
|
-
return `${v}
|
|
291
|
+
return `${v}/${price.product.unit_label}`;
|
|
278
292
|
}
|
|
279
293
|
if (price.recurring?.usage_type === 'metered' || item.quantity === 1) {
|
|
280
294
|
return alt;
|
|
281
295
|
}
|
|
282
296
|
|
|
283
|
-
return quantity ?
|
|
297
|
+
return quantity ? t('common.each', locale, { unit }) : '';
|
|
284
298
|
};
|
|
285
299
|
|
|
286
300
|
if (price.type === 'recurring' && price.recurring) {
|
|
287
301
|
if (trial > 0) {
|
|
288
302
|
return {
|
|
289
|
-
primary:
|
|
290
|
-
secondary: `${appendUnit(total, total)} ${formatRecurring(price.recurring, false, '
|
|
303
|
+
primary: t('common.trial', locale, { count: trial }),
|
|
304
|
+
secondary: `${appendUnit(total, total)} ${formatRecurring(price.recurring, false, 'slash', locale)}`,
|
|
291
305
|
quantity,
|
|
292
306
|
};
|
|
293
307
|
}
|
|
@@ -408,7 +422,8 @@ export function formatUpsellSaving(session: TCheckoutSessionExpanded, currency:
|
|
|
408
422
|
|
|
409
423
|
export function formatCheckoutHeadlines(
|
|
410
424
|
session: TCheckoutSessionExpanded,
|
|
411
|
-
currency: TPaymentCurrency
|
|
425
|
+
currency: TPaymentCurrency,
|
|
426
|
+
locale: string = 'en'
|
|
412
427
|
): {
|
|
413
428
|
action: string;
|
|
414
429
|
amount: string;
|
|
@@ -425,7 +440,7 @@ export function formatCheckoutHeadlines(
|
|
|
425
440
|
// empty
|
|
426
441
|
if (items.length === 0) {
|
|
427
442
|
return {
|
|
428
|
-
action: '
|
|
443
|
+
action: t('checkout.empty', locale),
|
|
429
444
|
amount: '0',
|
|
430
445
|
then: '',
|
|
431
446
|
};
|
|
@@ -435,21 +450,27 @@ export function formatCheckoutHeadlines(
|
|
|
435
450
|
|
|
436
451
|
// all one time
|
|
437
452
|
if (items.every((x) => x.price.type === 'one_time')) {
|
|
453
|
+
const action = t('checkout.pay', locale, { payee: brand });
|
|
438
454
|
if (items.length > 1) {
|
|
439
|
-
return { action
|
|
455
|
+
return { action, amount };
|
|
440
456
|
}
|
|
441
457
|
|
|
442
|
-
return { action
|
|
458
|
+
return { action, amount, then: '' };
|
|
443
459
|
}
|
|
444
460
|
|
|
445
461
|
const item = items.find((x) => x.price.type === 'recurring');
|
|
446
|
-
const recurring = formatRecurring(
|
|
462
|
+
const recurring = formatRecurring(
|
|
463
|
+
(item?.upsell_price || item?.price)?.recurring as PriceRecurring,
|
|
464
|
+
false,
|
|
465
|
+
'per',
|
|
466
|
+
locale
|
|
467
|
+
);
|
|
447
468
|
|
|
448
469
|
// all recurring
|
|
449
470
|
if (items.every((x) => x.price.type === 'recurring')) {
|
|
450
471
|
const hasMetered = items.some((x) => x.price.type === 'recurring' && x.price.recurring?.usage_type === 'metered');
|
|
451
472
|
const subscription = [
|
|
452
|
-
hasMetered ? '
|
|
473
|
+
hasMetered ? t('checkout.least', locale) : '',
|
|
453
474
|
fromUnitToToken(
|
|
454
475
|
items.reduce((acc, x) => {
|
|
455
476
|
if (x.price.recurring?.usage_type === 'metered') {
|
|
@@ -466,14 +487,14 @@ export function formatCheckoutHeadlines(
|
|
|
466
487
|
if (items.length > 1) {
|
|
467
488
|
if (trial > 0) {
|
|
468
489
|
return {
|
|
469
|
-
action:
|
|
470
|
-
amount:
|
|
471
|
-
then:
|
|
490
|
+
action: t('checkout.try2', locale, { name, count: items.length - 1 }),
|
|
491
|
+
amount: t('checkout.free', locale, { count: trial }),
|
|
492
|
+
then: t('checkout.then', locale, { subscription, recurring }),
|
|
472
493
|
};
|
|
473
494
|
}
|
|
474
495
|
|
|
475
496
|
return {
|
|
476
|
-
action:
|
|
497
|
+
action: t('checkout.sub2', locale, { name, count: items.length - 1 }),
|
|
477
498
|
amount,
|
|
478
499
|
then: recurring,
|
|
479
500
|
};
|
|
@@ -481,14 +502,14 @@ export function formatCheckoutHeadlines(
|
|
|
481
502
|
|
|
482
503
|
if (trial > 0) {
|
|
483
504
|
return {
|
|
484
|
-
action:
|
|
485
|
-
amount:
|
|
486
|
-
then:
|
|
505
|
+
action: t('checkout.try1', locale, { name }),
|
|
506
|
+
amount: t('checkout.free', locale, { count: trial }),
|
|
507
|
+
then: t('checkout.then', locale, { subscription, recurring }),
|
|
487
508
|
};
|
|
488
509
|
}
|
|
489
510
|
|
|
490
511
|
return {
|
|
491
|
-
action:
|
|
512
|
+
action: t('checkout.sub1', locale, { name }),
|
|
492
513
|
amount,
|
|
493
514
|
then: recurring,
|
|
494
515
|
};
|
|
@@ -508,9 +529,9 @@ export function formatCheckoutHeadlines(
|
|
|
508
529
|
);
|
|
509
530
|
|
|
510
531
|
return {
|
|
511
|
-
action:
|
|
532
|
+
action: t('checkout.pay', locale, { payee: brand }),
|
|
512
533
|
amount,
|
|
513
|
-
then:
|
|
534
|
+
then: t('checkout.then', locale, { subscription: `${subscription} ${currency.symbol}`, recurring }),
|
|
514
535
|
};
|
|
515
536
|
}
|
|
516
537
|
|
package/src/locales/en.tsx
CHANGED
|
@@ -28,7 +28,8 @@ export default flat({
|
|
|
28
28
|
confirm: 'Confirm',
|
|
29
29
|
cancel: 'Cancel',
|
|
30
30
|
every: 'every',
|
|
31
|
-
per: 'per',
|
|
31
|
+
per: 'per {interval}',
|
|
32
|
+
slash: '/ {interval}',
|
|
32
33
|
unit: 'units',
|
|
33
34
|
edit: 'Edit',
|
|
34
35
|
quantity: 'Quantity',
|
|
@@ -47,16 +48,29 @@ export default flat({
|
|
|
47
48
|
copied: 'Copied',
|
|
48
49
|
previous: 'Back',
|
|
49
50
|
continue: 'Continue',
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
qty: 'Qty {count}',
|
|
52
|
+
each: '{unit} each',
|
|
53
|
+
trial: 'Free for {count} days',
|
|
54
|
+
billed: 'billed {rule}',
|
|
55
|
+
metered: 'based on usage',
|
|
56
|
+
hour: 'hour',
|
|
57
|
+
day: 'day',
|
|
58
|
+
week: 'week',
|
|
59
|
+
month: 'month',
|
|
60
|
+
year: 'year',
|
|
61
|
+
hourly: 'hourly',
|
|
62
|
+
daily: 'daily',
|
|
63
|
+
weekly: 'weekly',
|
|
64
|
+
monthly: 'monthly',
|
|
65
|
+
yearly: 'yearly',
|
|
66
|
+
month3: 'every 3 months',
|
|
67
|
+
month6: 'every 6 months',
|
|
68
|
+
recurring: 'every {count} {interval}',
|
|
69
|
+
hours: 'hours',
|
|
70
|
+
days: 'days',
|
|
71
|
+
weeks: 'weeks',
|
|
72
|
+
months: 'months',
|
|
73
|
+
years: 'years',
|
|
60
74
|
metadata: {
|
|
61
75
|
label: 'Metadata',
|
|
62
76
|
add: 'Add more metadata',
|
|
@@ -145,6 +159,8 @@ export default flat({
|
|
|
145
159
|
name: 'Price',
|
|
146
160
|
type: 'Usage type',
|
|
147
161
|
info: 'Price information',
|
|
162
|
+
count: '{count} prices',
|
|
163
|
+
empty: 'No price',
|
|
148
164
|
lookupKey: 'Lookup key',
|
|
149
165
|
setAsDefault: 'Set as default price',
|
|
150
166
|
detail: 'Pricing details',
|
|
@@ -496,6 +512,15 @@ export default flat({
|
|
|
496
512
|
login: 'Login to load and save contact information',
|
|
497
513
|
portal: 'Manage subscriptions',
|
|
498
514
|
cardPay: '{action} with card',
|
|
515
|
+
empty: 'No thing to pay',
|
|
516
|
+
pay: 'Pay {payee}',
|
|
517
|
+
try1: 'Try {name}',
|
|
518
|
+
try2: 'Try {name} and {count} more',
|
|
519
|
+
sub1: 'Subscribe to {name}',
|
|
520
|
+
sub2: 'Subscribe to {name} and {count} more',
|
|
521
|
+
then: 'Then {subscription} {recurring}',
|
|
522
|
+
free: '{count} days free',
|
|
523
|
+
least: 'continue with at least',
|
|
499
524
|
completed: {
|
|
500
525
|
payment: 'Thanks for your purchase',
|
|
501
526
|
subscription: 'Thanks for your subscribing',
|
package/src/locales/index.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-prototype-builtins */
|
|
1
2
|
import en from './en';
|
|
2
3
|
import zh from './zh';
|
|
3
4
|
|
|
@@ -6,3 +7,27 @@ export const translations = {
|
|
|
6
7
|
zh,
|
|
7
8
|
en,
|
|
8
9
|
};
|
|
10
|
+
|
|
11
|
+
export const replace = (template: string, data: Record<string, any> = {}) =>
|
|
12
|
+
template.replace(/{(\w*)}/g, (_, key) => (data.hasOwnProperty(key) ? data[key] : ''));
|
|
13
|
+
|
|
14
|
+
export const createTranslator = ({ fallbackLocale = 'en' }: { fallbackLocale?: string }) => {
|
|
15
|
+
return (key: string, locale = fallbackLocale, data: Record<string, any> = {}) => {
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
if (!translations[locale] || !translations[locale][key]) {
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
if (fallbackLocale && translations[fallbackLocale]?.[key]) {
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
return replace(translations[fallbackLocale]?.[key], data);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return key;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
return replace(translations[locale][key], data);
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const translate = createTranslator({ fallbackLocale: 'en' });
|
|
33
|
+
export const t = translate;
|
package/src/locales/zh.tsx
CHANGED
|
@@ -28,8 +28,9 @@ export default flat({
|
|
|
28
28
|
confirm: '确认',
|
|
29
29
|
cancel: '取消',
|
|
30
30
|
every: '每',
|
|
31
|
-
per: '每',
|
|
32
|
-
|
|
31
|
+
per: '每{interval}',
|
|
32
|
+
slash: '每{interval}',
|
|
33
|
+
unit: '件',
|
|
33
34
|
edit: '编辑',
|
|
34
35
|
quantity: '数量',
|
|
35
36
|
yes: '是',
|
|
@@ -47,16 +48,29 @@ export default flat({
|
|
|
47
48
|
copied: '已复制',
|
|
48
49
|
previous: '返回',
|
|
49
50
|
continue: '继续',
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
qty: '{count} 件',
|
|
52
|
+
each: '每件 {unit}',
|
|
53
|
+
trial: '免费试用 {count} 天',
|
|
54
|
+
billed: '{rule}收费',
|
|
55
|
+
metered: '按用量',
|
|
56
|
+
hour: '小时',
|
|
57
|
+
day: '天',
|
|
58
|
+
week: '周',
|
|
59
|
+
month: '月',
|
|
60
|
+
year: '年',
|
|
61
|
+
hourly: '按小时',
|
|
62
|
+
daily: '按天',
|
|
63
|
+
weekly: '按周',
|
|
64
|
+
monthly: '按月',
|
|
65
|
+
yearly: '按年',
|
|
66
|
+
month3: '按季度',
|
|
67
|
+
month6: '按半年',
|
|
68
|
+
recurring: '每{count}{interval}',
|
|
69
|
+
hours: '小时',
|
|
57
70
|
days: '天',
|
|
58
71
|
weeks: '周',
|
|
59
72
|
months: '月',
|
|
73
|
+
years: '年',
|
|
60
74
|
metadata: {
|
|
61
75
|
label: '元数据',
|
|
62
76
|
add: '添加更多元数据',
|
|
@@ -488,6 +502,16 @@ export default flat({
|
|
|
488
502
|
login: '登录以加载并保存联系信息',
|
|
489
503
|
portal: '管理订阅',
|
|
490
504
|
cardPay: '使用卡片{action}',
|
|
505
|
+
empty: '没有可支付的项目',
|
|
506
|
+
per: '每',
|
|
507
|
+
pay: '付款给 {payee}',
|
|
508
|
+
try1: '免费试用 {name}',
|
|
509
|
+
try2: '免费试用 {name} 等{count}个产品',
|
|
510
|
+
sub1: '订阅 {name}',
|
|
511
|
+
sub2: '订阅 {name} 等{count}个产品',
|
|
512
|
+
then: '然后 {subscription} {recurring}',
|
|
513
|
+
free: '{count} 天',
|
|
514
|
+
least: '至少',
|
|
491
515
|
completed: {
|
|
492
516
|
payment: '感谢您的购买',
|
|
493
517
|
subscription: '感谢您的订阅',
|
|
@@ -158,7 +158,8 @@ export default function PaymentLinkDetail(props: { id: string }) {
|
|
|
158
158
|
description={formatProductPrice(
|
|
159
159
|
// @ts-ignore
|
|
160
160
|
{ ...item.price.product, prices: [item.price] },
|
|
161
|
-
settings.baseCurrency
|
|
161
|
+
settings.baseCurrency,
|
|
162
|
+
locale
|
|
162
163
|
)}
|
|
163
164
|
logo={item.price.product.images[0]}
|
|
164
165
|
/>
|
|
@@ -27,7 +27,7 @@ const fetchData = (id: string): Promise<TPriceExpanded> => {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
export default function PriceDetail(props: { id: string }) {
|
|
30
|
-
const { t } = useLocaleContext();
|
|
30
|
+
const { t, locale } = useLocaleContext();
|
|
31
31
|
const navigate = useNavigate();
|
|
32
32
|
const [state, setState] = useSetState({
|
|
33
33
|
adding: {
|
|
@@ -121,7 +121,11 @@ export default function PriceDetail(props: { id: string }) {
|
|
|
121
121
|
value={<Link to={`/admin/products/${data.product_id}`}>{data.product.name}</Link>}
|
|
122
122
|
divider
|
|
123
123
|
/>
|
|
124
|
-
<InfoMetric
|
|
124
|
+
<InfoMetric
|
|
125
|
+
label={t('admin.price.amount')}
|
|
126
|
+
value={formatPrice(data, data.currency, data.product.unit_label, 1, true, locale)}
|
|
127
|
+
divider
|
|
128
|
+
/>
|
|
125
129
|
<InfoMetric label={t('common.createdAt')} value={formatTime(data.created_at)} divider />
|
|
126
130
|
<InfoMetric label={t('common.updatedAt')} value={formatTime(data.updated_at)} />
|
|
127
131
|
</Stack>
|
|
@@ -221,7 +225,11 @@ export default function PriceDetail(props: { id: string }) {
|
|
|
221
225
|
const item = data.currency_options[index] as any;
|
|
222
226
|
return formatPrice(
|
|
223
227
|
{ type: data.type, unit_amount: item.unit_amount, recurring: data.recurring } as TPrice,
|
|
224
|
-
item.currency
|
|
228
|
+
item.currency,
|
|
229
|
+
data.product.unit_label,
|
|
230
|
+
1,
|
|
231
|
+
true,
|
|
232
|
+
locale
|
|
225
233
|
);
|
|
226
234
|
},
|
|
227
235
|
},
|
|
@@ -13,7 +13,7 @@ import { formatPrice, formatTime } from '../../../../libs/util';
|
|
|
13
13
|
import PriceActions from './actions';
|
|
14
14
|
|
|
15
15
|
export default function PricesList({ product, onChange }: { product: Product; onChange: Function }) {
|
|
16
|
-
const { t } = useLocaleContext();
|
|
16
|
+
const { t, locale } = useLocaleContext();
|
|
17
17
|
const { settings } = useSettingsContext();
|
|
18
18
|
|
|
19
19
|
const columns = [
|
|
@@ -32,7 +32,9 @@ export default function PricesList({ product, onChange }: { product: Product; on
|
|
|
32
32
|
<LockOutlined sx={{ color: 'text.secondary' }} />
|
|
33
33
|
</Tooltip>
|
|
34
34
|
)}
|
|
35
|
-
<Typography component="span">
|
|
35
|
+
<Typography component="span">
|
|
36
|
+
{formatPrice(price, settings.baseCurrency, '', 1, true, locale)}
|
|
37
|
+
</Typography>
|
|
36
38
|
<Typography component="span">
|
|
37
39
|
{price.id === product.default_price_id && <Status label="default" color="info" sx={{ height: 18 }} />}
|
|
38
40
|
</Typography>
|
|
@@ -138,7 +138,8 @@ export default function PricingTableDetail(props: { id: string }) {
|
|
|
138
138
|
description={formatProductPrice(
|
|
139
139
|
// @ts-ignore
|
|
140
140
|
{ ...item.product, prices: [item.price] },
|
|
141
|
-
settings.baseCurrency
|
|
141
|
+
settings.baseCurrency,
|
|
142
|
+
locale
|
|
142
143
|
)}
|
|
143
144
|
logo={item.product.images[0]}
|
|
144
145
|
/>
|
|
@@ -18,7 +18,7 @@ import api from '../../../../libs/api';
|
|
|
18
18
|
import { formatError, formatPrice } from '../../../../libs/util';
|
|
19
19
|
|
|
20
20
|
export default function ProductsCreate() {
|
|
21
|
-
const { t } = useLocaleContext();
|
|
21
|
+
const { t, locale } = useLocaleContext();
|
|
22
22
|
const { settings } = useSettingsContext();
|
|
23
23
|
|
|
24
24
|
const methods = useForm<Product>({
|
|
@@ -85,7 +85,7 @@ export default function ProductsCreate() {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// @ts-ignore
|
|
88
|
-
return formatPrice(getPrice(index), settings.baseCurrency, getValues().unit_label, 1, false);
|
|
88
|
+
return formatPrice(getPrice(index), settings.baseCurrency, getValues().unit_label, 1, false, locale);
|
|
89
89
|
}}>
|
|
90
90
|
<PriceForm prefix={`prices.${index}`} />
|
|
91
91
|
</Collapse>
|
|
@@ -29,7 +29,7 @@ const getProduct = (id: string): Promise<TProductExpanded> => {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export default function ProductDetail(props: { id: string }) {
|
|
32
|
-
const { t } = useLocaleContext();
|
|
32
|
+
const { t, locale } = useLocaleContext();
|
|
33
33
|
const navigate = useNavigate();
|
|
34
34
|
const { settings } = useSettingsContext();
|
|
35
35
|
const [state, setState] = useSetState({
|
|
@@ -128,7 +128,7 @@ export default function ProductDetail(props: { id: string }) {
|
|
|
128
128
|
logo={data.images[0]}
|
|
129
129
|
name={data.name}
|
|
130
130
|
// @ts-ignore
|
|
131
|
-
description={formatProductPrice(data, settings.baseCurrency)}
|
|
131
|
+
description={formatProductPrice(data, settings.baseCurrency, locale)}
|
|
132
132
|
/>
|
|
133
133
|
<ProductActions data={data} onChange={onChange} variant="normal" />
|
|
134
134
|
</Stack>
|
|
@@ -28,7 +28,7 @@ export default function ProductsList() {
|
|
|
28
28
|
const listKey = 'products';
|
|
29
29
|
const persisted = getDurableData(listKey);
|
|
30
30
|
|
|
31
|
-
const { t } = useLocaleContext();
|
|
31
|
+
const { t, locale } = useLocaleContext();
|
|
32
32
|
const navigate = useNavigate();
|
|
33
33
|
const { settings } = useSettingsContext();
|
|
34
34
|
const [search, setSearch] = useState<{ active: string; pageSize: number; page: number }>({
|
|
@@ -62,7 +62,7 @@ export default function ProductsList() {
|
|
|
62
62
|
return (
|
|
63
63
|
<InfoCard
|
|
64
64
|
name={product.name}
|
|
65
|
-
description={formatProductPrice(product as any, settings.baseCurrency)}
|
|
65
|
+
description={formatProductPrice(product as any, settings.baseCurrency, locale)}
|
|
66
66
|
logo={product.images[0]}
|
|
67
67
|
/>
|
|
68
68
|
);
|