From e2087ca2eeccb09e0e836cf9e0cc61d4282fe701 Mon Sep 17 00:00:00 2001 From: PrashantUnity Date: Wed, 2 Sep 2026 12:54:23 +0530 Subject: [PATCH 1/7] ui --- web/src/AppRoutes.tsx | 50 ++++++- web/src/components/AlertBanner.tsx | 7 +- web/src/components/AppShell.tsx | 14 +- web/src/components/Badge.tsx | 12 +- web/src/components/Button.tsx | 8 +- web/src/components/IntegrationsModal.tsx | 18 ++- web/src/components/ReportSelector.tsx | 6 +- web/src/components/Table.tsx | 4 +- web/src/components/ThemeToggle.tsx | 6 +- web/src/components/UrlInspectorDrawer.tsx | 14 +- web/src/components/ViewTabs.tsx | 6 +- web/src/components/chat/ChatFabDrawer.tsx | 14 +- .../components/chat/ChatStreamingStatus.tsx | 8 +- web/src/components/chat/ChatToolActivity.tsx | 8 +- .../chat/blocks/ChatArtifactDrawer.tsx | 13 +- .../components/contentStudio/DraftsTable.tsx | 4 +- .../contentStudio/GuidedDraftWizard.tsx | 15 +- .../contentStudio/NewDraftModal.tsx | 14 +- .../issues/AuditPromptGenerator.tsx | 7 + .../ContentTemplatesPanel.tsx | 57 +++++--- .../keywordsExplorer/TopicMapPanel.tsx | 26 ++-- .../components/overview/OverviewPagesTab.tsx | 5 +- .../overview/OverviewSummaryTab.tsx | 60 ++++---- .../components/pagesMarkdown/PreviewPanel.tsx | 8 +- .../components/pipeline/PipelineLogViewer.tsx | 2 +- web/src/hooks/useModalDismiss.test.ts | 14 ++ web/src/hooks/useModalDismiss.ts | 50 +++++++ .../lib/dashboard/builder/AiAssistModal.tsx | 29 +++- web/src/lib/dashboard/builder/ConfigPanel.tsx | 14 +- .../dashboard/interaction/SlicerControl.tsx | 10 +- web/src/lib/dashboard/widgets/TableWidget.tsx | 2 +- web/src/lib/dashboard/widgets/WidgetFrame.tsx | 8 +- web/src/views/Accessibility.tsx | 47 +++--- web/src/views/Chat.tsx | 9 +- web/src/views/CompareReports.tsx | 16 +-- web/src/views/Contacts.tsx | 9 +- web/src/views/Content.tsx | 62 ++++---- web/src/views/ContentAnalytics.tsx | 102 ++++++------- web/src/views/ContentPipeline.tsx | 6 +- web/src/views/Dashboards.tsx | 14 +- web/src/views/ExportReport.tsx | 7 +- web/src/views/GeoReadiness.tsx | 54 +++---- web/src/views/Home.tsx | 2 - web/src/views/ImageSeo.tsx | 28 ++-- web/src/views/Indexation.tsx | 46 +++--- web/src/views/Issues.tsx | 56 ++++---- web/src/views/JavaScriptErrors.tsx | 44 +++--- web/src/views/KeywordsExplorer.tsx | 37 ++--- web/src/views/Landing.tsx | 2 +- web/src/views/Lighthouse.tsx | 36 +++-- web/src/views/LogAnalyzer.tsx | 20 +-- web/src/views/McpSettings.tsx | 5 +- web/src/views/Redirects.tsx | 13 +- web/src/views/SearchPerformance.tsx | 134 ++++++++++-------- web/src/views/Secrets.tsx | 5 +- web/src/views/Security.tsx | 24 ++-- web/src/views/SiteStructure.tsx | 76 +++++----- web/src/views/Subdomains.tsx | 33 +++-- web/src/views/TechStack.tsx | 24 ++-- web/src/views/TextContentAnalysis.tsx | 88 ++++++------ web/src/views/Traffic.tsx | 78 +++++----- 61 files changed, 938 insertions(+), 652 deletions(-) create mode 100644 web/src/hooks/useModalDismiss.test.ts create mode 100644 web/src/hooks/useModalDismiss.ts diff --git a/web/src/AppRoutes.tsx b/web/src/AppRoutes.tsx index 815d99d0..46c69f3e 100644 --- a/web/src/AppRoutes.tsx +++ b/web/src/AppRoutes.tsx @@ -25,6 +25,7 @@ function LandingRoute() { } function ChatRoute() { + usePageTitle('AI Chat · Site Audit'); return ( @@ -32,6 +33,41 @@ function ChatRoute() { ); } +function WriteRoute() { + usePageTitle('Write Studio · Site Audit'); + return ; +} + +function PipelineRoute() { + usePageTitle('Run Audit · Site Audit'); + return ; +} + +function SettingsRoute() { + usePageTitle('Settings · Site Audit'); + return ; +} + +function SecretsRoute() { + usePageTitle('API Keys & Secrets · Site Audit'); + return ; +} + +function McpRoute() { + usePageTitle('MCP Tools · Site Audit'); + return ; +} + +function PagesMarkdownRoute() { + usePageTitle('Pages Markdown · Site Audit'); + return ; +} + +function ContentPipelineRoute() { + usePageTitle('Content Pipeline · Site Audit'); + return ; +} + function RiskSettingsRoute() { usePageTitle('Risk Settings · Site Audit'); return ; @@ -47,13 +83,13 @@ export default function AppRoutes() { } /> } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> } /> } /> } /> diff --git a/web/src/components/AlertBanner.tsx b/web/src/components/AlertBanner.tsx index 54e8b81c..b50b9baa 100644 --- a/web/src/components/AlertBanner.tsx +++ b/web/src/components/AlertBanner.tsx @@ -51,11 +51,12 @@ export default function AlertBanner({ children, onDismiss, className = '', - role = 'status', + role, collapsible = false, defaultOpen = false, }: AlertBannerProps) { const [open, setOpen] = useState(defaultOpen); + const resolvedRole = role ?? (variant === 'error' ? 'alert' : 'status'); const styles = VARIANT_STYLES[variant]; const DefaultIcon = styles.defaultIcon; const iconNode = icon ?? ; @@ -65,7 +66,7 @@ export default function AlertBanner({ if (collapsible && title) { const Chevron = open ? ChevronDown : ChevronRight; return ( -
+
+ ) : null}
) : (
)}
{headerExtra} +
diff --git a/web/src/components/Badge.tsx b/web/src/components/Badge.tsx index beaa8c42..8d13e6e7 100644 --- a/web/src/components/Badge.tsx +++ b/web/src/components/Badge.tsx @@ -6,12 +6,12 @@ import { getBadgeVariant } from '../lib/badges'; * Single size: text-xs, py-1, px-2. Normalize display value via optional `label` prop. */ const VARIANT_CLASSES: Record = { - critical: 'bg-red-500 text-white', - high: 'bg-red-500/20 text-red-700 dark:text-red-400 border border-red-500/30', - medium: 'bg-yellow-500/20 text-yellow-800 dark:text-yellow-400 border border-yellow-500/30', - low: 'bg-brand-700/20 text-muted-foreground border border-brand-700/30', - info: 'bg-brand-700/20 text-muted-foreground border border-brand-700/30', - success: 'bg-green-500/20 text-green-700 dark:text-green-400 border border-green-500/30', + critical: 'bg-red-500 text-white shadow-xs', + high: 'bg-red-500/15 text-red-700 dark:text-red-300 border border-red-500/30', + medium: 'bg-amber-500/15 text-amber-800 dark:text-amber-300 border border-amber-500/30', + low: 'bg-brand-700/50 text-muted-foreground border border-default', + info: 'bg-blue-500/15 text-blue-700 dark:text-blue-300 border border-blue-500/30', + success: 'bg-emerald-500/15 text-emerald-800 dark:text-emerald-300 border border-emerald-500/30', }; export default function Badge({ diff --git a/web/src/components/Button.tsx b/web/src/components/Button.tsx index af953350..d3b43c1b 100644 --- a/web/src/components/Button.tsx +++ b/web/src/components/Button.tsx @@ -1,7 +1,7 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react'; import { Loader2 } from 'lucide-react'; -type ButtonVariant = 'primary' | 'secondary' | 'ghost'; +type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'danger-outline'; type ButtonProps = { children?: ReactNode; @@ -12,9 +12,9 @@ type ButtonProps = { } & ButtonHTMLAttributes; /** - * Shared button: primary (Export style), secondary (border), ghost. + * Shared button: primary (Export style), secondary (border), ghost, danger, danger-outline. * Same size: px-4 py-2 rounded-lg text-sm font-medium/bold for primary. - * Includes tactile press feedback (.press) and, for primary, hover elevation. + * Includes tactile press feedback (.press) and, for primary/danger, hover elevation. */ export default function Button({ children, @@ -32,6 +32,8 @@ export default function Button({ primary: 'bg-blue-600 hover:bg-blue-500 text-white font-bold hover:shadow-[var(--elevation-2)]', secondary: 'border border-default text-foreground hover:bg-brand-700/80', ghost: 'text-muted-foreground hover:text-foreground hover:bg-brand-800/80', + danger: 'bg-red-600 hover:bg-red-500 text-white font-bold hover:shadow-[var(--elevation-2)]', + 'danger-outline': 'border border-red-500/40 text-red-600 dark:text-red-400 hover:bg-red-500/10 font-medium', }; const combined = `${base} ${variants[variant] || variants.primary} ${className}`.trim(); return ( diff --git a/web/src/components/IntegrationsModal.tsx b/web/src/components/IntegrationsModal.tsx index 5e8bbff9..fdd1ba4a 100644 --- a/web/src/components/IntegrationsModal.tsx +++ b/web/src/components/IntegrationsModal.tsx @@ -3,6 +3,7 @@ import { Settings2, X } from 'lucide-react'; import type { IntegrationToast } from '@/types/api'; import GoogleIntegrationsPanel from './GoogleIntegrationsPanel'; import { useOptionalReport } from '@/context/useReport'; +import { useModalDismiss } from '@/hooks/useModalDismiss'; export interface IntegrationsModalProps { open: boolean; @@ -17,19 +18,32 @@ export default function IntegrationsModal({ open, onClose, initialToast }: Integ report?.data?.start_url || report?.data?.google?.gsc?.site_url || '', ).trim(); + useModalDismiss({ + onDismiss: onClose, + enabled: open, + lockScroll: true, + }); + if (!open) return null; return (
-
+
e.stopPropagation()} + >
-

Google Integrations

+

Google Integrations

Connect Search Console, Analytics, and related data sources for this site. diff --git a/web/src/components/ReportSelector.tsx b/web/src/components/ReportSelector.tsx index be103651..1a889109 100644 --- a/web/src/components/ReportSelector.tsx +++ b/web/src/components/ReportSelector.tsx @@ -6,8 +6,8 @@ export default function ReportSelector() { const { reportList, selectedReportId, setSelectedReportId, loading, error } = useReport(); return ( -

-