diff --git a/frontend/src/components/ProgressBar.tsx b/frontend/src/components/ProgressBar.tsx index 6df47f0..656b27e 100644 --- a/frontend/src/components/ProgressBar.tsx +++ b/frontend/src/components/ProgressBar.tsx @@ -1,38 +1,35 @@ +import { Progress } from "@/components/ui/progress"; + interface ProgressBarProps { currentStep: number; totalSteps?: number; labels?: string[]; } -export default function ProgressBar({ currentStep, totalSteps = 4, labels = ['Connect', 'Graph', 'Configure', 'Launch'] }: ProgressBarProps) { +export default function ProgressBar({ + currentStep, + totalSteps = 4, + labels = ["Connect", "Graph", "Configure", "Launch"], +}: ProgressBarProps) { + const progressValue = + totalSteps > 1 ? ((currentStep - 1) / (totalSteps - 1)) * 100 : currentStep === 1 ? 0 : 100; + return (
-
- {Array.from({ length: totalSteps }).map((_, i) => ( -
-
-
- -
- {i < totalSteps - 1 && ( -
- )} -
- ))} +
+ +
+ {labels.map((label, i) => ( + + ))} +
); diff --git a/frontend/src/components/ui/progress.tsx b/frontend/src/components/ui/progress.tsx index f9f131e..1cab16a 100644 --- a/frontend/src/components/ui/progress.tsx +++ b/frontend/src/components/ui/progress.tsx @@ -1,23 +1,61 @@ -import * as React from "react"; -import * as ProgressPrimitive from "@radix-ui/react-progress"; - +import React from "react"; import { cn } from "@/lib/utils"; -const Progress = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, value, ...props }, ref) => ( - - - -)); -Progress.displayName = ProgressPrimitive.Root.displayName; +type TProgressType = "default" | "success" | "warning" | "error" | "secondary"; + +interface ProgressProps extends React.HTMLAttributes { + value: number; + max?: number; + colors?: { [key: string]: string }; + type?: TProgressType; +} -export { Progress }; +const getColor = (value: number, type: TProgressType, colors?: Record) => { + if (colors) { + const keys = Object.keys(colors).sort((a, b) => parseInt(a) - parseInt(b)); + for (let i = keys.length - 1; i >= 0; i--) { + if (value >= parseInt(keys[i])) { + return colors[keys[i]]; + } + } + } + switch (type) { + case "success": + return "hsl(var(--primary))"; + case "error": + return "hsl(var(--destructive))"; + case "warning": + return "hsl(var(--warning))"; + case "secondary": + return "hsl(var(--muted-foreground))"; + default: + return "hsl(var(--primary))"; + } +}; + +export const Progress = ({ + value, + max = 100, + colors, + type = "default", + className, + ...props +}: ProgressProps) => { + const fillColor = getColor(value, type, colors); + + return ( + + ); +}; diff --git a/frontend/src/index.css b/frontend/src/index.css index f26adb7..016cfef 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -118,3 +118,11 @@ .tabular-nums { font-variant-numeric: tabular-nums; } + +/* Smooth progress bar - uses --progress-fill from inline style */ +.progress-step::-webkit-progress-value { + background: var(--progress-fill, hsl(var(--primary))); +} +.progress-step::-moz-progress-bar { + background: var(--progress-fill, hsl(var(--primary))); +} diff --git a/frontend/src/pages/Graph.tsx b/frontend/src/pages/Graph.tsx index eb0a6cc..ae34759 100644 --- a/frontend/src/pages/Graph.tsx +++ b/frontend/src/pages/Graph.tsx @@ -4,6 +4,7 @@ import Navbar from '../components/Navbar'; import ProgressBar from '../components/ProgressBar'; import StepNav from '../components/StepNav'; import ForceGraph, { DEFAULT_NODES, DEFAULT_EDGES } from '../components/ForceGraph'; +import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from '../components/ui/resizable'; interface ChatMessage { role: 'ai' | 'user'; @@ -31,6 +32,7 @@ export default function Graph() { const [typing, setTyping] = useState(false); const chatEndRef = useRef(null); const [graphKey, setGraphKey] = useState(0); + const hasUserSentMessage = messages.some(m => m.role === 'user'); useEffect(() => { chatEndRef.current?.scrollIntoView({ behavior: 'smooth' }); @@ -51,9 +53,9 @@ export default function Graph() { }; return ( -
+
-
+
@@ -61,14 +63,13 @@ export default function Graph() { initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.2 }} - className="flex-1 flex flex-col md:flex-row overflow-hidden" + className="flex-1 min-h-0 flex overflow-hidden" > - {/* Left Panel — Chat */} -
- {/* Chat Header */} -
+ + + {/* Chat Header */} +
- 🧠 ArbOS Brain
@@ -77,7 +78,7 @@ export default function Graph() {
{/* Messages */} -
+
{messages.map((msg, i) => (
{/* Stats */} -
+
Nodes: 14 Edges: 23 @@ -113,7 +114,7 @@ export default function Graph() {
{/* Input */} -
+
-
- - {/* Right Panel — Graph */} -
- - {/* Legend */} -
-
── IMPLIES   -- EXCLUSIVE   ·· PARTITION
-
- Active Arb   - Monitored   - Low Liquidity + + + + + {/* Right Panel — Graph */} + +
+ {hasUserSentMessage ? ( + <> + + {/* Legend */} +
+
── IMPLIES   -- EXCLUSIVE   ·· PARTITION
+
+ Active Arb   + Monitored   + Low Liquidity +
+
+ + ) : ( +

+ Type something in the chat to build your graph +

+ )}
-
-
+ + - + } /> +
); }