11'use client' ;
22
33import React , { useState , useEffect } from 'react' ;
4- import { VeltComments , VeltCommentTool , useVeltClient } from '@veltdev/react' ;
4+ import { VeltComments , VeltCommentTool , useVeltClient , useLiveState } from '@veltdev/react' ;
55import './table-component.css' ;
66
77interface TableData {
@@ -57,8 +57,6 @@ const generateTableData = (): TableData[] => {
5757 return data ;
5858} ;
5959
60- const tableData : TableData [ ] = generateTableData ( ) ;
61-
6260// Figma asset URLs
6361const imgFrame = "http://localhost:3845/assets/209587c08c306a5d8ea4baadd1252bb9a8a07f4e.svg" ;
6462const imgTablerIconChevronRight = "http://localhost:3845/assets/583003e84220653f4b462b3834513dcd22c65261.svg" ;
@@ -76,8 +74,34 @@ const imgTablerIconTriangleSquareCircle = "http://localhost:3845/assets/a1276b76
7674const imgTablerIconLine = "http://localhost:3845/assets/e1bb298cc386ae6cf97f2bcb191e9a8d6b85d6bb.svg" ;
7775
7876export const TableComponent : React . FC = ( ) => {
79- const [ selectedCell , setSelectedCell ] = useState < SelectedCell | null > ( null ) ;
80- const [ cellFormatting , setCellFormatting ] = useState < Record < string , CellFormatting > > ( { } ) ;
77+ // Use Velt's useLiveState to sync selected cell across all users
78+ const [ selectedCell , setSelectedCell ] = useLiveState < SelectedCell | null > (
79+ 'selected-cell' ,
80+ null ,
81+ {
82+ syncDuration : 50 ,
83+ resetLiveState : false ,
84+ }
85+ ) ;
86+ // Use Velt's useLiveState to sync table data across all users
87+ const [ tableData , setTableData ] = useLiveState < TableData [ ] > (
88+ 'table-data' ,
89+ generateTableData ( ) ,
90+ {
91+ syncDuration : 100 ,
92+ resetLiveState : false ,
93+ }
94+ ) ;
95+ // Use Velt's useLiveState to sync cell formatting across all users
96+ const [ cellFormatting , setCellFormatting ] = useLiveState < Record < string , CellFormatting > > (
97+ 'cell-formatting' ,
98+ { } ,
99+ {
100+ syncDuration : 50 ,
101+ resetLiveState : false ,
102+ listenToNewChangesOnly : false , // Ensure we receive all historical data on mount
103+ }
104+ ) ;
81105 const { client } = useVeltClient ( ) ;
82106
83107 useEffect ( ( ) => {
@@ -98,7 +122,7 @@ export const TableComponent: React.FC = () => {
98122 } ;
99123
100124 const toggleFormatting = ( format : keyof CellFormatting ) => {
101- if ( ! selectedCell ) return ;
125+ if ( ! selectedCell || ! cellFormatting ) return ;
102126
103127 const cellKey = getCellKey ( selectedCell . row , selectedCell . col ) ;
104128 const currentFormatting = cellFormatting [ cellKey ] || { } ;
@@ -115,7 +139,7 @@ export const TableComponent: React.FC = () => {
115139 } ;
116140
117141 const setAlignment = ( align : 'left' | 'center' | 'right' ) => {
118- if ( ! selectedCell ) return ;
142+ if ( ! selectedCell || ! cellFormatting ) return ;
119143
120144 const cellKey = getCellKey ( selectedCell . row , selectedCell . col ) ;
121145 const currentFormatting = cellFormatting [ cellKey ] || { } ;
@@ -154,6 +178,8 @@ export const TableComponent: React.FC = () => {
154178 } ;
155179
156180 const getCellStyle = ( row : number , col : number , baseStyle : React . CSSProperties ) : React . CSSProperties => {
181+ if ( ! cellFormatting ) return baseStyle ;
182+
157183 const cellKey = getCellKey ( row , col ) ;
158184 const formatting = cellFormatting [ cellKey ] || { } ;
159185
@@ -169,6 +195,8 @@ export const TableComponent: React.FC = () => {
169195 } ;
170196
171197 const getCellAlignment = ( row : number , col : number ) : React . CSSProperties => {
198+ if ( ! cellFormatting ) return { } ;
199+
172200 const cellKey = getCellKey ( row , col ) ;
173201 const formatting = cellFormatting [ cellKey ] || { } ;
174202
@@ -191,6 +219,17 @@ export const TableComponent: React.FC = () => {
191219 return selectedCell ?. row === row ;
192220 } ;
193221
222+ const handleCellEdit = ( rowIndex : number , field : keyof TableData , newValue : string ) => {
223+ if ( ! tableData ) return ;
224+
225+ const updatedData = [ ...tableData ] ;
226+ updatedData [ rowIndex ] = {
227+ ...updatedData [ rowIndex ] ,
228+ [ field ] : newValue ,
229+ } ;
230+ setTableData ( updatedData ) ;
231+ } ;
232+
194233 return (
195234 < div style = { styles . container } >
196235 { /* Breadcrumb Navigation */ }
@@ -481,7 +520,14 @@ export const TableComponent: React.FC = () => {
481520 onClick = { ( ) => handleCellClick ( rowNum , 0 ) }
482521 >
483522 < div style = { getCellStyle ( rowNum , 0 , styles . cellTextDiv ) } >
484- < p style = { styles . cellTextP } > { row . date } </ p >
523+ < p
524+ contentEditable
525+ suppressContentEditableWarning
526+ style = { styles . cellTextP }
527+ onBlur = { ( e ) => handleCellEdit ( index , 'date' , e . currentTarget . textContent || '' ) }
528+ >
529+ { row . date }
530+ </ p >
485531 </ div >
486532 < div className = "comment-tool-wrapper" >
487533 < VeltCommentTool targetCommentElementId = { `cell-${ rowNum } -0` } />
@@ -503,7 +549,14 @@ export const TableComponent: React.FC = () => {
503549 onClick = { ( ) => handleCellClick ( rowNum , 1 ) }
504550 >
505551 < div style = { getCellStyle ( rowNum , 1 , styles . cellTextDiv ) } >
506- < p style = { styles . cellTextP } > { row . x } </ p >
552+ < p
553+ contentEditable
554+ suppressContentEditableWarning
555+ style = { styles . cellTextP }
556+ onBlur = { ( e ) => handleCellEdit ( index , 'x' , e . currentTarget . textContent || '' ) }
557+ >
558+ { row . x }
559+ </ p >
507560 </ div >
508561 < div className = "comment-tool-wrapper" >
509562 < VeltCommentTool targetCommentElementId = { `cell-${ rowNum } -1` } />
@@ -525,7 +578,14 @@ export const TableComponent: React.FC = () => {
525578 onClick = { ( ) => handleCellClick ( rowNum , 2 ) }
526579 >
527580 < div style = { getCellStyle ( rowNum , 2 , styles . cellTextDiv ) } >
528- < p style = { styles . cellTextP } > { row . linkedin } </ p >
581+ < p
582+ contentEditable
583+ suppressContentEditableWarning
584+ style = { styles . cellTextP }
585+ onBlur = { ( e ) => handleCellEdit ( index , 'linkedin' , e . currentTarget . textContent || '' ) }
586+ >
587+ { row . linkedin }
588+ </ p >
529589 </ div >
530590 < div className = "comment-tool-wrapper" >
531591 < VeltCommentTool targetCommentElementId = { `cell-${ rowNum } -2` } />
@@ -547,7 +607,14 @@ export const TableComponent: React.FC = () => {
547607 onClick = { ( ) => handleCellClick ( rowNum , 3 ) }
548608 >
549609 < div style = { getCellStyle ( rowNum , 3 , styles . cellTextDiv ) } >
550- < p style = { styles . cellTextP } > { row . twitter } </ p >
610+ < p
611+ contentEditable
612+ suppressContentEditableWarning
613+ style = { styles . cellTextP }
614+ onBlur = { ( e ) => handleCellEdit ( index , 'twitter' , e . currentTarget . textContent || '' ) }
615+ >
616+ { row . twitter }
617+ </ p >
551618 </ div >
552619 < div className = "comment-tool-wrapper" >
553620 < VeltCommentTool targetCommentElementId = { `cell-${ rowNum } -3` } />
@@ -568,7 +635,14 @@ export const TableComponent: React.FC = () => {
568635 onClick = { ( ) => handleCellClick ( rowNum , 4 ) }
569636 >
570637 < div style = { getCellStyle ( rowNum , 4 , styles . cellTextDiv ) } >
571- < p style = { styles . cellTextP } > { row . instagram } </ p >
638+ < p
639+ contentEditable
640+ suppressContentEditableWarning
641+ style = { styles . cellTextP }
642+ onBlur = { ( e ) => handleCellEdit ( index , 'instagram' , e . currentTarget . textContent || '' ) }
643+ >
644+ { row . instagram }
645+ </ p >
572646 </ div >
573647 < div className = "comment-tool-wrapper" >
574648 < VeltCommentTool targetCommentElementId = { `cell-${ rowNum } -4` } />
0 commit comments