Skip to content

Commit 452e5c8

Browse files
committed
update charts ui
1 parent b904af4 commit 452e5c8

6 files changed

Lines changed: 93 additions & 46 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Link } from "react-router";
2+
import { LayoutDashboard, Rocket } from "lucide-react";
3+
import logoSvg from "@/assets/logo.svg";
4+
5+
const items = [
6+
{ to: "/overview", label: "Dashboard", icon: LayoutDashboard },
7+
{ to: "/setup", label: "Setup", icon: Rocket },
8+
];
9+
10+
export function FloatingHeader() {
11+
return (
12+
<header className="fixed top-4 right-4 z-50">
13+
<nav className="flex items-center gap-1 rounded-full border border-border/50 bg-background/60 backdrop-blur-xl px-2 py-1.5 shadow-lg">
14+
{items.map(({ to, label, icon: Icon }) => (
15+
<Link
16+
key={to}
17+
to={to}
18+
className="flex items-center gap-1.5 rounded-full px-4 py-1.5 text-sm text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors"
19+
>
20+
<Icon className="h-3.5 w-3.5" />
21+
{label}
22+
</Link>
23+
))}
24+
</nav>
25+
</header>
26+
);
27+
}

packages/dashboard/src/components/setup-dialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export function SetupDialog() {
4949
<StepNumber n={4} /> Connect a sensor and start publishing data:
5050
</MessageBubble>
5151
<MessageBubble variant="primary">
52-
Set up a temperature sensor on my Raspberry Pi and start publishing data
52+
Set up a temperature sensor and start publishing data
5353
</MessageBubble>
5454

5555
{/* Step 5: Query data */}
Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import { Tag } from "lucide-react";
2+
import { useMemo } from "react";
13
import type { DecodedMessage } from "@/hooks/use-channel-messages";
24
import { useChartData } from "@/hooks/use-chart-data";
35
import { SensorChart } from "@/components/shared/sensor-chart";
6+
import { StatCard } from "@/components/shared/stat-card";
47

58
const COLORS = [
69
"#0ea5e9", // sky-500
@@ -11,25 +14,53 @@ const COLORS = [
1114
"#f43f5e", // rose-500
1215
];
1316

17+
const TIMESTAMP_KEYS = new Set(["ts", "timestamp"]);
18+
19+
function useTextFields(messages: DecodedMessage[]): { key: string; value: string }[] {
20+
return useMemo(() => {
21+
const latest = messages.find((m) => m.envelope);
22+
if (!latest?.envelope) return [];
23+
return Object.entries(latest.envelope.p)
24+
.filter(([key, val]) => {
25+
if (typeof val === "number") return false;
26+
if (TIMESTAMP_KEYS.has(key.toLowerCase())) return false;
27+
return val != null;
28+
})
29+
.map(([key, val]) => ({ key, value: String(val) }));
30+
}, [messages]);
31+
}
32+
1433
interface SensorChartsProps {
1534
messages: DecodedMessage[];
1635
}
1736

1837
export function SensorCharts({ messages }: SensorChartsProps) {
1938
const series = useChartData(messages);
39+
const textFields = useTextFields(messages);
2040

21-
if (series.length === 0) return null;
41+
if (series.length === 0 && textFields.length === 0) return null;
2242

2343
return (
24-
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
25-
{series.map((s, i) => (
26-
<SensorChart
27-
key={s.key}
28-
title={s.key}
29-
data={s.data}
30-
color={COLORS[i % COLORS.length]}
31-
/>
32-
))}
44+
<div className="space-y-4">
45+
{textFields.length > 0 && (
46+
<div className="grid grid-cols-2 sm:grid-cols-3 gap-3 sm:gap-4">
47+
{textFields.map((f) => (
48+
<StatCard key={f.key} title={f.key} value={f.value} icon={Tag} accent="violet" />
49+
))}
50+
</div>
51+
)}
52+
{series.length > 0 && (
53+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
54+
{series.map((s, i) => (
55+
<SensorChart
56+
key={s.key}
57+
title={s.key}
58+
data={s.data}
59+
color={COLORS[i % COLORS.length]}
60+
/>
61+
))}
62+
</div>
63+
)}
3364
</div>
3465
);
3566
}

packages/dashboard/src/components/ui/sonner.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export function Toaster(props: ToasterProps) {
88
toastOptions={{
99
classNames: {
1010
toast:
11-
"group toast !backdrop-blur-md !bg-emerald-500/15 !text-emerald-400 !border !border-emerald-500/20 !shadow-lg !rounded-2xl !py-2.5 !px-3.5 !text-sm !font-normal !min-h-0 !min-w-0 !w-auto",
11+
"group toast !backdrop-blur-md !bg-emerald-500/15 !text-emerald-400 !border !border-emerald-500/20 !shadow-lg !rounded-2xl !py-2.5 !px-3.5 !text-sm !font-normal !min-h-0 !min-w-0 !w-auto !max-w-[calc(100vw-2rem)]",
1212
icon: "!text-emerald-400",
1313
},
1414
}}

packages/dashboard/src/hooks/use-chart-data.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export function useChartData(messages: DecodedMessage[]): ChartSeries[] {
2020
const { ts, p } = msg.envelope;
2121
for (const [key, val] of Object.entries(p)) {
2222
if (typeof val !== "number") continue;
23+
const lk = key.toLowerCase();
24+
if (lk === "ts" || lk === "timestamp") continue;
2325
let arr = seriesMap.get(key);
2426
if (!arr) {
2527
arr = [];
Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,32 @@
1-
import { Link } from "react-router";
2-
import { Rocket, LayoutDashboard } from "lucide-react";
31
import { MessageBubble } from "@/components/ui/message-bubble";
42
import { SetupDialog } from "@/components/setup-dialog";
3+
import { FloatingHeader } from "@/components/floating-header";
54
import logoSvg from "@/assets/logo.svg";
65

76
export function HomePage() {
87
return (
9-
<div className="flex flex-col items-center max-w-2xl mx-auto py-20 px-4">
10-
<div className="flex items-center gap-3 mb-3">
11-
<img src={logoSvg} alt="SmartClaws" className="h-10 w-10" />
12-
<span className="text-3xl font-medium tracking-tight" style={{ color: "#FFD7DA" }}>SmartClaws</span>
13-
</div>
14-
<p className="text-foreground text-center mb-6 max-w-md font-normal text-md mt-4">
15-
Publish sensor data to SKALE and query it with natural language - powered by AI agents.
16-
</p>
17-
18-
<div className="w-full mb-8">
19-
<p className="text-foreground text-center max-w-md font-normal text-md pb-18 flex items-center justify-center gap-2 flex-wrap mx-auto">
20-
Copy
21-
<MessageBubble variant="primary" clickable className="inline-flex max-w-none self-auto text-md font-normal">
22-
messages
23-
</MessageBubble>
24-
to your agent to setup:
8+
<>
9+
<FloatingHeader />
10+
<div className="flex flex-col items-center max-w-2xl mx-auto py-20 px-4">
11+
<div className="flex items-center gap-3 mb-3">
12+
<img src={logoSvg} alt="SmartClaws" className="h-10 w-10" />
13+
<span className="text-3xl font-medium tracking-tight" style={{ color: "#FFD7DA" }}>SmartClaws</span>
14+
</div>
15+
<p className="text-foreground text-center mb-6 max-w-md font-normal text-md mt-4">
16+
Publish sensor data to SKALE and query it with natural language - powered by AI agents.
2517
</p>
26-
<SetupDialog />
27-
</div>
2818

29-
<div className="flex items-center gap-3 mt-4">
30-
<Link
31-
to="/setup"
32-
className="flex items-center gap-1.5 rounded-lg border border-border px-4 py-2 text-sm text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
33-
>
34-
<Rocket className="h-3.5 w-3.5" /> Full setup guide
35-
</Link>
36-
<Link
37-
to="/overview"
38-
className="flex items-center gap-1.5 rounded-lg border border-border px-4 py-2 text-sm text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
39-
>
40-
<LayoutDashboard className="h-3.5 w-3.5" /> Dashboard
41-
</Link>
19+
<div className="w-full mb-8">
20+
<p className="text-foreground text-center max-w-md font-normal text-md pb-18 flex items-center justify-center gap-2 flex-wrap mx-auto">
21+
Copy
22+
<MessageBubble variant="primary" clickable className="inline-flex max-w-none self-auto text-md font-normal">
23+
messages
24+
</MessageBubble>
25+
to your agent to setup:
26+
</p>
27+
<SetupDialog />
28+
</div>
4229
</div>
43-
</div>
30+
</>
4431
);
4532
}

0 commit comments

Comments
 (0)