@@ -4,7 +4,7 @@ import { useState, useEffect } from "react";
44import { Button } from "./Button" ;
55import { useAllSignals } from "../lib/useDataStore" ;
66import { loadPinnedSensors , savePinnedSensors , type CommsSensorConfig } from "./CommsSensorStrip" ;
7- import { Plus , X , Activity , Usb , Unplug , Save , Terminal } from "lucide-react" ;
7+ import { Plus , X , Activity , Usb , Unplug , Save , Terminal , Info } from "lucide-react" ;
88import { serialService } from "../services/SerialService" ;
99import { useRemoteConfig } from "../lib/useRemoteConfig" ;
1010import { getCategoryConfigString , updateCategories } from "../config/categories" ;
@@ -131,6 +131,7 @@ function SettingsModal({ isOpen, onClose, bannerApi }: Readonly<SettingsModalPro
131131 localStorage . getItem ( "perf-overlay-enabled" ) === "true"
132132 ) ;
133133 const [ isGameOpen , setIsGameOpen ] = useState ( false ) ;
134+ const [ bridgeOs , setBridgeOs ] = useState < "linux" | "windows" > ( "linux" ) ;
134135 const isSerialConnected = useSerialStatus ( ) ;
135136
136137 const { session, loadConfig, saveConfig } = useRemoteConfig ( ) ;
@@ -345,6 +346,69 @@ function SettingsModal({ isOpen, onClose, bannerApi }: Readonly<SettingsModalPro
345346 </ div >
346347 </ div >
347348
349+ { /* Kvaser Bridge Setup Instructions */ }
350+ < div className = "w-full rounded-lg text-white bg-option p-4" >
351+ < div className = "flex items-center justify-between mb-3" >
352+ < div className = "flex items-center gap-2" >
353+ < Info className = "w-5 h-5 text-blue-400" />
354+ < span className = "text-sm font-medium" > Kvaser Bridge Setup</ span >
355+ </ div >
356+ < div className = "flex bg-zinc-800 rounded-lg p-0.5 border border-gray-700" >
357+ < button
358+ onClick = { ( ) => setBridgeOs ( "linux" ) }
359+ className = { `px-3 py-1 text-[10px] font-medium rounded-md transition-all ${ bridgeOs === "linux" ? "bg-blue-600 text-white shadow-lg" : "text-gray-400 hover:text-gray-200" } ` }
360+ >
361+ LINUX
362+ </ button >
363+ < button
364+ onClick = { ( ) => setBridgeOs ( "windows" ) }
365+ className = { `px-3 py-1 text-[10px] font-medium rounded-md transition-all ${ bridgeOs === "windows" ? "bg-blue-600 text-white shadow-lg" : "text-gray-400 hover:text-gray-200" } ` }
366+ >
367+ WINDOWS
368+ </ button >
369+ </ div >
370+ </ div >
371+ < div className = "space-y-3 text-xs text-gray-400" >
372+ < p >
373+ Use the < code > kvaser-bridge</ code > to stream CAN data from a Kvaser adapter to this dashboard via WebSocket.
374+ </ p >
375+ < div className = "space-y-2" >
376+ < p className = "text-gray-300 font-medium" > Prerequisites:</ p >
377+ < ul className = "list-disc list-inside pl-1 space-y-1" >
378+ < li > Python 3.10+</ li >
379+ < li > Kvaser CANlib SDK installed</ li >
380+ { bridgeOs === "linux" && < li > < code > python3-tk</ code > (for GUI)</ li > }
381+ </ ul >
382+ </ div >
383+ < div className = "space-y-2" >
384+ < p className = "text-gray-300 font-medium" > Quick Start ({ bridgeOs === "linux" ? "Linux" : "Windows" } ):</ p >
385+ < div className = "bg-zinc-800 p-3 rounded font-mono text-[11px] space-y-1 border border-gray-700" >
386+ < div className = "text-emerald-500" > # Navigate to bridge directory</ div >
387+ < div > cd kvaser-bridge</ div >
388+ < div className = "text-emerald-500 mt-2" > # Create and activate virtual environment</ div >
389+ { bridgeOs === "linux" ? (
390+ < >
391+ < div > python3 -m venv .venv</ div >
392+ < div > source .venv/bin/activate</ div >
393+ </ >
394+ ) : (
395+ < >
396+ < div > python -m venv .venv</ div >
397+ < div > .venv\Scripts\activate</ div >
398+ </ >
399+ ) }
400+ < div className = "text-emerald-500 mt-2" > # Install dependencies</ div >
401+ < div > pip install -r requirements.txt</ div >
402+ < div className = "text-emerald-500 mt-2" > # Run the bridge</ div >
403+ < div > { bridgeOs === "linux" ? "python3 src/main.py" : "python src/main.py" } </ div >
404+ </ div >
405+ </ div >
406+ < p className = "italic" >
407+ Note: Ensure the bridge is pointing to < code > ws://localhost:9081</ code > (default).
408+ </ p >
409+ </ div >
410+ </ div >
411+
348412 { /* Category Configuration Area */ }
349413 < div className = "w-full rounded-lg text-white bg-option p-4" >
350414 < div className = "flex justify-between items-center mb-2" >
0 commit comments