Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d96a28f6cc | ||
|
|
5a6da7e507 | ||
|
|
b58640beb2 | ||
|
|
140ba10df6 | ||
|
|
48c31388db | ||
|
|
68b0e4d0bd |
@@ -24,7 +24,7 @@ export default async function DevicesPage({
|
|||||||
</div>
|
</div>
|
||||||
<Card className="bp-glass">
|
<Card className="bp-glass">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-base">Known devices</CardTitle>
|
<CardTitle className="text-sm">Known devices</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex flex-col gap-3">
|
<CardContent className="flex flex-col gap-3">
|
||||||
<DevicesTable devices={devices} />
|
<DevicesTable devices={devices} />
|
||||||
|
|||||||
+2
-2
@@ -18,7 +18,7 @@ export default async function DashboardPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-8">
|
<div className="flex flex-col gap-8">
|
||||||
<Card className="bp-glass overflow-hidden">
|
<Card className="bp-glass overflow-hidden">
|
||||||
<CardContent className="flex flex-col items-start gap-4 py-8">
|
<CardContent className="flex flex-col items-start gap-4 py-4">
|
||||||
<BrandMark size={48} animated className="rounded-[9px]" />
|
<BrandMark size={48} animated className="rounded-[9px]" />
|
||||||
<h1 className="font-heading text-3xl font-semibold">Welcome back</h1>
|
<h1 className="font-heading text-3xl font-semibold">Welcome back</h1>
|
||||||
<p className="max-w-xl text-sm text-muted-foreground">
|
<p className="max-w-xl text-sm text-muted-foreground">
|
||||||
@@ -56,7 +56,7 @@ export default async function DashboardPage() {
|
|||||||
|
|
||||||
<Card className="bp-glass">
|
<Card className="bp-glass">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-base">Recent sessions</CardTitle>
|
<CardTitle className="text-sm">Recent sessions</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex flex-col gap-3">
|
<CardContent className="flex flex-col gap-3">
|
||||||
<SessionsTable sessions={recentSessions} />
|
<SessionsTable sessions={recentSessions} />
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export default async function SessionDetailPage({ params }: { params: Promise<{
|
|||||||
|
|
||||||
<Card className="bp-glass">
|
<Card className="bp-glass">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-base">Intensity timeline</CardTitle>
|
<CardTitle className="text-sm">Intensity timeline</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<SessionTimelineChart timeline={timeline} />
|
<SessionTimelineChart timeline={timeline} />
|
||||||
@@ -81,7 +81,7 @@ export default async function SessionDetailPage({ params }: { params: Promise<{
|
|||||||
|
|
||||||
<Card className="bp-glass">
|
<Card className="bp-glass">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-base">Devices</CardTitle>
|
<CardTitle className="text-sm">Devices</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex flex-col gap-1">
|
<CardContent className="flex flex-col gap-1">
|
||||||
{detail.devices.map((d) => (
|
{detail.devices.map((d) => (
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default async function SessionsPage({
|
|||||||
</div>
|
</div>
|
||||||
<Card className="bp-glass">
|
<Card className="bp-glass">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-base">History</CardTitle>
|
<CardTitle className="text-sm">History</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex flex-col gap-3">
|
<CardContent className="flex flex-col gap-3">
|
||||||
<SessionsTable sessions={sessions} />
|
<SessionsTable sessions={sessions} />
|
||||||
|
|||||||
+29
-5
@@ -134,6 +134,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Themed scrollbar - follows --border/--muted-foreground so it swaps with
|
||||||
|
light/dark like everything else, instead of the OS-default bar. */
|
||||||
|
* {
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: var(--muted-foreground) transparent;
|
||||||
|
}
|
||||||
|
*::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
*::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
*::-webkit-scrollbar-thumb {
|
||||||
|
background-color: var(--border);
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
*::-webkit-scrollbar-thumb:hover {
|
||||||
|
background-color: var(--muted-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
/* Animated signature-sweep background - sits behind everything; cards use
|
/* Animated signature-sweep background - sits behind everything; cards use
|
||||||
.bp-glass (translucent + blurred) so it shines through instead of being
|
.bp-glass (translucent + blurred) so it shines through instead of being
|
||||||
fully hidden behind an opaque card surface. */
|
fully hidden behind an opaque card surface. */
|
||||||
@@ -181,12 +204,13 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Console-module surface: translucent + blurred so the animated background
|
/* Console-module surface: translucent + blurred so the animated background
|
||||||
sweep shines through. ring-0 zeroes out Card's own default
|
sweep shines through. Card's own default ring (components/ui/card.tsx:
|
||||||
`ring-1 ring-foreground/10` (components/ui/card.tsx) - shadow-xl's
|
`ring-1 ring-foreground/10`) still shows - ring-accent recolors it to the
|
||||||
box-shadow formula reads the same --tw-ring-shadow custom property, so
|
accent token instead of resetting it. border-accent is currently a no-op
|
||||||
without this the ring bleeds through regardless of shadow-xl "winning". */
|
(neither Card nor this rule sets a border-width utility to give it a
|
||||||
|
border to color). */
|
||||||
.bp-glass {
|
.bp-glass {
|
||||||
@apply shadow-xl ring-0 border-0;
|
@apply shadow-xs ring-accent border-accent;
|
||||||
background: color-mix(in srgb, var(--card) 55%, transparent);
|
background: color-mix(in srgb, var(--card) 55%, transparent);
|
||||||
backdrop-filter: blur(20px) saturate(150%);
|
backdrop-filter: blur(20px) saturate(150%);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,29 @@ export function SessionTimelineChart({ timeline }: { timeline: TimelineRow[] })
|
|||||||
className="bp-readout text-xs"
|
className="bp-readout text-xs"
|
||||||
/>
|
/>
|
||||||
<YAxis domain={[0, 100]} tickLine={false} axisLine={false} width={32} className="bp-readout text-xs" />
|
<YAxis domain={[0, 100]} tickLine={false} axisLine={false} width={32} className="bp-readout text-xs" />
|
||||||
<ChartTooltip content={<ChartTooltipContent />} />
|
<ChartTooltip
|
||||||
|
content={
|
||||||
|
<ChartTooltipContent
|
||||||
|
formatter={(value, name) => {
|
||||||
|
const itemConfig = config[name as string];
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className="h-2.5 w-2.5 shrink-0 rounded-[2px]"
|
||||||
|
style={{ backgroundColor: itemConfig?.color }}
|
||||||
|
/>
|
||||||
|
<div className="flex flex-1 items-center justify-between gap-4 leading-none">
|
||||||
|
<span className="text-muted-foreground">{itemConfig?.label ?? name}</span>
|
||||||
|
<span className="bp-readout font-medium text-foreground">
|
||||||
|
{typeof value === "number" ? value.toLocaleString() : String(value)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
{series.map(([sessionDeviceId]) => (
|
{series.map(([sessionDeviceId]) => (
|
||||||
<Area
|
<Area
|
||||||
key={sessionDeviceId}
|
key={sessionDeviceId}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export function DeviceUsageTable({ devices }: { devices: DeviceUsageRow[] }) {
|
|||||||
return (
|
return (
|
||||||
<Card className="bp-glass">
|
<Card className="bp-glass">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-base">Device usage</CardTitle>
|
<CardTitle className="text-sm">Device usage</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="text-sm text-muted-foreground">No device activity yet.</CardContent>
|
<CardContent className="text-sm text-muted-foreground">No device activity yet.</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -26,7 +26,7 @@ export function DeviceUsageTable({ devices }: { devices: DeviceUsageRow[] }) {
|
|||||||
return (
|
return (
|
||||||
<Card className="bp-glass">
|
<Card className="bp-glass">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-base">Device usage</CardTitle>
|
<CardTitle className="text-sm">Device usage</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Table>
|
<Table>
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sexy",
|
"name": "sexy",
|
||||||
"version": "0.9.1",
|
"version": "0.9.6",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
|||||||
Reference in New Issue
Block a user