From 91a76dc822f82a2a120439c13bd570ea83edde2a Mon Sep 17 00:00:00 2001 From: Swiss Bitcoin Pay Date: Sun, 27 Apr 2025 11:01:50 +0200 Subject: [PATCH 1/3] Download receipt --- .env | 4 +-- src/assets/translations/en.json | 4 ++- src/assets/translations/fr.json | 4 ++- src/components/QR/index.tsx | 20 ++++++++--- src/components/QR/styled.ts | 6 ++-- src/screens/Invoice/Invoice.tsx | 59 ++++++++++++++++++++++++++++++--- src/screens/Invoice/styled.tsx | 20 +++++++++++ 7 files changed, 101 insertions(+), 16 deletions(-) diff --git a/.env b/.env index 46888063..df7aea74 100644 --- a/.env +++ b/.env @@ -1,3 +1,3 @@ -APP_VERSION=2.5.2 +APP_VERSION=2.5.3 -APP_BUILD_NUMBER=428 \ No newline at end of file +APP_BUILD_NUMBER=429 \ No newline at end of file diff --git a/src/assets/translations/en.json b/src/assets/translations/en.json index a6850d32..1e2be985 100644 --- a/src/assets/translations/en.json +++ b/src/assets/translations/en.json @@ -160,7 +160,9 @@ "scanToVerify": "Scan to verify your identity", "or": "or", "scanToWithdraw": "Scan to receive bitcoin via", - "printReceipt": "Print receipt" + "printReceipt": "Print receipt", + "receipt": "Receipt", + "downloadReceipt": "Download receipt" }, "history": { "title": "Transaction history", diff --git a/src/assets/translations/fr.json b/src/assets/translations/fr.json index 76b4675d..60c09950 100644 --- a/src/assets/translations/fr.json +++ b/src/assets/translations/fr.json @@ -160,7 +160,9 @@ "scanToVerify": "Scanner pour vérifier votre identité", "or": "ou", "scanToWithdraw": "Scanner pour recevoir des bitcoins via", - "printReceipt": "Imprimer reçu" + "printReceipt": "Imprimer reçu", + "receipt": "Reçu", + "downloadReceipt": "Télécharger le reçu" }, "history": { "title": "Historique des transactions", diff --git a/src/components/QR/index.tsx b/src/components/QR/index.tsx index 2142ebda..e5d416a4 100644 --- a/src/components/QR/index.tsx +++ b/src/components/QR/index.tsx @@ -61,7 +61,15 @@ type QRProps = Omit & { { icon?: IconProp } >; -export const QR = ({ style, image, icon, size = 0, ...props }: QRProps) => { +export const QR = ({ + style, + image, + icon, + size = 0, + logoBackgroundColor, + logoColor, + ...props +}: QRProps) => { const theme = useTheme(); const { padding, borderRadius } = useMemo( () => extractPaddingFromStyle(style as React.CSSProperties), @@ -79,9 +87,13 @@ export const QR = ({ style, image, icon, size = 0, ...props }: QRProps) => { style={{ transform: [{ scale: image.scale || 1 }] }} /> ) : icon ? ( - - - + + + ) : null} ); diff --git a/src/components/QR/styled.ts b/src/components/QR/styled.ts index 935af65d..f05655f7 100644 --- a/src/components/QR/styled.ts +++ b/src/components/QR/styled.ts @@ -1,5 +1,5 @@ import styled from "styled-components"; -import { Icon, Image, View } from "@components"; +import { Image, View } from "@components"; export const QRContainer = styled(View)` background: ${({ theme }) => theme.colors.white}; @@ -19,10 +19,10 @@ export const QRImage = styled(Image)` height: 70px; `; -export const QRIconContinaer = styled(View)` +export const QRIconContainer = styled(View)` position: absolute; background-color: ${({ theme }) => theme.colors.white}; - padding: 8px; + padding: 2%; border-radius: 100px; align-items: center; justify-content: center; diff --git a/src/screens/Invoice/Invoice.tsx b/src/screens/Invoice/Invoice.tsx index 2a820909..2b8e84a0 100644 --- a/src/screens/Invoice/Invoice.tsx +++ b/src/screens/Invoice/Invoice.tsx @@ -22,14 +22,17 @@ import { QR, CountdownCircleTimer, Pressable, - Modal + Modal, + View } from "@components"; import { faArrowLeft, faArrowUpRightFromSquare, faBolt, faCheck, + faCircleDown, faClock, + faFileDownload, faGlobe, faHandPointer, faIdCard, @@ -55,6 +58,7 @@ import { FooterLine } from "./components/FooterLine"; import { DEFAULT_DECIMALS, apiRootDomain, + apiRootUrl, appRootUrl, currencies, rateUpdateDelay @@ -162,6 +166,8 @@ const STATUS_ICON_SIZE = 120; const MAX_QR_SIZE = 320; const FOOTER_VALUE_ITEMS_SIZE = 18; +const REDIRECT_DELAY = 60 * 1000; + export const Invoice = () => { const navigate = useNavigate(); const { colors, gridSize } = useTheme(); @@ -396,8 +402,6 @@ export const Invoice = () => { delay: springAnimationDelay }); - const REDIRECT_DELAY = 7000; - redirectProgressApi.start({ to: { left: "0%" }, config: { duration: REDIRECT_DELAY } @@ -539,7 +543,10 @@ export const Invoice = () => { ); } - setDescription(getInvoiceData.description); + if (getInvoiceData.description) { + // don't remove description if it already stored + setDescription(getInvoiceData.description); + } setAmount(getInvoiceData.amount * 1000); setPaidAt(getInvoiceData.paidAt); setInvoiceCurrency(getInvoiceData.input.unit || "CHF"); @@ -736,6 +743,11 @@ export const Invoice = () => { printInvoiceTicket ]); + const downloadPdfLink = useMemo( + () => `${apiRootUrl}/export-to-pdf/${invoiceId}`, + [invoiceId] + ); + const getPageContainerProps = useCallback( (isSuccessScreen = false) => { return { @@ -788,6 +800,13 @@ export const Invoice = () => { [qrCodeSize, gridSize] ); + const redirectDuration = useMemo(() => { + if (!isExternalInvoice) { + return REDIRECT_DELAY / 1000; + } + return 7; + }, [isExternalInvoice]); + return ( <> { > + + + + {t("receipt")} + + <> _ @@ -1025,7 +1059,7 @@ export const Invoice = () => { { )} + {status === "settled" && ( + +