@driveflux/pdf 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/.turbo/turbo-build.log +3 -3
  2. package/CHANGELOG.md +8 -0
  3. package/dist/__mocks__/quotation.d.ts +3 -0
  4. package/dist/__mocks__/quotation.d.ts.map +1 -0
  5. package/dist/__mocks__/quotation.js +59 -0
  6. package/dist/cjs/__mocks__/quotation.js +69 -0
  7. package/dist/cjs/debug.js +33 -1
  8. package/dist/cjs/templates/QuotationPdf/CustomerSubscriptionSection.js +147 -0
  9. package/dist/cjs/templates/QuotationPdf/GFV.js +57 -0
  10. package/dist/cjs/templates/QuotationPdf/Header.js +86 -0
  11. package/dist/cjs/templates/QuotationPdf/Pricing.js +430 -0
  12. package/dist/cjs/templates/QuotationPdf/QuotationPdfPage.js +45 -0
  13. package/dist/cjs/templates/QuotationPdf/SectionBoxNew.js +43 -0
  14. package/dist/cjs/templates/QuotationPdf/TermsSection.js +60 -0
  15. package/dist/cjs/templates/QuotationPdf/index.js +208 -0
  16. package/dist/cjs/templates/QuotationPdf/translations.js +103 -0
  17. package/dist/cjs/templates/QuotationPdf/utils.js +91 -0
  18. package/dist/cjs/templates/index.js +1 -0
  19. package/dist/debug.js +33 -1
  20. package/dist/templates/QuotationPdf/CustomerSubscriptionSection.d.ts +10 -0
  21. package/dist/templates/QuotationPdf/CustomerSubscriptionSection.d.ts.map +1 -0
  22. package/dist/templates/QuotationPdf/CustomerSubscriptionSection.js +132 -0
  23. package/dist/templates/QuotationPdf/GFV.d.ts +10 -0
  24. package/dist/templates/QuotationPdf/GFV.d.ts.map +1 -0
  25. package/dist/templates/QuotationPdf/GFV.js +47 -0
  26. package/dist/templates/QuotationPdf/Header.d.ts +9 -0
  27. package/dist/templates/QuotationPdf/Header.d.ts.map +1 -0
  28. package/dist/templates/QuotationPdf/Header.js +71 -0
  29. package/dist/templates/QuotationPdf/Pricing.d.ts +10 -0
  30. package/dist/templates/QuotationPdf/Pricing.d.ts.map +1 -0
  31. package/dist/templates/QuotationPdf/Pricing.js +415 -0
  32. package/dist/templates/QuotationPdf/QuotationPdfPage.d.ts +8 -0
  33. package/dist/templates/QuotationPdf/QuotationPdfPage.d.ts.map +1 -0
  34. package/dist/templates/QuotationPdf/QuotationPdfPage.js +30 -0
  35. package/dist/templates/QuotationPdf/SectionBoxNew.d.ts +8 -0
  36. package/dist/templates/QuotationPdf/SectionBoxNew.d.ts.map +1 -0
  37. package/dist/templates/QuotationPdf/SectionBoxNew.js +33 -0
  38. package/dist/templates/QuotationPdf/TermsSection.d.ts +8 -0
  39. package/dist/templates/QuotationPdf/TermsSection.d.ts.map +1 -0
  40. package/dist/templates/QuotationPdf/TermsSection.js +50 -0
  41. package/dist/templates/QuotationPdf/index.d.ts +9 -0
  42. package/dist/templates/QuotationPdf/index.d.ts.map +1 -0
  43. package/dist/templates/QuotationPdf/index.js +193 -0
  44. package/dist/templates/QuotationPdf/translations.d.ts +59 -0
  45. package/dist/templates/QuotationPdf/translations.d.ts.map +1 -0
  46. package/dist/templates/QuotationPdf/translations.js +93 -0
  47. package/dist/templates/QuotationPdf/utils.d.ts +6 -0
  48. package/dist/templates/QuotationPdf/utils.d.ts.map +1 -0
  49. package/dist/templates/QuotationPdf/utils.js +70 -0
  50. package/dist/templates/index.d.ts +1 -0
  51. package/dist/templates/index.d.ts.map +1 -1
  52. package/dist/templates/index.js +1 -0
  53. package/package.json +2 -2
  54. package/src/__mocks__/quotation.ts +62 -0
  55. package/src/debug.ts +12 -3
  56. package/src/templates/QuotationPdf/CustomerSubscriptionSection.tsx +65 -0
  57. package/src/templates/QuotationPdf/GFV.tsx +29 -0
  58. package/src/templates/QuotationPdf/Header.tsx +31 -0
  59. package/src/templates/QuotationPdf/Pricing.tsx +214 -0
  60. package/src/templates/QuotationPdf/QuotationPdfPage.tsx +25 -0
  61. package/src/templates/QuotationPdf/SectionBoxNew.tsx +20 -0
  62. package/src/templates/QuotationPdf/TermsSection.tsx +28 -0
  63. package/src/templates/QuotationPdf/index.tsx +46 -0
  64. package/src/templates/QuotationPdf/translations.ts +82 -0
  65. package/src/templates/QuotationPdf/utils.ts +44 -0
  66. package/src/templates/index.ts +1 -0
  67. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,31 @@
