Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 1 addition & 19 deletions apps/web/app/components/demo-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ type ApiConnectionBannerProps = {
health?: HealthResponse;
};

type DemoDataBadgeProps = {
label?: string;
};

type EmptyStateProps = {
nextStep?: string;
title: string;
Expand Down Expand Up @@ -102,19 +98,6 @@ export function ApiErrorPanel({
);
}

export function DemoDataBadge({
label = "Simulator-backed demo data",
}: DemoDataBadgeProps) {
return (
<span className="demo-notice">
<span className="demo-notice-label">{label}</span>
<span className="demo-notice-copy">
Synthetic local scenario; not real plant data.
</span>
</span>
);
}

export function EmptyState({ nextStep, title, text }: EmptyStateProps) {
return (
<div className="state-panel" role="status">
Expand All @@ -135,10 +118,9 @@ export function MissingDataPanel({ nextStep, text, title }: MissingDataPanelProp
);
}

export function LoadingState({ title = "Loading simulator-backed demo data" }: LoadingStateProps) {
export function LoadingState({ title = "Loading local demo data" }: LoadingStateProps) {
return (
<section className="content-panel loading-panel" aria-busy="true">
<DemoDataBadge />
<div className="state-panel" role="status">
<strong>{title}</strong>
<span>Connecting to the local FastAPI demo backend.</span>
Expand Down
9 changes: 6 additions & 3 deletions apps/web/app/connections/connections-workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,11 @@ export function ConnectionsWorkspace({

return (
<div className="connections-workspace">
<h1 className="connections-title">Connections</h1>
<div className="connections-actions">
<header className="page-heading">
<div>
<span className="status-label">Protocol Operations</span>
<h1 className="connections-title">Connections</h1>
</div>
<button
aria-label="Add connection profile"
className="icon-action add-connection-button"
Expand All @@ -188,7 +191,7 @@ export function ConnectionsWorkspace({
>
+
</button>
</div>
</header>
<section className="connection-table-shell" aria-label="Connections">
<div className="table-wrap">
<table className="connection-table">
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/connections/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default async function ConnectionsPage() {
const result = await loadConnectionProfiles();

return (
<section className="content-panel connections-page">
<section className="protocol-operations-page connections-page">
{!result.ok ? <ApiErrorPanel message={result.message} /> : null}
{result.ok ? <ConnectionsWorkspace initialProfiles={result.profiles} /> : null}
</section>
Expand Down
1 change: 0 additions & 1 deletion apps/web/app/detections/[detectionId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export default async function DetectionDetailPage({ params }: DetectionDetailPag

return (
<section className="content-panel">
<span className="demo-label">Simulator-backed demo data</span>
<div>
<Link className="back-link" href="/detections">
Back to detections
Expand Down
1 change: 0 additions & 1 deletion apps/web/app/detections/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export default async function DetectionsPage() {

return (
<section className="content-panel">
<span className="demo-label">Simulator-backed demo data</span>
<div>
<h1>Detections</h1>
<p className="lead">
Expand Down
206 changes: 177 additions & 29 deletions apps/web/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -282,29 +282,6 @@ a {
padding: 7px 8px;
}

.demo-notice {
display: inline-grid;
width: fit-content;
gap: 4px;
border: 1px solid #f5d38d;
border-radius: 7px;
background: var(--warning-bg);
color: var(--warning);
line-height: 1.2;
padding: 7px 9px;
}

.demo-notice-label {
font-size: 0.78rem;
font-weight: 760;
}

.demo-notice-copy {
color: #7a4f0f;
font-size: 0.72rem;
font-weight: 650;
}

.status-badge {
display: inline-flex;
width: fit-content;
Expand Down Expand Up @@ -421,8 +398,9 @@ h3 {
.status-label {
color: var(--muted);
font-size: 0.78rem;
font-variant-caps: all-small-caps;
font-weight: 760;
text-transform: uppercase;
text-transform: none;
}

.status-value {
Expand Down Expand Up @@ -1084,22 +1062,176 @@ h3 {
gap: 18px;
}

.protocol-operations-page {
display: grid;
gap: 22px;
}

.protocol-diagnostics-workspace {
display: grid;
gap: 22px;
}

.protocol-diagnostics-page {
align-content: start;
}

.page-heading,
.section-heading {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 16px;
}

.page-heading h1,
.section-heading h2 {
margin-bottom: 0;
}

.page-heading h1 {
font-size: clamp(2rem, 3vw, 3.1rem);
}

.protocol-operations-page .page-heading {
min-height: 58px;
align-items: center;
border-bottom: 1px solid var(--border);
padding-bottom: 18px;
}

.diagnostics-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 12px;
}

.diagnostics-card {
display: grid;
min-width: 0;
gap: 12px;
align-content: start;
border: 1px solid var(--border);
border-top: 4px solid var(--accent);
border-radius: 8px;
background: var(--surface);
padding: 16px;
}

.diagnostics-card-heading {
display: grid;
gap: 8px;
}

.diagnostics-card h2 {
margin-bottom: 0;
font-size: 1rem;
}

.diagnostics-card p {
margin-bottom: 0;
color: var(--muted);
font-size: 0.9rem;
line-height: 1.45;
}

.diagnostics-card-meta {
color: var(--muted-2);
font-size: 0.8rem;
font-weight: 650;
line-height: 1.35;
overflow-wrap: anywhere;
}

.diagnostics-table td span {
display: block;
margin-top: 4px;
color: var(--muted);
font-size: 0.84rem;
line-height: 1.35;
overflow-wrap: anywhere;
}

.diagnostics-table th,
.diagnostics-table td {
white-space: nowrap;
}

.diagnostics-table th:first-child,
.diagnostics-table td:first-child,
.diagnostics-table th:last-child,
.diagnostics-table td:last-child {
white-space: normal;
}

.protocol-operations-page .table-wrap {
box-shadow: var(--shadow);
}

.protocol-diagnostics-page .table-wrap {
max-height: 520px;
overflow: auto;
}

.protocol-diagnostics-page .connection-table th {
position: sticky;
z-index: 1;
top: 0;
}

.search-field {
display: grid;
min-width: min(100%, 320px);
gap: 6px;
color: var(--muted);
font-size: 0.78rem;
font-weight: 760;
text-transform: uppercase;
}

.search-field input {
width: 100%;
border: 1px solid var(--border);
border-radius: 7px;
background: var(--surface);
color: var(--text);
font: inherit;
line-height: 1.5;
padding: 11px 12px;
}

.search-field input:focus {
border-color: var(--accent);
outline: 3px solid var(--focus-ring);
outline-offset: 1px;
}

.troubleshooting-panel {
border-left: 4px solid var(--accent);
}

.command-list {
display: grid;
gap: 8px;
margin: 8px 0 0;
padding-left: 18px;
}

.command-list code {
overflow-wrap: anywhere;
}

.connections-title {
margin-bottom: 0;
}

.connections-actions,
.modal-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 16px;
}

.connections-actions {
justify-content: flex-end;
}

.icon-action {
display: inline-flex;
width: 42px;
Expand Down Expand Up @@ -1402,6 +1534,14 @@ code {
grid-template-columns: repeat(2, minmax(0, 1fr));
}

.diagnostics-card-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}

.section-heading {
display: grid;
}

.workflow-links {
grid-template-columns: 1fr;
}
Expand Down Expand Up @@ -1445,6 +1585,10 @@ code {
.metric-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}

.diagnostics-card-grid {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}

@media (max-width: 560px) {
Expand Down Expand Up @@ -1473,6 +1617,10 @@ code {
grid-template-columns: 1fr;
}

.diagnostics-card-grid {
grid-template-columns: 1fr;
}

.api-connection-details {
grid-template-columns: 1fr;
}
Expand Down
4 changes: 1 addition & 3 deletions apps/web/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { Metadata } from "next";
import Link from "next/link";
import type { ReactNode } from "react";

import { DemoDataBadge } from "./components/demo-state";
import { getApiBaseUrl } from "../lib/api-client";
import "./globals.css";

Expand Down Expand Up @@ -33,7 +32,7 @@ const navGroups: NavGroup[] = [
{
items: [
{ href: "/connections", label: "Connections" },
{ label: "Protocol Diagnostics", status: "Planned" },
{ href: "/protocol-diagnostics", label: "Protocol Diagnostics" },
{ label: "Tag/Source Browser", status: "Planned" },
],
label: "Protocol operations",
Expand All @@ -54,7 +53,6 @@ export default function RootLayout({ children }: { children: ReactNode }) {
<span className="brand-name">Factory Intelligence Platform</span>
<span className="brand-context">Operator Console</span>
</Link>
<DemoDataBadge />
</div>
<nav aria-label="Primary navigation" className="primary-nav">
{navGroups.map((group) => (
Expand Down
2 changes: 0 additions & 2 deletions apps/web/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import Link from "next/link";
import {
ApiConnectionBanner,
ApiErrorPanel,
DemoDataBadge,
StatusBadge,
} from "./components/demo-state";
import {
Expand Down Expand Up @@ -40,7 +39,6 @@ export default async function OverviewPage() {
<>
<section className="hero">
<div className="hero-copy">
<DemoDataBadge />
<h1>{overview.ok ? overview.context.siteName : "Operations Workbench"}</h1>
<p className="lead">
{overview.ok
Expand Down
Loading
Loading