11import clsx from "clsx" ;
2+ import { useMoneyFormatter } from "~/helpers/formatters" ;
23import { humanizeText } from "./utils" ;
34
45export type Benefit = {
@@ -20,7 +21,7 @@ const getBackgroundColor = (index: number) => {
2021 1 : "bg-yellow" ,
2122 2 : "bg-grey-100" ,
2223 3 : "bg-pink" ,
23- 4 : "bg-orange " ,
24+ 4 : "bg-cream " ,
2425 5 : "bg-blue" ,
2526 6 : "bg-coral" ,
2627 } [ index % 7 ] ;
@@ -34,14 +35,14 @@ const TableSection = ({
3435 totalPackages : number ;
3536} ) => {
3637 return (
37- < tr >
38- < td className = "uppercase font-bold text-coral px-[0.5cm] pt-[0.5cm] bg-cream" >
38+ < >
39+ < div className = "uppercase font-bold text-coral px-[0.5cm] pt-[0.5cm] bg-cream" >
3940 { humanizeText ( title ) }
40- </ td >
41+ </ div >
4142 { new Array ( totalPackages ) . fill ( null ) . map ( ( _ , i ) => (
42- < td className = { clsx ( "border-l" , getBackgroundColor ( i ) ) } />
43+ < div className = { clsx ( "border-l" , getBackgroundColor ( i ) ) } />
4344 ) ) }
44- </ tr >
45+ </ >
4546 ) ;
4647} ;
4748
@@ -53,34 +54,21 @@ function TableBenefit({
5354 values : Array < number | string | boolean > ;
5455} ) {
5556 return (
56- < tr >
57- < td className = "px-[0.5cm] font-medium pb-[0.5cm] bg-cream" > { title } </ td >
57+ < >
58+ < div className = "px-[0.5cm] font-medium pb-[0.5cm] bg-cream" > { title } </ div >
5859 { values . map ( ( value , i ) => {
5960 return (
60- < td
61+ < div
6162 className = { clsx (
6263 "border-l text-center pb-[0.5cm] relative" ,
6364 getBackgroundColor ( i ) ,
6465 ) }
6566 >
6667 { typeof value === "boolean" ? ( value ? "✓" : "-" ) : value }
67- { /* adding some divs here to prevent gaps when printing */ }
68- < span
69- className = { clsx (
70- "absolute top-[-2px] left-0 right-0 h-[4px]" ,
71- getBackgroundColor ( i ) ,
72- ) }
73- />
74- < span
75- className = { clsx (
76- "absolute bottom-[-2px] left-0 right-0 h-[4px]" ,
77- getBackgroundColor ( i ) ,
78- ) }
79- />
80- </ td >
68+ </ div >
8169 ) ;
8270 } ) }
83- </ tr >
71+ </ >
8472 ) ;
8573}
8674
@@ -116,70 +104,114 @@ export function PricingPage({
116104 ) => {
117105 return level . benefits . find ( ( b ) => b . name === benefit . name ) ;
118106 } ;
107+ const moneyFormatter = useMoneyFormatter ( { fractionDigits : 0 } ) ;
119108
120- return (
121- < div className = "page bg-cream flex flex-col gap-[1cm] pt-[2cm] !h-auto" >
122- < div className = "px-[2cm]" >
123- < h1 className = "text-xl font-bold" > Pricing</ h1 >
124- </ div >
109+ const sectionHeaderSize = 37 ;
110+ const itemSize = 55 ;
111+ let currentPageSize = 0 ;
112+ let currentContent = { } ;
113+ const pagesToRender : Record < string , { name : string ; category : string } [ ] > [ ] =
114+ [ ] ;
125115
126- < table className = "border-[4px] border-black border-collapse table-fixed w-full text-[12px] border-spacing-0" >
127- < thead >
128- < tr className = "uppercase [&>th]:font-medium border-b" >
129- < th />
116+ Object . entries ( benefitsByCategory ) . map ( ( [ category , benefits ] , index ) => {
117+ currentPageSize += sectionHeaderSize ;
118+ const maxPageSize = index === 0 ? 550 : 756 ;
119+ benefits . forEach ( ( benefit ) => {
120+ console . log ( { currentPageSize, benefit } ) ;
121+ if ( currentPageSize + itemSize > maxPageSize ) {
122+ currentPageSize = sectionHeaderSize ;
123+ pagesToRender . push ( currentContent ) ;
124+ currentContent = { } ;
125+ }
126+
127+ if ( ! currentContent [ category ] ) {
128+ currentContent [ category ] = [ ] ;
129+ }
130130
131+ currentContent [ category ] . push ( benefit ) ;
132+ currentPageSize += itemSize ;
133+ } ) ;
134+ } ) ;
135+
136+ pagesToRender . push ( currentContent ) ;
137+
138+ return (
139+ < div >
140+ { pagesToRender . map ( ( page , i ) => (
141+ < div
142+ key = { i }
143+ className = "page pricing-page-table flex flex-col gap-[1cm] bg-cream pt-[2cm]"
144+ >
145+ < div className = "px-[2cm]" >
146+ < h1 className = "text-xl font-bold" > Pricing</ h1 >
147+ </ div >
148+
149+ < div
150+ className = "border-[4px] grid gap-0 border-black w-full text-[12px]"
151+ style = { {
152+ gridTemplateColumns : `auto repeat(${ levels . length } , 2.1cm)` ,
153+ } }
154+ >
155+ < div className = "border-b-[4px] bg-cream" />
131156 { levels . map ( ( p , i ) => (
132157 < th
133158 className = { clsx (
134- "py-[0.5cm] w-[2.1cm] text-center border-l" ,
159+ "py-[0.5cm] w-[2.1cm] text-center border-l uppercase border-b-[4px] " ,
135160 getBackgroundColor ( i ) ,
136161 ) }
137162 key = { p . name }
138163 >
139164 { p . name }
140165 </ th >
141166 ) ) }
142- </ tr >
143- </ thead >
144-
145- < tbody >
146- < TableSection title = "Pricing" totalPackages = { levels . length } />
147- < TableBenefit
148- title = "Package price (VAT not included)"
149- values = { levels . map ( ( p ) => `${ p . price . toLocaleString ( ) } €` ) }
150- />
151-
152- < TableSection title = "Availability" totalPackages = { levels . length } />
153- < TableBenefit
154- title = "Number of slots available"
155- values = { levels . map (
156- ( p ) => `${ p . slots === 0 ? "Unlimited" : p . slots } ` ,
157- ) }
158- />
159-
160- { Object . entries ( benefitsByCategory ) . map ( ( [ category , benefits ] ) => {
161- return (
167+ { i === 0 && (
162168 < >
169+ < TableSection title = "Pricing" totalPackages = { levels . length } />
170+ < TableBenefit
171+ title = "Package price (VAT not included)"
172+ values = { levels . map (
173+ ( p ) =>
174+ `${ moneyFormatter . format ( Number . parseFloat ( p . price ) ) } ` ,
175+ ) }
176+ />
177+
163178 < TableSection
164- title = { category }
179+ title = "Availability"
165180 totalPackages = { levels . length }
166- key = { category }
167181 />
168- { benefits . map ( ( benefit ) => (
169- < TableBenefit
170- title = { benefit . name }
171- values = { levels . map ( ( p ) => {
172- const levelBenefit = getBenefitForLevel ( benefit , p ) ;
173- return levelBenefit ? levelBenefit . value : "-" ;
174- } ) }
175- key = { benefit . name }
176- />
177- ) ) }
182+ < TableBenefit
183+ title = "Number of slots available"
184+ values = { levels . map (
185+ ( p ) => `${ p . slots === 0 ? "Unlimited" : p . slots } ` ,
186+ ) }
187+ />
178188 </ >
179- ) ;
180- } ) }
181- </ tbody >
182- </ table >
189+ ) }
190+
191+ { Object . entries ( page ) . map ( ( [ category , benefits ] ) => {
192+ return (
193+ < >
194+ < TableSection
195+ title = { category }
196+ totalPackages = { levels . length }
197+ key = { category }
198+ />
199+ { benefits . map ( ( benefit ) => (
200+ < TableBenefit
201+ title = { benefit . name }
202+ values = { levels . map ( ( p ) => {
203+ const levelBenefit = getBenefitForLevel ( benefit , p ) ;
204+ return levelBenefit ? levelBenefit . value : "-" ;
205+ } ) }
206+ key = { benefit . name }
207+ />
208+ ) ) }
209+ </ >
210+ ) ;
211+ } ) }
212+ </ div >
213+ </ div >
214+ ) ) }
183215 </ div >
184216 ) ;
185217}
0 commit comments