1
+ import { Link, Text, View } from '@react-pdf/renderer'
2
+ import { FC } from 'react'
3
+ import FluxLogo from '../../components/FluxLogo.js'
4
+ import { colors } from '../../theme/colors.js'
5
+
6
+ type Props = {
7
+ tTitle: string
8
+ quotationId: string
9
+ quotationDate: string
10
+ }
11
+ const Header: FC<Props> = ({ tTitle, quotationId, quotationDate }) => {
12
+ return (
13
+ <View style={{ gap: 24 }}>
14
+ <Link src="https://driveflux.com">
15
+ <FluxLogo />
16
+ </Link>
17
+ <View style={{ gap: 4 }}>
18
+ <Text style={{ fontWeight: 'bold', textTransform: 'uppercase', fontSize: 18 }}>{tTitle}</Text>
19
+ <View style={{ justifyContent: 'space-between', flexDirection: 'row' }}>
20
+ <Text style={{ color: colors.primary3, fontSize: 10 }}>{quotationId}</Text>
21
+ <View style={{ gap: 8, flexDirection: 'row' }}>
22
+ <Text style={{ fontSize: 10, color: colors.black }}>Date</Text>
23
+ <Text style={{ color: colors.primary3, fontSize: 10 }}>{quotationDate}</Text>
24
+ </View>
25
+ </View>
26
+ </View>
27
+ </View>
28
+ )
29
+ }
30
+
31
+ export default Header
@@ -0,0 +1,214 @@
1
+ import { Quotation } from '@driveflux/db'
2
+ import { formatMoney } from '@driveflux/format-money'
3
+ import { Text, View } from '@react-pdf/renderer'
4
+ import { FC } from 'react'
5
+ import { colors } from '../../theme/colors.js'
6
+ import SectionBoxNew from './SectionBoxNew.js'
7
+ import { QuotationPdfTranslation } from './translations.js'
8
+
9
+ type Props = {
10
+ quotation: Quotation
11
+ t?: QuotationPdfTranslation['pricing']
12
+ }
13
+
14
+ const Pricing: FC<Props> = ({ quotation, t }) => {
15
+ const { startFee, reservationFee, deposit, subscriptionFee, extraCharges, couponCode, couponType, discountAmount } =
16
+ quotation.fees
17
+
18
+ let totalUpfrontFee = startFee + (reservationFee || 0) + deposit
19
+ let totalMonthlyFee = subscriptionFee
20
+
21
+ extraCharges.forEach((charge) => {
22
+ if (charge.type === 'upfront') {
23
+ totalUpfrontFee += charge.amount
24
+ } else if (charge.type === 'monthly') {
25
+ totalMonthlyFee += charge.amount
26
+ }
27
+ })
28
+
29
+ if (couponCode && couponType === 'upfront') {
30
+ totalUpfrontFee -= discountAmount || 0
31
+ }
32
+
33
+ if (couponCode && couponType === 'monthly') {
34
+ totalMonthlyFee -= discountAmount || 0
35
+ }
36
+
37
+ const getFeeValue = (key: string) => {
38
+ switch (key) {
39
+ case 'startFee':
40
+ return startFee
41
+ case 'reservationFee':
42
+ return reservationFee
43
+ case 'deposit':
44
+ return deposit
45
+ case 'subscriptionFee':
46
+ return subscriptionFee
47
+ default:
48
+ return null
49
+ }
50
+ }
51
+
52
+ return (
53
+ <View>
54
+ <SectionBoxNew
55
+ topContent={
56
+ <>
57
+ <Text style={{ textTransform: 'uppercase', fontSize: 12, fontWeight: 'bold' }}>{t?.title}</Text>
58
+ {/* upfront */}
59
+ <Text style={{ fontWeight: 'bold', color: colors.black, letterSpacing: 1 }}>{t?.fees.upfront.title}</Text>
60
+ {t?.fees.upfront.content.map((fee) => {
61
+ const feeValue = getFeeValue(fee.key)?.toFixed(2)
62
+ if (feeValue === '0.00') {
63
+ return null
64
+ }
65
+ return (
66
+ <View key={fee.key} style={{ justifyContent: 'space-between', flexDirection: 'row', rowGap: 8 }}>
67
+ <Text style={{ paddingRight: 4, letterSpacing: 1, color: colors.primary3 }}>{fee.title}</Text>
68
+ <Text style={{ color: colors.primary3, letterSpacing: 1 }}>{feeValue !== null ? feeValue : ''}</Text>
69
+ </View>
70
+ )
71
+ })}
72
+ {/* extra charge */}
73
+ {quotation.fees.extraCharges.length > 0 && (
74
+ <>
75
+ {quotation.fees.extraCharges
76
+ .filter((charge) => charge.amount > 0)
77
+ .filter((charge) => charge.type === 'upfront')
78
+ .map((charge, i) => (
79
+ <View key={i} style={{ justifyContent: 'space-between', flexDirection: 'row', rowGap: 8 }}>
80
+ <Text style={{ paddingRight: 4, letterSpacing: 1, color: colors.primary3 }}>
81
+ {t?.fees.extraCharge} - {charge.description}
82
+ </Text>
83
+ <Text style={{ color: colors.primary3, letterSpacing: 1 }}>{charge.amount.toFixed(2)}</Text>
84
+ </View>
85
+ ))}
86
+ </>
87
+ )}
88
+ {quotation.fees.couponCode !== null && quotation.fees.couponType === 'upfront' && (
89
+ <>
90
+ <View style={{ justifyContent: 'space-between', flexDirection: 'row', rowGap: 8 }}>
91
+ <Text style={{ paddingRight: 4, letterSpacing: 1, color: colors.primary3 }}>
92
+ {t?.fees.promo} - {quotation.fees.couponCode}
93
+ </Text>
94
+ <Text style={{ color: colors.accent4, letterSpacing: 1 }}>
95
+ {quotation.fees.discountAmount?.toFixed(2)}
96
+ </Text>
97
+ </View>
98
+ </>
99
+ )}
100
+ <View
101
+ style={{
102
+ backgroundColor: colors.primary1,
103
+ borderTop: `1px solid ${colors.primary1}`,
104
+ justifyContent: 'space-between',
105
+ flexDirection: 'row',
106
+ padding: 4
107
+ }}
108
+ >
109
+ <Text style={{ letterSpacing: 1, paddingRight: 4 }}>Total</Text>
110
+ <Text style={{ letterSpacing: 1 }}>{formatMoney(totalUpfrontFee)}</Text>
111
+ </View>
112
+
113
+ <View style={{ borderBottom: `1px solid ${colors.primary2}` }}></View>
114
+
115
+ {/* monthly */}
116
+ <Text style={{ fontWeight: 'bold', color: colors.black, letterSpacing: 1 }}>{t?.fees.monthly.title}</Text>
117
+ {t?.fees.monthly.content.map((fee) => {
118
+ const feeValue = getFeeValue(fee.key)?.toFixed(2)
119
+
120
+ return (
121
+ <View key={fee.key} style={{ justifyContent: 'space-between', flexDirection: 'row', rowGap: 8 }}>
122
+ <Text style={{ paddingRight: 4, letterSpacing: 1, color: colors.primary3 }}>{fee.title}</Text>
123
+ <Text style={{ color: colors.primary3, letterSpacing: 1 }}>{feeValue !== null ? feeValue : ''}</Text>
124
+ </View>
125
+ )
126
+ })}
127
+
128
+ {/* extra charges monthly*/}
129
+ {quotation.fees.extraCharges.length > 0 && (
130
+ <>
131
+ {quotation.fees.extraCharges
132
+ .filter((charge) => charge.type === 'monthly')
133
+ .map((charge, i) => (
134
+ <View key={i} style={{ justifyContent: 'space-between', flexDirection: 'row', rowGap: 8 }}>
135
+ <Text style={{ paddingRight: 4, letterSpacing: 1, color: colors.primary3 }}>
136
+ {t?.fees.extraCharge} - {charge.description}
137
+ </Text>
138
+ <Text style={{ color: colors.primary3, letterSpacing: 1 }}>{charge.amount.toFixed(2)}</Text>
139
+ </View>
140
+ ))}
141
+ </>
142
+ )}
143
+
144
+ {/* promo monthly */}
145
+ {quotation.fees.couponCode !== null && quotation.fees.couponType === 'monthly' && (
146
+ <>
147
+ <View style={{ justifyContent: 'space-between', flexDirection: 'row', rowGap: 8 }}>
148
+ <Text style={{ paddingRight: 4, letterSpacing: 1, color: colors.primary3 }}>
149
+ {t?.fees.promo} - {quotation.fees.couponCode}
150
+ </Text>
151
+ <Text style={{ color: colors.accent4, letterSpacing: 1 }}>
152
+ {quotation.fees.discountAmount?.toFixed(2)}
153
+ </Text>
154
+ </View>
155
+ </>
156
+ )}
157
+
158
+ <View
159
+ style={{
160
+ backgroundColor: colors.primary1,
161
+ borderTop: `1px solid ${colors.primary1}`,
162
+ justifyContent: 'space-between',
163
+ flexDirection: 'row',
164
+ padding: 4
165
+ }}
166
+ >
167
+ <Text style={{ letterSpacing: 1, paddingRight: 4 }}>Total</Text>
168
+ <Text style={{ letterSpacing: 1 }}>{formatMoney(totalMonthlyFee)}</Text>
169
+ </View>
170
+ </>
171
+ }
172
+ bottomContent={
173
+ <>
174
+ <View style={{ rowGap: 16 }}>
175
+ <Text style={{ textTransform: 'uppercase', fontSize: 12, fontWeight: 'bold', letterSpacing: 1 }}>
176
+ {t?.fees.dueToday.title}
177
+ </Text>
178
+ <Text style={{ color: colors.primary3, letterSpacing: 1 }}>{t?.fees.dueToday.description}</Text>
179
+ <View style={{ justifyContent: 'space-between', flexDirection: 'row' }}>
180
+ <Text style={{ letterSpacing: 1, color: colors.primary3 }}> {t?.fees.dueToday.subTotal}</Text>
181
+ <Text style={{ letterSpacing: 1, color: colors.primary3 }}>
182
+ {quotation.fees.amountBeforeTax.toFixed(2)}
183
+ </Text>
184
+ </View>
185
+ <View style={{ justifyContent: 'space-between', flexDirection: 'row' }}>
186
+ <Text style={{ letterSpacing: 1, color: colors.primary3 }}> {t?.fees.dueToday.serviceFee}</Text>
187
+ <Text style={{ letterSpacing: 1, color: colors.primary3 }}>{quotation.fees.taxAmount.toFixed(2)}</Text>
188
+ </View>
189
+
190
+ <View
191
+ style={{
192
+ backgroundColor: colors.primary1,
193
+ borderTop: `1px solid ${colors.primary1}`,
194
+ justifyContent: 'space-between',
195
+ flexDirection: 'row',
196
+ padding: 4
197
+ }}
198
+ >
199
+ <Text style={{ letterSpacing: 1, paddingRight: 4, fontWeight: 'bold' }}>
200
+ {t?.fees.dueToday.grandTotal}
201
+ </Text>
202
+ <Text style={{ letterSpacing: 1, fontWeight: 'bold' }}>
203
+ {formatMoney(quotation.fees.amountAfterTax)}
204
+ </Text>
205
+ </View>
206
+ </View>
207
+ </>
208
+ }
209
+ />
210
+ </View>
211
+ )
212
+ }
213
+
214
+ export default Pricing
@@ -0,0 +1,25 @@
1
+ import { Quotation } from '@driveflux/db'
2
+ import { View } from '@react-pdf/renderer'
3
+ import { format } from 'date-fns'
4
+ import { FC, PropsWithChildren } from 'react'
5
+ import StandardPage from '../../components/StandardPage.js'
6
+ import Header from './Header.js'
7
+
8
+ type Props = {
9
+ quotation: Quotation
10
+ }
11
+
12
+ const QuotationPdfPage: FC<PropsWithChildren<Props>> = ({ quotation, children }) => {
13
+ return (
14
+ <StandardPage style={{ padding: 40, fontSize: 10, gap: 16 }}>
15
+ <Header
16
+ tTitle={'Quotation'}
17
+ quotationId={quotation.id}
18
+ quotationDate={format(quotation.createdAt, 'dd-MM-yyyy')}
19
+ />
20
+ <View style={{ flex: 1, rowGap: 24 }}>{children}</View>
21
+ </StandardPage>
22
+ )
23
+ }
24
+
25
+ export default QuotationPdfPage
@@ -0,0 +1,20 @@
1
+ import { View } from '@react-pdf/renderer'
2
+ import { FC, ReactNode } from 'react'
3
+ import { colors } from '../../theme/colors.js'
4
+
5
+ type Props = {
6
+ topContent: ReactNode
7
+ bottomContent: ReactNode
8
+ }
9
+
10
+ const SectionBoxNew: FC<Props> = ({ topContent, bottomContent }) => {
11
+ return (
12
+ <View style={{ border: `1px solid ${colors.primary2}` }}>
13
+ <View style={{ padding: 16, rowGap: 16 }}>{topContent}</View>
14
+ <View style={{ borderBottom: `1px solid ${colors.primary2}` }} />
15
+ <View style={{ padding: 16, rowGap: 16 }}>{bottomContent}</View>
16
+ </View>
17
+ )
18
+ }
19
+
20
+ export default SectionBoxNew
@@ -0,0 +1,28 @@
1
+ import { Text, View } from '@react-pdf/renderer'
2
+ import { FC } from 'react'
3
+ import { colors } from '../../theme/colors.js'
4
+ import { QuotationPdfTranslation } from './translations.js'
5
+
6
+ type Props = {
7
+ t: QuotationPdfTranslation['terms']
8
+ }
9
+
10
+ const TermsSection: FC<Props> = ({ t }) => {
11
+ return (
12
+ <View style={{ gap: 16 }}>
13
+ <Text style={{ fontWeight: 'bold', color: colors.black, letterSpacing: 1, textTransform: 'uppercase' }}>
14
+ {t?.title}
15
+ </Text>
16
+ <View>
17
+ {t.content.map((line, i) => (
18
+ <View key={i} style={{ flexDirection: 'row', alignItems: 'flex-start' }}>
19
+ <Text style={{ marginRight: 4, fontSize: 8 }}>•</Text>
20
+ <Text style={{ color: colors.primary3, letterSpacing: 1, fontSize: 8 }}>{line}</Text>
21
+ </View>
22
+ ))}
23
+ </View>
24
+ </View>
25
+ )
26
+ }
27
+
28
+ export default TermsSection
@@ -0,0 +1,46 @@
1
+ import { Quotation } from '@driveflux/db'
2
+ import { Document } from '@react-pdf/renderer'
3
+ import { FC, useMemo } from 'react'
4
+ import { PdfTemplatesSupportedLocales } from '../../types.js'
5
+ import { toPdf } from '../../utils.js'
6
+ import CustomerSubscriptionSection from './CustomerSubscriptionSection.js'
7
+ import GFV from './GFV.js'
8
+ import Pricing from './Pricing.js'
9
+ import QuotationPdfPage from './QuotationPdfPage.js'
10
+ import TermsSection from './TermsSection.js'
11
+ import { useTranslations } from './translations.js'
12
+
13
+ type Props = {
14
+ locale?: PdfTemplatesSupportedLocales
15
+ quotation: Quotation
16
+ }
17
+
18
+ type Options = {
19
+ locale?: PdfTemplatesSupportedLocales
20
+ quotation: Quotation
21
+ }
22
+
23
+ export const generateQuotationPdf = async ({ locale = 'en', quotation }: Options, fileName: string) => {
24
+ return await toPdf(<QuotationPDF locale={locale} quotation={quotation} />, fileName)
25
+ }
26
+
27
+ const QuotationPDF: FC<Props> = ({ locale = 'en', quotation }) => {
28
+ const pageProps = useMemo(() => {
29
+ return {
30
+ t: useTranslations(locale),
31
+ quotation: quotation
32
+ }
33
+ }, [])
34
+ const { t } = pageProps
35
+
36
+ return (
37
+ <Document language={locale}>
38
+ <QuotationPdfPage quotation={quotation}>
39
+ <CustomerSubscriptionSection quotation={quotation} t={t} />
40
+ <Pricing quotation={quotation} t={t.pricing} />
41
+ {quotation.fees.gfv && <GFV quotation={quotation} t={t.pricing} />}
42
+ <TermsSection t={t.terms} />
43
+ </QuotationPdfPage>
44
+ </Document>
45
+ )
46
+ }
@@ -0,0 +1,82 @@
1
+ const enTranslation = {
2
+ quotation: `Quotation`,
3
+ date: 'Date',
4
+ customer: {
5
+ title: `Customer`,
6
+ name: `Name`,
7
+ email: `Email`,
8
+ address: `Address`
9
+ },
10
+ subscription: {
11
+ title: `Subscription`,
12
+ vehicleName: `Vehicle`,
13
+ plan: `Subscription Plan`,
14
+ mileagePackage: `Mileage Package`
15
+ },
16
+ subIncludes: {
17
+ title: `What's Included:`,
18
+ content: [
19
+ `Comprehensive insurance`,
20
+ `Road tax`,
21
+ `Regularly scheduled maintenance`,
22
+ `Selective wear & tear`,
23
+ `Ability to swap vehicles`,
24
+ `Doorstep delivery`,
25
+ `24/7 nationwide roadside assistance`,
26
+ `Theft recovery services`,
27
+ `Independently rated vehicle inspection`,
28
+ `Option to purchase the vehicle at the end of the subscription`
29
+ ]
30
+ },
31
+ pricing: {
32
+ title: `Pricing`,
33
+ fees: {
34
+ upfront: {
35
+ title: `Upfront Fees`,
36
+ content: [
37
+ { title: `Booking Fee`, key: 'reservationFee' },
38
+ { title: `Activation Fee`, key: 'startFee' },
39
+ { title: `Refundable Deposit`, key: 'deposit' }
40
+ ]
41
+ },
42
+ monthly: {
43
+ title: `Monthly Fees`,
44
+ content: [{ title: `Subscription Fee`, key: 'subscriptionFee' }]
45
+ },
46
+ dueToday: {
47
+ title: `Due Today`,
48
+ description: `Grand Total is due before your subscription start. Monthly fee is due on the first day of every cycle period.`,
49
+ subTotal: `Upfront Fees + Monthly Fee`,
50
+ serviceFee: `Service Fee (8%)`,
51
+ grandTotal: `Grand Total`
52
+ },
53
+ extraCharge: `Extra Charge`,
54
+ promo: `Promo`,
55
+ gfv: {
56
+ title: `Guaranteed Future Value (GFV)`
57
+ }
58
+ }
59
+ },
60
+ terms: {
61
+ title: `Terms`,
62
+ content: [
63
+ `This quotation is valid for 7 days.`,
64
+ `All vehicles proposed are unique and are available to our customers on a first come first served basis.`,
65
+ `The Mileage Package is the monthly mileage cap for the vehicle. If you exceed this cap for any given month, excess mileage charges will be incurred.`,
66
+ `Initial payment to be made within 7 days of the invoice date.`,
67
+ `Subscription starts on the date of the car delivery.`,
68
+ `The upfront fees are billed one-time per subscription, before the subscription starts.`,
69
+ `All monthly recurring fees are billed on the same date as the delivery of the vehicle.`,
70
+ `Scheduling delivery will only commence Grand Total is fully paid, 7 - 30+ days after payment and subject to vehicle availability.`
71
+ ]
72
+ }
73
+ }
74
+
75
+ export type QuotationPdfTranslation = typeof enTranslation
76
+
77
+ export const useTranslations = (locale: 'en'): QuotationPdfTranslation => {
78
+ const translation = {
79
+ en: enTranslation
80
+ }
81
+ return translation[locale]
82
+ }
@@ -0,0 +1,44 @@
1
+ import { MileagePackage, PlanType } from '@driveflux/db'
2
+ import { Address } from '@driveflux/db/types'
3
+
4
+ export const formatAddress = (originalAddress: Address) => {
5
+ const { coordinates, metadata, ...address } = originalAddress
6
+ return (Object.keys(address) as Array<keyof typeof address>)
7
+ .filter((key) => key !== 'name' && !!address[key])
8
+ .map((a) => address[a])
9
+ .join(', ')
10
+ }
11
+
12
+ export const getSimplifiedPlanTranslation = (plan: PlanType) => {
13
+ switch (plan) {
14
+ case 'plan60':
15
+ return `60 Months`
16
+ case 'plan36':
17
+ return `36 Months`
18
+ case 'plan24':
19
+ return `24 Months`
20
+ case 'plan12':
21
+ return `12 Months`
22
+ case 'plan1':
23
+ return `Monthly`
24
+ case 'planWeekly':
25
+ return `Weekly`
26
+ default:
27
+ return `Unknown Plan`
28
+ }
29
+ }
30
+
31
+ export const getMileagePackageTranslation = (mileagePackage?: MileagePackage) => {
32
+ switch (mileagePackage) {
33
+ case 'lite':
34
+ return `Lite`
35
+ case 'standard':
36
+ return `Standard`
37
+ case 'plus':
38
+ return `Plus`
39
+ case 'unlimited':
40
+ return `Unlimited`
41
+ default:
42
+ return `Unknown Mileage Package`
43
+ }
44
+ }
@@ -1 +1,2 @@
1
+ export * from './QuotationPdf/index.js'
1
2
  export * from './SubscriptionAgreement/index.js'