diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 711c23a..4b58bdf 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -44,7 +44,7 @@ jobs: - name: Check bundle size limits run: | BUNDLE_SIZE=$(du -sb dist/ | cut -f1) - MAX_SIZE=5242880 # 5MB limit (realistic for feature-rich React app) + MAX_SIZE=6291456 # 6MB limit (includes docs markdown assets) if [ $BUNDLE_SIZE -gt $MAX_SIZE ]; then echo "❌ Bundle size $BUNDLE_SIZE exceeds limit $MAX_SIZE" diff --git a/README.md b/README.md index 33cbc30..9137b09 100644 --- a/README.md +++ b/README.md @@ -1,112 +1,189 @@ +
+ # VSPEC -> AI-Powered Documentation Platform with GitBook-Style Design +### The Documentation Scope for AI Era -**VSPEC** is a lightweight SaaS documentation platform featuring AI-driven document review, narrative integration, quality acceptance, and automatic structure analysis. Built with a restrained, authoritative design philosophy. +**AI is the gun, VSPEC is the scope.** +Without VSPEC, AI shoots blind; with VSPEC, every shot hits the target. -## ✨ Features +[![React](https://img.shields.io/badge/React-18.3-61DAFB?style=flat-square&logo=react&logoColor=white)](https://react.dev) +[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178C6?style=flat-square&logo=typescript&logoColor=white)](https://typescriptlang.org) +[![Vite](https://img.shields.io/badge/Vite-6-646CFF?style=flat-square&logo=vite&logoColor=white)](https://vitejs.dev) +[![Tailwind](https://img.shields.io/badge/Tailwind_CSS-4.0-06B6D4?style=flat-square&logo=tailwindcss&logoColor=white)](https://tailwindcss.com) +[![License](https://img.shields.io/badge/License-Proprietary-7C85ED?style=flat-square)](#license) -- **AI Document Review (APE v1.1)** - Automated error detection, narrative optimization, and quality validation -- **Document Structure Analysis** - Auto-generated structure graphs and cluster maps -- **Real-time Collaboration** - Multi-user editing with live sync -- **GitBook-Style Editor** - Clean, distraction-free writing experience with right-click menus and manual editing modes -- **Eye-care Theme System** - Multiple reading modes optimized for long-form content -- **VDID Authentication** - Decentralized identity login integration -- **Command Center Dashboard** - Real-time monitoring with governance workflows +--- -## 🎨 Design System +*Obsidian (Local-first) + GitBook (Publishing) + AI (Automation)* -- **Brand Color**: `#7C85ED` (Medium-saturation blue-purple) - Used sparingly for emphasis -- **Typography**: Space Grotesk font system -- **Background**: `#FAFAFA` with pure white cards and subtle shadows -- **Philosophy**: Restrained, professional design - no marketing fluff or gradients -- **Icons**: Direct display without background containers, grayscale with strategic brand color accents -- **🔒 Text Visibility**: ENFORCED - No opacity on text elements ([Details](./TEXT_VISIBILITY_RULES.md)) +[Live Demo](https://vspec.pub)  ·  [Documentation](https://vspec.pub/docs)  ·  [Pricing](https://vspec.pub/pricing) -## 🏗️ Tech Stack +
-- **Frontend**: React + TypeScript -- **Styling**: Tailwind CSS v4.0 -- **Routing**: React Router -- **State Management**: React Hooks -- **Icons**: Lucide React -- **Build Tool**: Vite +--- -## 📦 Installation +## Why VSPEC? + +Knowledge workers spend **9.3 hours per week** on documentation. VSPEC cuts that in half with AI-powered automation that delivers **20x ROI** at $0.40/day. + +| Problem | VSPEC Solution | +|---------|---------------| +| Manual proofreading takes hours | **One-click Fix** - AI corrects grammar, style, and structure instantly | +| Processing 100+ docs is impossible | **Batch Processing** - Drag a folder, process everything automatically | +| Inconsistent terminology across docs | **Terminology Engine** - Maintains professional consistency throughout | +| Docs in one language limits reach | **7 Languages** - CN, EN, JP, KR, FR, DE, ES with native-quality output | +| No visibility into doc quality | **Structure Analysis** - Auto-generated structure graphs and quality scores | + +## Core Features + +**AI Document Intelligence** +- One-click fix: grammar, style, structure, and flow optimization +- Batch processing for bulk document operations +- Real-time AI suggestions as you write +- Automatic structure analysis and visualization + +**Editor & Publishing** +- GitBook-style distraction-free editor with markdown support +- Command palette (`Cmd+K`) - reach any feature in 2 keystrokes +- One-click publishing to `yourname.vspec.pub` +- Export to PDF, DOCX, HTML, Markdown, and JSON + +**Collaboration** +- Real-time multi-user editing with live cursors +- Comments, annotations, and approval workflows +- Role-based access control (Owner / Editor / Commenter / Viewer) +- Team workspaces with project isolation + +**Platform** +- VDID decentralized identity authentication +- Eye-care theme system (Light / Sepia / Soft Dark) +- Fully responsive: desktop, tablet, and mobile +- PWA support for offline access +- GitHub / GitLab integration for docs-as-code + +## Ecosystem + +VSPEC is part of the **Velon** product ecosystem: + +| Product | Description | Link | +|---------|-------------|------| +| **VELON** | Ecosystem hub | [velon.one](https://velon.one) | +| **VDID** | Decentralized identity | [vdid.io](https://vdid.io) | +| **VWORK** | Workspace platform | [velon.work](https://velon.work) | +| **RTPX** | Real-time protocol exchange | [rtpx.io](https://rtpx.io) | +| **VELGOO** | Discovery engine | [velgoo.cc](https://velgoo.cc) | +| **VSPEC** | Documentation OS | [vspec.pub](https://vspec.pub) | + +## Tech Stack + +| Layer | Technology | +|-------|-----------| +| Framework | React 18 + TypeScript | +| Build | Vite 6 with esbuild | +| Styling | Tailwind CSS v4 + Emotion | +| Routing | React Router v7 | +| State | Zustand + Immer | +| UI Components | Radix UI + Material UI | +| Rich Editor | Tiptap 3 | +| Animation | Motion (Framer Motion) | +| AI Backend | Multi-model (cost-optimized token routing) | +| Auth | Supabase + VDID OAuth 2.0 | +| i18n | i18next | + +## Quick Start ```bash +# Clone repository +git clone https://github.com/Vleonone/VSPEC.git +cd VSPEC + # Install dependencies -npm install +pnpm install # Start development server -npm run dev +pnpm dev +``` + +Open [http://localhost:5173](http://localhost:5173) in your browser. +```bash # Build for production -npm run build +pnpm build + +# Preview production build +pnpm preview + +# Run tests +pnpm test ``` -## 📁 Project Structure +## Project Structure ``` -vspec/ +VSPEC/ +├── docs/ # Markdown documentation (auto-synced to /docs page) +│ ├── guides/ # Quick start & usage guides +│ ├── internal/ # Internal strategy & planning docs +│ └── *.md # Architecture, specs, whitepapers ├── src/ │ ├── app/ -│ │ ├── components/ # Reusable UI components -│ │ ├── pages/ # Page components -│ │ └── App.tsx # Main app entry -│ ├── assets/ # Static assets (illustrations, logos) -│ ├── lib/ # Utilities and API helpers -│ └── styles/ # Global styles and theme -├── public/ # Public assets -└── package.json +│ │ ├── components/ # Reusable UI components +│ │ ├── hooks/ # Custom React hooks +│ │ ├── pages/ # Page components (lazy-loaded) +│ │ ├── stores/ # Zustand state stores +│ │ └── utils/ # Utilities & helpers +│ ├── lib/ # API clients, auth, storage +│ └── assets/ # Static assets +├── public/ # Public assets & PWA manifest +└── vite.config.ts # Vite configuration ``` -## 🚀 Core Pages - -- **Landing Page** (`/`) - Hero section with Spline 3D background -- **Dashboard** (`/dashboard`) - Command center with real-time monitoring -- **Editor** (`/editor`) - Full-featured document editor with structure graph -- **Login/Signup** - VDID integration for decentralized authentication - -## 🎯 Key Components - -### Editor Features -- Document tree with hierarchical indicators -- Right-click context menus -- Auto-structure graph visualization -- Real-time collaboration panel -- Manual editing mode toggle +## Documentation -### Dashboard Features -- Global Freshness Orb (Trust Score visualization) -- Ingestion Heatmap (Activity tracking) -- Governance Queue (Conflict management) -- Cluster Map (Document relationships) +Full documentation is available at [/docs](https://vspec.pub/docs) and is automatically generated from the `docs/` directory. Key references: -## 📚 Documentation - -For detailed documentation, see: +- [Product Specification](./docs/PRODUCT-SPEC.md) - [Architecture Guide](./docs/ARCHITECTURE.md) +- [AI Strategy](./docs/AI-STRATEGY.md) +- [Whitepaper (EN)](./docs/WHITEPAPER_EN.md) / [Whitepaper (CN)](./docs/WHITEPAPER.md) - [Deployment Guide](./docs/DEPLOYMENT_GUIDE.md) - [UI Style Guide](./docs/UI_STYLE_GUIDE.md) -- [VDID Integration](./docs/VDID_INTEGRATION.md) +- [Quick Start](./docs/guides/QUICK_START.md) + +## Design System -## 🔐 Authentication +| Token | Value | Usage | +|-------|-------|-------| +| Brand Color | `#7C85ED` | Accent, links, interactive elements | +| Typography | Space Grotesk / Inter | Headings / Body text | +| Background | `#FAFAFA` / `#0F0F12` | Light / Dark mode | +| Radius | `8px` / `12px` / `16px` | Buttons / Cards / Modals | +| Philosophy | Restrained & authoritative | No gradients, no marketing fluff | -VSPEC uses **VDID** (Decentralized Identity) for secure, privacy-first authentication. Users can sign in without traditional username/password systems. +## Pricing -## 🌐 Responsive Design +| | Personal | PRO | Team | +|---|---------|-----|------| +| **Price** | Free | $12/mo | $8/person/mo | +| **Documents** | 5 cloud | Unlimited | Unlimited | +| **AI Analyses** | 20/day | Unlimited | Unlimited | +| **One-click Fix** | - | Included | Included | +| **Batch Processing** | - | Included | Included | +| **Publishing** | - | Custom domain | Custom domain | +| **Collaboration** | - | 3 people | Unlimited | +| **Export** | Markdown | PDF/DOCX/HTML | PDF/DOCX/HTML | -All components are fully responsive with automatic breakpoints for mobile, tablet, and desktop views. +## License -## 📄 License +Proprietary - All rights reserved. -Proprietary - All rights reserved +--- -## 🤝 Contributing +
-This is a private project. For contribution guidelines, please contact the maintainers. +**VSPEC** - The Documentation Scope for AI Era ---- +[Website](https://vspec.pub)  ·  [Docs](https://vspec.pub/docs)  ·  [Pricing](https://vspec.pub/pricing) -**VSPEC** - Elevating documentation with AI-driven intelligence and restrained design. \ No newline at end of file +
diff --git a/src/app/pages/Docs.tsx b/src/app/pages/Docs.tsx index 7f6ec71..a557e77 100644 --- a/src/app/pages/Docs.tsx +++ b/src/app/pages/Docs.tsx @@ -1,832 +1,479 @@ /** - * VSPEC Documentation - Clean White Theme - * Light theme, minimal colors, no icon containers + * VSPEC Documentation - Dynamic Markdown Docs + * Loads documentation from docs/ directory at build time via Vite + * Dark purple-gray theme (Stripe/Linear style) */ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useMemo } from 'react'; import { motion, AnimatePresence } from 'motion/react'; import { Link } from 'react-router-dom'; +import ReactMarkdown from 'react-markdown'; +import remarkGfm from 'remark-gfm'; +import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; +import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism'; import { Search, ChevronRight, ChevronDown, Menu, - X, Copy, Check, ExternalLink, - Play, - BookOpen, FileText, - Code, - Users, - Layers, ArrowLeft, - ArrowRight + FolderOpen, + Loader2, } from 'lucide-react'; import { useResponsive } from '../hooks/useResponsive'; import VspecLogo from '../components/VspecLogo'; +import { + buildNavigation, + buildLookup, + loadDocContent, + extractHeadings, + type DocCategory, + type DocHeading, +} from '../utils/docsLoader'; + +// ── Static Data ──────────────────────────────────────────────── -// Ecosystem products - ordered as requested const ecosystemProducts = [ { id: 'velon', name: 'VELON', url: 'https://velon.one', external: true }, { id: 'vdid', name: 'VDID', url: 'https://vdid.io', external: true }, { id: 'vwork', name: 'VWORK', url: 'https://velon.work', external: true }, { id: 'rtpx', name: 'RTPX', url: 'https://rtpx.io', external: true }, { id: 'velgoo', name: 'VELGOO', url: 'https://velgoo.cc', external: true }, - { id: 'vspec', name: 'VSPEC', url: null, current: true }, + { id: 'vspec', name: 'VSPEC', url: null as string | null, current: true }, ]; -// Documentation navigation -const docNavItems = [ - { id: 'docs', label: 'Documentation', icon: FileText }, - { id: 'api', label: 'API', icon: Code }, - { id: 'guides', label: 'Guides', icon: BookOpen }, - { id: 'support', label: 'Support', icon: Users }, -]; +// Build navigation once at module level +const docsNavigation = buildNavigation(); +const docLookup = buildLookup(docsNavigation); +const defaultDocId = docsNavigation[0]?.items[0]?.id || ''; -// Tree node type - supports 5 levels of nesting -interface TreeNode { - id: string; - label: string; - children?: TreeNode[]; -} +// ── Colors ───────────────────────────────────────────────────── -// Documentation content for each page -const docContent: Record; -}> = { - 'introduction': { - title: 'Introduction to VSPEC', - breadcrumb: ['Getting Started', 'Introduction'], - sections: [ - { - content: 'VSPEC is a modern documentation platform powered by AI. It helps teams create, manage, and publish professional documentation with intelligent assistance at every step.', - }, - { - title: 'What is VSPEC?', - content: 'VSPEC combines a powerful editor with AI capabilities to streamline your documentation workflow:', - list: [ - 'AI-powered writing assistance and proofreading', - 'Real-time collaboration with team members', - 'Smart templates for common document types', - 'One-click publishing and sharing', - 'Version control and change tracking', - ], - }, - { - title: 'Key Features', - content: 'VSPEC offers a comprehensive set of features designed for modern documentation needs:', - list: [ - 'Rich text editor with markdown support', - 'AI review for grammar, style, and structure', - 'Team workspaces with role-based permissions', - 'Export to PDF, HTML, and Markdown', - 'Integration with VDID for authentication', - ], - }, - ], - }, - 'quickstart': { - title: 'Quick Start Guide', - breadcrumb: ['Getting Started', 'Quick Start'], - sections: [ - { - content: 'Get started with VSPEC in just a few minutes. Follow these steps to create your first document.', - }, - { - title: 'Step 1: Create an Account', - content: 'Sign up for VSPEC using your email or VDID account. VDID provides seamless authentication across the Velon ecosystem.', - }, - { - title: 'Step 2: Create a Document', - content: 'From your dashboard, click "New Document" to open the editor. You can start from scratch or choose a template.', - }, - { - title: 'Step 3: Write with AI Assistance', - content: 'As you write, VSPEC\'s AI assistant helps with:', - list: [ - 'Grammar and spelling corrections', - 'Style improvements and suggestions', - 'Structure optimization', - 'Consistency checks across your document', - ], - }, - { - title: 'Step 4: Publish & Share', - content: 'When you\'re ready, publish your document with one click. Share via link or export to various formats.', - }, - ], - }, - 'installation': { - title: 'Installation & Setup', - breadcrumb: ['Getting Started', 'Installation'], - sections: [ - { - content: 'VSPEC is a cloud-based platform that requires no installation. Simply access it through your web browser.', - }, - { - title: 'Browser Requirements', - content: 'VSPEC works best with modern browsers:', - list: [ - 'Google Chrome (recommended)', - 'Mozilla Firefox', - 'Microsoft Edge', - 'Safari 14+', - ], - }, - { - title: 'For Developers', - content: 'If you want to integrate VSPEC with your development workflow, install our CLI tool:', - code: 'npm install -g @vspec/cli', - }, - { - title: 'API Access', - content: 'For programmatic access, generate an API key from your Settings page. See the API Reference section for detailed documentation.', - }, - ], - }, - 'documents': { - title: 'Working with Documents', - breadcrumb: ['Core Concepts', 'Documents'], - sections: [ - { - content: 'Documents are the core of VSPEC. Learn how to create, organize, and manage your documentation.', - }, - { - title: 'Document Types', - content: 'VSPEC supports various document formats:', - list: [ - 'Technical Documentation', - 'API References', - 'User Guides', - 'Knowledge Base Articles', - 'Meeting Notes', - 'Project Specifications', - ], - }, - { - title: 'Organization', - content: 'Keep your documents organized with folders and tags. Use the search feature to quickly find any document in your workspace.', - }, - { - title: 'Version History', - content: 'Every change is automatically saved. Access version history to view previous versions, compare changes, or restore earlier content.', - }, - ], - }, - 'ai-review': { - title: 'AI Review System', - breadcrumb: ['Core Concepts', 'AI Review'], - sections: [ - { - content: 'VSPEC\'s AI Review system analyzes your documents and provides intelligent suggestions for improvement.', - }, - { - title: 'Review Categories', - content: 'The AI reviews your content across multiple dimensions:', - list: [ - 'Grammar & Spelling - Catch errors and typos', - 'Style & Tone - Ensure consistent voice', - 'Clarity - Improve readability', - 'Structure - Optimize document organization', - 'Completeness - Identify missing information', - ], - }, - { - title: 'How to Use', - content: 'Click the "AI Review" button in the editor toolbar. The AI will analyze your document and display suggestions in the sidebar. Accept, modify, or dismiss each suggestion.', - }, - { - title: 'Customization', - content: 'Configure review preferences in Settings to match your team\'s style guide and documentation standards.', - }, - ], - }, - 'collaboration': { - title: 'Collaboration Overview', - breadcrumb: ['Core Concepts', 'Collaboration'], - sections: [ - { - content: 'VSPEC makes it easy to work with your team on documentation projects.', - }, - { - title: 'Team Features', - content: 'Collaborate effectively with these features:', - list: [ - 'Real-time co-editing', - 'Comments and annotations', - 'Review workflows', - 'Role-based access control', - 'Activity tracking', - ], - }, - ], - }, - 'real-time': { - title: 'Real-time Editing', - breadcrumb: ['Core Concepts', 'Collaboration', 'Real-time Editing'], - sections: [ - { - content: 'Multiple team members can edit the same document simultaneously with real-time synchronization.', - }, - { - title: 'How It Works', - content: 'Changes are synced instantly across all connected users. Each user\'s cursor is visible with their name, making collaboration seamless.', - }, - { - title: 'Conflict Resolution', - content: 'VSPEC automatically handles edit conflicts. If two users edit the same section simultaneously, changes are merged intelligently.', - }, - ], - }, - 'comments': { - title: 'Comments & Reviews', - breadcrumb: ['Core Concepts', 'Collaboration', 'Comments & Reviews'], - sections: [ - { - content: 'Use comments to provide feedback and have discussions within your documents.', - }, - { - title: 'Adding Comments', - content: 'Select any text and click the comment icon to add a comment. Tag team members using @mentions to notify them.', - }, - { - title: 'Review Workflows', - content: 'Set up review processes where documents must be approved before publishing. Reviewers can approve, request changes, or leave feedback.', - }, - ], - }, - 'permissions': { - title: 'Permissions & Access', - breadcrumb: ['Core Concepts', 'Collaboration', 'Permissions'], - sections: [ - { - content: 'Control who can view and edit your documents with role-based permissions.', - }, - { - title: 'Permission Levels', - content: 'VSPEC offers granular permission control:', - list: [ - 'Owner - Full control including deletion', - 'Editor - Can edit and comment', - 'Commenter - Can view and comment only', - 'Viewer - Read-only access', - ], - }, - { - title: 'Sharing Options', - content: 'Share documents via direct invite, shareable links, or make them publicly accessible.', - }, - ], - }, - 'templates': { - title: 'Using Templates', - breadcrumb: ['Core Concepts', 'Templates'], - sections: [ - { - content: 'Templates help you create professional documents quickly with pre-designed structures.', - }, - { - title: 'Available Templates', - content: 'VSPEC includes templates for:', - list: [ - 'API Documentation', - 'User Manuals', - 'Technical Specs', - 'Release Notes', - 'Meeting Minutes', - 'Project Proposals', - ], - }, - { - title: 'Custom Templates', - content: 'Create your own templates from any document. Save time by reusing structures that work for your team.', - }, - ], - }, - 'authentication': { - title: 'API Authentication', - breadcrumb: ['API Reference', 'Authentication'], - sections: [ - { - content: 'Authenticate your API requests using API keys or OAuth tokens.', - }, - { - title: 'API Keys', - content: 'Generate API keys from your Settings page. Include the key in the Authorization header:', - code: 'Authorization: Bearer YOUR_API_KEY', - }, - { - title: 'OAuth Integration', - content: 'For user-facing applications, use OAuth 2.0 with VDID. This allows users to authorize your app without sharing credentials.', - }, - { - title: 'Rate Limits', - content: 'API requests are rate-limited based on your plan. Check response headers for current limits and usage.', - }, - ], - }, - 'endpoints': { - title: 'API Endpoints Overview', - breadcrumb: ['API Reference', 'Endpoints'], - sections: [ - { - content: 'The VSPEC API provides RESTful endpoints for managing documents, users, and teams programmatically.', - }, - { - title: 'Base URL', - code: 'https://api.vspec.app/v1', - }, - { - title: 'Available Endpoints', - content: 'Explore the following API sections:', - list: [ - 'Documents API - CRUD operations for documents', - 'Users API - User management and profiles', - 'Teams API - Team and workspace management', - ], - }, - ], - }, - 'documents-api': { - title: 'Documents API', - breadcrumb: ['API Reference', 'Endpoints', 'Documents API'], - sections: [ - { - title: 'List Documents', - code: 'GET /documents', - content: 'Returns a paginated list of documents in your workspace.', - }, - { - title: 'Get Document', - code: 'GET /documents/:id', - content: 'Retrieve a specific document by ID.', - }, - { - title: 'Create Document', - code: 'POST /documents', - content: 'Create a new document. Include title and optional content in the request body.', - }, - { - title: 'Update Document', - code: 'PUT /documents/:id', - content: 'Update an existing document.', - }, - { - title: 'Delete Document', - code: 'DELETE /documents/:id', - content: 'Permanently delete a document.', - }, - ], - }, - 'users-api': { - title: 'Users API', - breadcrumb: ['API Reference', 'Endpoints', 'Users API'], - sections: [ - { - title: 'Get Current User', - code: 'GET /users/me', - content: 'Returns the authenticated user\'s profile.', - }, - { - title: 'Update Profile', - code: 'PUT /users/me', - content: 'Update the current user\'s profile information.', - }, - { - title: 'List Team Members', - code: 'GET /users', - content: 'List all users in your workspace (requires admin permissions).', - }, - ], - }, - 'teams-api': { - title: 'Teams API', - breadcrumb: ['API Reference', 'Endpoints', 'Teams API'], - sections: [ - { - title: 'List Teams', - code: 'GET /teams', - content: 'Returns all teams the user belongs to.', - }, - { - title: 'Create Team', - code: 'POST /teams', - content: 'Create a new team workspace.', - }, - { - title: 'Invite Member', - code: 'POST /teams/:id/invites', - content: 'Send an invitation to join the team.', - }, - ], - }, - 'webhooks': { - title: 'Webhooks', - breadcrumb: ['API Reference', 'Webhooks'], - sections: [ - { - content: 'Receive real-time notifications when events occur in your workspace.', - }, - { - title: 'Supported Events', - list: [ - 'document.created', - 'document.updated', - 'document.deleted', - 'document.published', - 'comment.created', - 'team.member_added', - ], - }, - { - title: 'Webhook Payload', - content: 'Each webhook delivers a JSON payload containing the event type, timestamp, and relevant data.', - }, - ], - }, - 'vdid-auth': { - title: 'VDID Authentication', - breadcrumb: ['Integrations', 'VDID Authentication'], - sections: [ - { - content: 'VDID provides unified authentication across the Velon ecosystem.', - }, - { - title: 'Benefits', - list: [ - 'Single sign-on across all Velon products', - 'Secure OAuth 2.0 implementation', - 'Profile synchronization', - 'Team management integration', - ], - }, - { - title: 'Implementation', - content: 'Use the VDID SDK or standard OAuth 2.0 flow to authenticate users in your application.', - }, - ], - }, - 'git-sync': { - title: 'Git Sync', - breadcrumb: ['Integrations', 'Git Sync'], - sections: [ - { - content: 'Synchronize your VSPEC documents with Git repositories.', - }, - { - title: 'Supported Platforms', - list: [ - 'GitHub', - 'GitLab', - 'Bitbucket', - ], - }, - { - title: 'Setup', - content: 'Connect your repository from Settings > Integrations. Choose which documents to sync and configure automatic push on save.', - }, - ], - }, - 'export': { - title: 'Export Options', - breadcrumb: ['Integrations', 'Export Options'], - sections: [ - { - content: 'Export your documents in various formats for different use cases.', - }, - { - title: 'Available Formats', - list: [ - 'PDF - Professional printable documents', - 'HTML - Web-ready content', - 'Markdown - Developer-friendly format', - 'DOCX - Microsoft Word compatible', - 'JSON - Structured data export', - ], - }, - { - title: 'Batch Export', - content: 'Export multiple documents at once from the Documents page. Select documents and choose "Export" from the actions menu.', - }, - ], - }, +const colors = { + bg: '#0F0F12', + bgHeader: '#0A0A0D', + surface: '#1A1A2E', + surfaceHover: '#252540', + surfaceActive: '#2A2A4A', + border: '#2D2D45', + borderHover: '#3D3D5C', + text: '#F0F0F5', + textSecondary: '#A0A0B8', + textMuted: '#6B6B85', + accent: '#7C85ED', + accentHover: '#8B94F5', + accentDim: 'rgba(124, 133, 237, 0.15)', + codeBlock: '#16162A', + codeBorder: '#2A2A45', }; -// Sidebar documentation tree - supports nested children up to 5 levels -const sidebarTree: TreeNode[] = [ - { - id: 'getting-started', - label: 'Getting Started', - children: [ - { id: 'introduction', label: 'Introduction' }, - { id: 'quickstart', label: 'Quick Start' }, - { id: 'installation', label: 'Installation' }, - ], - }, - { - id: 'core-concepts', - label: 'Core Concepts', - children: [ - { id: 'documents', label: 'Documents' }, - { id: 'ai-review', label: 'AI Review' }, - { - id: 'collaboration', - label: 'Collaboration', - children: [ - { id: 'real-time', label: 'Real-time Editing' }, - { id: 'comments', label: 'Comments & Reviews' }, - { id: 'permissions', label: 'Permissions' }, - ], - }, - { id: 'templates', label: 'Templates' }, - ], +// ── Markdown Components ──────────────────────────────────────── + +function slugify(text: string): string { + return text + .toLowerCase() + .replace(/[^a-z0-9\u4e00-\u9fff]+/g, '-') + .replace(/^-|-$/g, ''); +} + +const markdownComponents = { + h1: ({ children }: { children?: React.ReactNode }) => { + const text = String(children || ''); + return ( +

