Merge pull request #691 from bigcapitalhq/pdf-templates-layout

fix: Pdf templates layout
This commit is contained in:
Ahmed Bouhuolia
2024-10-05 21:26:37 +02:00
committed by GitHub
17 changed files with 413 additions and 269 deletions

View File

@@ -10,21 +10,37 @@ block head
position: relative; position: relative;
box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color); box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color);
} }
.#{prefix}-header{
box-sizing: border-box;
display: flex;
flex-flow: wrap;
flex: 0 0 auto;
-webkit-box-align: start;
align-items: start;
-webkit-box-pack: start;
justify-content: flex-start;
gap: 10px;
}
.#{prefix}-header-details{
flex: 1;
display: flex;
flex-direction: column;
align-items: stretch;
gap: 20px;
flex: 1 1 0%;
}
.#{prefix}-big-title { .#{prefix}-big-title {
font-size: 60px; font-size: 60px;
margin: 0; margin: 0;
line-height: 1; line-height: 1;
margin-bottom: 25px;
font-weight: 500; font-weight: 500;
color: #333; color: #333;
} }
.#{prefix}-logo-wrap { .#{prefix}-logo-wrap img {
height: 120px; height: auto;
width: 120px; width: auto;
position: absolute; max-width: 400px;
right: 26px; max-height: 160px;
top: 26px;
overflow: hidden;
} }
.#{prefix}-terms-list { .#{prefix}-terms-list {
display: flex; display: flex;
@@ -132,22 +148,27 @@ block head
block content block content
div(class=`${prefix}-root`) div(class=`${prefix}-root`)
div(class=`${prefix}-big-title`) Credit Note
if showCompanyLogo && companyLogoUri //- Header (includes big title, details and logo)
div(class=`${prefix}-logo-wrap`) div(class=`${prefix}-header`)
img(src=companyLogoUri alt=`Company Logo`) //- Header details (includes big title and details)
div(class=`${prefix}-header-details`)
div(class=`${prefix}-big-title`) Credit Note
div(class=`${prefix}-terms-list`) div(class=`${prefix}-terms-list`)
if showCreditNoteNumber if showCreditNoteNumber
div(class=`${prefix}-terms-item`) div(class=`${prefix}-terms-item`)
div(class=`${prefix}-terms-item__label`) #{creditNoteNumberLabel}: div(class=`${prefix}-terms-item__label`) #{creditNoteNumberLabel}:
div(class=`${prefix}-terms-item__value`) #{creditNoteNumebr} div(class=`${prefix}-terms-item__value`) #{creditNoteNumebr}
if showCreditNoteDate if showCreditNoteDate
div(class=`${prefix}-terms-item`) div(class=`${prefix}-terms-item`)
div(class=`${prefix}-terms-item__label`) #{creditNoteDateLabel}: div(class=`${prefix}-terms-item__label`) #{creditNoteDateLabel}:
div(class=`${prefix}-terms-item__value`) #{creditNoteDate} div(class=`${prefix}-terms-item__value`) #{creditNoteDate}
if showCompanyLogo && companyLogoUri
div(class=`${prefix}-logo-wrap`)
img(src=companyLogoUri alt=`Company Logo`)
div(class=`${prefix}-address-section`) div(class=`${prefix}-address-section`)
if showCompanyAddress if showCompanyAddress

View File

