@@ -50,6 +50,15 @@ function entriesToCSV(entries: HistoryEntry[]): string {
5050 return [ headers , ...rows ] . join ( "\n" ) ;
5151}
5252
53+ const StatusIcon = ( { status } : { status : HistoryEntry [ "status" ] } ) => (
54+ < Image
55+ src = { status === "success" ? "/success-icon.svg" : "/fail-icon.svg" }
56+ alt = { status }
57+ width = { 16 }
58+ height = { 16 }
59+ />
60+ ) ;
61+
5362export default function DebugHistory ( ) {
5463 const [ selectedContract ] = useLocalStorage < ContractName > (
5564 "scaffoldStark2.selectedContract" ,
@@ -58,7 +67,9 @@ export default function DebugHistory() {
5867 ) ;
5968 const historyByContract = useHistoryStore ( ( s ) => s . historyByContract ) ;
6069 const clearHistory = useHistoryStore ( ( s ) => s . clearHistory ) ;
61- const selectedAddress = ( contractsData as Record < string , { address : string } > ) [ selectedContract as string ] ?. address as string ;
70+ const selectedAddress = (
71+ contractsData as Record < string , { address : string } >
72+ ) [ selectedContract as string ] ?. address as string ;
6273 const entries = useMemo (
6374 ( ) => historyByContract [ selectedAddress ] || [ ] ,
6475 [ historyByContract , selectedAddress ] ,
@@ -107,15 +118,6 @@ export default function DebugHistory() {
107118
108119 const formatDate = ( ts : number ) => formatTimestamp ( ts ) ;
109120
110- const StatusIcon = ( { status } : { status : HistoryEntry [ "status" ] } ) => (
111- < Image
112- src = { status === "success" ? "/success-icon.svg" : "/fail-icon.svg" }
113- alt = { status }
114- width = { 20 }
115- height = { 20 }
116- />
117- ) ;
118-
119121 const chips : FilterChip [ ] = [ "All" , "Read" , "Write" , "Success" , "Error" ] ;
120122
121123 const handleExportJSON = ( ) => {
@@ -137,99 +139,122 @@ export default function DebugHistory() {
137139 } ;
138140
139141 return (
140- < div className = "h-full max-h-[650px] w-full xl:w-[400px] space-y-4" >
141- < div className = "tab h-10 w-full xl:w-1/3 tab-active bg-[#8A45FC]! rounded-[5px] text-white!" >
142- History
142+ < div className = "w-full xl:w-[400px] flex flex-col gap-6" >
143+ { /* Tab header — matches Read/Write tab bar */ }
144+ < div className = "tabs tabs-box border border-[#8A45FC] rounded-[5px] bg-transparent" >
145+ < a className = "tab h-10 w-full tab-active bg-[#8A45FC]! rounded-[5px]! text-white!" >
146+ History
147+ </ a >
143148 </ div >
144149
145- { /* Search bar */ }
146- < input
147- type = "text"
148- className = "w-full bg-input text-sm rounded-[5px] px-3 py-1.5 outline-none border border-transparent focus:border-[#8A45FC] placeholder:text-neutral"
149- placeholder = "Search by function name..."
150- value = { searchTerm }
151- onChange = { ( e ) => setSearchTerm ( e . target . value ) }
152- />
153-
154- { /* Filter chips */ }
155- < div className = "flex flex-wrap gap-1.5" >
156- { chips . map ( ( chip ) => {
157- const isActive =
158- chip === "All" ? activeFilters . length === 0 : activeFilters . includes ( chip ) ;
159- return (
150+ { /* Content card — matches the contract methods card */ }
151+ < div className = "rounded-[5px] border border-[#8A45FC] bg-component flex flex-col max-h-[600px]" >
152+ { /* Search bar */ }
153+ < div className = "p-3 pb-0" >
154+ < input
155+ type = "text"
156+ className = { `w-full text-sm rounded-[5px] px-3 py-2 outline-none border transition-colors ${
157+ isDarkMode
158+ ? "bg-[#0C1023] border-[#ffffff1a] focus:border-[#8A45FC] placeholder:text-neutral"
159+ : "bg-base-200 border-transparent focus:border-[#8A45FC] placeholder:text-neutral"
160+ } `}
161+ placeholder = "Search by function name..."
162+ value = { searchTerm }
163+ onChange = { ( e ) => setSearchTerm ( e . target . value ) }
164+ />
165+ </ div >
166+
167+ { /* Filter chips + toolbar */ }
168+ < div className = "px-3 pt-3 space-y-2" >
169+ < div className = "flex flex-wrap gap-1.5" >
170+ { chips . map ( ( chip ) => {
171+ const isActive =
172+ chip === "All"
173+ ? activeFilters . length === 0
174+ : activeFilters . includes ( chip ) ;
175+ return (
176+ < button
177+ key = { chip }
178+ onClick = { ( ) => toggleFilter ( chip ) }
179+ className = { `px-2.5 py-1 rounded-[5px] text-xs font-medium transition-colors border ${
180+ isActive
181+ ? "bg-[#8A45FC] text-white border-[#8A45FC]"
182+ : isDarkMode
183+ ? "bg-transparent text-neutral border-[#ffffff1a] hover:border-[#8A45FC]/50"
184+ : "bg-transparent text-neutral border-black/10 hover:border-[#8A45FC]/50"
185+ } `}
186+ >
187+ { chip }
188+ </ button >
189+ ) ;
190+ } ) }
191+ </ div >
192+
193+ { /* Export / Clear toolbar */ }
194+ < div className = "flex items-center gap-1 border-b border-secondary pb-2" >
160195 < button
161- key = { chip }
162- onClick = { ( ) => toggleFilter ( chip ) }
163- className = { `px-2.5 py-0.5 rounded-full text-xs font-medium transition-colors ${
164- isActive
165- ? "bg-[#8A45FC] text-white"
166- : "bg-base-200 text-neutral hover:bg-base-300"
167- } `}
196+ className = "text-xs text-[#8A45FC] hover:text-[#a06aff] transition-colors disabled:opacity-40 disabled:hover:text-[#8A45FC] px-1.5 py-0.5"
197+ onClick = { handleExportJSON }
198+ disabled = { formatted . length === 0 }
168199 >
169- { chip }
200+ Export JSON
170201 </ button >
171- ) ;
172- } ) }
173- </ div >
174-
175- { /* Toolbar: export + clear */ }
176- < div className = "flex items-center gap-2" >
177- < button
178- className = "btn btn-ghost btn-xs"
179- onClick = { handleExportJSON }
180- disabled = { formatted . length === 0 }
181- >
182- Export JSON
183- </ button >
184- < button
185- className = "btn btn-ghost btn-xs"
186- onClick = { handleExportCSV }
187- disabled = { formatted . length === 0 }
188- >
189- Export CSV
190- </ button >
191- < button
192- className = "btn btn-ghost btn-xs text-error ml-auto"
193- onClick = { handleClear }
194- disabled = { entries . length === 0 }
195- >
196- Clear
197- </ button >
198- </ div >
202+ < span className = "text-neutral/30" > |</ span >
203+ < button
204+ className = "text-xs text-[#8A45FC] hover:text-[#a06aff] transition-colors disabled:opacity-40 disabled:hover:text-[#8A45FC] px-1.5 py-0.5"
205+ onClick = { handleExportCSV }
206+ disabled = { formatted . length === 0 }
207+ >
208+ Export CSV
209+ </ button >
210+ < button
211+ className = "text-xs text-red-400 hover:text-red-300 transition-colors disabled:opacity-40 ml-auto px-1.5 py-0.5"
212+ onClick = { handleClear }
213+ disabled = { entries . length === 0 }
214+ >
215+ Clear
216+ </ button >
217+ </ div >
218+ </ div >
199219
200- < div className = "border-gradient rounded-[5px] h-full w-full overflow-y-auto" >
201- < div className = "flex flex-col " >
220+ { /* History entries list */ }
221+ < div className = "flex-1 overflow-y-auto " >
202222 { formatted . length === 0 ? (
203- < div className = "p-4 text-sm text-neutral" > No history yet.</ div >
223+ < div className = "p-4 text-sm text-neutral text-center" >
224+ No history yet.
225+ </ div >
204226 ) : (
205227 formatted . map ( ( e ) => (
206228 < button
207229 key = { e . txHash ?? `${ e . functionName } -${ e . timestamp } ` }
208- className = { `w-full flex items-center justify-between py-3 px-3 text-left border-b ${ isDarkMode ? "bg-[#0000002E] border-b-[#ffffff4f]" : "bg-[#ffffff0f] border-b-black/40" } ` }
230+ className = { `w-full flex items-center justify-between py-3 px-3 text-left border-b transition-colors ${
231+ isDarkMode
232+ ? "border-b-[#ffffff12] hover:bg-[#ffffff08]"
233+ : "border-b-black/10 hover:bg-black/5"
234+ } `}
209235 onClick = { ( ) => setOpenEntry ( e ) }
210236 >
211- < div className = "flex items-center gap-1.5 min-w-0" >
212- { /* callType badge */ }
237+ < div className = "flex items-center gap-2 min-w-0" >
213238 < span
214- className = { `flex-shrink-0 inline-flex items-center justify-center w-4 h-4 rounded text-[10px] font-bold leading-none ${
239+ className = { `flex-shrink-0 inline-flex items-center justify-center w-5 h-5 rounded-[3px] text-[10px] font-bold leading-none ${
215240 e . callType === "read"
216241 ? "bg-blue-500/20 text-blue-400"
217242 : "bg-amber-500/20 text-amber-400"
218243 } `}
219244 >
220245 { e . callType === "read" ? "R" : "W" }
221246 </ span >
222- < span className = "truncate text-[#4DB4FF]" >
247+ < span className = "truncate text-sm text- [#4DB4FF]" >
223248 { e . functionName }
224249 </ span >
225250 </ div >
226- < div className = "flex items-center gap-3 flex-shrink-0" >
251+ < div className = "flex items-center gap-2 flex-shrink-0 ml-2 " >
227252 < div className = "flex flex-col items-end" >
228- < span className = "text-xs text-neutral" >
253+ < span className = "text-[11px] text-neutral" >
229254 { formatDate ( e . timestamp ) }
230255 </ span >
231256 { e . duration !== undefined && (
232- < span className = "text-[10px] text-neutral/60 " >
257+ < span className = "text-[10px] text-neutral/50 " >
233258 { e . duration } ms
234259 </ span >
235260 ) }
0 commit comments