mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-14 11:50:31 +00:00
fix: attach branding template attrs to payment page
This commit is contained in:
@@ -25,7 +25,7 @@ export class GetInvoicePaymentLinkMetadata {
|
||||
.findOne('linkId', linkId)
|
||||
.where('resourceType', 'SaleInvoice')
|
||||
.throwIfNotFound();
|
||||
|
||||
|
||||
// Validate the expiry at date.
|
||||
if (paymentLink.expiryAt) {
|
||||
const currentDate = moment();
|
||||
@@ -46,6 +46,7 @@ export class GetInvoicePaymentLinkMetadata {
|
||||
.withGraphFetched('customer')
|
||||
.withGraphFetched('taxes.taxRate')
|
||||
.withGraphFetched('paymentMethods.paymentIntegration')
|
||||
.withGraphFetched('pdfTemplate')
|
||||
.throwIfNotFound();
|
||||
|
||||
return this.transformer.transform(
|
||||
|
||||
@@ -4,6 +4,7 @@ import { SaleInvoiceTaxEntryTransformer } from './SaleInvoiceTaxEntryTransformer
|
||||
import { SaleInvoiceTransformer } from './SaleInvoiceTransformer';
|
||||
import { Transformer } from '@/lib/Transformer/Transformer';
|
||||
import { contactAddressTextFormat } from '@/utils/address-text-format';
|
||||
import { GetPdfTemplateTransformer } from '@/services/PdfTemplate/GetPdfTemplateTransformer';
|
||||
|
||||
export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer {
|
||||
/**
|
||||
@@ -45,6 +46,7 @@ export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer
|
||||
'isReceivable',
|
||||
'hasStripePaymentMethod',
|
||||
'formattedCustomerAddress',
|
||||
'brandingTemplate',
|
||||
];
|
||||
};
|
||||
|
||||
@@ -63,6 +65,18 @@ export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the branding template for the payment link.
|
||||
* @param {} invoice
|
||||
* @returns
|
||||
*/
|
||||
public brandingTemplate(invoice) {
|
||||
return this.item(
|
||||
invoice.pdfTemplate,
|
||||
new GetInvoicePaymentLinkBrandingTemplate()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the entries of the sale invoice.
|
||||
* @param {ISaleInvoice} invoice
|
||||
@@ -114,7 +128,7 @@ export class GetInvoicePaymentLinkMetaTransformer extends SaleInvoiceTransformer
|
||||
|
||||
/**
|
||||
* Retrieves the formatted customer address.
|
||||
* @param invoice
|
||||
* @param invoice
|
||||
* @returns {string}
|
||||
*/
|
||||
protected formattedCustomerAddress(invoice) {
|
||||
@@ -193,3 +207,17 @@ class GetInvoicePaymentLinkTaxEntryTransformer extends SaleInvoiceTaxEntryTransf
|
||||
return ['name', 'taxRateCode', 'taxRateAmount', 'taxRateAmountFormatted'];
|
||||
};
|
||||
}
|
||||
|
||||
class GetInvoicePaymentLinkBrandingTemplate extends GetPdfTemplateTransformer {
|
||||
public includeAttributes = (): string[] => {
|
||||
return ['companyLogoUri', 'primaryColor'];
|
||||
};
|
||||
|
||||
public excludeAttributes = (): string[] => {
|
||||
return ['*'];
|
||||
};
|
||||
|
||||
primaryColor = (template) => {
|
||||
return template.attributes?.primaryColor;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
|
||||
:root {
|
||||
--payment-page-background-color: #fff;
|
||||
--payment-page-primary-button: #0052cc;
|
||||
}
|
||||
|
||||
.rootBodyPage {
|
||||
background: #1c1d29;
|
||||
background: var(--payment-page-background-color);
|
||||
}
|
||||
|
||||
.root {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Text, Classes, Button, Intent } from '@blueprintjs/core';
|
||||
import clsx from 'classnames';
|
||||
import { css } from '@emotion/css';
|
||||
import { AppToaster, Box, Group, Stack } from '@/components';
|
||||
import { usePaymentPortalBoot } from './PaymentPortalBoot';
|
||||
import { useDrawerActions } from '@/hooks/state';
|
||||
@@ -66,11 +67,11 @@ export function PaymentPortal() {
|
||||
<Stack spacing={0} className={styles.body}>
|
||||
<Stack>
|
||||
<Group spacing={10}>
|
||||
{sharableLinkMeta?.organization?.logoUri && (
|
||||
{sharableLinkMeta?.brandingTemplate?.companyLogoUri && (
|
||||
<Box
|
||||
className={styles.companyLogoWrap}
|
||||
style={{
|
||||
backgroundImage: `url(${sharableLinkMeta?.organization?.logoUri})`,
|
||||
backgroundImage: `url(${sharableLinkMeta?.brandingTemplate?.companyLogoUri})`,
|
||||
}}
|
||||
></Box>
|
||||
)}
|
||||
@@ -170,7 +171,22 @@ export function PaymentPortal() {
|
||||
sharableLinkMeta?.hasStripePaymentMethod && (
|
||||
<Button
|
||||
intent={Intent.PRIMARY}
|
||||
className={clsx(styles.footerButton, styles.buyButton)}
|
||||
className={clsx(
|
||||
styles.footerButton,
|
||||
styles.buyButton,
|
||||
css`
|
||||
&.bp4-button.bp4-intent-primary {
|
||||
background-color: var(--payment-page-primary-button);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(
|
||||
--payment-page-primary-button-hover
|
||||
);
|
||||
}
|
||||
}
|
||||
`,
|
||||
)}
|
||||
loading={isStripeCheckoutLoading}
|
||||
onClick={handlePayButtonClick}
|
||||
>
|
||||
|
||||
@@ -6,6 +6,8 @@ import { PaymentPortalBoot, usePaymentPortalBoot } from './PaymentPortalBoot';
|
||||
import { PaymentInvoicePreviewDrawer } from './drawers/PaymentInvoicePreviewDrawer/PaymentInvoicePreviewDrawer';
|
||||
import { DRAWERS } from '@/constants/drawers';
|
||||
import styles from './PaymentPortal.module.scss';
|
||||
import { useEffect } from 'react';
|
||||
import { hsl, lighten, parseToHsl } from 'polished';
|
||||
|
||||
export default function PaymentPortalPage() {
|
||||
const { linkId } = useParams<{ linkId: string }>();
|
||||
@@ -14,6 +16,7 @@ export default function PaymentPortalPage() {
|
||||
<BodyClassName className={styles.rootBodyPage}>
|
||||
<PaymentPortalBoot linkId={linkId}>
|
||||
<PaymentPortalHelmet />
|
||||
<PaymentPortalCssVariables />
|
||||
<PaymentPortal />
|
||||
<PaymentInvoicePreviewDrawer name={DRAWERS.PAYMENT_INVOICE_PREVIEW} />
|
||||
</PaymentPortalBoot>
|
||||
@@ -36,3 +39,33 @@ function PaymentPortalHelmet() {
|
||||
</Helmet>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the dynamic CSS variables for the current payment page.
|
||||
* @returns {React.ReactNode}
|
||||
*/
|
||||
function PaymentPortalCssVariables() {
|
||||
const { sharableLinkMeta } = usePaymentPortalBoot();
|
||||
|
||||
useEffect(() => {
|
||||
if (sharableLinkMeta?.brandingTemplate?.primaryColor) {
|
||||
const primaryColorHsl = parseToHsl(
|
||||
sharableLinkMeta?.brandingTemplate?.primaryColor,
|
||||
);
|
||||
document.body.style.setProperty(
|
||||
'--payment-page-background-color',
|
||||
hsl(primaryColorHsl.hue, 0.19, 0.14),
|
||||
);
|
||||
document.body.style.setProperty(
|
||||
'--payment-page-primary-button',
|
||||
sharableLinkMeta?.brandingTemplate?.primaryColor,
|
||||
);
|
||||
document.body.style.setProperty(
|
||||
'--payment-page-primary-button-hover',
|
||||
lighten(0.05, sharableLinkMeta?.brandingTemplate?.primaryColor),
|
||||
);
|
||||
}
|
||||
}, [sharableLinkMeta?.brandingTemplate?.primaryColor]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,10 @@ export interface GetInvoicePaymentLinkResponse {
|
||||
taxRateAmountFormatted: string;
|
||||
taxRateCode: string;
|
||||
}>;
|
||||
brandingTemplate: {
|
||||
companyLogoUri: string;
|
||||
primaryColor: string;
|
||||
};
|
||||
organization: GetInvoicePaymentLinkOrganizationRes;
|
||||
hasStripePaymentMethod: boolean;
|
||||
isReceivable: boolean;
|
||||
|
||||
Reference in New Issue
Block a user