Commit Graph

1025 Commits

Author SHA1 Message Date
shenlan
43cdc009f8 feat: extract shared search component (#669) 2025-11-11 14:02:23 +08:00
shenlan
cf7c017a72 Fix blog pagination search params handling (#668) 2025-11-11 13:50:17 +08:00
Haitao Pan
fff6816077 fix: add force-dynamic directive to blog page for searchParams support
### Issue:
The root layout has `export const dynamic = 'error'` which forces static rendering.
The blog page uses `searchParams` which requires dynamic rendering.

**Error Message:**
"Route /blog with `dynamic = "error"` couldn't be rendered statically because it used `searchParams`"

### Solution:
Added `export const dynamic = 'force-dynamic'` to `src/app/blog/page.tsx` to override
the parent's static rendering directive and enable dynamic rendering for searchParams.

### Changes:
- **BlogPage** - Added `export const dynamic = 'force-dynamic'` at the top of the file
- This allows the page to use `searchParams` for pagination
- Page will be dynamically rendered on each request with the correct page data

### Result:
- Fixed runtime error when accessing pagination params
- Blog list pages load successfully with `/blog?page=X`
- Pagination works correctly with dynamic searchParams
- Build passes successfully

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 13:46:03 +08:00
Haitao Pan
987703c5e7 fix: handle async searchParams in blog pagination
### Issue:
Next.js 15 requires searchParams to be awaited as it's now a Promise.

**Error Message:**
"Route "/blog" used `searchParams.page`. `searchParams` is a Promise and must be unwrapped with `await`"

### Solution:
Updated `src/app/blog/page.tsx` to properly await searchParams before accessing its properties.

**Changes:**
- **BlogPage component** - Added `await searchParams` before accessing page property
- Used destructuring: `const { page } = await searchParams`
- Updated parseInt to use destructured `page` variable

### Result:
- Fixed runtime error when accessing pagination params
- Pagination now works correctly with async searchParams
- Blog list pages load successfully with `/blog?page=X`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 13:43:26 +08:00
Haitao Pan
a5d88a22b6 feat: add pagination and fix blog post links
### Changes to Blog Listing Page (src/app/blog/page.tsx):

1. **Implemented Pagination**
   - Added support for `page` query parameter (e.g., `/blog?page=2`)
   - Displays 10 posts per page
   - Shows pagination controls with Previous/Next buttons
   - Page numbers displayed as clickable buttons
   - Active page highlighted with brand color
   - Handles edge cases (invalid page numbers, out of bounds)

2. **Fixed "Read more" Links**
   - Changed from `/blog` to `/blog/${post.slug}`
   - Each blog card's "Read more" now links to individual article page
   - Clicking "Read more" on Cloud-Neutral-Hybrid-Network-Architecture → `/blog/Cloud-Neutral-Hybrid-Network-Architecture`

3. **Features**
   - **Server-side pagination**: Posts are sliced on the server
   - **URL-based navigation**: Pagination state in URL
   - **Responsive design**: Clean pagination controls
   - **Error handling**: 404 for invalid pages
   - **Navigation**: Previous/Next buttons with disabled states
   - **Accessibility**: aria-disabled attribute on navigation

### Example URLs:
- `/blog` - First page (default)
- `/blog?page=1` - First page
- `/blog?page=2` - Second page
- Each post card → `/blog/[post-slug]`

### Result:
-  Blog list supports pagination
-  "Read more" links work correctly
-  Better UX for browsing multiple blog posts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 13:42:11 +08:00
Haitao Pan
38b6f7ae01 fix: handle async params in dynamic blog route
### Issue:
Next.js 15 requires params to be awaited as it's now a Promise.

**Error Message:**
"Route "/blog/[slug]" used `params.slug`. `params` is a Promise and must be unwrapped with `await`"

### Solution:
Updated `src/app/blog/[slug]/page.tsx` to properly await params before accessing its properties.

**Changes:**
1. **generateMetadata function** - Added `await params` before accessing slug
2. **BlogPostPage component** - Added `await params` before accessing slug
3. Used destructuring: `const { slug } = await params`

### Result:
- Fixed runtime error when accessing blog posts
- Dynamic routes now work correctly with async params
- Blog post pages load successfully

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 13:37:45 +08:00
Haitao Pan
47306b2d41 feat: implement dynamic blog post routing with individual article pages
### Changes:

1. **Updated CommunityFeed Links** (`src/components/home/CommunityFeed.tsx`)
   - Changed "Read more" buttons to link to `/blog/${post.slug}`
   - Made post titles clickable with same link
   - Each article now navigates to its own full page

2. **Created Dynamic Blog Post Route** (`src/app/blog/[slug]/page.tsx`)
   - New dynamic route: `/blog/[slug]` for individual articles
   - Displays full article content with markdown rendering
   - Shows metadata: title, author, date, tags
   - Includes "Back to Blog" navigation
   - 404 handling for non-existent posts
   - Dynamic metadata generation for SEO
   - Responsive typography styling

### Features:
- **Individual Article Pages**: Each blog post has its own URL
- **Full Content Display**: Renders complete markdown content with HTML
- **Rich Metadata**: Shows author, date, and tags
- **Navigation**: Easy back-and-forth between list and article views
- **SEO Ready**: Dynamic metadata per post
- **Error Handling**: 404 page for invalid post slugs

### Usage:
- Click "Read more" or post title → `/blog/[slug]`
- View full article with all content
- Navigate back to blog list

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 13:35:46 +08:00
Haitao Pan
1e241ed8a8 fix: make CommunityFeed span full width of content section
### Change:
Modified content section layout to allow CommunityFeed to occupy the **full width** of the lower section (not constrained to left column only).

**File: commonHome.tsx**
- Removed grid constraint when Sidebar is present
- Content slots now use simple `<div>` wrapper instead of grid with spacer
- CommunityFeed can now utilize the entire content width
- Maintains visual consistency while maximizing content space

**Result:**
- CommunityFeed spans the full width of the content section
- Matches the total width of hero section (ProductMatrix + Sidebar)
- Better visual balance and more space for content

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 13:26:11 +08:00
Haitao Pan
3cbc9fbb7e 973e0ea - Adjust layout for consistent sidebar height and section width across homepage 2025-11-11 13:19:57 +08:00
Haitao Pan
973e0ea3f5 refactor: adjust layout dimensions for consistent width and height
### Changes:
1. **Hero Section Layout** (commonHome.tsx)
   - Changed `lg:items-start` → `lg:items-stretch` for equal height alignment
   - Added `min-h-full` to hero content column for full height
   - Ensures Sidebar height matches ProductMatrix height

2. **Content Section Layout** (commonHome.tsx)
   - When Sidebar present, uses matching grid structure from hero section
   - Grid: `grid-cols-[minmax(0,1fr)_360px]` (same as hero)
   - Content slots span full width with hidden spacer for visual balance
   - CommunityFeed now matches total width of (ProductMatrix + Sidebar)

3. **Sidebar Component** (Sidebar.tsx)
   - Added `h-full` and `flex flex-col` for full height support
   - Maintains sticky positioning while filling available space

4. **HomepageLanding** (page.tsx)
   - Applied same height adjustment: `lg:items-stretch` + `min-h-full`
   - Consistent with template version layout

### Result:
- Sidebar height = Hero section height (full height alignment)
- CommunityFeed width = ProductMatrix width + Sidebar width
- Visual consistency across hero and content sections
- Both homepage versions (template and direct) have identical layout

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 13:13:00 +08:00
Haitao Pan
10f0d14c0b fix: restore Sidebar to template system for hero section
### Issue:
Sidebar (社区热议, 推荐资源, 热门标签) was missing from CMS template version of homepage because it was only in HomepageLanding component.

### Solution:
1. **Restored Sidebar to Template Slots** (`src/modules/templates/types.ts`)
   - Added Sidebar back to HomePageTemplateSlots interface
   - Updated HomePageSlotKey type to include Sidebar

2. **Updated Template Registration** (`src/modules/templates/default/index.tsx`)
   - Added Sidebar import and registration to default template
   - Template now passes Sidebar slot

3. **Updated App Route** (`src/app/page.tsx`)
   - Added Sidebar to slot props in HomePageTemplate

4. **Modified Common Home Template** (`src/modules/templates/layouts/commonHome.tsx`)
   - Enhanced template to detect and render Sidebar in hero section
   - When Sidebar is available, renders two-column grid layout:
     - Left: ProductMatrix (hero content)
     - Right: Sidebar (360px width, sticky)
   - Grid: `lg:grid-cols-[minmax(0,1fr)_360px]`
   - Maintains backward compatibility if Sidebar not provided

### Result:
- Sidebar now appears in BOTH homepage versions (template and direct)
- Consistent layout: Sidebar positioned to the right of hero content
- Visual consistency with HomepageLanding component layout
- Bilingual support (Chinese/English) maintained

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 13:09:08 +08:00
Haitao Pan
0a55d3c4a1 refactor: move Sidebar to hero section with two-column layout
### Layout Changes:
1. **Homepage Layout Restructure** (`src/modules/homepage/page.tsx`)
   - Changed hero section to two-column grid: `lg:grid-cols-[minmax(0,1fr)_360px]`
   - Moved Sidebar component to right side of hero section (360px width)
   - Hero content now spans left column with full-width appearance
   - Sidebar is sticky on large screens: `lg:sticky lg:top-0`
   - Maintains consistent width between upper and lower sections

2. **Template System Updates**
   - Removed Sidebar from `HomePageTemplateSlots` type (`src/modules/templates/types.ts`)
   - Updated `defaultHomeLayoutConfig` to remove Sidebar from content slots
   - Updated default template to remove Sidebar registration
   - Updated `app/page.tsx` to pass only ProductMatrix and CommunityFeed slots

3. **Sidebar Component Conversion** (`src/components/home/Sidebar.tsx`)
   - Converted from Server Component to Client Component
   - Added 'use client' directive to enable useLanguage hook
   - Replaced dynamic CMS content with static bilingual content
   - Hardcoded sections: 社区热议, 推荐资源, 热门标签
   - Maintains same visual structure and styling

4. **Homepage Module Cleanup** (`src/modules/homepage/page.tsx`)
   - Removed unused `getHomepagePosts` import (was causing fs error in client)
   - Kept useLanguage hook for internationalization support
   - Sidebar now works as client component alongside homepage

### Technical Details:
- Grid layout: Two columns on large screens (hero + sidebar)
- Sidebar width: Fixed 360px, sticky positioning
- Hero content: Flexible width with max-w-6xl constraint
- Visual consistency: Upper and lower sections maintain same max-width
- Component architecture: All client components, no server-client mixing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 13:06:49 +08:00
Haitao Pan
7a6bd66ad0 refactor: separate blog content from code
### Changes:
1. **Create Blog Content Directory**
   - Created src/content/blog/ directory for content management
   - Added README.md with usage instructions
   - Added 3 sample blog posts

2. **Update Content Retrieval Function**
   - Modified getHomepagePosts() in homepage.ts
   - Now reads from src/content/blog/ instead of CMS config
   - Content and style are now separated

3. **Content Management**
   - Style: Keep existing components and styles
   - Content: Manage via markdown files in src/content/blog/
   - Metadata: YAML front matter (title, author, date, tags, excerpt)
   - Sorting: Sort by date (newest first)

### Benefits:
- Content separated from code
- Easy for non-technical users to add content
- Version control friendly
- Unified metadata management

To add new blog posts:
1. Create .md file in src/content/blog/
2. Use standard front matter format
3. Use kebab-case for filenames

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-11 12:58:49 +08:00
Haitao Pan
851c82ea7b refactor: remove ArticleFeed, keep only CommunityFeed
- Remove ArticleFeed and ArticleFeedClient components
- Update template types to remove ArticleFeed
- Update default template configuration
- Update app/page.tsx to remove ArticleFeed
- Keep only CommunityFeed for blog updates (latest 3 posts)
- All blog content now uses CommunityFeed

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-11 12:55:23 +08:00
Haitao Pan
ae1c77aada feat: add CommunityFeed to template configuration
- Update HomePageTemplateSlots type to include CommunityFeed
- Add CommunityFeed slot to default layout config
- CMS content now displays CommunityFeed between ArticleFeed and Sidebar

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-11 12:53:05 +08:00
Haitao Pan
c36a9e0d17 fix: restructure CommunityFeed to separate Server and Client logic
- CommunityFeed now Client Component (accepts posts via props)
- Created CommunityFeedServer wrapper to fetch posts on server
- Fixes Module not found: Can't resolve 'fs' error
- HomepageLanding no longer imports CommunityFeed
- app/page.tsx passes CommunityFeedServer to template

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-11 12:51:12 +08:00
Haitao Pan
6d16ed0289 fix: dynamic import CommunityFeed in HomepageLanding
- Use Next.js dynamic() to import CommunityFeed as Server Component
- Fixes Module not found: Can't resolve 'fs' error
- Client Component can now safely import Server Component

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-11 12:48:21 +08:00
Haitao Pan
ec67982d13 feat: implement blog system with homepage integration
### Changes:
1. **Remove Contact Panel from ProductMatrix**
   - Removed ContactPanel from ProductMatrix component
   - Simplified layout to center content with max-width

2. **Update Community Feed Section**
   - Changed title to "产品与社区快讯" (Product & Community Pulse)
   - Updated CTA text to "浏览全部更新" (View all updates)
   - All links now point to /blog

3. **Create /blog Route**
   - Created new blog page at src/app/blog/page.tsx
   - Displays all blog posts with metadata
   - Shows author, date, tags, and excerpts

4. **Dynamic Blog Feed**
   - Community feed now displays latest 3 blog posts
   - Posts are fetched from CMS using getHomepagePosts()
   - Shows relative time (e.g., "2 hours ago")
   - Displays author information
   - Graceful handling of empty state

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-11 12:44:59 +08:00
Haitao Pan
83aad76b38 refactor: use path alias for products registry import
- Change from relative path to path alias
- import from '@modules/products/registry'
- Consistent with project alias configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-11 12:37:31 +08:00
Haitao Pan
e3a747a804 fix: correct import path for products registry (v2)
- Fix import path in src/app/[slug]/page.tsx
- Changed from '../../../modules/products/registry' to '../../modules/products/registry'
- Correct relative path calculation

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-11 12:36:30 +08:00
Haitao Pan
979e83f1f9 fix: correct import path for products registry module
- Fix import path in src/app/[slug]/page.tsx
- Changed from '../../../../modules/products/registry' to '../../../modules/products/registry'
- Resolves Module not found error

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-11 12:34:05 +08:00
Haitao Pan
3148c42619 refactor(config): modernize to ES Module format
- Convert tailwind.config.js and postcss.config.js to ES Module syntax
- Remove duplicate .mjs files and temporary config files
- Update CONFIG_SYSTEM_SUMMARY.md with migration guide
- All configs now use import/export consistently

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-11 12:26:04 +08:00
Haitao Pan
9f146f44f2 fix(dashboard): resolve all module import errors and fix CSS loading
## Module Import Fixes:
- Fix cloud_iac JSON import paths: '../../../../public/_build/cloud_iac_index.json' → '../../../../../public/_build/cloud_iac_index.json'
- Fix docs JSON import paths: '../../public/dl-index/*' and '../../public/_build/*' → '../../../public/*'
- Fix ThemePreferenceCard theme import: '../../../../theme' → '../routes/theme'
- Fix products registry import: '@src/products/registry' → '../../../../modules/products/registry'

## CSS Loading Fix:
- Update tailwind.config.js content paths to include './src/**/*.{js,ts,jsx,tsx,mdx}'
- Ensures Tailwind CSS scans all src/ directory files for class names

Resolves "Module not found" errors and ensures CSS styles are correctly loaded during build.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 12:04:29 +08:00
Haitao Pan
f9e1983e18 fix(dashboard): resolve markdown import path in homepage.ts
- Fix markdown import path from '../../lib/markdown' to '../../../lib/markdown'
- Correct relative path from src/lib/cms/content/homepage.ts to src/lib/markdown.ts
- Resolves "Module not found" error during Next.js build

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 11:59:29 +08:00
Haitao Pan
9ec2db8a0f fix(dashboard): resolve CMS content source paths in config
- Fix homepage and docs content source root paths from 'cms/content/*' to 'src/lib/cms/content/*'
- Paths are relative to process.cwd() and need the full path from project root
- Resolves ENOENT errors when reading markdown directories

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 11:59:19 +08:00
Haitao Pan
63cc1db1d4 fix(dashboard): resolve import path errors in extensionRuntime.ts
- Fix AppShellBypass import path from '../../../lib/appShellBypass' to '../appShellBypass'
- Correct relative path from src/lib/cms/extensionRuntime.ts to src/lib/appShellBypass.tsx
- Resolves "Module not found" error during Next.js build

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 11:51:04 +08:00
Haitao Pan
8bf8f36a37 fix(dashboard): resolve featureToggles import path in homepage.ts
- Fix import path from '../../lib/featureToggles' to '../../../lib/featureToggles'
- Correct relative path from src/lib/cms/content/homepage.ts to src/lib/featureToggles.ts
- Resolves "Module not found" error during Next.js build

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 11:23:09 +08:00
shenlan
e505e7297b refactor(dashboard): adopt src app router layout (#667) 2025-11-11 10:45:37 +08:00
Haitao Pan
25e35d2223 feat(account): add database management targets to Makefile
- Add create-db-user: create database user and grant privileges
- Add db-reset: reset entire PostgreSQL cluster (dangerous operation)
- Update help text to document new database management commands

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 23:12:07 +08:00
shenlan
1c4a686f6e Merge pull request #666 from Cloud-Neutral/codex/simplify-dashboard-tab-presentation 2025-11-10 07:59:20 +08:00
shenlan
3739dcb19f Simplify open source hero copy 2025-11-10 07:53:00 +08:00
shenlan
3c543026fa Refine homepage hero to minimal Cloud-Neutral layout (#665)
* Refine homepage hero to minimal Cloud-Neutral layout

* Simplify homepage hero layout
2025-11-09 23:37:25 +08:00
shenlan
772d178d06 Revert "Remove marketing-focused components from dashboards (#663)" (#664)
This reverts commit 518c01dd20.
2025-11-09 23:27:47 +08:00
shenlan
518c01dd20 Remove marketing-focused components from dashboards (#663) 2025-11-09 23:24:00 +08:00
shenlan
11057ab5ac Remove newsletter sidebar component (#662) 2025-11-09 22:40:59 +08:00
shenlan
63689ff9c7 refine homepage ecosystem narrative (#661) 2025-11-09 22:38:14 +08:00
shenlan
880c4ff36b Fix tenant mail route slug for Next.js build (#660) 2025-11-09 20:54:05 +08:00
shenlan
3783fde141 Fix tenant mail route segment name (#659) 2025-11-09 19:46:40 +08:00
shenlan
cf9f0a3c8e Merge pull request #658 from Cloud-Neutral/codex/fix-yarn-next-build-error 2025-11-09 18:11:56 +08:00
shenlan
d6f919c33e Disable typed routes to avoid stale validator imports 2025-11-09 18:10:55 +08:00
shenlan
c0a37205f6 Keep navbar dropdown open on focus (#657) 2025-11-09 17:53:15 +08:00
shenlan
6ca05527cb Fix navbar dropdown click handling (#656) 2025-11-09 17:34:44 +08:00
shenlan
6a09b47b53 feat(dashboard): add open source dropdown to navbar (#655) 2025-11-09 17:21:27 +08:00
shenlan
559b3e40f9 Fix marketing product routes for Next.js params (#653) 2025-11-09 16:51:47 +08:00
shenlan
369c615560 Ensure html2canvas loads only in browser (#652) 2025-11-09 16:34:54 +08:00
shenlan
3823234cbd fix: lazily load html2canvas in poster export (#651) 2025-11-09 16:15:11 +08:00
shenlan
0919e7a5fe Align dynamic slug names for tenant and product routes (#650) 2025-11-09 15:59:20 +08:00
shenlan
895d5727b5 feat(dashboard): add marketing product pages (#649) 2025-11-09 15:44:38 +08:00
shenlan
21d7f40fc5 Rename CloudNative Suite to Cloud-Neutral in dashboards (#648) 2025-11-09 10:06:34 +08:00
Haitao Pan
94b7cbe632 fix(dashboard): resolve @types/react version conflict
- Downgrade @types/react from 19.1.8 → 18.3.26
- Align with @types/react-dom and @testing-library/react
- No build errors, all dependencies compatible

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-11-06 11:49:09 +08:00