mirror of
https://github.com/renee-png/acmcc.git
synced 2026-06-21 01:40:01 +00:00
Merge pull request #12 from renee-png/vendor-profile-email-billing-instructions
Vendor profile email: where-to-send-invoices block
This commit is contained in:
+23
-1
@@ -7,11 +7,14 @@ interface VendorProfileRequestProps {
|
|||||||
requesterName?: string
|
requesterName?: string
|
||||||
link?: string
|
link?: string
|
||||||
expiresAt?: string
|
expiresAt?: string
|
||||||
|
associationName?: string
|
||||||
|
billingAddress?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const SITE_NAME = 'Avria Community Management'
|
const SITE_NAME = 'Avria Community Management'
|
||||||
|
const AP_EMAIL = 'ap@avriacam.com'
|
||||||
|
|
||||||
const VendorProfileRequestEmail = ({ vendorName, requesterName, link, expiresAt }: VendorProfileRequestProps) => (
|
const VendorProfileRequestEmail = ({ vendorName, requesterName, link, expiresAt, associationName, billingAddress }: VendorProfileRequestProps) => (
|
||||||
<Html lang="en" dir="ltr">
|
<Html lang="en" dir="ltr">
|
||||||
<Head />
|
<Head />
|
||||||
<Preview>Vendor profile information requested for {vendorName || 'your account'}</Preview>
|
<Preview>Vendor profile information requested for {vendorName || 'your account'}</Preview>
|
||||||
@@ -27,6 +30,18 @@ const VendorProfileRequestEmail = ({ vendorName, requesterName, link, expiresAt
|
|||||||
</Text>
|
</Text>
|
||||||
{link && <Button href={link} style={button}>Submit vendor profile</Button>}
|
{link && <Button href={link} style={button}>Submit vendor profile</Button>}
|
||||||
{expiresAt && <Text style={meta}>This secure link expires on {expiresAt}.</Text>}
|
{expiresAt && <Text style={meta}>This secure link expires on {expiresAt}.</Text>}
|
||||||
|
<Section style={billingBox}>
|
||||||
|
<Text style={billingHeading}>Where to send your invoices</Text>
|
||||||
|
<Text style={billingText}>
|
||||||
|
Please email all invoices and bills to{' '}
|
||||||
|
<a href={`mailto:${AP_EMAIL}`} style={emailLink}>{AP_EMAIL}</a>, or mail them to:
|
||||||
|
</Text>
|
||||||
|
<Text style={addressText}>
|
||||||
|
{[associationName, 'c/o Avria Community Management, LLC', billingAddress]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join('\n')}
|
||||||
|
</Text>
|
||||||
|
</Section>
|
||||||
<Text style={footer}>
|
<Text style={footer}>
|
||||||
This request was sent by {SITE_NAME}. If you weren't expecting it, you can ignore this email.
|
This request was sent by {SITE_NAME}. If you weren't expecting it, you can ignore this email.
|
||||||
</Text>
|
</Text>
|
||||||
@@ -45,6 +60,8 @@ export const template = {
|
|||||||
requesterName: 'Avria Community Management',
|
requesterName: 'Avria Community Management',
|
||||||
link: 'https://avria.cloud/vendor-profile/sample-token',
|
link: 'https://avria.cloud/vendor-profile/sample-token',
|
||||||
expiresAt: 'June 1, 2026',
|
expiresAt: 'June 1, 2026',
|
||||||
|
associationName: 'Village Woods of La Cita Homeowners Association, Inc.',
|
||||||
|
billingAddress: 'P.O. Box 560099\nRockledge, FL 32956',
|
||||||
},
|
},
|
||||||
} satisfies TemplateEntry
|
} satisfies TemplateEntry
|
||||||
|
|
||||||
@@ -56,3 +73,8 @@ const text = { color: '#374151', fontSize: '15px', lineHeight: '24px', margin: '
|
|||||||
const meta = { color: '#6b7280', fontSize: '13px', lineHeight: '20px', margin: '14px 0 0' }
|
const meta = { color: '#6b7280', fontSize: '13px', lineHeight: '20px', margin: '14px 0 0' }
|
||||||
const button = { backgroundColor: '#2563eb', color: '#ffffff', borderRadius: '6px', fontSize: '14px', fontWeight: '600', textDecoration: 'none', padding: '12px 18px' }
|
const button = { backgroundColor: '#2563eb', color: '#ffffff', borderRadius: '6px', fontSize: '14px', fontWeight: '600', textDecoration: 'none', padding: '12px 18px' }
|
||||||
const footer = { color: '#6b7280', fontSize: '12px', lineHeight: '18px', margin: '28px 0 0' }
|
const footer = { color: '#6b7280', fontSize: '12px', lineHeight: '18px', margin: '28px 0 0' }
|
||||||
|
const billingBox = { backgroundColor: '#f9fafb', border: '1px solid #e5e7eb', borderRadius: '8px', padding: '16px 18px', margin: '26px 0 0' }
|
||||||
|
const billingHeading = { color: '#111827', fontSize: '15px', lineHeight: '22px', fontWeight: '700', margin: '0 0 8px' }
|
||||||
|
const billingText = { color: '#374151', fontSize: '14px', lineHeight: '22px', margin: '0 0 10px' }
|
||||||
|
const emailLink = { color: '#2563eb', textDecoration: 'underline' }
|
||||||
|
const addressText = { color: '#111827', fontSize: '14px', lineHeight: '22px', margin: '0', whiteSpace: 'pre-line' as const, fontWeight: '600' }
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ Deno.serve(async (req) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { data: vendor, error: vErr } = await admin
|
const { data: vendor, error: vErr } = await admin
|
||||||
.from('vendors').select('id, name, email').eq('id', vendor_id).single()
|
.from('vendors').select('id, name, email, association_id, association_ids').eq('id', vendor_id).single()
|
||||||
if (vErr || !vendor) {
|
if (vErr || !vendor) {
|
||||||
return new Response(JSON.stringify({ error: 'Vendor not found' }), {
|
return new Response(JSON.stringify({ error: 'Vendor not found' }), {
|
||||||
status: 404, headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
status: 404, headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
||||||
@@ -61,6 +61,18 @@ Deno.serve(async (req) => {
|
|||||||
const { data: profile } = await admin
|
const { data: profile } = await admin
|
||||||
.from('profiles').select('full_name').eq('user_id', userId).maybeSingle()
|
.from('profiles').select('full_name').eq('user_id', userId).maybeSingle()
|
||||||
|
|
||||||
|
// Resolve the vendor's association for the "where to send invoices" block.
|
||||||
|
const assocId = vendor.association_id
|
||||||
|
|| (Array.isArray(vendor.association_ids) ? vendor.association_ids[0] : null)
|
||||||
|
let associationName: string | undefined
|
||||||
|
let billingAddress: string | undefined
|
||||||
|
if (assocId) {
|
||||||
|
const { data: assoc } = await admin
|
||||||
|
.from('associations').select('name, mailing_address').eq('id', assocId).maybeSingle()
|
||||||
|
associationName = assoc?.name || undefined
|
||||||
|
billingAddress = assoc?.mailing_address || undefined
|
||||||
|
}
|
||||||
|
|
||||||
const { data: reqRow, error: reqErr } = await admin
|
const { data: reqRow, error: reqErr } = await admin
|
||||||
.from('vendor_profile_requests')
|
.from('vendor_profile_requests')
|
||||||
.insert({ vendor_id, sent_to_email: vendor.email, created_by: userId })
|
.insert({ vendor_id, sent_to_email: vendor.email, created_by: userId })
|
||||||
@@ -99,6 +111,8 @@ Deno.serve(async (req) => {
|
|||||||
requesterName: profile?.full_name || 'Avria Community Management',
|
requesterName: profile?.full_name || 'Avria Community Management',
|
||||||
link,
|
link,
|
||||||
expiresAt,
|
expiresAt,
|
||||||
|
associationName,
|
||||||
|
billingAddress,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user