feat(invoice): make the phone number on the PDF a clickable tel: link
Wraps the phone in a @react-pdf 'Link' with src='tel:+\u2026' just like the existing email (mailto:) and website (https:) entries in the contact footer. Display string keeps the human-readable formatting (spaces, parens) while the underlying URL is normalized per RFC 3966 (digits plus an optional leading '+'). PDF readers on macOS, iOS, Android and most desktop Linux setups launch the system dialer or a VoIP app on click; readers without a 'tel' handler fall back to selecting the number.
This commit is contained in:
@@ -588,7 +588,11 @@ function Footer({ issuer, language }: { issuer: IssuerData; language: InvoiceLan
|
|||||||
</View>
|
</View>
|
||||||
<View style={styles.footerCol}>
|
<View style={styles.footerCol}>
|
||||||
<Text style={styles.footerHeading}>{t.contactHeading}</Text>
|
<Text style={styles.footerHeading}>{t.contactHeading}</Text>
|
||||||
{issuer.phone ? <Text>{t.phoneLabel}: {issuer.phone}</Text> : null}
|
{issuer.phone ? (
|
||||||
|
<Text>
|
||||||
|
{t.phoneLabel}: <Link src={toTelUrl(issuer.phone)}>{issuer.phone}</Link>
|
||||||
|
</Text>
|
||||||
|
) : null}
|
||||||
{issuer.email ? (
|
{issuer.email ? (
|
||||||
<Text>
|
<Text>
|
||||||
{t.emailLabel}: <Link src={`mailto:${issuer.email}`}>{issuer.email}</Link>
|
{t.emailLabel}: <Link src={`mailto:${issuer.email}`}>{issuer.email}</Link>
|
||||||
@@ -644,6 +648,21 @@ function normaliseWebUrl(url: string): string {
|
|||||||
return `https://${trimmed.replace(/^\/\//, "")}`;
|
return `https://${trimmed.replace(/^\/\//, "")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a `tel:` URL from a free-form phone string. RFC 3966 allows only
|
||||||
|
* digits and a leading `+`, so we strip everything else (spaces, parens,
|
||||||
|
* dashes, slashes, dots, internal letters). The display string above the
|
||||||
|
* link keeps the human-readable formatting.
|
||||||
|
*/
|
||||||
|
function toTelUrl(phone: string): string {
|
||||||
|
const cleaned = phone.replace(/[^\d+]/g, "");
|
||||||
|
// Keep only a single leading '+' if present.
|
||||||
|
const normalized = cleaned.startsWith("+")
|
||||||
|
? "+" + cleaned.slice(1).replace(/\+/g, "")
|
||||||
|
: cleaned.replace(/\+/g, "");
|
||||||
|
return `tel:${normalized}`;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn a Shopify payment-gateway machine name (e.g. `shopify_payments`,
|
* Turn a Shopify payment-gateway machine name (e.g. `shopify_payments`,
|
||||||
* `manual`, `bogus`) or a built-in manual-payment template name (e.g.
|
* `manual`, `bogus`) or a built-in manual-payment template name (e.g.
|
||||||
|
|||||||
Reference in New Issue
Block a user