@@ -10,21 +10,37 @@ block head
position: relative; position: relative;
box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color); box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color);
} }
.#{prefix}-header {
box-sizing: border-box;
display: flex;
flex-flow: wrap;
flex: 0 0 auto;
-webkit-box-align: start;
align-items: start;
-webkit-box-pack: start;
justify-content: flex-start;
gap: 10px;
}
.#{prefix}-header-details {
flex: 1;
display: flex;
flex-direction: column;
align-items: stretch;
gap: 20px;
flex: 1 1 0%;
}
.#{prefix}-big-title { .#{prefix}-big-title {
font-size: 60px; font-size: 60px;
margin: 0; margin: 0;
line-height: 1; line-height: 1;
margin-bottom: 25px;
font-weight: 500; font-weight: 500;
color: #333; color: #333;
} }
.#{prefix}-logo-wrap { .#{prefix}-logo-wrap img {
height: 120px; height: auto;
width: 120px; width: auto;
position: absolute; max-width: 400px;
right: 26px; max-height: 160px;
top: 26px;
overflow: hidden;
} }
.#{prefix}-terms { .#{prefix}-terms {
display: flex; display: flex;
@@ -131,26 +147,35 @@ block head
block content block content
div(class=`${prefix}-root`, style=`--invoice-primary-color: ${primaryColor}; --invoice-secondary-color: ${secondaryColor};`) div(class=`${prefix}-root`, style=`--invoice-primary-color: ${primaryColor}; --invoice-secondary-color: ${secondaryColor};`)
h1(class=`${prefix}-big-title`) Estimate
if showCompanyLogo && companyLogoUri //- Header (invluces big title, details and logo)
div(class=`${prefix}-logo-wrap`) div(class=`${prefix}-header`)
img(alt="Company logo", src=companyLogoUri)
//- Terms List //- Header details (includes big title and details )
div(class=`${prefix}-terms`) div(class=`${prefix}-header-details`)
if showEstimateNumber h1(class=`${prefix}-big-title`) Estimate
div(class=`${prefix}-terms-item`)
div(class=`${prefix}-terms-item__label`) #{estimateNumberLabel} //- Terms List
div(class=`${prefix}-terms-item__value`) #{estimateNumebr} div(class=`${prefix}-terms`)
if showEstimateDate if showEstimateNumber
div(class=`${prefix}-terms-item`) div(class=`${prefix}-terms-item`)
div(class=`${prefix}-terms-item__label`) #{estimateDateLabel} div(class=`${prefix}-terms-item__label`) #{estimateNumberLabel}
div(class=`${prefix}-terms-item__value`) #{estimateDate} div(class=`${prefix}-terms-item__value`) #{estimateNumebr}
if showExpirationDate
div(class=`${prefix}-terms-item`) if showEstimateDate
div(class=`${prefix}-terms-item__label`) #{expirationDateLabel} div(class=`${prefix}-terms-item`)
div(class=`${prefix}-terms-item__value`) #{expirationDate} div(class=`${prefix}-terms-item__label`) #{estimateDateLabel}
div(class=`${prefix}-terms-item__value`) #{estimateDate}
if showExpirationDate
div(class=`${prefix}-terms-item`)
div(class=`${prefix}-terms-item__label`) #{expirationDateLabel}
div(class=`${prefix}-terms-item__value`) #{expirationDate}
//- Company logo
if showCompanyLogo && companyLogoUri
div(class=`${prefix}-logo-wrap`)
img(alt="Company logo", src=companyLogoUri)
//- Addresses (Group section) //- Addresses (Group section)
div(class=`${prefix}-addresses`) div(class=`${prefix}-addresses`)

View File

@@ -10,21 +10,37 @@ block head
position: relative; position: relative;
box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color); box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color);
} }
.#{prefix}-header{
box-sizing: border-box;
display: flex;
flex-flow: wrap;
flex: 0 0 auto;
-webkit-box-align: start;
align-items: start;
-webkit-box-pack: start;
justify-content: flex-start;
gap: 10px;
}
.#{prefix}-header-details{
flex: 1;
display: flex;
flex-direction: column;
align-items: stretch;
gap: 20px;
flex: 1 1 0%;
}
.#{prefix}-big-title { .#{prefix}-big-title {
font-size: 60px; font-size: 60px;
margin: 0; margin: 0;
line-height: 1; line-height: 1;
margin-bottom: 25px;
font-weight: 500; font-weight: 500;
color: #333; color: #333;
} }
.#{prefix}-logo-wrap { .#{prefix}-logo-wrap img {
height: 120px; height: auto;
width: 120px; width: auto;
position: absolute; max-width: 400px;
right: 26px; max-height: 160px;
top: 26px;
overflow: hidden;
} }
.#{prefix}-details { .#{prefix}-details {
display: flex; display: flex;
@@ -139,29 +155,34 @@ block content
//- block head //- block head
div(class=`${prefix}-root`, style=`--invoice-primary-color: ${primaryColor}; --invoice-secondary-color: ${secondaryColor};`) div(class=`${prefix}-root`, style=`--invoice-primary-color: ${primaryColor}; --invoice-secondary-color: ${secondaryColor};`)
//- Title and company logo //- Header (includes big title, details and logo )
h1(class=`${prefix}-big-title`) Invoice div(class=`${prefix}-header`)
//- Header details (includes big title and details )
div(class=`${prefix}-header-details`)
//- Title and company logo
h1(class=`${prefix}-big-title`) Invoice
if showCompanyLogo && companyLogoUri //- Invoice details
div(class=`${prefix}-logo-wrap`) div(class=`${prefix}-details`)
img(alt="Company logo", src=companyLogoUri) if showInvoiceNumber
div(class=`${prefix}-detail`)
div(class=`${prefix}-detail__label`) #{invoiceNumberLabel}
div(class=`${prefix}-detail__value`) #{invoiceNumber}
//- Invoice details if showDateIssue
div(class=`${prefix}-details`) div(class=`${prefix}-detail`)
if showInvoiceNumber div(class=`${prefix}-detail__label`) #{dateIssueLabel}
div(class=`${prefix}-detail`) div(class=`${prefix}-detail__value`) #{dateIssue}
div(class=`${prefix}-detail__label`) #{invoiceNumberLabel}
div(class=`${prefix}-detail__value`) #{invoiceNumber}
if showDateIssue if showDueDate
div(class=`${prefix}-detail`) div(class=`${prefix}-detail`)
div(class=`${prefix}-detail__label`) #{dateIssueLabel} div(class=`${prefix}-detail__label`) #{dueDateLabel}
div(class=`${prefix}-detail__value`) #{dateIssue} div(class=`${prefix}-detail__value`) #{dueDate}
if showDueDate //- Company logo
div(class=`${prefix}-detail`) if showCompanyLogo && companyLogoUri
div(class=`${prefix}-detail__label`) #{dueDateLabel} div(class=`${prefix}-logo-wrap`)
div(class=`${prefix}-detail__value`) #{dueDate} img(alt="Company logo", src=companyLogoUri)
//- Address section //- Address section
div(class=`${prefix}-address-root`) div(class=`${prefix}-address-root`)

