mirror of
https://github.com/valitydev/checkout.git
synced 2024-11-06 10:35:20 +00:00
Added copy btn for qr code (#121)
This commit is contained in:
parent
cbf893098b
commit
a6449446dc
@ -7,11 +7,19 @@ import { getActiveModalFormSelector, getLocaleSelector } from 'checkout/selector
|
||||
import { QRCode } from './qr-code';
|
||||
import { QrCodeInteractionFormInfo } from 'checkout/state';
|
||||
import { finishInteraction } from 'checkout/actions';
|
||||
import { CopyToClipboardButton, Hr, Input } from 'checkout/components/ui';
|
||||
|
||||
const Instruction = styled.p`
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
`;
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
`;
|
||||
|
||||
export const QrCodeInteractionForm: React.FC = () => {
|
||||
@ -24,9 +32,12 @@ export const QrCodeInteractionForm: React.FC = () => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Container>
|
||||
<Instruction>{locale['form.qr.code']}</Instruction>
|
||||
<QRCode text={request.qrCode} />
|
||||
</>
|
||||
<Hr />
|
||||
<Input defaultValue={request.qrCode} readOnly={true}></Input>
|
||||
<CopyToClipboardButton data={request.qrCode} />
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
@ -38,13 +38,14 @@ export const Button = styled.button<{ color?: ButtonType }>`
|
||||
}
|
||||
`
|
||||
: css`
|
||||
:hover,
|
||||
:active {
|
||||
border-color: ${theme.color.secondary[1.1]};
|
||||
:hover {
|
||||
color: ${theme.color.primary[1.1]};
|
||||
border-color: ${theme.color.primary[1.1]};
|
||||
}
|
||||
|
||||
:active {
|
||||
color: ${theme.color.secondary[1.1]};
|
||||
color: ${theme.color.primary[1.2]};
|
||||
border-color: ${theme.color.primary[1.2]};
|
||||
}
|
||||
`};
|
||||
`;
|
||||
|
@ -0,0 +1,25 @@
|
||||
import * as React from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useAppSelector } from 'checkout/configure-store';
|
||||
import { getLocaleSelector } from 'checkout/selectors';
|
||||
import { Button } from '../button';
|
||||
|
||||
export const CopyToClipboardButton: React.FC<{ data: string; timeout?: number }> = ({ data, timeout = 3000 }) => {
|
||||
const locale = useAppSelector(getLocaleSelector);
|
||||
const [label, setLabel] = useState(locale['form.button.copy.label']);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
setLabel(locale['form.button.copy.label']);
|
||||
}, timeout);
|
||||
return () => clearTimeout(timer);
|
||||
}, [label]);
|
||||
|
||||
const copyToClipboard = (qrCode: string) => {
|
||||
navigator.clipboard.writeText(qrCode);
|
||||
setLabel(locale['form.button.copied.label']);
|
||||
};
|
||||
|
||||
return <Button onClick={() => copyToClipboard(data)}>{label}</Button>;
|
||||
};
|
1
src/app/components/ui/copy-to-clipboard-button/index.ts
Normal file
1
src/app/components/ui/copy-to-clipboard-button/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './copy-to-clipboard-button';
|
7
src/app/components/ui/hr/hr.tsx
Normal file
7
src/app/components/ui/hr/hr.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import styled from 'checkout/styled-components';
|
||||
|
||||
export const Hr = styled.hr`
|
||||
width: 100%;
|
||||
border: 0;
|
||||
border-top: 1px solid ${({ theme }) => theme.color.neutral[0.1]};
|
||||
`;
|
1
src/app/components/ui/hr/index.ts
Normal file
1
src/app/components/ui/hr/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './hr';
|
@ -8,3 +8,5 @@ export * from './input';
|
||||
export * from './button';
|
||||
export * from './metadata';
|
||||
export * from './payment-method';
|
||||
export * from './hr';
|
||||
export * from './copy-to-clipboard-button';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { put, call, CallEffect, PutEffect } from 'redux-saga/effects';
|
||||
import { put, PutEffect } from 'redux-saga/effects';
|
||||
import { InvoiceEvent, InvoiceChangeType } from 'checkout/backend';
|
||||
import { Direction, GoToFormInfo, TypeKeys, SetModalState } from 'checkout/actions';
|
||||
import { ResultFormInfo, ResultType } from 'checkout/state';
|
||||
@ -7,7 +7,7 @@ import { getLastChange } from 'checkout/utils';
|
||||
|
||||
type SetStateFromEvents = GoToFormInfo | SetModalState;
|
||||
|
||||
function* toPayload(events: InvoiceEvent[]): IterableIterator<CallEffect | SetStateFromEvents> {
|
||||
function toPayload(events: InvoiceEvent[]): SetStateFromEvents {
|
||||
const change = getLastChange(events);
|
||||
switch (change.changeType) {
|
||||
case InvoiceChangeType.PaymentStatusChanged:
|
||||
@ -22,16 +22,13 @@ function* toPayload(events: InvoiceEvent[]): IterableIterator<CallEffect | SetSt
|
||||
case InvoiceChangeType.PaymentInteractionRequested:
|
||||
return {
|
||||
type: TypeKeys.SET_MODAL_STATE,
|
||||
payload: yield call(provideInteraction, events)
|
||||
payload: provideInteraction(events)
|
||||
};
|
||||
default:
|
||||
throw { code: 'error.unsupported.invoice.change.type' };
|
||||
}
|
||||
}
|
||||
|
||||
export function* provideFromInvoiceEvent(
|
||||
events: InvoiceEvent[]
|
||||
): IterableIterator<CallEffect | PutEffect<SetStateFromEvents>> {
|
||||
const payload = yield call(toPayload, events);
|
||||
return yield put<SetStateFromEvents>(payload);
|
||||
export function* provideFromInvoiceEvent(events: InvoiceEvent[]): IterableIterator<PutEffect<SetStateFromEvents>> {
|
||||
return yield put<SetStateFromEvents>(toPayload(events));
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import {
|
||||
QrCodeDisplayRequest,
|
||||
Redirect
|
||||
} from 'checkout/backend';
|
||||
import { SelectEffect } from 'redux-saga/effects';
|
||||
import last from 'lodash-es/last';
|
||||
import { findChange } from 'checkout/utils';
|
||||
|
||||
@ -71,9 +70,7 @@ const provideQrCode = (userInteraction: QrCodeDisplayRequest): ModalForms => {
|
||||
return new ModalForms([formInfo], true);
|
||||
};
|
||||
|
||||
export function* provideInteraction(
|
||||
events: InvoiceEvent[]
|
||||
): IterableIterator<ModalForms | ModalInteraction | SelectEffect> {
|
||||
export function provideInteraction(events: InvoiceEvent[]): ModalState {
|
||||
const lastEvent = last(events);
|
||||
const change = last(lastEvent.changes);
|
||||
if (change.changeType !== InvoiceChangeType.PaymentInteractionRequested) {
|
||||
|
@ -39,6 +39,8 @@
|
||||
"form.button.use.other.default.label": "Use different details",
|
||||
"form.button.pay.again.label": "Try again",
|
||||
"form.button.pay.label": "Pay",
|
||||
"form.button.copy.label": "Copy",
|
||||
"form.button.copied.label": "Copied!",
|
||||
"form.payment.method.name.card.label": "Card",
|
||||
"form.payment.method.name.apple.pay.label": "Apple Pay",
|
||||
"form.payment.method.name.google.pay.label": "Google Pay",
|
||||
|
@ -39,6 +39,8 @@
|
||||
"form.button.use.other.default.label": "他の詳細情報を使う",
|
||||
"form.button.pay.again.label": "もう一度お試しください",
|
||||
"form.button.pay.label": "支払う",
|
||||
"form.button.copy.label": "Copy",
|
||||
"form.button.copied.label": "Copied!",
|
||||
"form.payment.method.name.card.label": "カード",
|
||||
"form.payment.method.name.apple.pay.label": "Apple Pay",
|
||||
"form.payment.method.name.google.pay.label": "Google Pay",
|
||||
|
@ -39,6 +39,8 @@
|
||||
"form.button.use.other.default.label": "Use dados diferentes",
|
||||
"form.button.pay.again.label": "Tente de novo",
|
||||
"form.button.pay.label": "Pagar",
|
||||
"form.button.copy.label": "Copiar",
|
||||
"form.button.copied.label": "Сopiado!",
|
||||
"form.payment.method.name.card.label": "Card",
|
||||
"form.payment.method.name.apple.pay.label": "Apple Pay",
|
||||
"form.payment.method.name.google.pay.label": "Google Pay",
|
||||
|
@ -39,6 +39,8 @@
|
||||
"form.button.use.other.default.label": "Попробовать с другими данными",
|
||||
"form.button.pay.again.label": "Попробовать ещё раз",
|
||||
"form.button.pay.label": "Оплатить",
|
||||
"form.button.copy.label": "Скопировать",
|
||||
"form.button.copied.label": "Скопировано!",
|
||||
"form.payment.method.name.card.label": "Банковская карта",
|
||||
"form.payment.method.name.apple.pay.label": "Apple Pay",
|
||||
"form.payment.method.name.google.pay.label": "Google Pay",
|
||||
|
Loading…
Reference in New Issue
Block a user