+ {children} +

+ ); }, - { - id: 'api-reference', - label: 'API Reference', - children: [ - { id: 'authentication', label: 'Authentication' }, - { - id: 'endpoints', - label: 'Endpoints', - children: [ - { id: 'documents-api', label: 'Documents API' }, - { id: 'users-api', label: 'Users API' }, - { id: 'teams-api', label: 'Teams API' }, - ], - }, - { id: 'webhooks', label: 'Webhooks' }, - ], + + h2: ({ children }: { children?: React.ReactNode }) => { + const text = String(children || ''); + return ( +

+ {children} +

+ ); }, - { - id: 'integrations', - label: 'Integrations', - children: [ - { id: 'vdid-auth', label: 'VDID Authentication' }, - { id: 'git-sync', label: 'Git Sync' }, - { id: 'export', label: 'Export Options' }, - ], + + h3: ({ children }: { children?: React.ReactNode }) => { + const text = String(children || ''); + return ( +

+ {children} +

+ ); }, -]; -// Recursive TreeItem component with connection lines -interface TreeItemProps { - node: TreeNode; - level: number; - activeDoc: string; - setActiveDoc: (id: string) => void; - expandedSections: string[]; - toggleSection: (id: string) => void; - colors: Record; - isMobile: boolean; - setIsSidebarOpen: (open: boolean) => void; -} + p: ({ children }: { children?: React.ReactNode }) => ( +

+ {children} +

+ ), -function TreeItem({ node, level, activeDoc, setActiveDoc, expandedSections, toggleSection, colors, isMobile, setIsSidebarOpen }: TreeItemProps) { - const hasChildren = node.children && node.children.length > 0; - const isExpanded = expandedSections.includes(node.id); - const isActive = activeDoc === node.id; - const indent = 12 + level * 16; // Base indent + level offset - - return ( -
- {/* Connection line for nested items */} - {level > 0 && ( -
- )} - - {/* Horizontal connector */} - {level > 0 && ( -
- )} - - - - {/* Render children recursively */} - {hasChildren && isExpanded && ( -
- {node.children!.map((child, idx) => ( - - ))} -
- )} + + {codeString} + +
+ ); + }, + + table: ({ children }: { children?: React.ReactNode }) => ( +
+ {children}
- ); - } - + ), + + thead: ({ children }: { children?: React.ReactNode }) => ( + + {children} + + ), + + th: ({ children }: { children?: React.ReactNode }) => ( + + {children} + + ), + + td: ({ children }: { children?: React.ReactNode }) => ( + + {children} + + ), + + hr: () => ( +
+ ), + + strong: ({ children }: { children?: React.ReactNode }) => ( + {children} + ), + + img: ({ src, alt }: { src?: string; alt?: string }) => ( + {alt + ), +}; + +// ── Main Component ───────────────────────────────────────────── + export default function Docs() { const { isMobile, isTablet } = useResponsive(); - const [activeProduct, setActiveProduct] = useState('vspec'); - const [activeDoc, setActiveDoc] = useState('introduction'); - const [activeNav, setActiveNav] = useState('docs'); + const [activeDocId, setActiveDocId] = useState(defaultDocId); const [isSidebarOpen, setIsSidebarOpen] = useState(false); - // Auto-expand all sections with children - const [expandedSections, setExpandedSections] = useState([ - 'getting-started', 'core-concepts', 'collaboration', - 'api-reference', 'endpoints', 'integrations' - ]); + const [expandedCategories, setExpandedCategories] = useState( + docsNavigation.map((c) => c.id) + ); const [showSearch, setShowSearch] = useState(false); const [searchQuery, setSearchQuery] = useState(''); - const [copiedCode, setCopiedCode] = useState(false); + const [markdownContent, setMarkdownContent] = useState(''); + const [loading, setLoading] = useState(true); + const [copiedLink, setCopiedLink] = useState(false); - const toggleSection = (title: string) => { - setExpandedSections(prev => - prev.includes(title) - ? prev.filter(s => s !== title) - : [...prev, title] - ); - }; + const activeDoc = docLookup.get(activeDocId); + const headings = useMemo(() => extractHeadings(markdownContent), [markdownContent]); - const handleCopyCode = (code: string) => { - navigator.clipboard.writeText(code); - setCopiedCode(true); - setTimeout(() => setCopiedCode(false), 2000); - }; + // Load content when doc changes + useEffect(() => { + const doc = docLookup.get(activeDocId); + if (!doc) return; + + setLoading(true); + loadDocContent(doc.filePath).then((content) => { + setMarkdownContent(content); + setLoading(false); + }); + }, [activeDocId]); - // Keyboard shortcut for search (⌘K / Ctrl+K) + // Keyboard shortcut for search useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); setShowSearch(true); } - if (e.key === 'Escape') { - setShowSearch(false); - } + if (e.key === 'Escape') setShowSearch(false); }; - document.addEventListener('keydown', handleKeyDown); return () => document.removeEventListener('keydown', handleKeyDown); }, []); - // Colors - Stripe/Linear Dark Purple-Gray Theme - const colors = { - bg: '#0F0F12', // Deep dark background - bgHeader: '#0A0A0D', // Darker header - surface: '#1A1A2E', // Sidebar/card surface - surfaceHover: '#252540', // Hover state - surfaceActive: '#2A2A4A',// Active/selected state - border: '#2D2D45', // Subtle border - borderHover: '#3D3D5C', // Border hover - text: '#F0F0F5', // Primary text (near white) - textSecondary: '#A0A0B8',// Secondary text - textMuted: '#6B6B85', // Muted text - accent: '#7C85ED', // Purple accent - accentHover: '#8B94F5', // Accent hover (lighter) - accentDim: 'rgba(124, 133, 237, 0.15)', // Accent background - codeBlock: '#16162A', // Code block background - codeBorder: '#2A2A45', // Code block border + const toggleCategory = (catId: string) => { + setExpandedCategories((prev) => + prev.includes(catId) ? prev.filter((c) => c !== catId) : [...prev, catId] + ); + }; + + // Search results (title matching) + const searchResults = useMemo(() => { + if (!searchQuery.trim()) return []; + const q = searchQuery.toLowerCase(); + const results: { id: string; label: string; category: string }[] = []; + for (const cat of docsNavigation) { + for (const item of cat.items) { + if (item.label.toLowerCase().includes(q) || item.id.includes(q)) { + results.push({ id: item.id, label: item.label, category: cat.label }); + } + } + } + return results; + }, [searchQuery]); + + const handleCopyLink = () => { + navigator.clipboard.writeText(window.location.href); + setCopiedLink(true); + setTimeout(() => setCopiedLink(false), 2000); }; + // ── Render ───────────────────────────────────────────────── + return ( -
- {/* ========== TOP HEADER ========== */} -
- {/* Primary Nav: Logo + Search + Actions */} -
+
+ {/* ═══════ TOP HEADER ═══════ */} +
+ {/* Primary Nav */} +
{/* Left: Logo */}
{isMobile && ( )} - - VSPEC - DOCS + + VSPEC + + + DOCS +
@@ -848,26 +495,24 @@ export default function Docs() { gap: '8px', transition: 'all 0.2s ease', }} - onMouseEnter={(e) => { - e.currentTarget.style.borderColor = colors.borderHover; - }} - onMouseLeave={(e) => { - e.currentTarget.style.borderColor = colors.border; - }} + onMouseEnter={(e) => { e.currentTarget.style.borderColor = colors.borderHover; }} + onMouseLeave={(e) => { e.currentTarget.style.borderColor = colors.border; }} > Search - ⌘K + + ⌘K + )} - - {/* Home Button - Minimal */}
- {/* ========== ECOSYSTEM NAV ========== */} -
-
+ {/* ═══════ ECOSYSTEM NAV ═══════ */} +
+
{ecosystemProducts.map((product) => (
- - {/* ========== SECONDARY NAV (Docs/API/Guides/Support) ========== */} -
- {docNavItems.map((item) => ( - - ))} -
- {/* ========== MAIN LAYOUT ========== */} -
- {/* ========== LEFT SIDEBAR WITH IMPROVED MOBILE ========== */} + {/* ═══════ MAIN LAYOUT ═══════ */} +
+ {/* Mobile overlay */} {isMobile && isSidebarOpen && (
setIsSidebarOpen(false)} style={{ position: 'fixed', inset: 0, - background: 'rgba(0, 0, 0, 0.7)', + background: 'rgba(0,0,0,0.7)', backdropFilter: 'blur(4px)', WebkitBackdropFilter: 'blur(4px)', zIndex: 100, }} /> )} - - {/* LEFT SIDEBAR - Navigation */} - - - {/* MAIN CONTENT AREA */} -
- {(() => { - const currentDoc = docContent[activeDoc]; - // Fallback for unknown docs - if (!currentDoc) { - return ( -
-

Content Coming Soon

-

This documentation page is being written.

-
- ); - } - - return ( - <> - {/* Breadcrumb - GitBook Style */} - + gap: '8px', + }} + > + + Search docs... + +
+ )} - {/* Page Title - GitBook Style */} -

