-
Notifications
You must be signed in to change notification settings - Fork 3
✨ feat: Add Xyzen chat landing page with HeroParallax and CTA button #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- ♻️ refactor:Create /chat route with HeroParallax component for product showcase - Add products.ts with Xyzen product data - Implement chat page layout with animated parallax effect - Add CTA button linking to Bohrium Xyzen application - Update Navbar to include Projects menu with 5 ScienceOL products - Add dark mode styling for better visual appearance - Integrate React Router with new /chat route in router.tsx
评审指南此 PR 通过为动画产品展示创建 HeroParallax 组件和一个带有 CTA 按钮的 ChatPage,实现了新的 Xyzen 聊天登录页;将 HeroParallax 和 ChatPage 组件的类图classDiagram
class ChatPage {
+HeroParallax products
+CTA button ("开始使用 Xyzen")
}
class HeroParallax {
+products: Product[]
+Header()
+ProductCard(product, translate)
}
class Product {
+title: string
+link: string
+thumbnail: string
}
ChatPage --> HeroParallax : uses
HeroParallax --> Product : displays
文件级变更
提示和命令与 Sourcery 交互
自定义你的体验访问你的仪表盘以:
获取帮助Original review guide in EnglishReviewer's GuideThis PR implements a new Xyzen chat landing page by creating a HeroParallax component for animated product showcases and a ChatPage with a CTA button, integrates the /chat route into React Router, updates the Navbar Projects and Tutorials menus to surface the new page, and enhances styling with dark mode theming and utility functions. Class diagram for HeroParallax and ChatPage componentsclassDiagram
class ChatPage {
+HeroParallax products
+CTA button ("开始使用 Xyzen")
}
class HeroParallax {
+products: Product[]
+Header()
+ProductCard(product, translate)
}
class Product {
+title: string
+link: string
+thumbnail: string
}
ChatPage --> HeroParallax : uses
HeroParallax --> Product : displays
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
你好 - 我已经审查了你的更改 - 这里有一些反馈:
- 删除 Projects.tsx 和 Tutorials.tsx 中大块注释掉的代码,以提高可读性并保持代码库整洁。
- 将 index.css 中大量的 CSS 自定义属性提取到专门的主题文件或 Tailwind 配置中,以使你的基础样式表保持专注和可维护。
- 重构 HeroParallax 以动态生成行(或接受一个 columns prop),而不是硬编码五个项目的切片,以便在产品数量不同时具有更好的灵活性。
供 AI 代理使用的提示
请处理此代码审查中的评论:
## 总体评论
- 删除 Projects.tsx 和 Tutorials.tsx 中大块注释掉的代码,以提高可读性并保持代码库整洁。
- 将 index.css 中大量的 CSS 自定义属性提取到专门的主题文件或 Tailwind 配置中,以使你的基础样式表保持专注和可维护。
- 重构 HeroParallax 以动态生成行(或接受一个 columns prop),而不是硬编码五个项目的切片,以便在产品数量不同时具有更好的灵活性。
## 单独评论
### 评论 1
<location> `web/src/app/navbar/Tutorials.tsx:64-73` </location>
<code_context>
+
+// import Link from 'next/link';
+
+export default function Tutorial() {
return (
- <NavbarFullWidth
- buttonName="tutorial"
- solutions={resources}
- callsToAction={callsToAction}
- numberOfCallsToAction={2}
- numberOfSolutions={3}
- {...props}
- />
+ <a
+ href="https://docs.sciol.ac.cn"
+ target="_blank"
+ rel="noopener noreferrer"
+ className="text-sm font-medium text-gray-700 hover:text-gray-900 dark:text-gray-300 dark:hover:text-gray-100"
+ >
+ 教程
+ </a>
);
}
</code_context>
<issue_to_address>
**issue (bug_risk):** Tutorial 组件签名已更改,但 Navbar 需要 props。
Navbar 将多个 props 传递给 Tutorial,但 Tutorial 不再接受任何 props。这种不匹配可能会导致运行时问题。请更新 Tutorial 以处理这些 props,或调整 Navbar 以避免传递它们。
</issue_to_address>
### 评论 2
<location> `web/src/components/ui/hero-parallax.tsx:20-22` </location>
<code_context>
+ thumbnail: string;
+ }[];
+}) => {
+ const firstRow = products.slice(0, 5);
+ const secondRow = products.slice(5, 10);
+ const thirdRow = products.slice(10, 15);
+ const ref = React.useRef(null);
+ const { scrollYProgress } = useScroll({
</code_context>
<issue_to_address>
**suggestion:** 将产品切片为固定大小的行可能会导致 `products.length < 15` 时出现问题。
如果产品少于 15 个,行可能会为空或不完整。考虑处理更短的数组或动态计算行大小。
建议的实现:
```typescript
// Dynamically split products into rows of up to 5 items each
const rowSize = 5;
const rows = [];
for (let i = 0; i < products.length; i += rowSize) {
rows.push(products.slice(i, i + rowSize));
}
```
如果你在文件中的其他地方引用了 `firstRow`、`secondRow` 或 `thirdRow`,请更新这些用法以使用 `rows[0]`、`rows[1]`、`rows[2]` 等。如果要在循环中渲染它们,你可能还需要迭代 `rows`。
</issue_to_address>
### 评论 3
<location> `web/src/components/ui/hero-parallax.tsx:141-146` </location>
<code_context>
+ className="group/product h-96 w-[30rem] relative shrink-0"
+ >
+ <a href={product.link} className="block group-hover/product:shadow-2xl ">
+ <img
+ src={product.thumbnail}
+ height="600"
+ width="600"
+ className="object-cover object-left-top absolute h-full w-full inset-0"
+ alt={product.title}
+ />
+ </a>
</code_context>
<issue_to_address>
**suggestion:** ProductCard 使用带有外部 URL 的 `<img>`;考虑处理加载失败的错误。
实施备用图像或错误处理程序,以防止 URL 加载失败时显示损坏的图像。
</issue_to_address>
### 评论 4
<location> `web/src/app/navbar/Projects.tsx:1` </location>
<code_context>
-import { GitHubIcon } from '@/assets/SocialIcons';
-import { EnvelopeIcon, RocketLaunchIcon } from '@heroicons/react/24/outline';
+// import { GitHubIcon } from '@/assets/SocialIcons';
+// import { EnvelopeIcon, RocketLaunchIcon } from '@heroicons/react/24/outline';
+
</code_context>
<issue_to_address>
**issue (complexity):** 考虑删除注释掉的代码,并动态推导数组长度,而不是硬编码计数。
```suggestion
删除所有过时的、注释掉的导入和选项定义(你总是可以从 Git 中恢复它们),并避免硬编码计数——从你的数组中推导它们。例如:
1) 清理文件顶部:
```ts
// before: dozens of // import ... and // const options = { ... }
// after:
import { EnvelopeIcon } from '@heroicons/react/24/outline';
import { SiUnrealengine, SiUnity, SiProton, SiX, SiStmicroelectronics } from 'react-icons/si';
import { GitHubIcon } from '@/assets/SocialIcons';
import NavbarFullWidth from './NavbarFullWidth';
import type { NavbarFullWidthProps } from './types';
```
2) 内联你的数据并推导长度,而不是传递字面量:
```ts
const resources = [
{ name: 'Studio', icon: SiStmicroelectronics, /* ... */ },
/* other items */
];
const callsToAction = [
{ name: 'Follow on GitHub', href: 'https://github.com/Protium', icon: GitHubIcon },
{ name: 'Contact us', href: '#', icon: EnvelopeIcon },
];
export default function Projects(
props: Omit<NavbarFullWidthProps, 'solutions' | 'callsToAction' | 'buttonName'>
) {
return (
<NavbarFullWidth
buttonName="project"
solutions={resources}
callsToAction={callsToAction}
numberOfSolutions={resources.length}
numberOfCallsToAction={callsToAction.length}
{...props}
/>
);
}
```
3) (可选)如果 `NavbarFullWidth` 可以自行推断这些计数,则完全删除 `numberOf*` props,并在该组件内部计算 `solutions.length` / `callsToAction.length`。这可以使 API 表面最小化并消除魔术数字。
```ts
// inside NavbarFullWidth.tsx
const numSolutions = solutions.length;
const numActions = callsToAction.length;
```
</issue_to_address>帮助我更有用!请点击每个评论上的 👍 或 👎,我将利用这些反馈来改进你的评论。
Original comment in English
Hey there - I've reviewed your changes - here's some feedback:
- Remove large blocks of commented-out code in Projects.tsx and Tutorials.tsx to improve readability and keep the codebase clean.
- Extract the extensive CSS custom properties in index.css into a dedicated theme file or Tailwind config so your base stylesheet stays focused and maintainable.
- Refactor HeroParallax to generate rows dynamically (or accept a columns prop) rather than hard-coding slices of five items for better flexibility with varying product counts.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Remove large blocks of commented-out code in Projects.tsx and Tutorials.tsx to improve readability and keep the codebase clean.
- Extract the extensive CSS custom properties in index.css into a dedicated theme file or Tailwind config so your base stylesheet stays focused and maintainable.
- Refactor HeroParallax to generate rows dynamically (or accept a columns prop) rather than hard-coding slices of five items for better flexibility with varying product counts.
## Individual Comments
### Comment 1
<location> `web/src/app/navbar/Tutorials.tsx:64-73` </location>
<code_context>
+
+// import Link from 'next/link';
+
+export default function Tutorial() {
return (
- <NavbarFullWidth
- buttonName="tutorial"
- solutions={resources}
- callsToAction={callsToAction}
- numberOfCallsToAction={2}
- numberOfSolutions={3}
- {...props}
- />
+ <a
+ href="https://docs.sciol.ac.cn"
+ target="_blank"
+ rel="noopener noreferrer"
+ className="text-sm font-medium text-gray-700 hover:text-gray-900 dark:text-gray-300 dark:hover:text-gray-100"
+ >
+ 教程
+ </a>
);
}
</code_context>
<issue_to_address>
**issue (bug_risk):** Tutorial component signature changed, but Navbar expects props.
Navbar passes several props to Tutorial, but Tutorial no longer accepts any. This mismatch may cause runtime issues. Please update Tutorial to handle these props or adjust Navbar to avoid passing them.
</issue_to_address>
### Comment 2
<location> `web/src/components/ui/hero-parallax.tsx:20-22` </location>
<code_context>
+ thumbnail: string;
+ }[];
+}) => {
+ const firstRow = products.slice(0, 5);
+ const secondRow = products.slice(5, 10);
+ const thirdRow = products.slice(10, 15);
+ const ref = React.useRef(null);
+ const { scrollYProgress } = useScroll({
</code_context>
<issue_to_address>
**suggestion:** Slicing products into fixed-size rows may cause issues if products.length < 15.
Rows may be empty or incomplete if there are fewer than 15 products. Consider handling shorter arrays or calculating row sizes dynamically.
Suggested implementation:
```typescript
// Dynamically split products into rows of up to 5 items each
const rowSize = 5;
const rows = [];
for (let i = 0; i < products.length; i += rowSize) {
rows.push(products.slice(i, i + rowSize));
}
```
If you reference `firstRow`, `secondRow`, or `thirdRow` elsewhere in the file, update those usages to use `rows[0]`, `rows[1]`, `rows[2]`, etc. You may also want to iterate over `rows` if rendering them in a loop.
</issue_to_address>
### Comment 3
<location> `web/src/components/ui/hero-parallax.tsx:141-146` </location>
<code_context>
+ className="group/product h-96 w-[30rem] relative shrink-0"
+ >
+ <a href={product.link} className="block group-hover/product:shadow-2xl ">
+ <img
+ src={product.thumbnail}
+ height="600"
+ width="600"
+ className="object-cover object-left-top absolute h-full w-full inset-0"
+ alt={product.title}
+ />
+ </a>
</code_context>
<issue_to_address>
**suggestion:** ProductCard uses <img> with external URLs; consider error handling for failed loads.
Implement a fallback image or error handler to prevent broken image displays when URLs fail to load.
</issue_to_address>
### Comment 4
<location> `web/src/app/navbar/Projects.tsx:1` </location>
<code_context>
-import { GitHubIcon } from '@/assets/SocialIcons';
-import { EnvelopeIcon, RocketLaunchIcon } from '@heroicons/react/24/outline';
+// import { GitHubIcon } from '@/assets/SocialIcons';
+// import { EnvelopeIcon, RocketLaunchIcon } from '@heroicons/react/24/outline';
+
</code_context>
<issue_to_address>
**issue (complexity):** Consider removing commented-out code and deriving array lengths dynamically instead of hard-coding counts.
```suggestion
Remove all of the stale, commented-out imports and option definitions (you can always recover them from Git), and avoid hard-coding counts—derive them from your arrays. For example:
1) Clean up the top of the file:
```ts
// before: dozens of // import ... and // const options = { ... }
// after:
import { EnvelopeIcon } from '@heroicons/react/24/outline';
import { SiUnrealengine, SiUnity, SiProton, SiX, SiStmicroelectronics } from 'react-icons/si';
import { GitHubIcon } from '@/assets/SocialIcons';
import NavbarFullWidth from './NavbarFullWidth';
import type { NavbarFullWidthProps } from './types';
```
2) Inline your data and derive lengths instead of passing literals:
```ts
const resources = [
{ name: 'Studio', icon: SiStmicroelectronics, /* ... */ },
/* other items */
];
const callsToAction = [
{ name: 'Follow on GitHub', href: 'https://github.com/Protium', icon: GitHubIcon },
{ name: 'Contact us', href: '#', icon: EnvelopeIcon },
];
export default function Projects(
props: Omit<NavbarFullWidthProps, 'solutions' | 'callsToAction' | 'buttonName'>
) {
return (
<NavbarFullWidth
buttonName="project"
solutions={resources}
callsToAction={callsToAction}
numberOfSolutions={resources.length}
numberOfCallsToAction={callsToAction.length}
{...props}
/>
);
}
```
3) (Optional) If `NavbarFullWidth` can infer those counts itself, remove the `numberOf*` props entirely and compute `solutions.length` / `callsToAction.length` inside that component. This keeps the API surface minimal and removes magic numbers.
```ts
// inside NavbarFullWidth.tsx
const numSolutions = solutions.length;
const numActions = callsToAction.length;
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| export default function Tutorial() { | ||
| return ( | ||
| <NavbarFullWidth | ||
| buttonName="tutorial" | ||
| solutions={resources} | ||
| callsToAction={callsToAction} | ||
| numberOfCallsToAction={2} | ||
| numberOfSolutions={3} | ||
| {...props} | ||
| /> | ||
| <a | ||
| href="https://docs.sciol.ac.cn" | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| className="text-sm font-medium text-gray-700 hover:text-gray-900 dark:text-gray-300 dark:hover:text-gray-100" | ||
| > | ||
| 教程 | ||
| </a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Tutorial 组件签名已更改,但 Navbar 需要 props。
Navbar 将多个 props 传递给 Tutorial,但 Tutorial 不再接受任何 props。这种不匹配可能会导致运行时问题。请更新 Tutorial 以处理这些 props,或调整 Navbar 以避免传递它们。
Original comment in English
issue (bug_risk): Tutorial component signature changed, but Navbar expects props.
Navbar passes several props to Tutorial, but Tutorial no longer accepts any. This mismatch may cause runtime issues. Please update Tutorial to handle these props or adjust Navbar to avoid passing them.
| const firstRow = products.slice(0, 5); | ||
| const secondRow = products.slice(5, 10); | ||
| const thirdRow = products.slice(10, 15); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: 将产品切片为固定大小的行可能会导致 products.length < 15 时出现问题。
如果产品少于 15 个,行可能会为空或不完整。考虑处理更短的数组或动态计算行大小。
建议的实现:
// Dynamically split products into rows of up to 5 items each
const rowSize = 5;
const rows = [];
for (let i = 0; i < products.length; i += rowSize) {
rows.push(products.slice(i, i + rowSize));
}如果你在文件中的其他地方引用了 firstRow、secondRow 或 thirdRow,请更新这些用法以使用 rows[0]、rows[1]、rows[2] 等。如果要在循环中渲染它们,你可能还需要迭代 rows。
Original comment in English
suggestion: Slicing products into fixed-size rows may cause issues if products.length < 15.
Rows may be empty or incomplete if there are fewer than 15 products. Consider handling shorter arrays or calculating row sizes dynamically.
Suggested implementation:
// Dynamically split products into rows of up to 5 items each
const rowSize = 5;
const rows = [];
for (let i = 0; i < products.length; i += rowSize) {
rows.push(products.slice(i, i + rowSize));
}If you reference firstRow, secondRow, or thirdRow elsewhere in the file, update those usages to use rows[0], rows[1], rows[2], etc. You may also want to iterate over rows if rendering them in a loop.
| <img | ||
| src={product.thumbnail} | ||
| height="600" | ||
| width="600" | ||
| className="object-cover object-left-top absolute h-full w-full inset-0" | ||
| alt={product.title} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: ProductCard 使用带有外部 URL 的 <img>;考虑处理加载失败的错误。
实施备用图像或错误处理程序,以防止 URL 加载失败时显示损坏的图像。
变更内容
简要描述本次 PR 的主要变更内容。
相关 Issue
请关联相关 Issue(如有):#编号
检查清单
默认已勾选,如不满足,请检查。
其他说明
如有特殊说明或注意事项,请补充。
Sourcery 总结
添加一个新的 Xyzen 聊天着陆页,带有动画视差产品展示,并将其集成到网站导航和样式中。
新功能:
/chat路由,使用ChatPage组件,该组件包含HeroParallax展示和一个启动 Xyzen 的 CTA 按钮products.ts数据文件,列出 Xyzen 缩略图和链接HeroParallaxUI 组件以实现滚动视差效果改进:
Projects导航栏以使用NavbarFullWidth,并更新资源图标,包括 Xyzen 入口Tutorials导航栏下拉菜单替换为一个直接的外部文档链接tw-animate-css、主题 CSS 变量和深色模式样式扩展全局样式构建:
index.css中导入tw-animate-css杂项:
className合并的cn工具函数Original summary in English
Summary by Sourcery
Add a new Xyzen chat landing page with animated parallax product showcase and integrate it into the site navigation and styling
New Features:
Enhancements:
Build:
Chores: