Skip to content

Commit fed4396

Browse files
author
Jon Tzeng
committed
Add QuoteId row and card-level copy to GiftCardDetailsCard
Extend the gift card tx details card with a Quote ID row and a single copy button on the right side that copies all data at once. Dividers stop short of the copy button. The redeem row remains separate with its own chevron. Document backward-compat: orderId stores quoteId in prior versions.
1 parent 16b7421 commit fed4396

3 files changed

Lines changed: 98 additions & 23 deletions

File tree

Lines changed: 96 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
import Clipboard from '@react-native-clipboard/clipboard'
12
import type { EdgeTxActionGiftCard } from 'edge-core-js'
23
import * as React from 'react'
3-
import { Linking } from 'react-native'
4+
import { Linking, View } from 'react-native'
45

56
import { useHandler } from '../../hooks/useHandler'
67
import { lstrings } from '../../locales/strings'
8+
import { triggerHaptic } from '../../util/haptic'
79
import { removeIsoPrefix } from '../../util/utils'
810
import { CircularBrandIcon } from '../common/CircularBrandIcon'
11+
import { DividerLineUi4 } from '../common/DividerLineUi4'
12+
import { EdgeTouchableOpacity } from '../common/EdgeTouchableOpacity'
13+
import { CopyIcon } from '../icons/ThemedIcons'
914
import { EdgeRow } from '../rows/EdgeRow'
15+
import { showToast } from '../services/AirshipInstance'
16+
import { cacheStyles, type Theme, useTheme } from '../services/ThemeContext'
1017
import { EdgeText } from '../themed/EdgeText'
1118
import { EdgeCard } from './EdgeCard'
1219

@@ -15,11 +22,21 @@ interface Props {
1522
}
1623

1724
/**
18-
* Displays gift card details including brand, amount, and redemption code
19-
* in TransactionDetailsScene for gift card purchases.
25+
* Displays gift card details including brand, amount, quote ID, and redemption
26+
* code in TransactionDetailsScene for gift card purchases.
27+
*
28+
* Layout: A left column of data rows with dividers and a single card-level copy
29+
* button on the right. Dividers stop short of the copy button area.
2030
*/
2131
export const GiftCardDetailsCard: React.FC<Props> = ({ action }) => {
2232
const { card, redemption } = action
33+
const theme = useTheme()
34+
const styles = getStyles(theme)
35+
36+
// Backward compat: Prior versions stored the quoteId in the `orderId` field
37+
// of EdgeTxActionGiftCard. Once edge-core-js adds an explicit `quoteId`
38+
// field, prefer that and fall back to `orderId` for older transactions.
39+
const quoteId = action.orderId
2340

2441
const handleRedeemPress = useHandler(() => {
2542
if (redemption?.url != null) {
@@ -43,30 +60,86 @@ export const GiftCardDetailsCard: React.FC<Props> = ({ action }) => {
4360
const fiatCurrency = removeIsoPrefix(card.fiatCurrencyCode)
4461
const amountDisplay = `${card.fiatAmount} ${fiatCurrency}`
4562

63+
// Build formatted string for card-level copy
64+
const copyText = React.useMemo(() => {
65+
const lines = [
66+
`${lstrings.gift_card_label}: ${card.name}`,
67+
`${lstrings.string_amount}: ${amountDisplay}`,
68+
`${lstrings.gift_card_quote_id_label}: ${quoteId}`
69+
]
70+
if (redemption?.code != null) {
71+
lines.push(`${lstrings.gift_card_security_code}: ${redemption.code}`)
72+
}
73+
return lines.join('\n')
74+
}, [card.name, amountDisplay, quoteId, redemption?.code])
75+
76+
const handleCopyAll = useHandler(() => {
77+
triggerHaptic('impactLight')
78+
Clipboard.setString(copyText)
79+
showToast(lstrings.fragment_copied)
80+
})
81+
4682
return (
47-
<EdgeCard sections>
48-
<EdgeRow icon={brandIcon} title={lstrings.gift_card_label}>
49-
<EdgeText>{card.name}</EdgeText>
50-
</EdgeRow>
51-
52-
<EdgeRow title={lstrings.string_amount} body={amountDisplay} />
53-
54-
{redemption?.code != null ? (
55-
<EdgeRow
56-
title={lstrings.gift_card_security_code}
57-
body={redemption.code}
58-
rightButtonType="copy"
59-
/>
60-
) : null}
83+
<EdgeCard>
84+
<View style={styles.cardLayout}>
85+
{/* Left column: data rows with dividers */}
86+
<View style={styles.dataColumn}>
87+
<EdgeRow icon={brandIcon} title={lstrings.gift_card_label}>
88+
<EdgeText>{card.name}</EdgeText>
89+
</EdgeRow>
90+
91+
<DividerLineUi4 />
6192

93+
<EdgeRow title={lstrings.string_amount} body={amountDisplay} />
94+
95+
<DividerLineUi4 />
96+
97+
<EdgeRow title={lstrings.gift_card_quote_id_label} body={quoteId} />
98+
99+
{redemption?.code != null ? (
100+
<>
101+
<DividerLineUi4 />
102+
<EdgeRow
103+
title={lstrings.gift_card_security_code}
104+
body={redemption.code}
105+
/>
106+
</>
107+
) : null}
108+
</View>
109+
110+
{/* Right column: card-level copy button */}
111+
<EdgeTouchableOpacity style={styles.copyColumn} onPress={handleCopyAll}>
112+
<CopyIcon size={theme.rem(1)} color={theme.iconTappable} />
113+
</EdgeTouchableOpacity>
114+
</View>
115+
116+
{/* Redeem row outside the copy layout - has its own chevron */}
62117
{redemption?.url != null ? (
63-
<EdgeRow
64-
title={lstrings.gift_card_redeem}
65-
body={lstrings.gift_card_redeem_visit}
66-
rightButtonType="touchable"
67-
onPress={handleRedeemPress}
68-
/>
118+
<>
119+
<DividerLineUi4 />
120+
<EdgeRow
121+
title={lstrings.gift_card_redeem}
122+
body={lstrings.gift_card_redeem_visit}
123+
rightButtonType="touchable"
124+
onPress={handleRedeemPress}
125+
/>
126+
</>
69127
) : null}
70128
</EdgeCard>
71129
)
72130
}
131+
132+
const getStyles = cacheStyles((theme: Theme) => ({
133+
cardLayout: {
134+
flexDirection: 'row' as const
135+
},
136+
dataColumn: {
137+
flex: 1,
138+
flexDirection: 'column' as const
139+
},
140+
copyColumn: {
141+
justifyContent: 'center' as const,
142+
alignItems: 'center' as const,
143+
paddingHorizontal: theme.rem(0.75)
144+
}
145+
}))

src/locales/en_US.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,6 +1969,7 @@ const strings = {
19691969
gift_card_pending: 'Pending Delivery, Please Wait...',
19701970
gift_card_pending_toast:
19711971
'Your gift card is being delivered. Please wait for a few minutes for it to arrive.',
1972+
gift_card_quote_id_label: 'Quote ID',
19721973
gift_card_quote_id_label_1s: 'QuoteID: %1$s',
19731974
gift_card_quote_expired_toast: 'Your quote has expired. Please try again.',
19741975
gift_card_product_unavailable_title: 'Temporarily Unavailable',

src/locales/strings/enUS.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,6 +1530,7 @@
15301530
"gift_card_failed": "Failed",
15311531
"gift_card_pending": "Pending Delivery, Please Wait...",
15321532
"gift_card_pending_toast": "Your gift card is being delivered. Please wait for a few minutes for it to arrive.",
1533+
"gift_card_quote_id_label": "Quote ID",
15331534
"gift_card_quote_id_label_1s": "QuoteID: %1$s",
15341535
"gift_card_quote_expired_toast": "Your quote has expired. Please try again.",
15351536
"gift_card_product_unavailable_title": "Temporarily Unavailable",

0 commit comments

Comments
 (0)