( +
+ {/* Category header */} +

- - {/* Optional subtitle/description */} - {currentDoc.description && ( -

- {currentDoc.description} -

- )} - - {/* Sections - GitBook Style */} - {currentDoc.sections.map((section, idx) => ( -
- {section.title && ( -

- {section.title} -

- )} - - {section.code && ( -
- -
-                          {section.code}
-                        
-
- )} - - {section.content && ( -

- {section.content} -

- )} - - {section.list && ( -
    - {section.list.map((item, listIdx) => ( -
  • {item}
  • - ))} -
- )} -
- ))} - - {/* Quick Links for Introduction page - GitBook Style */} - {activeDoc === 'introduction' && ( -
-

- Next Steps -

-
- {/* Quick Start - navigates to dashboard */} - - -
- -
-

- Quick Start -

-

- Jump into your dashboard now -

-
- - {/* Installation - shows installation docs */} - setActiveDoc('installation')} - whileHover={{ - y: -2, - boxShadow: '0 8px 24px rgba(0,0,0,0.08)', - }} - style={{ - padding: '20px', - background: colors.bg, - border: `1px solid ${colors.border}`, - borderRadius: '12px', - cursor: 'pointer', - transition: 'all 0.2s ease', - boxShadow: '0 2px 8px rgba(0,0,0,0.04)', - }} - > -

- Installation -

-

- Set up VSPEC for development -

-
-
-
- )} - - {/* Try Workspace CTA for quickstart page */} - {activeDoc === 'quickstart' && ( -
- - -
- - Launch VSPEC Workspace - -
-
- -
- )} - - ); - })()} - - - {/* RIGHT SIDEBAR - Table of Contents (GitBook Style) */} - {!isMobile && !isTablet && ( -
+ )} +
+ ))} + - {/* Copy Link */} -
- -
- - ); - })()} + {/* ═══════ MAIN CONTENT ═══════ */} +
+ {/* Breadcrumb */} + {activeDoc && ( + + )} + + {/* Loading state */} + {loading ? ( +
+ + Loading document... + +
+ ) : ( + /* Markdown content */ +
+ + {markdownContent} + +
+ )} +
+ + {/* ═══════ RIGHT SIDEBAR - TOC ═══════ */} + {!isMobile && !isTablet && headings.length > 0 && !loading && ( + )}
- {/* ========== SEARCH MODAL ========== */} + {/* ═══════ SEARCH MODAL ═══════ */} {showSearch && ( <> - {/* Backdrop */} - - {/* Search Modal */} - {/* Search Input */} -
- - setSearchQuery(e.target.value)} - autoFocus - style={{ - flex: 1, - background: 'transparent', - border: 'none', - outline: 'none', - fontSize: '16px', - color: colors.text, - fontFamily: 'var(--font-sans)', - }} - /> - -
- - {/* Search Results */} -
- {searchQuery.trim() === '' ? ( -
- Type to search documentation... -
- ) : ( - <> - {/* Filter matching docs */} - {Object.entries(docContent) - .filter(([_, doc]) => - doc.title.toLowerCase().includes(searchQuery.toLowerCase()) || - doc.sections.some(s => - s.content?.toLowerCase().includes(searchQuery.toLowerCase()) || - s.title?.toLowerCase().includes(searchQuery.toLowerCase()) - ) - ) - .map(([docId, doc]) => ( - - )) - } + }} + > + + setSearchQuery(e.target.value)} + autoFocus + style={{ + flex: 1, + background: 'transparent', + border: 'none', + outline: 'none', + fontSize: '16px', + color: colors.text, + fontFamily: 'var(--font-sans)', + }} + /> + +
- {/* No results message */} - {Object.entries(docContent).filter(([_, doc]) => - doc.title.toLowerCase().includes(searchQuery.toLowerCase()) || - doc.sections.some(s => - s.content?.toLowerCase().includes(searchQuery.toLowerCase()) || - s.title?.toLowerCase().includes(searchQuery.toLowerCase()) - ) - ).length === 0 && ( -
- No results found for "{searchQuery}" -
- )} - - )} + {/* Search Results */} +
+ {searchQuery.trim() === '' ? ( +
+ Type to search documentation... +
+ ) : searchResults.length > 0 ? ( + searchResults.map((result) => ( + + )) + ) : ( +
+ No results found for “{searchQuery}” +
+ )}
diff --git a/src/app/utils/docsLoader.ts b/src/app/utils/docsLoader.ts new file mode 100644 index 0000000..6b8691b --- /dev/null +++ b/src/app/utils/docsLoader.ts @@ -0,0 +1,169 @@ +/** + * Docs Loader - Build-time markdown file discovery via Vite + * Automatically discovers and organizes all .md files from /docs directory + */ + +// Discover all markdown files at build time +// ?url gives us static asset URLs instead of bundling content into JS chunks +// This keeps markdown files out of the JS bundle (~500KB savings) +const markdownUrls = import.meta.glob('/docs/**/*.md', { + eager: true, + query: '?url', + import: 'default', +}) as Record; + +// ── Types ────────────────────────────────────────────────────── + +export interface DocItem { + id: string; + label: string; + filePath: string; +} + +export interface DocCategory { + id: string; + label: string; + items: DocItem[]; +} + +export interface DocHeading { + level: number; + text: string; + id: string; +} + +// ── Helpers ──────────────────────────────────────────────────── + +const ACRONYMS = new Set([ + 'AI', 'API', 'UI', 'UX', 'SEO', 'CSS', 'VDID', 'HTML', '3D', + 'RTPX', 'PWA', 'VSPEC', 'SDK', 'CLI', 'URL', 'PDF', 'FAQ', +]); + +/** Convert a filename like "AI-STRATEGY.md" to "AI Strategy" */ +function fileToLabel(fileName: string): string { + const name = fileName.replace(/\.md$/, ''); + if (name === 'README') return 'Overview'; + + return name + .replace(/[-_]/g, ' ') + .split(' ') + .map(word => { + const upper = word.toUpperCase(); + if (ACRONYMS.has(upper)) return upper; + // Handle date-like segments (2025, 12, 25) + if (/^\d+$/.test(word)) return word; + return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); + }) + .join(' '); +} + +// ── Navigation Builder ───────────────────────────────────────── + +/** Build the full navigation tree from discovered files */ +export function buildNavigation(): DocCategory[] { + const categoryMap: Record = {}; + + for (const filePath of Object.keys(markdownUrls)) { + const rel = filePath.replace(/^\/docs\//, ''); + const parts = rel.split('/'); + + // Skip html directory (not markdown docs) + if (parts[0] === 'html') continue; + + const fileName = parts[parts.length - 1]; + const category = parts.length > 1 ? parts[0] : 'root'; + const id = rel + .replace(/\.md$/, '') + .replace(/[/\s]/g, '-') + .toLowerCase(); + + if (!categoryMap[category]) categoryMap[category] = []; + categoryMap[category].push({ id, label: fileToLabel(fileName), filePath }); + } + + // Sort alphabetically, Overview first + for (const items of Object.values(categoryMap)) { + items.sort((a, b) => { + if (a.label === 'Overview') return -1; + if (b.label === 'Overview') return 1; + return a.label.localeCompare(b.label); + }); + } + + const result: DocCategory[] = []; + + // Ordered sections + if (categoryMap['root']) { + result.push({ id: 'documentation', label: 'Documentation', items: categoryMap['root'] }); + } + if (categoryMap['guides']) { + result.push({ id: 'guides', label: 'Guides', items: categoryMap['guides'] }); + } + if (categoryMap['internal']) { + result.push({ id: 'internal', label: 'Internal', items: categoryMap['internal'] }); + } + + // Any other folders + for (const [cat, items] of Object.entries(categoryMap)) { + if (!['root', 'guides', 'internal', 'html'].includes(cat)) { + result.push({ + id: cat, + label: cat.charAt(0).toUpperCase() + cat.slice(1), + items, + }); + } + } + + return result; +} + +// ── Content Loader ───────────────────────────────────────────── + +/** Load markdown content for a doc by its file path (runtime fetch) */ +export async function loadDocContent(filePath: string): Promise { + const url = markdownUrls[filePath]; + if (!url) { + return `# Document Not Found\n\nThe requested document could not be loaded.`; + } + const response = await fetch(url); + if (!response.ok) { + return `# Load Error\n\nFailed to load document (${response.status}).`; + } + return response.text(); +} + +// ── Heading Extractor ────────────────────────────────────────── + +/** Extract h2/h3 headings from markdown for table of contents */ +export function extractHeadings(markdown: string): DocHeading[] { + const headings: DocHeading[] = []; + const regex = /^(#{2,3})\s+(.+)$/gm; + let match; + + while ((match = regex.exec(markdown)) !== null) { + const text = match[2].replace(/[*`#[\]]/g, '').trim(); + headings.push({ + level: match[1].length, + text, + id: text + .toLowerCase() + .replace(/[^a-z0-9\u4e00-\u9fff]+/g, '-') + .replace(/^-|-$/g, ''), + }); + } + + return headings; +} + +// ── Lookup Map ───────────────────────────────────────────────── + +/** Build a flat id -> doc info map for quick lookups */ +export function buildLookup(nav: DocCategory[]): Map { + const map = new Map(); + for (const cat of nav) { + for (const item of cat.items) { + map.set(item.id, { ...item, category: cat.label }); + } + } + return map; +} diff --git a/vite.config.ts b/vite.config.ts index 7e1e215..9ae5e3a 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -54,7 +54,8 @@ export default defineConfig({ 'vendor-xyflow': ['@xyflow/react'], // Icons 'vendor-icons': ['lucide-react'], - // Syntax highlighting (heavy) + // Markdown rendering + syntax highlighting + 'vendor-markdown': ['react-markdown', 'remark-gfm'], 'vendor-syntax': ['react-syntax-highlighter'], // Lottie animations 'vendor-lottie': ['lottie-react'],