payment-kit 1.13.18 → 1.13.20
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/README.md +14 -0
- package/api/src/index.ts +17 -6
- package/api/src/integrations/stripe/handlers/index.ts +53 -0
- package/api/src/integrations/stripe/handlers/invoice.ts +252 -0
- package/api/src/integrations/stripe/handlers/payment-intent.ts +172 -0
- package/api/src/integrations/stripe/handlers/setup-intent.ts +42 -0
- package/api/src/integrations/stripe/handlers/subscription.ts +61 -0
- package/api/src/integrations/stripe/resource.ts +317 -0
- package/api/src/integrations/stripe/setup.ts +50 -0
- package/api/src/jobs/invoice.ts +11 -0
- package/api/src/jobs/payment.ts +15 -7
- package/api/src/jobs/subscription.ts +18 -2
- package/api/src/libs/session.ts +104 -8
- package/api/src/libs/util.ts +47 -1
- package/api/src/routes/checkout-sessions.ts +134 -27
- package/api/src/routes/connect/collect.ts +12 -4
- package/api/src/routes/connect/pay.ts +30 -20
- package/api/src/routes/connect/setup.ts +12 -4
- package/api/src/routes/connect/shared.ts +28 -4
- package/api/src/routes/connect/subscribe.ts +12 -5
- package/api/src/routes/customers.ts +37 -5
- package/api/src/routes/events.ts +9 -6
- package/api/src/routes/index.ts +2 -0
- package/api/src/routes/integrations/stripe.ts +64 -0
- package/api/src/routes/invoices.ts +19 -9
- package/api/src/routes/payment-intents.ts +19 -9
- package/api/src/routes/payment-links.ts +57 -15
- package/api/src/routes/payment-methods.ts +98 -1
- package/api/src/routes/prices.ts +71 -14
- package/api/src/routes/products.ts +79 -22
- package/api/src/routes/settings.ts +10 -11
- package/api/src/routes/subscription-items.ts +5 -5
- package/api/src/routes/subscriptions.ts +61 -10
- package/api/src/routes/usage-records.ts +52 -18
- package/api/src/routes/webhook-attempts.ts +5 -5
- package/api/src/routes/webhook-endpoints.ts +5 -5
- package/api/src/store/migrations/20230905-genesis.ts +2 -2
- package/api/src/store/migrations/20230911-seeding.ts +4 -3
- package/api/src/store/models/checkout-session.ts +15 -7
- package/api/src/store/models/index.ts +31 -7
- package/api/src/store/models/invoice.ts +1 -1
- package/api/src/store/models/payment-intent.ts +2 -5
- package/api/src/store/models/payment-link.ts +1 -1
- package/api/src/store/models/payment-method.ts +54 -33
- package/api/src/store/models/price.ts +52 -17
- package/api/src/store/models/product.ts +0 -3
- package/api/src/store/models/subscription.ts +3 -5
- package/api/src/store/models/types.ts +56 -2
- package/api/third.d.ts +2 -0
- package/blocklet.yml +1 -1
- package/package.json +13 -6
- package/public/currencies/dai.png +0 -0
- package/public/currencies/dollar.png +0 -0
- package/public/currencies/usdc.png +0 -0
- package/public/currencies/usdt.png +0 -0
- package/public/methods/arcblock.png +0 -0
- package/public/methods/binance.png +0 -0
- package/public/methods/coinbase.png +0 -0
- package/public/methods/ethereum.jpg +0 -0
- package/public/methods/stripe.png +0 -0
- package/src/components/checkout/form/address.tsx +84 -10
- package/src/components/checkout/form/index.tsx +169 -83
- package/src/components/checkout/form/phone.tsx +102 -0
- package/src/components/checkout/form/stripe.tsx +195 -0
- package/src/components/checkout/pay.tsx +115 -34
- package/src/components/checkout/product-item.tsx +4 -3
- package/src/components/checkout/summary.tsx +5 -4
- package/src/components/customer/edit.tsx +73 -0
- package/src/components/customer/form.tsx +104 -0
- package/src/components/drawer-form.tsx +4 -4
- package/src/components/input.tsx +22 -4
- package/src/components/invoice/table.tsx +8 -3
- package/src/components/metadata/editor.tsx +2 -3
- package/src/components/payment-link/after-pay.tsx +1 -1
- package/src/components/payment-link/before-pay.tsx +11 -6
- package/src/components/payment-link/chrome.tsx +13 -0
- package/src/components/payment-link/preview.tsx +31 -0
- package/src/components/payment-link/product-select.tsx +8 -3
- package/src/components/payment-link/rename.tsx +2 -2
- package/src/components/payment-method/arcblock.tsx +53 -0
- package/src/components/payment-method/bitcoin.tsx +53 -0
- package/src/components/payment-method/ethereum.tsx +53 -0
- package/src/components/payment-method/form.tsx +54 -0
- package/src/components/payment-method/stripe.tsx +45 -0
- package/src/components/portal/invoice/list.tsx +1 -1
- package/src/components/portal/subscription/list.tsx +1 -1
- package/src/components/price/currency-select.tsx +53 -0
- package/src/components/price/form.tsx +118 -24
- package/src/components/product/add-price.tsx +1 -1
- package/src/components/product/edit-price.tsx +6 -2
- package/src/components/subscription/items/index.tsx +7 -6
- package/src/components/subscription/items/usage-records.tsx +98 -0
- package/src/components/subscription/list.tsx +3 -2
- package/src/components/subscription/status.tsx +68 -0
- package/src/contexts/settings.tsx +2 -2
- package/src/env.d.ts +2 -0
- package/src/libs/util.ts +116 -21
- package/src/locales/en.tsx +72 -3
- package/src/pages/admin/billing/invoices/detail.tsx +5 -2
- package/src/pages/admin/billing/subscriptions/detail.tsx +6 -6
- package/src/pages/admin/customers/customers/detail.tsx +43 -9
- package/src/pages/admin/payments/intents/detail.tsx +8 -3
- package/src/pages/admin/payments/links/create.tsx +23 -3
- package/src/pages/admin/payments/links/detail.tsx +13 -26
- package/src/pages/admin/products/prices/detail.tsx +55 -11
- package/src/pages/admin/products/prices/list.tsx +7 -1
- package/src/pages/admin/products/products/create.tsx +1 -1
- package/src/pages/admin/products/products/detail.tsx +14 -7
- package/src/pages/admin/settings/index.tsx +16 -6
- package/src/pages/admin/settings/payment-methods/create.tsx +81 -0
- package/src/pages/admin/settings/{payment-methods.tsx → payment-methods/index.tsx} +9 -6
- package/src/pages/checkout/pay.tsx +3 -1
- package/src/pages/customer/index.tsx +36 -1
- package/public/.gitkeep +0 -0
|
@@ -8,7 +8,7 @@ import type { LiteralUnion } from 'type-fest';
|
|
|
8
8
|
|
|
9
9
|
import { useProductsContext } from '../../contexts/products';
|
|
10
10
|
import { useSettingsContext } from '../../contexts/settings';
|
|
11
|
-
import { formatPrice } from '../../libs/util';
|
|
11
|
+
import { formatPrice, getPriceCurrencyOptions } from '../../libs/util';
|
|
12
12
|
|
|
13
13
|
type Props = {
|
|
14
14
|
mode: LiteralUnion<'waiting' | 'selecting', string>;
|
|
@@ -39,7 +39,7 @@ export default function ProductSelect({ mode: initialMode, hasSelected, onSelect
|
|
|
39
39
|
|
|
40
40
|
if (mode === 'selecting') {
|
|
41
41
|
return (
|
|
42
|
-
<Select value="" fullWidth size="small" onChange={handleSelect}>
|
|
42
|
+
<Select value="" fullWidth size="small" onChange={handleSelect} MenuProps={{ style: { maxHeight: 480 } }}>
|
|
43
43
|
<MenuItem value="add">
|
|
44
44
|
<AddOutlined />
|
|
45
45
|
{t('admin.product.add')}
|
|
@@ -50,7 +50,12 @@ export default function ProductSelect({ mode: initialMode, hasSelected, onSelect
|
|
|
50
50
|
</ListSubheader>,
|
|
51
51
|
...product.prices.map((price) => (
|
|
52
52
|
<MenuItem key={price.id} sx={{ pl: 3 }} value={price.id}>
|
|
53
|
-
{formatPrice(price, settings.baseCurrency)}
|
|
53
|
+
<Typography color="text.primary">{formatPrice(price, settings.baseCurrency)}</Typography>
|
|
54
|
+
<Typography color="text.secondary" sx={{ ml: 2 }}>
|
|
55
|
+
{getPriceCurrencyOptions(price).length > 1
|
|
56
|
+
? ` +${getPriceCurrencyOptions(price).length - 1} more currencies`
|
|
57
|
+
: ''}
|
|
58
|
+
</Typography>
|
|
54
59
|
</MenuItem>
|
|
55
60
|
)),
|
|
56
61
|
])}
|
|
@@ -26,8 +26,8 @@ export default function RenamePaymentLink({
|
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
const { handleSubmit, reset } = methods;
|
|
29
|
-
const onSubmit = async (
|
|
30
|
-
await handleSubmit(onSave)(
|
|
29
|
+
const onSubmit = async () => {
|
|
30
|
+
await handleSubmit(onSave)();
|
|
31
31
|
reset();
|
|
32
32
|
onCancel(null);
|
|
33
33
|
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/* eslint-disable no-nested-ternary */
|
|
2
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
|
+
|
|
4
|
+
import FormInput from '../input';
|
|
5
|
+
|
|
6
|
+
export default function ArcBlockMethodForm() {
|
|
7
|
+
const { t } = useLocaleContext();
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<FormInput
|
|
12
|
+
key="name"
|
|
13
|
+
name="name"
|
|
14
|
+
type="text"
|
|
15
|
+
rules={{ required: true }}
|
|
16
|
+
label={t('admin.paymentMethod.name.label')}
|
|
17
|
+
placeholder={t('admin.paymentMethod.name.tip')}
|
|
18
|
+
/>
|
|
19
|
+
<FormInput
|
|
20
|
+
key="description"
|
|
21
|
+
name="description"
|
|
22
|
+
type="text"
|
|
23
|
+
rules={{ required: true }}
|
|
24
|
+
label={t('admin.paymentMethod.description.label')}
|
|
25
|
+
placeholder={t('admin.paymentMethod.description.tip')}
|
|
26
|
+
/>
|
|
27
|
+
<FormInput
|
|
28
|
+
key="secret_key"
|
|
29
|
+
name="settings.arcblock.chain_id"
|
|
30
|
+
type="text"
|
|
31
|
+
rules={{ required: true }}
|
|
32
|
+
label={t('admin.paymentMethod.arcblock.chain_id.label')}
|
|
33
|
+
placeholder={t('admin.paymentMethod.arcblock.chain_id.tip')}
|
|
34
|
+
/>
|
|
35
|
+
<FormInput
|
|
36
|
+
key="api_host"
|
|
37
|
+
name="settings.arcblock.api_host"
|
|
38
|
+
type="text"
|
|
39
|
+
rules={{ required: true }}
|
|
40
|
+
label={t('admin.paymentMethod.arcblock.api_host.label')}
|
|
41
|
+
placeholder={t('admin.paymentMethod.arcblock.api_host.tip')}
|
|
42
|
+
/>
|
|
43
|
+
<FormInput
|
|
44
|
+
key="explorer_host"
|
|
45
|
+
name="settings.arcblock.explorer_host"
|
|
46
|
+
type="text"
|
|
47
|
+
rules={{ required: true }}
|
|
48
|
+
label={t('admin.paymentMethod.arcblock.explorer_host.label')}
|
|
49
|
+
placeholder={t('admin.paymentMethod.arcblock.explorer_host.tip')}
|
|
50
|
+
/>
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/* eslint-disable no-nested-ternary */
|
|
2
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
|
+
|
|
4
|
+
import FormInput from '../input';
|
|
5
|
+
|
|
6
|
+
export default function BitcoinMethodForm() {
|
|
7
|
+
const { t } = useLocaleContext();
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<FormInput
|
|
12
|
+
key="name"
|
|
13
|
+
name="name"
|
|
14
|
+
type="text"
|
|
15
|
+
rules={{ required: true }}
|
|
16
|
+
label={t('admin.paymentMethod.name.label')}
|
|
17
|
+
placeholder={t('admin.paymentMethod.name.tip')}
|
|
18
|
+
/>
|
|
19
|
+
<FormInput
|
|
20
|
+
key="description"
|
|
21
|
+
name="description"
|
|
22
|
+
type="text"
|
|
23
|
+
rules={{ required: true }}
|
|
24
|
+
label={t('admin.paymentMethod.description.label')}
|
|
25
|
+
placeholder={t('admin.paymentMethod.description.tip')}
|
|
26
|
+
/>
|
|
27
|
+
<FormInput
|
|
28
|
+
key="secret_key"
|
|
29
|
+
name="settings.bitcoin.chain_id"
|
|
30
|
+
type="text"
|
|
31
|
+
rules={{ required: true }}
|
|
32
|
+
label={t('admin.paymentMethod.bitcoin.chain_id.label')}
|
|
33
|
+
placeholder={t('admin.paymentMethod.bitcoin.chain_id.tip')}
|
|
34
|
+
/>
|
|
35
|
+
<FormInput
|
|
36
|
+
key="api_host"
|
|
37
|
+
name="settings.bitcoin.api_host"
|
|
38
|
+
type="text"
|
|
39
|
+
rules={{ required: true }}
|
|
40
|
+
label={t('admin.paymentMethod.bitcoin.api_host.label')}
|
|
41
|
+
placeholder={t('admin.paymentMethod.bitcoin.api_host.tip')}
|
|
42
|
+
/>
|
|
43
|
+
<FormInput
|
|
44
|
+
key="explorer_host"
|
|
45
|
+
name="settings.bitcoin.explorer_host"
|
|
46
|
+
type="text"
|
|
47
|
+
rules={{ required: true }}
|
|
48
|
+
label={t('admin.paymentMethod.bitcoin.explorer_host.label')}
|
|
49
|
+
placeholder={t('admin.paymentMethod.bitcoin.explorer_host.tip')}
|
|
50
|
+
/>
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/* eslint-disable no-nested-ternary */
|
|
2
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
|
+
|
|
4
|
+
import FormInput from '../input';
|
|
5
|
+
|
|
6
|
+
export default function EthereumMethodForm() {
|
|
7
|
+
const { t } = useLocaleContext();
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<FormInput
|
|
12
|
+
key="name"
|
|
13
|
+
name="name"
|
|
14
|
+
type="text"
|
|
15
|
+
rules={{ required: true }}
|
|
16
|
+
label={t('admin.paymentMethod.name.label')}
|
|
17
|
+
placeholder={t('admin.paymentMethod.name.tip')}
|
|
18
|
+
/>
|
|
19
|
+
<FormInput
|
|
20
|
+
key="description"
|
|
21
|
+
name="description"
|
|
22
|
+
type="text"
|
|
23
|
+
rules={{ required: true }}
|
|
24
|
+
label={t('admin.paymentMethod.description.label')}
|
|
25
|
+
placeholder={t('admin.paymentMethod.description.tip')}
|
|
26
|
+
/>
|
|
27
|
+
<FormInput
|
|
28
|
+
key="secret_key"
|
|
29
|
+
name="settings.ethereum.chain_id"
|
|
30
|
+
type="text"
|
|
31
|
+
rules={{ required: true }}
|
|
32
|
+
label={t('admin.paymentMethod.ethereum.chain_id.label')}
|
|
33
|
+
placeholder={t('admin.paymentMethod.ethereum.chain_id.tip')}
|
|
34
|
+
/>
|
|
35
|
+
<FormInput
|
|
36
|
+
key="api_host"
|
|
37
|
+
name="settings.ethereum.api_host"
|
|
38
|
+
type="text"
|
|
39
|
+
rules={{ required: true }}
|
|
40
|
+
label={t('admin.paymentMethod.ethereum.api_host.label')}
|
|
41
|
+
placeholder={t('admin.paymentMethod.ethereum.api_host.tip')}
|
|
42
|
+
/>
|
|
43
|
+
<FormInput
|
|
44
|
+
key="explorer_host"
|
|
45
|
+
name="settings.ethereum.explorer_host"
|
|
46
|
+
type="text"
|
|
47
|
+
rules={{ required: true }}
|
|
48
|
+
label={t('admin.paymentMethod.ethereum.explorer_host.label')}
|
|
49
|
+
placeholder={t('admin.paymentMethod.ethereum.explorer_host.tip')}
|
|
50
|
+
/>
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
2
|
+
import { Stack, ToggleButton, ToggleButtonGroup, Typography } from '@mui/material';
|
|
3
|
+
import { styled } from '@mui/system';
|
|
4
|
+
import { Controller, useFormContext, useWatch } from 'react-hook-form';
|
|
5
|
+
|
|
6
|
+
import ArcBlockMethodForm from './arcblock';
|
|
7
|
+
import BitcoinMethodForm from './bitcoin';
|
|
8
|
+
import EthereumMethodForm from './ethereum';
|
|
9
|
+
import StripeMethodForm from './stripe';
|
|
10
|
+
|
|
11
|
+
export default function PaymentMethodForm() {
|
|
12
|
+
const { t } = useLocaleContext();
|
|
13
|
+
const { control, setValue } = useFormContext();
|
|
14
|
+
|
|
15
|
+
const type = useWatch({ control, name: 'type' });
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Root direction="column" alignItems="flex-start" spacing={2}>
|
|
19
|
+
<Controller
|
|
20
|
+
name="type"
|
|
21
|
+
control={control}
|
|
22
|
+
render={({ field }) => (
|
|
23
|
+
<ToggleButtonGroup {...field} onChange={(_, value: string) => setValue(field.name, value)} exclusive>
|
|
24
|
+
<ToggleButton value="arcblock">ArcBlock</ToggleButton>
|
|
25
|
+
<ToggleButton value="stripe">Stripe</ToggleButton>
|
|
26
|
+
<ToggleButton value="ethereum" disabled>
|
|
27
|
+
Ethereum
|
|
28
|
+
</ToggleButton>
|
|
29
|
+
<ToggleButton value="bitcoin" disabled>
|
|
30
|
+
Bitcoin
|
|
31
|
+
</ToggleButton>
|
|
32
|
+
</ToggleButtonGroup>
|
|
33
|
+
)}
|
|
34
|
+
/>
|
|
35
|
+
<Typography variant="h6" sx={{ mb: 3, fontWeight: 600 }}>
|
|
36
|
+
{t('admin.paymentMethod.settings')}
|
|
37
|
+
</Typography>
|
|
38
|
+
{type === 'stripe' && <StripeMethodForm />}
|
|
39
|
+
{type === 'arcblock' && <ArcBlockMethodForm />}
|
|
40
|
+
{type === 'ethereum' && <EthereumMethodForm />}
|
|
41
|
+
{type === 'bitcoin' && <BitcoinMethodForm />}
|
|
42
|
+
</Root>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const Root = styled(Stack)`
|
|
47
|
+
select {
|
|
48
|
+
border: none;
|
|
49
|
+
&:active,
|
|
50
|
+
&:focus {
|
|
51
|
+
border: none;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/* eslint-disable no-nested-ternary */
|
|
2
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
|
+
|
|
4
|
+
import FormInput from '../input';
|
|
5
|
+
|
|
6
|
+
export default function StripeMethodForm() {
|
|
7
|
+
const { t } = useLocaleContext();
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<FormInput
|
|
12
|
+
key="name"
|
|
13
|
+
name="name"
|
|
14
|
+
type="text"
|
|
15
|
+
rules={{ required: true }}
|
|
16
|
+
label={t('admin.paymentMethod.name.label')}
|
|
17
|
+
placeholder={t('admin.paymentMethod.name.tip')}
|
|
18
|
+
/>
|
|
19
|
+
<FormInput
|
|
20
|
+
key="description"
|
|
21
|
+
name="description"
|
|
22
|
+
type="text"
|
|
23
|
+
rules={{ required: true }}
|
|
24
|
+
label={t('admin.paymentMethod.description.label')}
|
|
25
|
+
placeholder={t('admin.paymentMethod.description.tip')}
|
|
26
|
+
/>
|
|
27
|
+
<FormInput
|
|
28
|
+
key="publishable_key"
|
|
29
|
+
name="settings.stripe.publishable_key"
|
|
30
|
+
type="text"
|
|
31
|
+
rules={{ required: true }}
|
|
32
|
+
label={t('admin.paymentMethod.stripe.publishable_key.label')}
|
|
33
|
+
placeholder={t('admin.paymentMethod.stripe.publishable_key.tip')}
|
|
34
|
+
/>
|
|
35
|
+
<FormInput
|
|
36
|
+
key="secret_key"
|
|
37
|
+
name="settings.stripe.secret_key"
|
|
38
|
+
type="password"
|
|
39
|
+
rules={{ required: true }}
|
|
40
|
+
label={t('admin.paymentMethod.stripe.secret_key.label')}
|
|
41
|
+
placeholder={t('admin.paymentMethod.stripe.secret_key.tip')}
|
|
42
|
+
/>
|
|
43
|
+
</>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -43,7 +43,7 @@ export default function CustomerInvoiceList({ customer_id }: Props) {
|
|
|
43
43
|
const { data, loadMore, loadingMore, loading } = useInfiniteScroll<Paginated<TInvoiceExpanded>>(
|
|
44
44
|
(d) => {
|
|
45
45
|
const page = d ? Math.ceil(d.list.length / pageSize) + 1 : 1;
|
|
46
|
-
return fetchData({ page,
|
|
46
|
+
return fetchData({ page, pageSize, status: 'open,paid', customer_id });
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
reloadDeps: [customer_id],
|
|
@@ -41,7 +41,7 @@ export function CurrentSubscriptionsInner({ id, onChange }: Props) {
|
|
|
41
41
|
const { data, loadMore, loadingMore, loading } = useInfiniteScroll<Paginated<TSubscriptionExpanded>>(
|
|
42
42
|
(d) => {
|
|
43
43
|
const page = d ? Math.ceil(d.list.length / pageSize) + 1 : 1;
|
|
44
|
-
return fetchData({ page,
|
|
44
|
+
return fetchData({ page, pageSize, status: 'active,trialing,paused', customer_id: id });
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
reloadDeps: [id],
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
2
|
+
import { AddOutlined } from '@mui/icons-material';
|
|
3
|
+
import { ListSubheader, MenuItem, Select, Stack, Typography } from '@mui/material';
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import type { LiteralUnion } from 'type-fest';
|
|
6
|
+
|
|
7
|
+
import { useSettingsContext } from '../../contexts/settings';
|
|
8
|
+
import { getSupportedPaymentMethods } from '../../libs/util';
|
|
9
|
+
import Currency from '../currency';
|
|
10
|
+
|
|
11
|
+
type Props = {
|
|
12
|
+
mode: LiteralUnion<'waiting' | 'selecting', string>;
|
|
13
|
+
hasSelected: (currency: any) => boolean;
|
|
14
|
+
onSelect: (currencyId: string) => void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default function CurrencySelect({ mode: initialMode, hasSelected, onSelect }: Props) {
|
|
18
|
+
const { t } = useLocaleContext();
|
|
19
|
+
const { settings } = useSettingsContext();
|
|
20
|
+
const [mode, setMode] = useState(initialMode);
|
|
21
|
+
|
|
22
|
+
const handleSelect = (e: any) => {
|
|
23
|
+
setMode('waiting');
|
|
24
|
+
onSelect(e.target.value);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
if (mode === 'selecting') {
|
|
28
|
+
return (
|
|
29
|
+
<Select value="" sx={{ width: 260 }} size="small" onChange={handleSelect}>
|
|
30
|
+
{getSupportedPaymentMethods(settings.paymentMethods, hasSelected).map((method) => [
|
|
31
|
+
<ListSubheader key={method.id} sx={{ fontSize: '1rem', color: 'text.secondary', lineHeight: '2.5rem' }}>
|
|
32
|
+
{method.name}
|
|
33
|
+
</ListSubheader>,
|
|
34
|
+
...method.payment_currencies.map((currency) => (
|
|
35
|
+
<MenuItem key={currency.id} sx={{ pl: 3 }} value={currency.id}>
|
|
36
|
+
<Stack direction="row" justifyContent="space-between" sx={{ width: '100%' }}>
|
|
37
|
+
<Currency logo={currency.logo} name={currency.name} />
|
|
38
|
+
<Typography fontWeight="bold">{currency.symbol}</Typography>
|
|
39
|
+
</Stack>
|
|
40
|
+
</MenuItem>
|
|
41
|
+
)),
|
|
42
|
+
])}
|
|
43
|
+
</Select>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Stack sx={{ cursor: 'pointer' }} direction="row" alignItems="center" onClick={() => setMode('selecting')}>
|
|
49
|
+
<AddOutlined color="primary" />
|
|
50
|
+
<Typography color="primary">{t('admin.price.currency.add')}</Typography>
|
|
51
|
+
</Stack>
|
|
52
|
+
);
|
|
53
|
+
}
|