1+ import React , { useState , useEffect } from 'react' ;
2+ import { IconFileCode } from '@tabler/icons-react' ;
3+
4+ interface ConfigPreviewProps {
5+ owner : string ;
6+ repo : string ;
7+ path : string ;
8+ branch ?: string ;
9+ }
10+
11+ const getLanguage = ( path : string ) : string => {
12+ const ext = path . split ( '.' ) . pop ( ) ?. toLowerCase ( ) ;
13+ switch ( ext ) {
14+ case 'lua' : return 'lua' ;
15+ case 'js' : return 'javascript' ;
16+ case 'ts' : return 'typescript' ;
17+ case 'json' : return 'json' ;
18+ default : return 'text' ;
19+ }
20+ } ;
21+
22+ const ConfigPreview : React . FC < ConfigPreviewProps > = ( { owner, repo, path, branch = 'main' } ) => {
23+ const [ content , setContent ] = useState < string > ( '' ) ;
24+ const [ loading , setLoading ] = useState ( true ) ;
25+ const [ error , setError ] = useState < string | null > ( null ) ;
26+
27+ useEffect ( ( ) => {
28+ const fetchContent = async ( ) => {
29+ try {
30+ setLoading ( true ) ;
31+ const response = await fetch (
32+ `https://raw.githubusercontent.com/${ owner } /${ repo } /${ branch } /${ path } `
33+ ) ;
34+
35+ if ( ! response . ok ) {
36+ throw new Error ( 'Failed to fetch file content' ) ;
37+ }
38+
39+ const text = await response . text ( ) ;
40+ setContent ( text ) ;
41+ setError ( null ) ;
42+ } catch ( err ) {
43+ setError ( err instanceof Error ? err . message : 'An error occurred' ) ;
44+ } finally {
45+ setLoading ( false ) ;
46+ }
47+ } ;
48+
49+ fetchContent ( ) ;
50+ } , [ owner , repo , path , branch ] ) ;
51+
52+ if ( loading ) {
53+ return (
54+ < div className = "animate-pulse bg-zinc-200 dark:bg-zinc-800 rounded-lg p-4" >
55+ < div className = "h-4 bg-zinc-300 dark:bg-zinc-700 rounded w-3/4 mb-2" > </ div >
56+ < div className = "h-4 bg-zinc-300 dark:bg-zinc-700 rounded w-1/2" > </ div >
57+ </ div >
58+ ) ;
59+ }
60+
61+ if ( error ) {
62+ return (
63+ < div className = "bg-red-100 dark:bg-red-900/20 border border-red-400 dark:border-red-800 text-red-700 dark:text-red-400 px-4 py-3 rounded relative" >
64+ < strong className = "font-bold" > Error:</ strong >
65+ < span className = "block sm:inline" > { error } </ span >
66+ </ div >
67+ ) ;
68+ }
69+
70+ return (
71+ < div className = "border border-zinc-300 dark:border-zinc-700 rounded-lg overflow-hidden" >
72+ < div className = "bg-zinc-100 dark:bg-zinc-800 px-4 py-2 flex items-center border-b border-zinc-300 dark:border-zinc-700" >
73+ < IconFileCode className = "w-5 h-5 text-zinc-500 dark:text-zinc-400 mr-2" />
74+ < span className = "text-sm text-zinc-600 dark:text-zinc-300 font-mono" > { path } </ span >
75+ </ div >
76+ < pre className = "p-4 bg-white dark:bg-zinc-900 overflow-x-auto" >
77+ < code className = "text-sm font-mono text-zinc-800 dark:text-zinc-200" >
78+ { content }
79+ </ code >
80+ </ pre >
81+ </ div >
82+ ) ;
83+ } ;
84+
85+ export default ConfigPreview ;
0 commit comments