@@ -15,6 +15,10 @@ import React, {
1515import { ErrorBoundary } from "react-error-boundary" ;
1616import * as ts from "typescript" ;
1717import type { Network } from "@/lib/types/network" ;
18+ import { MultiAddress , paseo , roc , wnd } from "@polkadot-api/descriptors" ;
19+ import { getWsProvider } from "polkadot-api/ws-provider/web" ;
20+ import { withPolkadotSdkCompat } from "polkadot-api/polkadot-sdk-compat" ;
21+ import { createClient } from "polkadot-api" ;
1822
1923const ALLOWED_MODULES : Record < string , unknown > = {
2024 react : React ,
@@ -23,6 +27,10 @@ const ALLOWED_MODULES: Record<string, unknown> = {
2327 jsx : React . createElement ,
2428 jsxs : React . createElement ,
2529 } ,
30+ "polkadot-api/ws-provider/web" : { getWsProvider } ,
31+ "polkadot-api/polkadot-sdk-compat" : { withPolkadotSdkCompat } ,
32+ "@polkadot-api/descriptors" : { paseo, roc, wnd, MultiAddress } ,
33+ "polkadot-api" : { createClient } ,
2634} ;
2735
2836const COMPILER_OPTIONS : ts . CompilerOptions = {
@@ -284,7 +292,7 @@ const evaluateComponent = (code: string) => {
284292 const component = normalizeComponent ( result as Record < string , unknown > ) ;
285293 if ( ! component ) {
286294 throw new Error (
287- `No valid component found. Exports analysis:\n${ analyzeExports ( result as Record < string , unknown > ) } ` ,
295+ `No valid React component found. Please ensure your code exports a valid React component.\n\nExport analysis:\n${ analyzeExports ( result as Record < string , unknown > ) } \n\nA valid React component can be:\n- A function component: const MyComponent = () => <div>Hello</div>\n- A class component: class MyComponent extends React.Component { ... }\n- Exported as default: export default MyComponent\n- A memo, forwardRef, or lazy component ` ,
288296 ) ;
289297 }
290298 return { component, originalCode } ;
@@ -301,41 +309,84 @@ const ErrorFallback: React.FC<{ error: Error; originalCode?: string }> = ({
301309 < div
302310 style = { {
303311 padding : "20px" ,
304- backgroundColor : "rgba(255, 0, 0, 0.1)" ,
305- borderRadius : "8px" ,
312+ backgroundColor : "rgba(255, 59, 48, 0.05)" ,
313+ borderRadius : "12px" ,
314+ border : "1px solid rgba(255, 59, 48, 0.2)" ,
306315 color : "#333" ,
307316 } }
308317 >
309- < h3 style = { { color : "#d32f2f" , marginTop : 0 } } > Erro no Componente</ h3 >
318+ < h3 style = { {
319+ color : "#ff3b30" ,
320+ marginTop : 0 ,
321+ marginBottom : "12px" ,
322+ fontSize : "18px" ,
323+ fontWeight : 600 ,
324+ } } >
325+ Component Error
326+ </ h3 >
310327 < pre
311328 style = { {
312- backgroundColor : "#f5f5f5 " ,
313- padding : "15px " ,
314- borderRadius : "6px " ,
329+ backgroundColor : "#f8f9fa " ,
330+ padding : "16px " ,
331+ borderRadius : "8px " ,
315332 overflowX : "auto" ,
333+ margin : "0 0 16px" ,
334+ fontSize : "14px" ,
335+ lineHeight : "1.5" ,
336+ fontFamily : "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace" ,
316337 } }
317338 >
318339 < code > { error . message } </ code >
319340 </ pre >
320341 { originalCode && (
321- < details >
322- < summary > Código Original</ summary >
342+ < details style = { { marginTop : "16px" } } >
343+ < summary style = { {
344+ cursor : "pointer" ,
345+ color : "#007aff" ,
346+ fontWeight : 500 ,
347+ padding : "8px 0" ,
348+ } } >
349+ View Original Code
350+ </ summary >
323351 < pre
324352 style = { {
325- backgroundColor : "#f5f5f5 " ,
326- padding : "15px " ,
327- borderRadius : "6px " ,
353+ backgroundColor : "#f8f9fa " ,
354+ padding : "16px " ,
355+ borderRadius : "8px " ,
328356 maxHeight : "300px" ,
329357 overflow : "auto" ,
358+ marginTop : "8px" ,
359+ fontSize : "14px" ,
360+ lineHeight : "1.5" ,
361+ fontFamily : "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace" ,
330362 } }
331363 >
332364 < code > { originalCode } </ code >
333365 </ pre >
334366 </ details >
335367 ) }
336- < details style = { { marginTop : "15px" } } >
337- < summary > Pilha de Erro Completa</ summary >
338- < pre style = { { whiteSpace : "pre-wrap" , wordBreak : "break-word" } } >
368+ < details style = { { marginTop : "16px" } } >
369+ < summary style = { {
370+ cursor : "pointer" ,
371+ color : "#007aff" ,
372+ fontWeight : 500 ,
373+ padding : "8px 0" ,
374+ } } >
375+ View Stack Trace
376+ </ summary >
377+ < pre
378+ style = { {
379+ whiteSpace : "pre-wrap" ,
380+ wordBreak : "break-word" ,
381+ backgroundColor : "#f8f9fa" ,
382+ padding : "16px" ,
383+ borderRadius : "8px" ,
384+ marginTop : "8px" ,
385+ fontSize : "14px" ,
386+ lineHeight : "1.5" ,
387+ fontFamily : "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace" ,
388+ } }
389+ >
339390 { error . stack }
340391 </ pre >
341392 </ details >
@@ -354,7 +405,7 @@ const LivePreview: React.FC<LivePreviewProps> = ({
354405 code,
355406 width = "100%" ,
356407 height = "auto" ,
357- fallbackMessage = "Carregando Componente ..." ,
408+ fallbackMessage = "Loading component ..." ,
358409} ) => {
359410 const [ componentData , setComponentData ] = useState < {
360411 Component : ComponentType ;
@@ -388,12 +439,14 @@ const LivePreview: React.FC<LivePreviewProps> = ({
388439 const containerStyle : React . CSSProperties = {
389440 width,
390441 height,
391- border : "1px solid #ddd " ,
392- borderRadius : "8px " ,
442+ border : "1px solid #e0e0e0 " ,
443+ borderRadius : "12px " ,
393444 padding : "20px" ,
394- backgroundColor : "rgba(255, 255, 255, 0.7)" ,
445+ backgroundColor : "rgba(255, 255, 255, 0.8)" ,
446+ backdropFilter : "blur(10px)" ,
395447 overflow : "auto" ,
396448 position : "relative" ,
449+ boxShadow : "0 2px 8px rgba(0, 0, 0, 0.05)" ,
397450 } ;
398451
399452 return (
@@ -408,14 +461,30 @@ const LivePreview: React.FC<LivePreviewProps> = ({
408461 ) }
409462 >
410463 { loading ? (
411- < div > { fallbackMessage } </ div >
464+ < div style = { {
465+ textAlign : "center" ,
466+ color : "#666" ,
467+ padding : "20px" ,
468+ fontFamily : "system-ui, -apple-system, sans-serif" ,
469+ } } >
470+ { fallbackMessage }
471+ </ div >
412472 ) : error ? (
413473 < ErrorFallback
414474 error = { error }
415475 originalCode = { componentData ?. originalCode }
416476 />
417477 ) : componentData ?. Component ? (
418- < Suspense fallback = { < div > { fallbackMessage } </ div > } >
478+ < Suspense fallback = {
479+ < div style = { {
480+ textAlign : "center" ,
481+ color : "#666" ,
482+ padding : "20px" ,
483+ fontFamily : "system-ui, -apple-system, sans-serif" ,
484+ } } >
485+ { fallbackMessage }
486+ </ div >
487+ } >
419488 { createElement ( componentData . Component ) }
420489 </ Suspense >
421490 ) : null }
@@ -424,4 +493,4 @@ const LivePreview: React.FC<LivePreviewProps> = ({
424493 ) ;
425494} ;
426495
427- export default LivePreview ;
496+ export default LivePreview ;
0 commit comments