From 0509597bde241b665452840261a1b246b65f9a4f Mon Sep 17 00:00:00 2001 From: 1PoPTRoN Date: Wed, 4 Feb 2026 07:23:59 +0530 Subject: [PATCH] docs: audit and fix documentation architecture, build, and i18n Signed-off-by: 1PoPTRoN --- CONTRIBUTING.md | 30 +-- docs/DEVELOPER_GUIDE.md | 45 ++++ docs/content/.pages | 8 - docs/content/console/all-cards.md | 24 +- docs/content/console/cards.md | 86 ------ docs/content/console/console-cards.md | 245 ------------------ .../content/direct/acquire-hosting-cluster.md | 2 +- docs/content/direct/binding.md | 4 +- docs/content/direct/control.md | 2 +- docs/content/direct/example-scenarios.md | 2 +- docs/content/direct/packaging.md | 2 +- messages/en.json | 17 ++ next.config.ts | 12 + package-lock.json | 19 +- src/app/docs/layout.tsx | 35 +-- src/app/docs/page-map.ts | 22 +- src/components/docs/DocsSidebar.tsx | 59 ++++- 17 files changed, 195 insertions(+), 419 deletions(-) create mode 100644 docs/DEVELOPER_GUIDE.md delete mode 100644 docs/content/.pages delete mode 100644 docs/content/console/cards.md delete mode 100644 docs/content/console/console-cards.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4d71ea8e..c6716671 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -172,35 +172,23 @@ These commands help maintainers manage community contributions effectively and a ### Overview -This documentation website is a **separate repository** from the main KubeStellar codebase. Here's the key architecture: +This documentation website manages all content locally. Here's the repository structure: ``` ┌─────────────────────────────────────────────────────────────┐ -│ Main KubeStellar Repository │ -│ github.com/kubestellar/kubestellar │ +│ Docs Website Repository (THIS REPO) │ +│ github.com/kubestellar/docs │ │ │ -│ 📁 docs/content/ │ +│ 📁 docs/content/ ← [SOURCE] All Markdown/MDX files │ │ ├── readme.md │ -│ ├── architecture.md │ │ ├── direct/ │ -│ │ ├── binding.md │ -│ │ └── wds.md │ -│ └── ... (all documentation content) │ -└─────────────────────────────────────────────────────────────┘ - ↓ - (Fetched via GitHub API) - ↓ -┌─────────────────────────────────────────────────────────────┐ -│ Docs Website Repository (THIS REPO) │ -│ github.com/kubestellar/docs │ +│ └── ... │ │ │ -│ 📁 src/app/docs/ │ -│ ├── page-map.ts ← Defines navigation structure │ -│ ├── layout.tsx ← Nextra theme integration │ -│ └── [...slug]/page.tsx ← Renders fetched content │ +│ 📁 src/app/docs/ ← [ENGINE] Next.js/Nextra logic │ +│ ├── page-map.ts ← Defines sidebar structure │ +│ └── [...slug]/page.tsx ← Renders content from docs/content│ │ │ -│ 📁 next.config.ts ← Nextra configuration │ -│ 📁 mdx-components.js ← MDX component mappings │ +│ 📁 messages/ ← [I18N] Translation files │ └─────────────────────────────────────────────────────────────┘ ↓ (Built & Deployed) diff --git a/docs/DEVELOPER_GUIDE.md b/docs/DEVELOPER_GUIDE.md new file mode 100644 index 00000000..e15d1edc --- /dev/null +++ b/docs/DEVELOPER_GUIDE.md @@ -0,0 +1,45 @@ +# KubeStellar Documentation Developer Guide + +Welcome! This guide explains how the documentation system works and how to contribute effectively. + +## Architecture + +This site is built with **Next.js 15** and **Nextra 4**. It uses a hybrid approach: + +- **Unified Content**: Almost all documentation resides in `docs/content/`. +- **Dynamic Routing**: The `src/app/docs/[...slug]` route dynamically renders Markdown/MDX files from the content folder. +- **Navigation**: Sidebar structure is defined statically in `src/app/docs/page-map.ts`. + +## How to Add a Page + +1. **Add the File**: Create a `.md` or `.mdx` file in `docs/content/` (or a subfolder). +2. **Update Navigation**: Add an entry to the `NAV_STRUCTURE` array in [page-map.ts](file:///Users/p0ptr0n/Documents/c0des/LFX/docs/src/app/docs/page-map.ts). + ```typescript + { 'My New Page': 'path/to/file.md' } + ``` + +## Images and Assets + +- Images should be placed in `docs/content/images/` or a subfolder within the project (e.g., `docs/content/console/images/`). +- **Pathing Rule**: Use the standardized `/docs-images/` prefix in your MDX/Markdown. + - Good: `![Logo](/docs-images/logo.png)` + - Next.js will automatically rewrite this to the correct local API for serving images from the content folder. + +## Internationalization (i18n) + +- UI strings are located in `messages/*.json`. +- **Sidebar Titles**: We are currently migrating sidebar titles to use `next-intl`. Use the translation keys defined in the JSON files. + +## Maintenance Commands + +- `npm run dev`: Start local development server. +- `npm run build`: Run production build (verifies MDX integrity). +- `npm run lint`: Check for code and accessibility issues. + +## Common Issues + +### Build Failure: `localStorage is not defined` +The build runs on the server. If a dependency uses `localStorage`, it will break. We have a mock in `next.config.ts`, but try to keep client-side code inside `useEffect` or behind a client-check. + +### Link Resolution +The dynamic router tries to resolve relative links. If a link breaks, check that the file path in [page-map.ts](file:///Users/p0ptr0n/Documents/c0des/LFX/docs/src/app/docs/page-map.ts) exactly matches the file on disk. diff --git a/docs/content/.pages b/docs/content/.pages deleted file mode 100644 index 4464eb86..00000000 --- a/docs/content/.pages +++ /dev/null @@ -1,8 +0,0 @@ -# nav: -# - About: index.md -# - QuickStart: Getting-Started/quickstart/ -# - ... -# - 'Blog': https://medium.com/@kubestellar/list/predefined:e785a0675051:READING_LIST -# - GitHub: {{ config.repo_url }} -# -# \ No newline at end of file diff --git a/docs/content/console/all-cards.md b/docs/content/console/all-cards.md index 0c86dd84..3105e94f 100644 --- a/docs/content/console/all-cards.md +++ b/docs/content/console/all-cards.md @@ -224,7 +224,29 @@ The console includes 44+ additional specialized cards across categories like: - **Deploy** - Deployment management and progress tracking - **Events** - Event timeline and filtering - **Data Compliance** - Data classification and compliance checks -- **Arcade** - Interactive visualizations +- **Data Compliance** - Data classification and compliance checks +- **Arcade** - Interactive visualizations: + - Kube-Man (Pac-Man style) + - Kube Kong (Donkey Kong style) + - Node Invaders (Space Invaders) + - Pod Pitfall (Pitfall adventure) + - Container Tetris + - Flappy Pod + - Pod Sweeper (Minesweeper) + - Kube 2048 + - AI Checkers + - AI Chess + - Kube Solitaire + - Kube Match (Memory game) + - Kubedle (Wordle style) + - Sudoku + - Pod Brothers (Mario style) + - Kube Kart (Racing) + - Kube Pong + - Kube Snake + - Kube Galaga + - KubeCraft 2D + - KubeCraft 3D - **Card History** - Track card changes over time - **User Management** - Console user management diff --git a/docs/content/console/cards.md b/docs/content/console/cards.md deleted file mode 100644 index 1cc233cb..00000000 --- a/docs/content/console/cards.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: "Card Types" -linkTitle: "Cards" -weight: 4 -description: > - Available dashboard cards and their configuration ---- - -# Dashboard Cards - -KubeStellar Console provides a variety of cards to monitor and manage your clusters. - -## Available Card Types - -| Card Type | Description | Data Source | -|-----------|-------------|-------------| -| **Cluster Health** | Availability graph per cluster | `get_cluster_health` | -| **App Status** | Multi-cluster application health | `get_app_status` | -| **Event Stream** | Live event feed with filtering | `get_events` | -| **Deployment Progress** | Rollout status visualization | `get_app_status` | -| **Pod Issues** | CrashLoopBackOff, OOMKilled pods | `find_pod_issues` | -| **Deployment Issues** | Stuck or failing rollouts | `find_deployment_issues` | -| **Resource Capacity** | CPU/memory/GPU utilization | `list_cluster_capabilities` | -| **GPU Inventory** | GPU nodes and counts across clusters | `get_gpu_nodes` | -| **GPU Status** | Real-time GPU allocation and usage | `get_gpu_nodes` | -| **GPU Overview** | Summary of GPU resources | `get_gpu_nodes` | -| **Security Issues** | Privileged, root, host access | `check_security_issues` | -| **Upgrade Status** | Cluster version and upgrade state | `get_upgrade_status` | - -## GPU Cards - -### GPU Inventory - -Shows all GPU nodes across clusters with: -- Node name and cluster -- GPU type (e.g., NVIDIA A100) -- Total GPU count -- Allocated vs available - -### GPU Status - -Real-time GPU utilization: -- Allocation percentage per cluster -- Memory usage -- Temperature (if available) - -### GPU Overview - -Summary card showing: -- Total GPUs across all clusters -- Overall utilization -- Top consumers - -## Card Configuration - -Each card can be configured with: - -```typescript -interface CardConfig { - id: string; - type: string; - title: string; - position: { x: number; y: number }; - size: { width: number; height: number }; - config: { - clusters?: string[]; // Filter to specific clusters - namespaces?: string[]; // Filter to specific namespaces - refreshInterval?: number; // Update frequency in seconds - warningsOnly?: boolean; // For event stream - }; -} -``` - -## AI Recommendations - -In **High** AI mode, the console analyzes your cluster state and suggests relevant cards: - -- **Pod Issues** - Suggested when >5 pods have issues -- **GPU Status** - Suggested when GPU utilization >90% -- **Event Stream** - Suggested when >10 warning events -- **Cluster Health** - Suggested when clusters are unhealthy - -You can: -- **Accept** - Add the recommended card -- **Snooze** - Hide suggestion for 1 hour -- **Dismiss** - Don't suggest this card again diff --git a/docs/content/console/console-cards.md b/docs/content/console/console-cards.md deleted file mode 100644 index 5c1b2a2f..00000000 --- a/docs/content/console/console-cards.md +++ /dev/null @@ -1,245 +0,0 @@ ---- -title: "Card Reference" -linkTitle: "Cards" -weight: 3 -description: > - Complete reference of all dashboard cards available in the KubeStellar Console ---- - -# Card Reference - -The KubeStellar Console includes over 100 dashboard cards organized into categories. Cards can display live data from your clusters or demo data for evaluation. - -![Card Catalog](images/card-catalog.png) - -## Card Categories - -### Cluster Health (9 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Cluster Health | Health status of all clusters | Live | -| Offline Detection | Monitors nodes and GPUs for offline/unhealthy status | Live | -| Cluster Metrics | CPU, memory, and pod metrics over time | Live | -| Cluster Locations | Clusters grouped by region and cloud provider | Live | -| Cluster Focus | Single cluster detailed view | Live | -| Cluster Comparison | Side-by-side cluster metrics | Live | -| Cluster Costs | Resource cost estimation | Demo | -| Cluster Upgrade Status | Available cluster upgrades | Live | -| Cluster Resource Tree | Hierarchical view of cluster resources | Live | - -### Workloads (7 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Deployment Status | Deployment health across clusters | Live | -| Deployment Issues | Deployments with problems | Live | -| Deployment Progress | Rolling update progress | Live | -| Pod Issues | Pods with errors or restarts | Live | -| Top Pods | Highest resource consuming pods | Live | -| Workload Status | Workload health overview | Live | -| Workload Deployment | Multi-cluster workload deployment | Live | - -### Compute (8 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Compute Overview | CPU, memory, and GPU summary | Live | -| Resource Usage | CPU and memory utilization | Live | -| Resource Capacity | Cluster capacity and allocation | Live | -| GPU Overview | Total GPUs across clusters | Live | -| GPU Status | GPU utilization by state | Live | -| GPU Inventory | Detailed GPU list | Live | -| GPU Workloads | Pods running on GPU nodes | Live | -| GPU Usage Trend | GPU used vs available over time | Live | - -### Storage (2 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Storage Overview | Total storage capacity and PVC summary | Live | -| PVC Status | Persistent Volume Claims with status | Live | - -### Network (7 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Network Overview | Services breakdown by type | Live | -| Service Status | Service list with type and ports | Live | -| Cluster Network | API server and network info | Live | -| Service Exports (MCS) | Multi-cluster service exports | Live | -| Service Imports (MCS) | Multi-cluster service imports | Live | -| Gateway API | Kubernetes Gateway API resources | Live | -| Service Topology | Animated service mesh visualization | Demo | - -### GitOps (7 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Helm Releases | Helm release status and versions | Live | -| Helm History | Release revision history | Live | -| Helm Values Diff | Compare values vs defaults | Live | -| Helm Chart Versions | Available chart upgrades | Live | -| Kustomization Status | Flux kustomizations health | Live | -| Overlay Comparison | Compare kustomize overlays | Demo | -| GitOps Drift | Configuration drift detection | Live | - -### ArgoCD (3 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| ArgoCD Applications | ArgoCD app status | Live | -| ArgoCD Sync Status | Sync state of applications | Live | -| ArgoCD Health | Application health overview | Live | - -### Operators (3 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| OLM Operators | Operator Lifecycle Manager status | Live | -| Operator Subscriptions | Subscriptions and pending upgrades | Live | -| CRD Health | Custom resource definitions status | Live | - -### Namespaces (5 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Namespace Monitor | Real-time resource monitoring | Live | -| Namespace Overview | Namespace resources and health | Live | -| Namespace Quotas | Resource quota usage | Live | -| Namespace RBAC | Roles, bindings, service accounts | Live | -| Namespace Events | Events in namespace | Live | - -### Security and Events (3 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Security Issues | Security findings and vulnerabilities | Live | -| Event Stream | Live Kubernetes event feed | Live | -| User Management | Console users and Kubernetes RBAC | Live | - -### Live Trends (4 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Events Timeline | Warning vs normal events over time | Live | -| Pod Health Trend | Healthy/unhealthy/pending pods | Live | -| Resource Trend | CPU, memory, pods, nodes over time | Live | -| GPU Utilization | GPU allocation trend | Live | - -### AI (3 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| AI Issues | AI-powered issue detection | Live | -| AI Kubeconfig Audit | Audit kubeconfig for stale contexts | Live | -| AI Health Check | Comprehensive AI health analysis | Live | - -### Alerting (2 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Active Alerts | Firing alerts with severity | Live | -| Alert Rules | Manage alert rules and notifications | Live | - -### Cost Management (3 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Cluster Costs | Resource cost estimation by cluster | Demo | -| OpenCost | Cost allocation by namespace | Demo | -| Kubecost | Cost optimization recommendations | Demo | - -### Security Posture (7 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| OPA Gatekeeper | Policy enforcement status | Live | -| Kyverno Policies | Kubernetes-native policy management | Live | -| Falco Alerts | Runtime security monitoring | Demo | -| Trivy Scanner | Vulnerability scanning | Demo | -| Kubescape | Security posture management | Demo | -| Policy Violations | Aggregated policy violations | Live | -| Compliance Score | Overall compliance posture | Demo | - -### Data Compliance (4 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| HashiCorp Vault | Secrets management | Demo | -| External Secrets | Sync secrets from external providers | Live | -| Cert-Manager | TLS certificate lifecycle | Live | -| Access Controls | RBAC policies and auditing | Live | - -### Workload Detection (7 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Prow Jobs | Prow CI/CD job status | Live | -| Prow Status | Prow controller health | Live | -| Prow History | Recent Prow job runs | Live | -| llm-d inference | vLLM, llm-d, TGI server status | Live | -| llm-d models | Deployed language models | Live | -| ML Training Jobs | Kubeflow, Ray training status | Demo | -| ML Notebooks | Running Jupyter notebook servers | Demo | - -### Arcade (21 cards) - -Fun games and entertainment: - -- Kube-Man (Pac-Man style) -- Kube Kong (Donkey Kong style) -- Node Invaders (Space Invaders) -- Pod Pitfall (Pitfall adventure) -- Container Tetris -- Flappy Pod -- Pod Sweeper (Minesweeper) -- Kube 2048 -- AI Checkers -- AI Chess -- Kube Solitaire -- Kube Match (Memory game) -- Kubedle (Wordle style) -- Sudoku -- Pod Brothers (Mario style) -- Kube Kart (Racing) -- Kube Pong -- Kube Snake -- Kube Galaga -- KubeCraft 2D -- KubeCraft 3D - -### Utilities (4 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Network Utils | Ping hosts, check ports | Live | -| Mobile Browser | iPhone-style web browser | Live | -| RSS Feed | Read RSS feeds from tech sources | Live | -| Iframe Embed | Embed external dashboards | Live | - -### Miscellaneous (4 cards) - -| Card | Description | Data Source | -|------|-------------|-------------| -| Weather | Weather with forecasts | Live | -| GitHub Activity | Monitor GitHub repository activity | Live | -| Kubectl | Interactive kubectl terminal | Live | -| Stock Market Ticker | Track stocks with charts | Live | - -## Adding Cards - -1. Click **Add Card** on the dashboard -2. Browse categories or search for specific cards -3. Click a card to add it to your dashboard -4. Drag to reposition, use the menu to configure - -## Card Data Sources - -- **Live**: Data fetched from your connected clusters -- **Demo**: Simulated data for demonstration purposes - -Demo cards can be useful for: -- Evaluating features before deployment -- Training and onboarding -- Showcasing capabilities diff --git a/docs/content/direct/acquire-hosting-cluster.md b/docs/content/direct/acquire-hosting-cluster.md index ea459d39..f6f6ae0d 100644 --- a/docs/content/direct/acquire-hosting-cluster.md +++ b/docs/content/direct/acquire-hosting-cluster.md @@ -16,7 +16,7 @@ The clients in KubeStellar comprise the following. - The OCM Agent and the OCM Status Add-On Agent in each WEC. - The KubeStellar controller-manager and the transport controller for each WDS, running in the KubeFlex hosting cluster. -TODO: finish writing this subsection for real. Following are some clues. +{/* TODO: finish writing this subsection for real. Following are some clues. */} When everything runs on one machine, the defaults just work. When core and some WECs are on different machines, it gets more challenging. When the KubeFlex hosting cluster is an OpenShift cluster with a public domain name, the defaults just work. diff --git a/docs/content/direct/binding.md b/docs/content/direct/binding.md index c97094d6..367cd1f8 100644 --- a/docs/content/direct/binding.md +++ b/docs/content/direct/binding.md @@ -17,7 +17,7 @@ modulations on how downsync is done. has a controller that translates each `BindingPolicy` to a `Binding`. A user _could_ eschew the `BindingPolicy` and directly maintain a `Binding` object or let a different controller maintain the -`Binding` object (TODO: check that this is true). The `Binding` object +`Binding` object {/* (TODO: check that this is true) */}. The `Binding` object shows which workload objects and which WECs matched the predicates in the `BindingPolicy` and so is also useful as feedback to the user about that. @@ -74,4 +74,4 @@ spec: ## Binding -TODO: write this +{/* TODO: write this */} diff --git a/docs/content/direct/control.md b/docs/content/direct/control.md index bada3b72..b7def4b7 100644 --- a/docs/content/direct/control.md +++ b/docs/content/direct/control.md @@ -6,4 +6,4 @@ This is the parent document for docs about particular kinds of control. - [Transforming](transforming.md) workload objects on their way to WECs - [Combining returned status](combined-status.md) -TODO: write this for real. +{/* TODO: write this for real. */} diff --git a/docs/content/direct/example-scenarios.md b/docs/content/direct/example-scenarios.md index 10a1d6c0..e1b1eff4 100644 --- a/docs/content/direct/example-scenarios.md +++ b/docs/content/direct/example-scenarios.md @@ -410,7 +410,7 @@ kubectl --context "$wds_context" delete deployments nginx-singleton-deployment This is a test that you can do after finishing Scenario 1. -TODO: rewrite this so that it makes sense after Scenario 4. +{/* TODO: rewrite this so that it makes sense after Scenario 4. */} Bring down the control plane: stop and restart the ITS and WDS API servers, KubeFlex and KubeStellar controllers: diff --git a/docs/content/direct/packaging.md b/docs/content/direct/packaging.md index c6de28b1..1d24cdaf 100644 --- a/docs/content/direct/packaging.md +++ b/docs/content/direct/packaging.md @@ -293,7 +293,7 @@ Currently only showing kubestellar and ocm-status-addon. Again, omitting clusteradm and Helm CLI container images for simplicity. -TODO: finish this +{/* TODO: finish this */} ```mermaid flowchart LR diff --git a/messages/en.json b/messages/en.json index 0595035b..19d5ed87 100644 --- a/messages/en.json +++ b/messages/en.json @@ -1,4 +1,21 @@ { + "docs": { + "overview": "Overview", + "architecture": "Architecture", + "gettingStarted": "Getting Started", + "userGuide": "User Guide", + "reference": "Reference", + "contributing": "Contributing", + "relatedProjects": "Related Projects", + "whatIsKubeStellar": "What is KubeStellar?", + "installation": "Installation", + "usage": "Usage", + "troubleshooting": "Troubleshooting", + "releaseNotes": "Release Notes", + "roadmap": "Roadmap", + "guideOverview": "Guide Overview", + "observability": "Observability" + }, "heroSection": { "line1": "Multi-Cluster", "line2": "Kubernetes", diff --git a/next.config.ts b/next.config.ts index 9f893910..eb8e25f3 100644 --- a/next.config.ts +++ b/next.config.ts @@ -3,6 +3,18 @@ import nextra from "nextra"; import createNextIntlPlugin from "next-intl/plugin"; +// Mock localStorage for server-side build to prevent TypeError from client-side dependencies +if (typeof window === "undefined") { + (global as any).localStorage = { + getItem: () => null, + setItem: () => {}, + removeItem: () => {}, + clear: () => {}, + length: 0, + key: () => null, + }; +} + const withNextra = nextra({ latex: true, search: { diff --git a/package-lock.json b/package-lock.json index 4787dc53..f3caabeb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1718,7 +1718,6 @@ "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.4.0.tgz", "integrity": "sha512-k4iu1R6e5D54918V4sqmISUkI5OgTw3v7/sDRKEC632Wd5g2WBtUS5gyG63X0GJO/HZUj1tsjSXfyzwrUHZl1g==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.17.8", "@types/react-reconciler": "^0.32.0", @@ -2566,7 +2565,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -2601,7 +2599,6 @@ "resolved": "https://registry.npmjs.org/@types/three/-/three-0.180.0.tgz", "integrity": "sha512-ykFtgCqNnY0IPvDro7h+9ZeLY+qjgUWv+qEvUt84grhenO60Hqd4hScHE7VTB9nOQ/3QM8lkbNE+4vKjEpUxKg==", "license": "MIT", - "peer": true, "dependencies": { "@dimforge/rapier3d-compat": "~0.12.0", "@tweenjs/tween.js": "~23.1.3", @@ -2675,7 +2672,6 @@ "integrity": "sha512-FuYgkHwZLuPbZjQHzJXrtXreJdFMKl16BFYyRrLxDhWr6Qr7Kbcu2s1Yhu8tsiMXw1S0W1pjfFfYEt+R604s+Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.36.0", "@typescript-eslint/types": "8.36.0", @@ -3239,7 +3235,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3819,7 +3814,6 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", - "peer": true, "dependencies": { "@chevrotain/cst-dts-gen": "11.0.3", "@chevrotain/gast": "11.0.3", @@ -4005,7 +3999,6 @@ "version": "3.33.1", "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz", "integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==", - "peer": true, "engines": { "node": ">=0.10" } @@ -4406,7 +4399,6 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -5009,7 +5001,6 @@ "integrity": "sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -5184,7 +5175,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -8942,7 +8932,6 @@ "resolved": "https://registry.npmjs.org/next/-/next-15.5.9.tgz", "integrity": "sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg==", "license": "MIT", - "peer": true, "dependencies": { "@next/env": "15.5.9", "@swc/helpers": "0.5.15", @@ -9745,7 +9734,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -9763,7 +9751,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -10591,7 +10578,6 @@ "version": "3.13.0", "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.13.0.tgz", "integrity": "sha512-aZW4l8Og16CokuCLf8CF8kq+KK2yOygapU5m3+hoGw0Mdosc6fPitjM+ujYarppj5ZIKGyPDPP1vqmQhr+5/0g==", - "peer": true, "dependencies": { "@shikijs/core": "3.13.0", "@shikijs/engine-javascript": "3.13.0", @@ -11088,8 +11074,7 @@ "version": "0.180.0", "resolved": "https://registry.npmjs.org/three/-/three-0.180.0.tgz", "integrity": "sha512-o+qycAMZrh+TsE01GqWUxUIKR1AL0S8pq7zDkYOQw8GqfX8b8VoCKYUoHbhiX5j+7hr8XsuHDVU6+gkQJQKg9w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/three-mesh-bvh": { "version": "0.8.3", @@ -11163,7 +11148,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -11454,7 +11438,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/src/app/docs/layout.tsx b/src/app/docs/layout.tsx index d1db4a4b..7783fa6c 100644 --- a/src/app/docs/layout.tsx +++ b/src/app/docs/layout.tsx @@ -2,6 +2,8 @@ import { DocsNavbar, DocsFooter, DocsBanner } from '@/components/docs/index' import { DocsProvider } from '@/components/docs/DocsProvider' import { Inter, JetBrains_Mono } from "next/font/google" import { Suspense } from 'react' +import { NextIntlClientProvider } from 'next-intl'; +import { getMessages } from 'next-intl/server'; import { ThemeProvider } from "next-themes" import "../globals.css" import { buildPageMap } from './page-map' @@ -29,24 +31,27 @@ type Props = { export default async function DocsLayout({ children }: Props) { // Build page map from local docs buildPageMap(); - + const messages = await getMessages(); + return ( - - -
- - }> - - -
- {children} -
- -
-
-
+ + + +
+ + }> + + +
+ {children} +
+ +
+
+
+
) diff --git a/src/app/docs/page-map.ts b/src/app/docs/page-map.ts index 85a4ea8a..dc716928 100644 --- a/src/app/docs/page-map.ts +++ b/src/app/docs/page-map.ts @@ -55,17 +55,17 @@ const pretty = (s: string) => s.charAt(0).toUpperCase() + s.slice(1).replace(/-/ // Recursively get all markdown files from the local docs directory function getAllDocFiles(dir: string, baseDir: string = dir): string[] { const files: string[] = [] - + if (!fs.existsSync(dir)) { return files } - + const entries = fs.readdirSync(dir, { withFileTypes: true }) - + for (const entry of entries) { const fullPath = path.join(dir, entry.name) const relativePath = path.relative(baseDir, fullPath) - + if (entry.isDirectory()) { // Skip hidden directories and node_modules if (!entry.name.startsWith('.') && entry.name !== 'node_modules') { @@ -76,7 +76,7 @@ function getAllDocFiles(dir: string, baseDir: string = dir): string[] { files.push(relativePath.replace(/\\/g, '/')) } } - + return files } @@ -221,6 +221,13 @@ const NAV_STRUCTURE: Array<{ title: string; items: NavItem[] }> = [ items: [ { 'Overview': 'readme.md' }, { 'Architecture': 'direct/architecture.md' }, + { + 'Related Projects': [ + { 'KubeStellar UI': 'direct/ui-intro.md' }, + { 'KubeFlex': 'direct/kubeflex-intro.md' }, + { 'KubeStellar Galaxy': 'direct/galaxy-intro.md' } + ] + }, { 'Release Notes': 'direct/release-notes.md' }, { 'Roadmap': 'direct/roadmap.md' } ] @@ -228,7 +235,6 @@ const NAV_STRUCTURE: Array<{ title: string; items: NavItem[] }> = [ { title: 'User Guide', items: [ - { 'Quick Start': 'direct/get-started.md' }, { 'Guide Overview': 'direct/user-guide-intro.md' }, { 'Observability': 'direct/observability.md' }, { 'Getting Started': 'direct/get-started.md' }, @@ -294,10 +300,10 @@ const NAV_STRUCTURE: Array<{ title: string; items: NavItem[] }> = [ } ] }, - { + { 'UI': [ { 'Overview': 'ui-docs/ui-overview.md' }, - { 'ITS cluster management': 'ui-docs/its-cluster-management.md'} + { 'ITS cluster management': 'ui-docs/its-cluster-management.md' } ] }, { 'Teardown': 'direct/teardown.md' } diff --git a/src/components/docs/DocsSidebar.tsx b/src/components/docs/DocsSidebar.tsx index 7ddf9929..68a5b587 100644 --- a/src/components/docs/DocsSidebar.tsx +++ b/src/components/docs/DocsSidebar.tsx @@ -5,6 +5,7 @@ import Link from 'next/link'; import { usePathname } from 'next/navigation'; import { useTheme } from 'next-themes'; import { ChevronRight, ChevronDown, FileText } from 'lucide-react'; +import { useTranslations } from 'next-intl'; import { RelatedProjects } from './RelatedProjects'; import { useDocsMenu } from './DocsProvider'; @@ -38,6 +39,7 @@ export function DocsSidebar({ pageMap, className }: DocsSidebarProps) { toggleNavCollapsed, navInitialized } = useDocsMenu(); + const t = useTranslations('docs'); useEffect(() => { setMounted(true); @@ -128,7 +130,7 @@ export function DocsSidebar({ pageMap, className }: DocsSidebarProps) { findActivePath(pageMap); collapseAll(pageMap); setCollapsed(initialCollapsed); - }, [pageMap]); + }, [pageMap, navInitialized, setCollapsed]); const toggleCollapse = (itemKey: string) => { toggleNavCollapsed(itemKey); @@ -139,13 +141,49 @@ export function DocsSidebar({ pageMap, className }: DocsSidebarProps) { const itemKey = parentKey ? `${parentKey}-${item.name}` : item.name; const isCollapsed = collapsed.has(itemKey); const isActive = item.route && pathname === item.route; - const displayTitle = item.title || item.name; + + // Mapping of hardcoded titles to translation keys + const titleToKey: Record = { + 'What is KubeStellar?': 'whatIsKubeStellar', + 'Overview': 'overview', + 'Architecture': 'architecture', + 'User Guide': 'userGuide', + 'Guide Overview': 'guideOverview', + 'Observability': 'observability', + 'Getting Started': 'gettingStarted', + 'Related Projects': 'relatedProjects', + 'Release Notes': 'releaseNotes', + 'Roadmap': 'roadmap' + }; + + let displayTitle = item.title || item.name; + + // If title is in our mapping, translate it + if (displayTitle && titleToKey[displayTitle]) { + try { + const translated = t(titleToKey[displayTitle]); + if (translated) displayTitle = translated; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (e) { + // Fallback to original + } + } + // Backward compatibility for dot notation if used in files + else if (displayTitle && displayTitle.includes('.')) { + try { + const translated = t(displayTitle.split('.')[1]); + if (translated) displayTitle = translated; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + } catch (e) { + // Fallback to original + } + } // Skip separator, meta items, and items without title/name if (item.kind === 'Separator' || item.kind === 'Meta' || !displayTitle || displayTitle.trim() === '') { return null; } - + // Skip index files and hidden items if (item.name === 'index' || item.name === '_meta' || item.route === '#') { return null; @@ -156,12 +194,12 @@ export function DocsSidebar({ pageMap, className }: DocsSidebarProps) {
{/* Vertical line for nested items */} {depth > 0 && ( -
)} - + {/* Folder or Page */} {hasChildren ? ( // Folder - clickable to toggle @@ -185,10 +223,9 @@ export function DocsSidebar({ pageMap, className }: DocsSidebarProps) { href={item.route || '#'} className={` flex-1 flex items-start gap-2 px-3 py-2 text-sm rounded-lg transition-all relative z-10 - ${ - isActive - ? 'font-thin text-blue-500 bg-blue-500/10' - : 'hover:font-semibold' + ${isActive + ? 'font-thin text-blue-500 bg-blue-500/10' + : 'hover:font-semibold' } `} style={{ @@ -207,14 +244,14 @@ export function DocsSidebar({ pageMap, className }: DocsSidebarProps) { {/* Render children */} {hasChildren && ( -
{/* Vertical line connecting children */} -