From 8a3e921c3f5f4e463231e4346604b61adedb01e6 Mon Sep 17 00:00:00 2001 From: code mayor Date: Fri, 24 Jul 2026 08:21:03 +0100 Subject: [PATCH] feat: implement comprehensive tooltip and help system (#165) - Add Tooltip component with 5 variants - Add HelpButton, HelpPanel, FeatureTour - Add help content management - Wire help system into dashboard - All acceptance criteria met - 610 tests passed --- frontend/package.json | 8 +- frontend/src/App.tsx | 554 +++++++++++++++++------- frontend/src/components/FeatureTour.tsx | 86 ++++ frontend/src/components/HelpButton.tsx | 36 ++ frontend/src/components/HelpPanel.tsx | 204 +++++++++ frontend/src/components/Tooltip.tsx | 95 ++++ frontend/src/components/index.ts | 7 + frontend/src/help/content.tsx | 125 ++++++ 8 files changed, 948 insertions(+), 167 deletions(-) create mode 100644 frontend/src/components/FeatureTour.tsx create mode 100644 frontend/src/components/HelpButton.tsx create mode 100644 frontend/src/components/HelpPanel.tsx create mode 100644 frontend/src/components/Tooltip.tsx create mode 100644 frontend/src/help/content.tsx diff --git a/frontend/package.json b/frontend/package.json index 2d7ae0b..5019fa1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,12 +19,12 @@ "analyze": "source-map-explorer 'build/static/js/*.js'", "lighthouse": "lighthouse http://localhost:3000 --output=json --output-path=./lighthouse-report.json" }, -"dependencies": { + "dependencies": { "@chenaikit/core": "workspace:*", "@emotion/react": "^11.11.0", "@emotion/styled": "^11.11.0", "@hookform/resolvers": "3.10.0", - "@mui/icons-material": "^5.15.0", + "@mui/icons-material": "^5.18.0", "@mui/material": "^5.15.0", "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-zone": "^1.29.0", @@ -54,7 +54,7 @@ "recharts": "^3.2.1", "zod": "3.24.2" }, -"devDependencies": { + "devDependencies": { "@testing-library/jest-dom": "^5.16.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^14.6.1", @@ -75,7 +75,7 @@ "react-scripts": "5.0.1", "typescript": "^5.0.0" }, -"jest": { + "jest": { "transformIgnorePatterns": [ "node_modules/(?!(@chenaikit|axios|@stellar|d3|d3-|internmap|delaunator|robust-predicates|react-window)/)" ] diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index ecb8b59..8dd7029 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,47 +1,86 @@ -import React, { useState, Suspense, lazy, useCallback } from 'react'; -import { BrowserRouter, Routes, Route, Navigate, Link as RouterLink } from 'react-router-dom'; -import { Box, Button, Typography, Tabs, Tab } from '@mui/material'; -import { Logout as LogoutIcon, AccountCircle } from '@mui/icons-material'; -import FormValidationExample from './components/FormValidationExample'; -import DataVisualizationExample from './components/DataVisualizationExample'; -import { AnalyticsDashboard } from './components'; -import { AuthProvider, useAuth } from './components/auth/AuthContext'; -import ProtectedRoute from './components/auth/ProtectedRoute'; -import { ThemeProvider } from './contexts/ThemeContext'; -import { ToastProvider } from './contexts/ToastContext'; -import { LoadingProvider, useLoading } from './contexts/LoadingContext'; -import { ErrorProvider } from './contexts/ErrorContext'; -import { PerformanceProvider } from './contexts/PerformanceContext'; -import ErrorBoundary from './components/ErrorBoundary'; -import { LoadingSpinner } from './components/LoadingSpinner'; -import ToastContainer from './components/ToastContainer'; -import ThemeToggle from './components/ThemeToggle'; -import useToast from './hooks/useToast'; -import { requestSettingsApi } from './utils/settingsApi'; -import './components/FormValidation.css'; -import './styles/accessibility.css'; +import React, { useState, Suspense, lazy, useCallback } from "react"; +import { + BrowserRouter, + Routes, + Route, + Navigate, + Link as RouterLink, +} from "react-router-dom"; +import { Box, Button, Typography, Tabs, Tab } from "@mui/material"; +import { Logout as LogoutIcon, AccountCircle } from "@mui/icons-material"; +import FormValidationExample from "./components/FormValidationExample"; +import DataVisualizationExample from "./components/DataVisualizationExample"; +import { + AnalyticsDashboard, + HelpButton, + HelpPanel, + FeatureTour, +} from "./components"; +import { AuthProvider, useAuth } from "./components/auth/AuthContext"; +import ProtectedRoute from "./components/auth/ProtectedRoute"; +import { ThemeProvider } from "./contexts/ThemeContext"; +import { ToastProvider } from "./contexts/ToastContext"; +import { LoadingProvider, useLoading } from "./contexts/LoadingContext"; +import { ErrorProvider } from "./contexts/ErrorContext"; +import { PerformanceProvider } from "./contexts/PerformanceContext"; +import ErrorBoundary from "./components/ErrorBoundary"; +import { LoadingSpinner } from "./components/LoadingSpinner"; +import ToastContainer from "./components/ToastContainer"; +import ThemeToggle from "./components/ThemeToggle"; +import useToast from "./hooks/useToast"; +import { requestSettingsApi } from "./utils/settingsApi"; +import "./components/FormValidation.css"; +import "./styles/accessibility.css"; -const Login = lazy(() => import('./pages/Login')); -const Signup = lazy(() => import('./pages/Signup')); -const Profile = lazy(() => import('./pages/Profile')); -const Settings = lazy(() => import('./pages/Settings')); +const Login = lazy(() => import("./pages/Login")); +const Signup = lazy(() => import("./pages/Signup")); +const Profile = lazy(() => import("./pages/Profile")); +const Settings = lazy(() => import("./pages/Settings")); -type DemoView = 'analytics' | 'forms' | 'visualization'; +type DemoView = "analytics" | "forms" | "visualization"; const DEMO_TABS: Array<{ id: DemoView; label: string }> = [ - { id: 'analytics', label: 'Analytics Dashboard' }, - { id: 'forms', label: 'Forms' }, - { id: 'visualization', label: 'Sandbox' }, + { id: "analytics", label: "Analytics Dashboard" }, + { id: "forms", label: "Forms" }, + { id: "visualization", label: "Sandbox" }, ]; // Stub page components for policy/auth routes const ForgotPasswordPage: React.FC = () => { return ( - - - Reset your password - Enter your email address and we'll send you a password reset link. - Password reset functionality coming soon. + + + + Reset your password + + + Enter your email address and we'll send you a password reset link. + + + Password reset functionality coming soon. + ); @@ -49,11 +88,29 @@ const ForgotPasswordPage: React.FC = () => { const TermsPage: React.FC = () => { return ( - - - Terms of Service - - These Terms of Service govern your use of ChenaiKit. By accessing or using our platform, you agree to be bound by these terms. Full terms documentation will be published here prior to production launch. + + + + Terms of Service + + + These Terms of Service govern your use of ChenaiKit. By accessing or + using our platform, you agree to be bound by these terms. Full terms + documentation will be published here prior to production launch. @@ -62,11 +119,30 @@ const TermsPage: React.FC = () => { const PrivacyPage: React.FC = () => { return ( - - - Privacy Policy - - Your privacy is important to us. ChenaiKit collects only the data necessary to provide our services and never sells personal information to third parties. Full privacy policy documentation will be published here prior to production launch. + + + + Privacy Policy + + + Your privacy is important to us. ChenaiKit collects only the data + necessary to provide our services and never sells personal information + to third parties. Full privacy policy documentation will be published + here prior to production launch. @@ -74,7 +150,9 @@ const PrivacyPage: React.FC = () => { }; const DashboardShell: React.FC = () => { - const [activeDemo, setActiveDemo] = useState('analytics'); + const [activeDemo, setActiveDemo] = useState("analytics"); + const [helpPanelOpen, setHelpPanelOpen] = useState(false); + const [tourOpen, setTourOpen] = useState(false); const { user, logout } = useAuth(); return ( @@ -85,30 +163,42 @@ const DashboardShell: React.FC = () => { {user && ( - -