View File

@@ -10,22 +10,38 @@ block head
font-size: 12px; font-size: 12px;
position: relative; position: relative;
box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color); box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color);
}
.#{prefix}-header{
box-sizing: border-box;
display: flex;
flex-flow: wrap;
flex: 0 0 auto;
-webkit-box-align: start;
align-items: start;
-webkit-box-pack: start;
justify-content: flex-start;
gap: 10px;
}
.#{prefix}-header-details{
flex: 1;
display: flex;
flex-direction: column;
align-items: stretch;
gap: 20px;
flex: 1 1 0%;
} }
.#{prefix}-big-title{ .#{prefix}-big-title{
font-size: 60px; font-size: 60px;
margin: 0; margin: 0;
line-height: 1; line-height: 1;
margin-bottom: 25px;
font-weight: 500; font-weight: 500;
color: #333; color: #333;
} }
.#{prefix}-logo-wrap{ .#{prefix}-logo-wrap img {
height: 120px; height: auto;
width: 120px; width: auto;
position: absolute; max-width: 400px;
right: 26px; max-height: 160px;
top: 26px;
overflow: hidden;
} }
.#{prefix}-terms-list{ .#{prefix}-terms-list{
display: flex; display: flex;
@@ -120,22 +136,25 @@ block head
} }
block content block content
div(class=`${prefix}-root`) div(class=`${prefix}-root`)
div(class=`${prefix}-big-title`) Payment //- Header (includes big title, details and logo )
div(class=`${prefix}-header`)
//- Header details (includes big title and details )
div(class=`${prefix}-header-details`)
div(class=`${prefix}-big-title`) Payment
div(class=`${prefix}-terms-list`)
if showPaymentReceivedNumber
div(class=`${prefix}-terms-item`)
div(class=`${prefix}-terms-item__label`) #{paymentReceivedNumberLabel}
div(class=`${prefix}-terms-item__value`) #{paymentReceivedNumebr}
if showCompanyLogo && companyLogoUri if showPaymentReceivedDate
div(class=`${prefix}-logo-wrap`) div(class=`${prefix}-terms-item`)
img(src=companyLogoUri alt="Company Logo") div(class=`${prefix}-terms-item__label`) #{paymentReceivedDateLabel}
div(class=`${prefix}-terms-item__value`) #{paymentReceivedDate}
div(class=`${prefix}-terms-list`) if showCompanyLogo && companyLogoUri
if showPaymentReceivedNumber div(class=`${prefix}-logo-wrap`)
div(class=`${prefix}-terms-item`) img(src=companyLogoUri alt="Company Logo")
div(class=`${prefix}-terms-item__label`) #{paymentReceivedNumberLabel}
div(class=`${prefix}-terms-item__value`) #{paymentReceivedNumebr}
if showPaymentReceivedDate
div(class=`${prefix}-terms-item`)
div(class=`${prefix}-terms-item__label`) #{paymentReceivedDateLabel}
div(class=`${prefix}-terms-item__value`) #{paymentReceivedDate}
div(class=`${prefix}-addresses`) div(class=`${prefix}-addresses`)
if showCompanyAddress if showCompanyAddress

View File

