feat: 添加项目功能 - #548
Conversation
|
@wuziyue840 is attempting to deploy a commit to the xiaye's projects Team on Vercel. A member of the Team first needs to authorize it. |
✅ Deploy Preview for demo-firefly ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Reviewer's Guide添加一个可配置的项目页面和项目详情页面,具备完整的 i18n 支持并集成到导航中。 浏览新的项目列表和详情页面的序列图sequenceDiagram
actor User
participant NavBar
participant Browser
participant ProjectsPage
participant ProjectsDetailPage
User->>NavBar: click LinkPresets.Projects
NavBar->>Browser: navigate /projects/
Browser->>ProjectsPage: load projects.astro
ProjectsPage->>ProjectsPage: check siteConfig.pages.projects
alt [projects page disabled]
ProjectsPage-->>Browser: Astro.redirect("/404/")
else [projects page enabled]
ProjectsPage->>ProjectsPage: group projectsConfig.projects by category
ProjectsPage->>ProjectsPage: build tabs from projectsConfig.categories
ProjectsPage-->>Browser: render ProjectsGrid
User->>Browser: click ProjectCard
alt [item.link && item.external]
Browser-->>Browser: open item.link in new tab
else [item.link && !item.external]
Browser-->>Browser: navigate to item.link
else [no link but has content/features/screenshots]
Browser->>ProjectsDetailPage: request /projects/{id}/
ProjectsDetailPage->>ProjectsDetailPage: getStaticPaths()
ProjectsDetailPage->>ProjectsDetailPage: find project by id
alt [project not found or !siteConfig.pages.projects]
ProjectsDetailPage-->>Browser: Astro.redirect("/404/")
else [project found with detail]
ProjectsDetailPage-->>Browser: render detail sections
end
else [no link and no detail]
Browser-->>User: no navigation (card is not clickable)
end
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your Experience访问你的 dashboard 以:
Getting HelpOriginal review guide in EnglishReviewer's GuideAdds a configurable projects page and project detail pages, with full i18n support and navigation integration. Sequence diagram for navigating the new projects list and detail pagessequenceDiagram
actor User
participant NavBar
participant Browser
participant ProjectsPage
participant ProjectsDetailPage
User->>NavBar: click LinkPresets.Projects
NavBar->>Browser: navigate /projects/
Browser->>ProjectsPage: load projects.astro
ProjectsPage->>ProjectsPage: check siteConfig.pages.projects
alt [projects page disabled]
ProjectsPage-->>Browser: Astro.redirect("/404/")
else [projects page enabled]
ProjectsPage->>ProjectsPage: group projectsConfig.projects by category
ProjectsPage->>ProjectsPage: build tabs from projectsConfig.categories
ProjectsPage-->>Browser: render ProjectsGrid
User->>Browser: click ProjectCard
alt [item.link && item.external]
Browser-->>Browser: open item.link in new tab
else [item.link && !item.external]
Browser-->>Browser: navigate to item.link
else [no link but has content/features/screenshots]
Browser->>ProjectsDetailPage: request /projects/{id}/
ProjectsDetailPage->>ProjectsDetailPage: getStaticPaths()
ProjectsDetailPage->>ProjectsDetailPage: find project by id
alt [project not found or !siteConfig.pages.projects]
ProjectsDetailPage-->>Browser: Astro.redirect("/404/")
else [project found with detail]
ProjectsDetailPage-->>Browser: render detail sections
end
else [no link and no detail]
Browser-->>User: no navigation (card is not clickable)
end
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:
ProjectCard.svelte组件在可点击和不可点击两种分支间几乎重复了所有标记;可以考虑将共享的布局提取到一个单独的结构中,只在需要时用<a>包裹,从而降低维护成本。- 新增的
LinkPresets.Projects条目和projectsConfig.categories名称使用了硬编码的中文字符串;如果导航和页面标题的其他部分都是通过 i18n 做本地化的,建议也通过翻译键来驱动这些字段,以保持语言行为的一致性。 - 在
TabNav.svelte和ProjectsGrid.svelte中直接访问了window;因为这些组件是通过client:load使用的,这样做是安全的,但你仍然可以考虑对window是否为undefined做保护,以避免未来如果更改 hydration 模式可能带来的问题。
给 AI Agent 的提示
Please address the comments from this code review:
## Overall Comments
- The `ProjectCard.svelte` component duplicates almost all markup between the clickable and non-clickable branches; consider extracting the shared layout into a single structure and only conditionally wrapping it with an `<a>` to reduce maintenance overhead.
- The new `LinkPresets.Projects` entry and `projectsConfig.categories` names are hardcoded Chinese strings; if the rest of the nav and page titles are localized via i18n, consider wiring these through the translation keys to keep language behavior consistent.
- In `TabNav.svelte` and `ProjectsGrid.svelte`, direct `window` access is assumed; since these components are used with `client:load`, it’s safe but you may still want to guard against `window` being undefined to avoid issues if the hydration mode changes in the future.
## Individual Comments
### Comment 1
<location path="src/components/pages/projects/ProjectSection.svelte" line_range="15" />
<code_context>
+const { sectionId, sectionTitle, items, isActive }: Props = $props();
+</script>
+
+<div id="projects-section-{sectionId}" class="{isActive ? 'block' : 'hidden'}">
+ {#if sectionTitle}
+ <h3 class="text-lg font-semibold text-neutral-900 dark:text-neutral-100 mb-4 flex items-center gap-2">
</code_context>
<issue_to_address>
**issue (bug_risk):** The section `id` attribute is treated as a literal string rather than interpolating `sectionId`.
In Svelte, `id="projects-section-{sectionId}"` is treated as a literal string, so `sectionId` is never interpolated. If you need unique IDs per section (for anchors, scrolling, etc.), use template syntax instead: `id={`projects-section-${sectionId}`}` so the ID actually includes the `sectionId` value.
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的评审。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- The
ProjectCard.sveltecomponent duplicates almost all markup between the clickable and non-clickable branches; consider extracting the shared layout into a single structure and only conditionally wrapping it with an<a>to reduce maintenance overhead. - The new
LinkPresets.Projectsentry andprojectsConfig.categoriesnames are hardcoded Chinese strings; if the rest of the nav and page titles are localized via i18n, consider wiring these through the translation keys to keep language behavior consistent. - In
TabNav.svelteandProjectsGrid.svelte, directwindowaccess is assumed; since these components are used withclient:load, it’s safe but you may still want to guard againstwindowbeing undefined to avoid issues if the hydration mode changes in the future.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `ProjectCard.svelte` component duplicates almost all markup between the clickable and non-clickable branches; consider extracting the shared layout into a single structure and only conditionally wrapping it with an `<a>` to reduce maintenance overhead.
- The new `LinkPresets.Projects` entry and `projectsConfig.categories` names are hardcoded Chinese strings; if the rest of the nav and page titles are localized via i18n, consider wiring these through the translation keys to keep language behavior consistent.
- In `TabNav.svelte` and `ProjectsGrid.svelte`, direct `window` access is assumed; since these components are used with `client:load`, it’s safe but you may still want to guard against `window` being undefined to avoid issues if the hydration mode changes in the future.
## Individual Comments
### Comment 1
<location path="src/components/pages/projects/ProjectSection.svelte" line_range="15" />
<code_context>
+const { sectionId, sectionTitle, items, isActive }: Props = $props();
+</script>
+
+<div id="projects-section-{sectionId}" class="{isActive ? 'block' : 'hidden'}">
+ {#if sectionTitle}
+ <h3 class="text-lg font-semibold text-neutral-900 dark:text-neutral-100 mb-4 flex items-center gap-2">
</code_context>
<issue_to_address>
**issue (bug_risk):** The section `id` attribute is treated as a literal string rather than interpolating `sectionId`.
In Svelte, `id="projects-section-{sectionId}"` is treated as a literal string, so `sectionId` is never interpolated. If you need unique IDs per section (for anchors, scrolling, etc.), use template syntax instead: `id={`projects-section-${sectionId}`}` so the ID actually includes the `sectionId` value.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| const { sectionId, sectionTitle, items, isActive }: Props = $props(); | ||
| </script> | ||
|
|
||
| <div id="projects-section-{sectionId}" class="{isActive ? 'block' : 'hidden'}"> |
There was a problem hiding this comment.
issue (bug_risk): 区块的 id 属性被当作字面字符串处理,而不是插入 sectionId。
在 Svelte 中,id="projects-section-{sectionId}" 会被视为字面量字符串,因此 sectionId 根本不会被插入。如果你需要为每个区块生成唯一的 ID(用于锚点、滚动等),请使用模板语法:id={projects-section-${sectionId}},这样生成的 ID 才会真正包含 sectionId 的值。
Original comment in English
issue (bug_risk): The section id attribute is treated as a literal string rather than interpolating sectionId.
In Svelte, id="projects-section-{sectionId}" is treated as a literal string, so sectionId is never interpolated. If you need unique IDs per section (for anchors, scrolling, etc.), use template syntax instead: id={projects-section-${sectionId}} so the ID actually includes the sectionId value.
Type of change
Checklist
Related Issue
无
Changes
How To Test
Screenshots (if applicable)
Additional Notes
Summary by Sourcery
添加一个可配置的项目页面,包含列表视图和详情视图,并集成导航,同时为所有支持的语言提供国际化文案。
新功能:
改进:
Original summary in English
Summary by Sourcery
Add a configurable projects page with listing and detail views, including navigation integration and internationalized text for all supported languages.
New Features:
Enhancements: