@@ -2043,6 +2043,18 @@ <h4>File Upload</h4>
20432043 </ div >
20442044 </ div >
20452045
2046+ <!-- Result tabs -->
2047+ < div class ="result-tabs " role ="tablist " aria-label ="Analysis Results ">
2048+ < button class ="result-tab active " data-rtab ="explain " role ="tab " aria-selected ="true " aria-controls ="pane-explain " tabindex ="0 ">
2049+ < svg width ="15 " height ="15 " viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 " aria-hidden ="true "> < path d ="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z "/> < path d ="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z "/> </ svg > Explain < span class ="tab-badge " id ="explainBadge "> </ span >
2050+ </ button >
2051+ < button class ="result-tab " data-rtab ="debug " role ="tab " aria-selected ="false " aria-controls ="pane-debug " tabindex ="-1 ">
2052+ < svg width ="15 " height ="15 " viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 " aria-hidden ="true "> < path d ="M8 2l1.5 1.5 "/> < path d ="M14.5 3.5L16 2 "/> < path d ="M9 7.5A3 3 0 0 1 12 5a3 3 0 0 1 3 2.5 "/> < path d ="M6.5 9H4a1 1 0 0 0-1 1v1a8 8 0 0 0 16 0v-1a1 1 0 0 0-1-1h-2.5 "/> < line x1 ="12 " y1 ="12 " x2 ="12 " y2 ="16 "/> < path d ="M4.5 15H2 "/> < path d ="M22 15h-2.5 "/> < path d ="M4.5 19l-2 2 "/> < path d ="M19.5 19l2 2 "/> </ svg > Debug < span class ="tab-badge " id ="debugBadge "> </ span >
2053+ </ button >
2054+ < button class ="result-tab " data-rtab ="suggest " role ="tab " aria-selected ="false " aria-controls ="pane-suggest " tabindex ="-1 ">
2055+ < svg width ="15 " height ="15 " viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 " aria-hidden ="true "> < polygon points ="13,2 3,14 12,14 11,22 21,10 12,10 "/> </ svg > Improve < span class ="tab-badge " id ="suggestBadge "> </ span >
2056+ </ button >
2057+ </ div >
20462058 <!-- Results Panel -->
20472059 < div class ="panel ">
20482060 < div class ="panel-header ">
@@ -2392,6 +2404,96 @@ <h3>No suggestions yet</h3>
23922404 }
23932405 }
23942406
2407+ /* ═══════════════════════════════════════════════════════════════
2408+ MODE BUTTONS
2409+ ═══════════════════════════════════════════════════════════════ */
2410+ document . querySelectorAll ( '.mode-btn' ) . forEach ( b => {
2411+ b . addEventListener ( 'click' , ( ) => {
2412+ selectedMode = b . dataset . mode ;
2413+ document . querySelectorAll ( '.mode-btn' ) . forEach ( x => {
2414+ x . classList . remove ( 'active' ) ;
2415+ x . setAttribute ( 'aria-pressed' , 'false' ) ;
2416+ } ) ;
2417+ b . classList . add ( 'active' ) ;
2418+ b . setAttribute ( 'aria-pressed' , 'true' ) ;
2419+ } ) ;
2420+ } ) ;
2421+
2422+ /* ═══════════════════════════════════════════════════════════════
2423+ RESULT TABS
2424+ ═══════════════════════════════════════════════════════════════ */
2425+ document . querySelectorAll ( '.result-tab' ) . forEach ( ( t , index , tabs ) => {
2426+ t . addEventListener ( 'click' , ( ) => {
2427+ const tab = t . dataset . rtab ;
2428+
2429+ document . querySelectorAll ( '.result-tab' ) . forEach ( x => {
2430+ x . classList . remove ( 'active' ) ;
2431+ x . setAttribute ( 'aria-selected' , 'false' ) ;
2432+ } ) ;
2433+
2434+ document . querySelectorAll ( '.result-pane' ) . forEach ( x =>
2435+ x . classList . remove ( 'active' )
2436+ ) ;
2437+
2438+ t . classList . add ( 'active' ) ;
2439+ t . setAttribute ( 'aria-selected' , 'true' ) ;
2440+
2441+ document . getElementById ( `pane-${ tab } ` ) . classList . add ( 'active' ) ;
2442+ } ) ;
2443+
2444+ t . addEventListener ( 'keydown' , ( e ) => {
2445+ if ( e . key === 'ArrowRight' ) {
2446+ e . preventDefault ( ) ;
2447+ tabs [ ( index + 1 ) % tabs . length ] . focus ( ) ;
2448+ }
2449+
2450+ if ( e . key === 'ArrowLeft' ) {
2451+ e . preventDefault ( ) ;
2452+ tabs [ ( index - 1 + tabs . length ) % tabs . length ] . focus ( ) ;
2453+ }
2454+
2455+ if ( e . key === 'Enter' || e . key === ' ' ) {
2456+ e . preventDefault ( ) ;
2457+ t . click ( ) ;
2458+ }
2459+ } ) ;
2460+ } ) ;
2461+
2462+ /* ═══════════════════════════════════════════════════════════════
2463+ CLEAR / COPY
2464+ ═══════════════════════════════════════════════════════════════ */
2465+ document . getElementById ( 'clearBtn' ) . addEventListener ( 'click' , ( ) => {
2466+ editor . value = '' ;
2467+ updateEditor ( ) ;
2468+ resetResults ( ) ;
2469+ } ) ;
2470+ document . getElementById ( 'copyBtn' ) . addEventListener ( 'click' , ( ) => {
2471+ if ( ! editor . value . trim ( ) ) return ;
2472+ navigator . clipboard . writeText ( editor . value ) . then ( ( ) => toast ( 'Code copied!' , 'success' ) ) ;
2473+ } ) ;
2474+
2475+ /* ═══════════════════════════════════════════════════════════════
2476+ API PING
2477+ ═══════════════════════════════════════════════════════════════ */
2478+ async function pingApi ( ) {
2479+ const base = apiUrlInput . value . replace ( / \/ $ / , '' ) ;
2480+ try {
2481+ const r = await fetch ( `${ base } /health` , { signal : AbortSignal . timeout ( 5000 ) } ) ;
2482+ if ( r . ok ) {
2483+ apiDot . classList . add ( 'connected' ) ;
2484+ apiStatusText . textContent = 'Connected' ;
2485+ toast ( 'API is reachable' , 'success' ) ;
2486+ } else {
2487+ apiDot . classList . remove ( 'connected' ) ;
2488+ apiStatusText . textContent = 'Error ' + r . status ;
2489+ }
2490+ } catch {
2491+ apiDot . classList . remove ( 'connected' ) ;
2492+ apiStatusText . textContent = 'Unreachable' ;
2493+ toast ( 'Cannot reach API. Check the URL.' , 'error' ) ;
2494+ }
2495+ }
2496+ document . getElementById ( 'pingBtn' ) . addEventListener ( 'click' , pingApi ) ;
23952497 // CTRL + ENTER
23962498 else if (
23972499 e . key === 'Enter' &&
0 commit comments