feat: obfuscate email with click-to-reveal across all pages
Replace all bare info@ occurrences with a click-to-reveal pattern: - New EmailLink React component (base64 decode on click, never in DOM pre-click) - privacy, terms, refund pages use EmailLink - contact/index.html uses a vanilla JS button with the same pattern - PaymentForm mailto builder uses atob() to keep email out of source literals Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3330c47af2
commit
57cc5840b9
@ -1,4 +1,5 @@
|
||||
import type { Metadata } from 'next'
|
||||
import EmailLink from '@/components/EmailLink'
|
||||
|
||||
export const metadata: Metadata = { title: 'Privacy Policy' }
|
||||
|
||||
@ -75,13 +76,12 @@ export default function PrivacyPage() {
|
||||
<h2>8. Your rights</h2>
|
||||
<p>
|
||||
You may request access to, correction of, or deletion of your personal data at any
|
||||
time by emailing <a href="mailto:info@beachpartyballoons.com">info@beachpartyballoons.com</a>.
|
||||
time by emailing <EmailLink label="us directly" />.
|
||||
</p>
|
||||
|
||||
<h2>9. Contact</h2>
|
||||
<p>
|
||||
Questions about this policy? Email us at{' '}
|
||||
<a href="mailto:info@beachpartyballoons.com">info@beachpartyballoons.com</a> or call{' '}
|
||||
Questions about this policy? <EmailLink label="Email us" /> or call{' '}
|
||||
<a href="tel:+12035551234">(203) 555-1234</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import type { Metadata } from 'next'
|
||||
import EmailLink from '@/components/EmailLink'
|
||||
|
||||
export const metadata: Metadata = { title: 'Refund & Cancellation Policy' }
|
||||
|
||||
@ -19,8 +20,7 @@ export default function RefundPage() {
|
||||
<strong>75% store credit</strong>.
|
||||
</p>
|
||||
<p>
|
||||
To cancel, please contact us as soon as possible at{' '}
|
||||
<a href="mailto:info@beachpartyballoons.com">info@beachpartyballoons.com</a>.
|
||||
To cancel, please contact us as soon as possible — <EmailLink label="email us" />.
|
||||
</p>
|
||||
|
||||
<h2>After Delivery or Pickup</h2>
|
||||
@ -45,7 +45,7 @@ export default function RefundPage() {
|
||||
|
||||
<h2>Questions?</h2>
|
||||
<p>
|
||||
Email <a href="mailto:info@beachpartyballoons.com">info@beachpartyballoons.com</a> —
|
||||
<EmailLink label="Email us" /> —
|
||||
we’re a small local business and we’ll always do our best to make things right.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import type { Metadata } from 'next'
|
||||
import EmailLink from '@/components/EmailLink'
|
||||
|
||||
export const metadata: Metadata = { title: 'Terms & Conditions' }
|
||||
|
||||
@ -32,8 +33,7 @@ export default function TermsPage() {
|
||||
be resolved in the courts of New Haven County, Connecticut.
|
||||
</p>
|
||||
<p>
|
||||
Questions or concerns? Email us at{' '}
|
||||
<a href="mailto:info@beachpartyballoons.com">info@beachpartyballoons.com</a>.
|
||||
Questions or concerns? <EmailLink label="Email us" />.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
|
||||
42
estore/src/components/EmailLink.tsx
Normal file
42
estore/src/components/EmailLink.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
|
||||
const ENCODED = 'aW5mb0BiZWFjaHBhcnR5YmFsbG9vbnMuY29t'
|
||||
|
||||
interface Props {
|
||||
label?: string
|
||||
subject?: string
|
||||
body?: string
|
||||
}
|
||||
|
||||
export default function EmailLink({ label = 'click to reveal', subject, body }: Props) {
|
||||
const [addr, setAddr] = useState<string | null>(null)
|
||||
|
||||
if (!addr) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setAddr(atob(ENCODED))}
|
||||
style={{
|
||||
background: 'none',
|
||||
border: 'none',
|
||||
padding: 0,
|
||||
color: 'inherit',
|
||||
cursor: 'pointer',
|
||||
textDecoration: 'underline',
|
||||
font: 'inherit',
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
const params: string[] = []
|
||||
if (subject) params.push(`subject=${encodeURIComponent(subject)}`)
|
||||
if (body) params.push(`body=${encodeURIComponent(body)}`)
|
||||
const href = `mailto:${addr}${params.length ? '?' + params.join('&') : ''}`
|
||||
|
||||
return <a href={href}>{addr}</a>
|
||||
}
|
||||
@ -90,7 +90,8 @@ function buildMailtoLink(payload: CheckoutPayload): string {
|
||||
`Total: ${fmtCents(payload.grandTotal)}`,
|
||||
].join('\n')
|
||||
|
||||
return `mailto:info@beachpartyballoons.com?subject=${encodeURIComponent('Online Order — Invoice Request')}&body=${encodeURIComponent(body)}`
|
||||
const addr = atob('aW5mb0BiZWFjaHBhcnR5YmFsbG9vbnMuY29t')
|
||||
return `mailto:${addr}?subject=${encodeURIComponent('Online Order — Invoice Request')}&body=${encodeURIComponent(body)}`
|
||||
}
|
||||
|
||||
export default function PaymentForm({ payload, onSuccess, onError, active }: Props) {
|
||||
|
||||
@ -51,7 +51,17 @@
|
||||
<div class="is-flex-direction-column is-dark">
|
||||
<h2 class="is-size-4" style="text-align: center;"> <a target="_blank" href="https://maps.app.goo.gl/gRk6NztgMRUsSVJf9">554 Boston Post Road, Milford, CT 06460</a> </h2>
|
||||
<h2 class="is-size-4" style="text-align: center;" ><a href="tel:203.283.5626">203.283.5626</a> </h2>
|
||||
<h2 class="is-size-4" style="text-align: center;" ><a href="mailto:info@beachpartyballoons.com">info@beachpartyballoons.com</a> </h2>
|
||||
<h2 class="is-size-4" style="text-align: center;" id="bpb-email-h2">
|
||||
<button id="bpb-email-btn" style="background:none;border:none;cursor:pointer;font:inherit;color:inherit;text-decoration:underline;padding:0;">
|
||||
Click to show email address
|
||||
</button>
|
||||
</h2>
|
||||
<script>
|
||||
document.getElementById('bpb-email-btn').addEventListener('click', function () {
|
||||
var a = atob('aW5mb0BiZWFjaHBhcnR5YmFsbG9vbnMuY29t');
|
||||
document.getElementById('bpb-email-h2').innerHTML = '<a href="mailto:' + a + '">' + a + '<\/a>';
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user