@@ -4,11 +4,20 @@ import React from "react";
44import "@/public/vendor/handsontable/handsontable.full.min.css" ;
55import { Brand , DataroomBrand } from "@prisma/client" ;
66
7+ import { Button } from "@/components/ui/button" ;
8+
9+ import { cn } from "@/lib/utils" ;
10+
711import { TDocumentData } from "../dataroom/dataroom-view" ;
812import Nav from "../nav" ;
913
1014// Define the type for the JSON data
11- type SheetData = { [ key : string ] : any } ;
15+ type RowData = { [ key : string ] : any } ;
16+ type SheetData = {
17+ sheetName : string ;
18+ columnData : string [ ] ;
19+ rowData : RowData [ ] ;
20+ } ;
1221
1322const trackPageView = async ( data : {
1423 linkId : string ;
@@ -34,8 +43,7 @@ export default function ExcelViewer({
3443 documentId,
3544 documentName,
3645 versionNumber,
37- columns,
38- data,
46+ sheetData,
3947 brand,
4048 dataroomId,
4149 setDocumentData,
@@ -45,15 +53,15 @@ export default function ExcelViewer({
4553 documentId : string ;
4654 documentName : string ;
4755 versionNumber : number ;
48- columns : string [ ] ;
49- data : SheetData [ ] ;
56+ sheetData : SheetData [ ] ;
5057 brand ?: Partial < Brand > | Partial < DataroomBrand > | null ;
5158 dataroomId ?: string ;
5259 setDocumentData ?: React . Dispatch < React . SetStateAction < TDocumentData | null > > ;
5360} ) {
5461 const [ availableWidth , setAvailableWidth ] = useState < number > ( 200 ) ;
5562 const [ availableHeight , setAvailableHeight ] = useState < number > ( 200 ) ;
5663 const [ handsontableLoaded , setHandsontableLoaded ] = useState < boolean > ( false ) ;
64+ const [ selectedSheetIndex , setSelectedSheetIndex ] = useState < number > ( 0 ) ;
5765
5866 useEffect ( ( ) => {
5967 const script = document . createElement ( "script" ) ;
@@ -84,8 +92,8 @@ export default function ExcelViewer({
8492 const calculateSize = ( ) => {
8593 if ( containerRef . current ) {
8694 const offset = containerRef . current . getBoundingClientRect ( ) ;
87- setAvailableWidth ( Math . max ( offset . width - 60 , 200 ) ) ;
88- setAvailableHeight ( Math . max ( offset . height - 10 , 200 ) ) ;
95+ setAvailableWidth ( Math . max ( offset . width , 200 ) ) ;
96+ setAvailableHeight ( Math . max ( offset . height - 50 , 200 ) ) ;
8997 }
9098 } ;
9199
@@ -113,7 +121,7 @@ export default function ExcelViewer({
113121 documentId,
114122 viewId,
115123 duration,
116- pageNumber : 1 ,
124+ pageNumber : selectedSheetIndex + 1 ,
117125 versionNumber,
118126 dataroomId,
119127 } ) ;
@@ -130,24 +138,27 @@ export default function ExcelViewer({
130138 documentId,
131139 viewId,
132140 duration,
133- pageNumber : 1 ,
141+ pageNumber : selectedSheetIndex + 1 ,
134142 versionNumber,
135143 dataroomId,
136144 } ) ; // Also capture duration if component unmounts while visible
145+ startTimeRef . current = Date . now ( ) ;
137146 }
138147 document . removeEventListener ( "visibilitychange" , handleVisibilityChange ) ;
139148 } ;
140- } , [ ] ) ;
149+ } , [ selectedSheetIndex ] ) ;
141150
142151 useEffect ( ( ) => {
143152 const handleBeforeUnload = ( ) => {
153+ if ( ! visibilityRef . current ) return ;
154+
144155 const duration = Date . now ( ) - startTimeRef . current ;
145156 trackPageView ( {
146157 linkId,
147158 documentId,
148159 viewId,
149160 duration,
150- pageNumber : 1 ,
161+ pageNumber : selectedSheetIndex + 1 ,
151162 versionNumber,
152163 dataroomId,
153164 } ) ;
@@ -158,22 +169,24 @@ export default function ExcelViewer({
158169 return ( ) => {
159170 window . removeEventListener ( "beforeunload" , handleBeforeUnload ) ;
160171 } ;
161- } , [ ] ) ;
172+ } , [ selectedSheetIndex ] ) ;
162173
163174 useEffect ( ( ) => {
164- if ( handsontableLoaded && data . length && columns . length ) {
175+ if ( handsontableLoaded && sheetData . length ) {
165176 if ( hotInstanceRef . current ) {
166177 hotInstanceRef . current . destroy ( ) ;
167178 }
168179
180+ const { columnData, rowData } = sheetData [ selectedSheetIndex ] ;
181+
169182 // @ts -ignore - Handsontable import has not types
170183 hotInstanceRef . current = new Handsontable ( hotRef . current ! , {
171- data : data ,
184+ data : rowData ,
172185 readOnly : true ,
173186 disableVisualSelection : true ,
174187 comments : false ,
175188 contextMenu : false ,
176- colHeaders : columns ,
189+ colHeaders : columnData ,
177190 rowHeaders : true ,
178191 manualColumnResize : true ,
179192 width : availableWidth ,
@@ -190,7 +203,13 @@ export default function ExcelViewer({
190203 // },
191204 } ) ;
192205 }
193- } , [ handsontableLoaded , data , columns , availableHeight , availableWidth ] ) ;
206+ } , [
207+ handsontableLoaded ,
208+ sheetData ,
209+ selectedSheetIndex ,
210+ availableHeight ,
211+ availableWidth ,
212+ ] ) ;
194213
195214 return (
196215 < >
@@ -202,11 +221,27 @@ export default function ExcelViewer({
202221 type = "sheet"
203222 />
204223 < div
205- style = { { height : "calc(100vh - 64px)" } }
206- className = "flex h-screen items-center justify-center "
224+ style = { { height : "calc(100dvh - 64px)" } }
225+ className = "mx-2 flex h-screen flex-col sm:mx-6 lg:mx-8 "
207226 ref = { containerRef }
208227 >
209- < div ref = { hotRef } > </ div >
228+ < div className = "" ref = { hotRef } > </ div >
229+ < div className = "flex max-w-fit divide-x divide-gray-200 overflow-x-scroll whitespace-nowrap rounded-b-sm bg-[#f0f0f0] px-1 " >
230+ { sheetData . map ( ( sheet , index ) => (
231+ < div className = "px-1" key = { sheet . sheetName } >
232+ < Button
233+ onClick = { ( ) => setSelectedSheetIndex ( index ) }
234+ className = { cn (
235+ "mb-1 rounded-none rounded-b-sm bg-[#f0f0f0] font-normal text-gray-950 hover:bg-gray-50" ,
236+ index === selectedSheetIndex &&
237+ "bg-white font-medium text-black ring-1 ring-gray-500 hover:bg-white" ,
238+ ) }
239+ >
240+ { sheet . sheetName }
241+ </ Button >
242+ </ div >
243+ ) ) }
244+ </ div >
210245 </ div >
211246 </ >
212247 ) ;
0 commit comments