@@ -10,19 +10,33 @@ block head
position: relative; position: relative;
box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color); box-shadow: inset 0 4px 0px 0 var(--invoice-primary-color);
} }
.#{prefix}-logo-wrap { .#{prefix}-header{
height: 120px; box-sizing: border-box;
width: 120px; display: flex;
position: absolute; flex-flow: wrap;
right: 26px; flex: 0 0 auto;
top: 26px; align-items: start;
overflow: hidden; justify-content: flex-start;
gap: 10px;
}
.#{prefix}-header-details{
flex: 1;
display: flex;
flex-direction: column;
align-items: stretch;
gap: 20px;
flex: 1 1 0%;
}
.#{prefix}-logo-wrap img {
height: auto;
width: auto;
max-width: 400px;
max-height: 160px;
} }
.#{prefix}-big-title { .#{prefix}-big-title {
font-size: 60px; font-size: 60px;
margin: 0; margin: 0;
line-height: 1; line-height: 1;
margin-bottom: 25px;
font-weight: 500; font-weight: 500;
color: #333; color: #333;
} }
@@ -125,24 +139,29 @@ block content
//- block head //- block head
div(class=`${prefix}-root`, style=`--invoice-primary-color: ${primaryColor}; --invoice-secondary-color: ${secondaryColor};`) div(class=`${prefix}-root`, style=`--invoice-primary-color: ${primaryColor}; --invoice-secondary-color: ${secondaryColor};`)
//- Title and company logo //- Header (includes big title, details and logo )
h1(class=`${prefix}-big-title`) Receipt div(class=`${prefix}-header`)
//- Header details (includes big title and details )
div(class=`${prefix}-header-details`)
//- Title and company logo
h1(class=`${prefix}-big-title`) Receipt
//- Company Logo //- Terms List
if showCompanyLogo && companyLogoUri div(class=`${prefix}-terms-list`)
div(class=`${prefix}-logo-wrap`) if showReceiptNumber
img(src=companyLogoUri alt=`Company Logo`) div(class=`${prefix}-terms-item`)
span(class=`${prefix}-terms-item__label`)= receiptNumberLabel
span(class=`${prefix}-terms-item__value`)= receiptNumber
//- Terms List if showReceiptDate
div(class=`${prefix}-terms-list`) div(class=`${prefix}-terms-item`)
if showReceiptNumber span(class=`${prefix}-terms-item__label`)= receiptDateLabel
div(class=`${prefix}-terms-item`) span(class=`${prefix}-terms-item__value`)= receiptDate
span(class=`${prefix}-terms-item__label`)= receiptNumberLabel
span(class=`${prefix}-terms-item__value`)= receiptNumber //- Company logo
if showReceiptDate if showCompanyLogo && companyLogoUri
div(class=`${prefix}-terms-item`) div(class=`${prefix}-logo-wrap`)
span(class=`${prefix}-terms-item__label`)= receiptDateLabel img(src=companyLogoUri alt=`Company Logo`)
span(class=`${prefix}-terms-item__value`)= receiptDate
//- Address Section //- Address Section
div(class=`${prefix}-address-section`) div(class=`${prefix}-address-section`)

View File

@@ -27,11 +27,14 @@ export interface GroupProps extends React.ComponentPropsWithoutRef<'div'> {
/** Defines align-items css property */ /** Defines align-items css property */
align?: React.CSSProperties['alignItems']; align?: React.CSSProperties['alignItems'];
flex?: React.CSSProperties['flex'];
} }
const defaultProps: Partial<GroupProps> = { const defaultProps: Partial<GroupProps> = {
position: 'left', position: 'left',
spacing: 20, spacing: 20,
flex: 'none'
}; };
export function Group({ children, ...props }: GroupProps) { export function Group({ children, ...props }: GroupProps) {
@@ -48,6 +51,7 @@ const GroupStyled = styled(Box)`
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex: ${(props: GroupProps) => (props.flex)};
align-items: ${(props: GroupProps) => (props.align || 'center')}; align-items: ${(props: GroupProps) => (props.align || 'center')};
flex-wrap: ${(props: GroupProps) => (props.noWrap ? 'nowrap' : 'wrap')}; flex-wrap: ${(props: GroupProps) => (props.noWrap ? 'nowrap' : 'wrap')};
justify-content: ${(props: GroupProps) => justify-content: ${(props: GroupProps) =>

View File

@@ -11,12 +11,15 @@ export interface StackProps extends React.ComponentPropsWithoutRef<'div'> {
/** justify-content CSS property */ /** justify-content CSS property */
justify?: React.CSSProperties['justifyContent']; justify?: React.CSSProperties['justifyContent'];
flex?: React.CSSProperties['flex'];
} }
const defaultProps: Partial<StackProps> = { const defaultProps: Partial<StackProps> = {
spacing: 20, spacing: 20,
align: 'stretch', align: 'stretch',
justify: 'top', justify: 'top',
flex: 'none',
}; };
export function Stack(props: StackProps) { export function Stack(props: StackProps) {
@@ -33,4 +36,5 @@ const StackStyled = styled(Box)`
align-items: ${(props: StackProps) => props.align}; align-items: ${(props: StackProps) => props.align};
justify-content: justify; justify-content: justify;
gap: ${(props: StackProps) => props.spacing}px; gap: ${(props: StackProps) => props.spacing}px;
flex: ${(props: StackProps) => props.flex};
`; `;

View File

@@ -1,4 +1,4 @@
import { Box, Stack } from '@/components'; import { Box, Group, Stack } from '@/components';
import { import {
PaperTemplate, PaperTemplate,
PaperTemplateProps, PaperTemplateProps,
@@ -13,6 +13,13 @@ import {
} from '@/constants/PdfTemplates'; } from '@/constants/PdfTemplates';
export interface CreditNotePaperTemplateProps extends PaperTemplateProps { export interface CreditNotePaperTemplateProps extends PaperTemplateProps {
// # Company logo
showCompanyLogo?: boolean;
companyLogoUri?: string;
// # Company name
companyName?: string;
// Address // Address
showCustomerAddress?: boolean; showCustomerAddress?: boolean;
customerAddress?: string; customerAddress?: string;
@@ -122,26 +129,30 @@ export function CreditNotePaperTemplate({
creditNoteDateLabel = 'Credit Note Date', creditNoteDateLabel = 'Credit Note Date',
}: CreditNotePaperTemplateProps) { }: CreditNotePaperTemplateProps) {
return ( return (
<PaperTemplate <PaperTemplate primaryColor={primaryColor} secondaryColor={secondaryColor}>
primaryColor={primaryColor}
secondaryColor={secondaryColor}
showCompanyLogo={showCompanyLogo}
companyLogoUri={companyLogoUri}
bigtitle={'Credit Note'}
>
<Stack spacing={24}> <Stack spacing={24}>
<PaperTemplate.TermsList> <Group align={'start'} spacing={10}>
{showCreditNoteNumber && ( <Stack flex={1}>
<PaperTemplate.TermsItem label={creditNoteNumberLabel}> <PaperTemplate.BigTitle title={'Credit Note'} />
{creditNoteNumebr}
</PaperTemplate.TermsItem> <PaperTemplate.TermsList>
{showCreditNoteNumber && (
<PaperTemplate.TermsItem label={creditNoteNumberLabel}>
{creditNoteNumebr}
</PaperTemplate.TermsItem>
)}
{showCreditNoteDate && (
<PaperTemplate.TermsItem label={creditNoteDateLabel}>
{creditNoteDate}
</PaperTemplate.TermsItem>
)}
</PaperTemplate.TermsList>
</Stack>
{companyLogoUri && showCompanyLogo && (
<PaperTemplate.Logo logoUri={companyLogoUri} />
)} )}
{showCreditNoteDate && ( </Group>
<PaperTemplate.TermsItem label={creditNoteDateLabel}>
{creditNoteDate}
</PaperTemplate.TermsItem>
)}
</PaperTemplate.TermsList>
<PaperTemplate.AddressesGroup> <PaperTemplate.AddressesGroup>
{showCompanyAddress && ( {showCompanyAddress && (

View File

@@ -1,4 +1,4 @@
import { Box, Stack } from '@/components'; import { Box, Group, Stack } from '@/components';
import { import {
PaperTemplate, PaperTemplate,
PaperTemplateProps, PaperTemplateProps,
@@ -13,6 +13,10 @@ import {
} from '@/constants/PdfTemplates'; } from '@/constants/PdfTemplates';
export interface EstimatePaperTemplateProps extends PaperTemplateProps { export interface EstimatePaperTemplateProps extends PaperTemplateProps {
// # Company
showCompanyLogo?: boolean;
companyLogoUri?: string;
// # Estimate number // # Estimate number
estimateNumebr?: string; estimateNumebr?: string;
estimateNumberLabel?: string; estimateNumberLabel?: string;
@@ -132,31 +136,35 @@ export function EstimatePaperTemplate({
expirationDate = 'September 3, 2024', expirationDate = 'September 3, 2024',
}: EstimatePaperTemplateProps) { }: EstimatePaperTemplateProps) {
return ( return (
<PaperTemplate <PaperTemplate primaryColor={primaryColor} secondaryColor={secondaryColor}>
primaryColor={primaryColor}
secondaryColor={secondaryColor}
showCompanyLogo={showCompanyLogo}
companyLogoUri={companyLogoUri}
bigtitle={'Estimate'}
>
<Stack spacing={24}> <Stack spacing={24}>
<PaperTemplate.TermsList> <Group align={'start'} spacing={10}>
{showEstimateNumber && ( <Stack flex={1}>
<PaperTemplate.TermsItem label={estimateNumberLabel}> <PaperTemplate.BigTitle title={'Estimate'} />
{estimateNumebr}
</PaperTemplate.TermsItem> <PaperTemplate.TermsList>
{showEstimateNumber && (
<PaperTemplate.TermsItem label={estimateNumberLabel}>
{estimateNumebr}
</PaperTemplate.TermsItem>
)}
{showEstimateDate && (
<PaperTemplate.TermsItem label={estimateDateLabel}>
{estimateDate}
</PaperTemplate.TermsItem>
)}
{showExpirationDate && (
<PaperTemplate.TermsItem label={expirationDateLabel}>
{expirationDate}
</PaperTemplate.TermsItem>
)}
</PaperTemplate.TermsList>
</Stack>
{companyLogoUri && showCompanyLogo && (
<PaperTemplate.Logo logoUri={companyLogoUri} />
)} )}
{showEstimateDate && ( </Group>
<PaperTemplate.TermsItem label={estimateDateLabel}>
{estimateDate}
</PaperTemplate.TermsItem>
)}
{showExpirationDate && (
<PaperTemplate.TermsItem label={expirationDateLabel}>
{expirationDate}
</PaperTemplate.TermsItem>
)}
</PaperTemplate.TermsList>
<PaperTemplate.AddressesGroup> <PaperTemplate.AddressesGroup>
{showCompanyAddress && ( {showCompanyAddress && (

View File

@@ -11,16 +11,13 @@
width: 794px; width: 794px;
height: 1123px; height: 1123px;
} }
.bigTitle{ .bigTitle{
font-size: 60px; font-size: 60px;
margin: 0; margin: 0;
line-height: 1; line-height: 1;
margin-bottom: 25px;
font-weight: 500; font-weight: 500;
color: #333; color: #333;
} }
.details { .details {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -35,13 +32,11 @@
min-width: 120px; min-width: 120px;
color: #333; color: #333;
} }
.addressRoot{ .addressRoot{
> div{ > div{
flex: 1; flex: 1;
} }
} }
.table { .table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
@@ -66,10 +61,6 @@
} }
tbody{ tbody{
tr {
}
td{ td{
border-bottom: 1px solid #F6F6F6; border-bottom: 1px solid #F6F6F6;
padding: 12px 10px; padding: 12px 10px;
@@ -80,7 +71,6 @@
&:last-of-type{ &:last-of-type{
padding-right: 0; padding-right: 0;
} }
&.rate, &.rate,
&.total{ &.total{
text-align: right; text-align: right;
@@ -88,7 +78,6 @@
} }
} }
} }
.totals{ .totals{
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -112,25 +101,22 @@
.totalBottomGrayBordered { .totalBottomGrayBordered {
border-bottom: 1px solid #DADADA; border-bottom: 1px solid #DADADA;
} }
.logoWrap{ .logoWrap{
height: 120px;
width: 120px;
position: absolute;
right: 26px;
top: 26px;
border-radius: 5px;
overflow: hidden; overflow: hidden;
img{ img{
max-width: 100%; max-width: 100%;
} }
} }
.logoImg {
height: auto;
width: auto;
max-width: 400px;
max-height: 160px;
}
.footer{ .footer{
} }
.paragraph{ .paragraph{
margin-bottom: 20px; margin-bottom: 20px;
} }

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { PaperTemplate, PaperTemplateTotalBorder } from './PaperTemplate'; import { PaperTemplate, PaperTemplateTotalBorder } from './PaperTemplate';
import { Box, Stack } from '@/components'; import { Box, Group, Stack } from '@/components';
import { import {
DefaultPdfTemplateTerms, DefaultPdfTemplateTerms,
DefaultPdfTemplateItemDescription, DefaultPdfTemplateItemDescription,
@@ -178,31 +178,35 @@ export function InvoicePaperTemplate({
statement = DefaultPdfTemplateStatement, statement = DefaultPdfTemplateStatement,
}: InvoicePaperTemplateProps) { }: InvoicePaperTemplateProps) {
return ( return (
<PaperTemplate <PaperTemplate primaryColor={primaryColor} secondaryColor={secondaryColor}>
primaryColor={primaryColor}
secondaryColor={secondaryColor}
showCompanyLogo={showCompanyLogo}
companyLogoUri={companyLogoUri}
bigtitle={'Invoice'}
>
<Stack spacing={24}> <Stack spacing={24}>
<PaperTemplate.TermsList> <Group align="start" spacing={10}>
{showInvoiceNumber && ( <Stack flex={1}>
<PaperTemplate.TermsItem label={invoiceNumberLabel}> <PaperTemplate.BigTitle title={'Invoice'} />
{invoiceNumber}
</PaperTemplate.TermsItem> <PaperTemplate.TermsList>
{showInvoiceNumber && (
<PaperTemplate.TermsItem label={invoiceNumberLabel}>
{invoiceNumber}
</PaperTemplate.TermsItem>
)}
{showDateIssue && (
<PaperTemplate.TermsItem label={dateIssueLabel}>
{dateIssue}
</PaperTemplate.TermsItem>
)}
{showDueDate && (
<PaperTemplate.TermsItem label={dueDateLabel}>
{dueDate}
</PaperTemplate.TermsItem>
)}
</PaperTemplate.TermsList>
</Stack>
{companyLogoUri && showCompanyLogo && (
<PaperTemplate.Logo logoUri={companyLogoUri} />
)} )}
{showDateIssue && ( </Group>
<PaperTemplate.TermsItem label={dateIssueLabel}>
{dateIssue}
</PaperTemplate.TermsItem>
)}
{showDueDate && (
<PaperTemplate.TermsItem label={dueDateLabel}>
{dueDate}
</PaperTemplate.TermsItem>
)}
</PaperTemplate.TermsList>
<PaperTemplate.AddressesGroup> <PaperTemplate.AddressesGroup>
{showCompanyAddress && ( {showCompanyAddress && (

View File

@@ -7,38 +7,18 @@ import styles from './InvoicePaperTemplate.module.scss';
export interface PaperTemplateProps { export interface PaperTemplateProps {
primaryColor?: string; primaryColor?: string;
secondaryColor?: string; secondaryColor?: string;
showCompanyLogo?: boolean;
companyLogoUri?: string;
companyName?: string;
bigtitle?: string;
children?: React.ReactNode; children?: React.ReactNode;
} }
export function PaperTemplate({ export function PaperTemplate({
primaryColor, primaryColor,
secondaryColor, secondaryColor,
showCompanyLogo,
companyLogoUri,
bigtitle = 'Invoice',
children, children,
}: PaperTemplateProps) { }: PaperTemplateProps) {
return ( return (
<div className={styles.root}> <div className={styles.root}>
<style>{`:root { --invoice-primary-color: ${primaryColor}; --invoice-secondary-color: ${secondaryColor}; }`}</style> <style>{`:root { --invoice-primary-color: ${primaryColor}; --invoice-secondary-color: ${secondaryColor}; }`}</style>
<div>
<h1 className={styles.bigTitle}>{bigtitle}</h1>
{showCompanyLogo && companyLogoUri && (
<div className={styles.logoWrap}>
<img alt="" src={companyLogoUri} />
</div>
)}
</div>
{children} {children}
</div> </div>
); );
@@ -53,6 +33,26 @@ interface PaperTemplateTableProps {
data: Array<Record<string, any>>; data: Array<Record<string, any>>;
} }
interface PaperTemplateBigTitleProps {
title: string;
}
PaperTemplate.BigTitle = ({ title }: PaperTemplateBigTitleProps) => {
return <h1 className={styles.bigTitle}>{title}</h1>;
};
interface PaperTemplateLogoProps {
logoUri: string;
}
PaperTemplate.Logo = ({ logoUri }: PaperTemplateLogoProps) => {
return (
<div className={styles.logoWrap}>
<img className={styles.logoImg} alt="" src={logoUri} />
</div>
);
};
PaperTemplate.Table = ({ columns, data }: PaperTemplateTableProps) => { PaperTemplate.Table = ({ columns, data }: PaperTemplateTableProps) => {
return ( return (
<table className={styles.table}> <table className={styles.table}>

View File

@@ -1,4 +1,4 @@
import { Box, Stack } from '@/components'; import { Box, Group, Stack } from '@/components';
import { import {
PaperTemplate, PaperTemplate,
PaperTemplateProps, PaperTemplateProps,
@@ -10,6 +10,13 @@ import {
} from '@/constants/PdfTemplates'; } from '@/constants/PdfTemplates';
export interface PaymentReceivedPaperTemplateProps extends PaperTemplateProps { export interface PaymentReceivedPaperTemplateProps extends PaperTemplateProps {
// # Company logo
showCompanyLogo?: boolean;
companyLogoUri?: string;
// # Company name
companyName?: string;
// Customer address // Customer address
showCustomerAddress?: boolean; showCustomerAddress?: boolean;
customerAddress?: string; customerAddress?: string;
@@ -93,27 +100,31 @@ export function PaymentReceivedPaperTemplate({
paymentReceivedDateLabel = 'Payment Date', paymentReceivedDateLabel = 'Payment Date',
}: PaymentReceivedPaperTemplateProps) { }: PaymentReceivedPaperTemplateProps) {
return ( return (
<PaperTemplate <PaperTemplate primaryColor={primaryColor} secondaryColor={secondaryColor}>
primaryColor={primaryColor}
secondaryColor={secondaryColor}
showCompanyLogo={showCompanyLogo}
companyLogoUri={companyLogoUri}
bigtitle={'Payment'}
>
<Stack spacing={24}> <Stack spacing={24}>
<PaperTemplate.TermsList> <Group align={'start'} spacing={10}>
{showPaymentReceivedNumber && ( <Stack flex={1}>
<PaperTemplate.TermsItem label={paymentReceivedNumberLabel}> <PaperTemplate.BigTitle title={'Payment'} />
{paymentReceivedNumebr}
</PaperTemplate.TermsItem>
)}
{showPaymentReceivedDate && ( <PaperTemplate.TermsList>
<PaperTemplate.TermsItem label={paymentReceivedDateLabel}> {showPaymentReceivedNumber && (
{paymentReceivedDate} <PaperTemplate.TermsItem label={paymentReceivedNumberLabel}>
</PaperTemplate.TermsItem> {paymentReceivedNumebr}
</PaperTemplate.TermsItem>
)}
{showPaymentReceivedDate && (
<PaperTemplate.TermsItem label={paymentReceivedDateLabel}>
{paymentReceivedDate}
</PaperTemplate.TermsItem>
)}
</PaperTemplate.TermsList>
</Stack>
{companyLogoUri && showCompanyLogo && (
<PaperTemplate.Logo logoUri={companyLogoUri} />
)} )}
</PaperTemplate.TermsList> </Group>
<PaperTemplate.AddressesGroup> <PaperTemplate.AddressesGroup>
{showCompanyAddress && ( {showCompanyAddress && (

View File

@@ -1,4 +1,4 @@
import { Box, Stack } from '@/components'; import { Box, Group, Stack } from '@/components';
import { import {
PaperTemplate, PaperTemplate,
PaperTemplateProps, PaperTemplateProps,
@@ -13,6 +13,13 @@ import {
} from '@/constants/PdfTemplates'; } from '@/constants/PdfTemplates';
export interface ReceiptPaperTemplateProps extends PaperTemplateProps { export interface ReceiptPaperTemplateProps extends PaperTemplateProps {
// # Company logo
showCompanyLogo?: boolean;
companyLogoUri?: string;
// # Company name
companyName?: string;
// Addresses // Addresses
showCustomerAddress?: boolean; showCustomerAddress?: boolean;
customerAddress?: string; customerAddress?: string;
@@ -117,26 +124,30 @@ export function ReceiptPaperTemplate({
receiptDateLabel = 'Receipt Date', receiptDateLabel = 'Receipt Date',
}: ReceiptPaperTemplateProps) { }: ReceiptPaperTemplateProps) {
return ( return (
<PaperTemplate <PaperTemplate primaryColor={primaryColor} secondaryColor={secondaryColor}>
primaryColor={primaryColor}
secondaryColor={secondaryColor}
showCompanyLogo={showCompanyLogo}
companyLogoUri={companyLogoUri}
bigtitle={'Receipt'}
>
<Stack spacing={24}> <Stack spacing={24}>
<PaperTemplate.TermsList> <Group align={'start'} spacing={10}>
{showReceiptNumber && ( <Stack flex={1}>
<PaperTemplate.TermsItem label={receiptNumberLabel}> <PaperTemplate.BigTitle title={'Receipt'} />
{receiptNumebr}
</PaperTemplate.TermsItem> <PaperTemplate.TermsList>
{showReceiptNumber && (
<PaperTemplate.TermsItem label={receiptNumberLabel}>
{receiptNumebr}
</PaperTemplate.TermsItem>
)}
{showReceiptDate && (
<PaperTemplate.TermsItem label={receiptDateLabel}>
{receiptDate}
</PaperTemplate.TermsItem>
)}
</PaperTemplate.TermsList>
</Stack>
{companyLogoUri && showCompanyLogo && (
<PaperTemplate.Logo logoUri={companyLogoUri} />
)} )}
{showReceiptDate && ( </Group>
<PaperTemplate.TermsItem label={receiptDateLabel}>
{receiptDate}
</PaperTemplate.TermsItem>
)}
</PaperTemplate.TermsList>
<PaperTemplate.AddressesGroup> <PaperTemplate.AddressesGroup>
{showCompanyAddress && ( {showCompanyAddress && (