Skip to content

Implement landing page#48

Merged
hackartists merged 14 commits intobiyard:mainfrom
hackartists:feature/landing
Mar 9, 2025
Merged

Implement landing page#48
hackartists merged 14 commits intobiyard:mainfrom
hackartists:feature/landing

Conversation

@hackartists
Copy link
Copy Markdown
Contributor

@hackartists hackartists commented Mar 8, 2025

Summary by CodeRabbit

  • New Features

    • Introduced modular UI components for About, Community, Header, Bottom Sheet, Politician Stance, Support, Top, MissionCard, SectionHeader, InputWithButton, LabeledInput, Socials, and Indicator.
    • Added new button components: PrimaryButton and SecondaryButton for improved user interaction.
    • Introduced a new Footer component for enhanced user engagement.
  • Refactor

    • Redesigned the page layout with a dynamic header and improved scroll responsiveness.
    • Streamlined navigation by simplifying inactive routes.
    • Removed deprecated components like LogoWrapper and Footer to enhance clarity.
  • Style

    • Updated global styles with dynamic theming and refreshed typography.
  • Chores

    • Upgraded dependencies and refined build processes for improved reliability and maintainability.

- Added new icon components for Bsky, Telegram, and X in the ~icons~ module.
- Updated the ~Header~ component to accept a ~selected~ prop for dynamic styling.
- Introduced a new ~BottomSheet~ component for improved UI interaction.
- Enhanced the ~Top~ component with new layout and styling.
- Updated the ~RootLayout~ to include scroll position tracking and dynamic ~BottomSheet~ display.
Copilot AI review requested due to automatic review settings March 8, 2025 14:04
@hackartists hackartists requested a review from a team as a code owner March 8, 2025 14:04
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 8, 2025

Walkthrough

This update encompasses numerous modifications spanning configuration files, build scripts, UI components, and routing. The Rust workspace’s edition and dependency definitions have been updated, and subproject references are revised. Several CSS files now include new theme variables and typography settings, while assets like app icons are removed. The build process has been cleaned up with active Tailwind CSS generation. On the application side, multiple new UI components have been introduced, and some obsolete ones removed. Additionally, scrolling behavior in the layout has been enhanced, and many route definitions and module visibilities have been updated.

Changes

File(s) Change Summary
Cargo.toml (workspace) Updated Rust edition from "2021" to "2024"; added btracing dependency with a local path; modified dioxus and dioxus-web to use a Git repository URL.
deps/rust-sdk Updated subproject commit reference from 25e2c1fe1f4561f7a3239ff49638c05c04a4b4a0 to a1f3417846eb8ef842e25d129f79d424fc2da4f6.
packages/main-ui/Cargo.toml Changed wallet-adapter dependency from flexible to exact version (=1.0.4-beta); added btracing.workspace = true.
packages/main-ui/Makefile Modified build target to include clean; replaced echo commands with active Tailwind CSS generation command.
packages/main-ui/public/input.css Added new theme definitions with custom CSS variables (colors, spacing, etc.).
packages/main-ui/public/logos/Assets.xcassets/.../Contents.json Removed file defining app icon assets.
packages/main-ui/public/main.css Updated styling: changed background to use a CSS variable, switched font-family, added smooth scrolling and scrollbar hiding rules.
packages/main-ui/src/components/footer/mod.rs and .../logo/mod.rs Removed Footer and LogoWrapper components.
packages/main-ui/src/components/icons/* and .../icons/mod.rs Added new SVG icon components (Bsky, Telegram, X); updated module exports to include these new components.
packages/main-ui/src/components/mod.rs Removed logo and footer modules; added a new indicators module.
packages/main-ui/src/main.rs Commented out initialization of certain services; updated favicon links and Tailwind CSS script reference; added local Tailwind CSS style.
packages/main-ui/src/pages/* and subdirectories Introduced new components (About, BottomSheet, Community, Header, PoliticianStance, Support, Top); removed outdated header components and translations; restructured HomePage to use new components; updated RootLayout for scroll event handling; modified module visibility in mod.rs; commented out specific route definitions in route.rs.
packages/main-ui/src/components/indicators/mod.rs Added new Indicator component.
packages/main-ui/src/pages/components/* Added new common UI components: MissionCard, SectionHeader, Footer, InputWithButton, and Socials.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Browser
    participant RootLayout
    participant ScrollHandler
    participant Header
    participant BottomSheet

    User->>Browser: Scroll action
    Browser->>RootLayout: Emit scroll event
    RootLayout->>ScrollHandler: Update scroll_position
    ScrollHandler-->>RootLayout: Compute selected section
    RootLayout->>Header: Update header with selected section
    alt Further section available
       RootLayout->>BottomSheet: Render BottomSheet for smooth scroll
    end
Loading
sequenceDiagram
    participant Mouse as User
    participant BottomSheet
    participant SVG

    Mouse->>BottomSheet: Hover over clickable area
    BottomSheet->>BottomSheet: Set hover state to true
    BottomSheet->>SVG: Apply updated fill and stroke
    Mouse->>BottomSheet: Mouse leaves area
    BottomSheet->>BottomSheet: Reset hover state to false
    BottomSheet->>SVG: Revert fill and stroke properties
Loading

Poem

I'm a hopping rabbit in the code domain,
New components sprout like carrots after the rain.
Dependencies updated, scrolls now dance so free,
Icons and themes are setting our UI spree.
I nibble on clean builds and delightful change,
A joyful code garden where ideas rearrange! 🐇🌟


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c083bd9 and 678c537.

📒 Files selected for processing (1)
  • .github/workflows/pr-workflow.yml (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/pr-workflow.yml
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: main-ui
  • GitHub Check: main-api

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (17)
packages/main-ui/src/components/icons/logos/telegram.rs (1)

1-35: Well-structured SVG icon component

The Telegram icon component is well-implemented using Dioxus's component model. The SVG structure is clean and properly defined.

Consider adding accessibility attributes to make the icon more screen-reader friendly:

 svg {
+    aria_label: "Telegram logo",
+    role: "img",
     fill: "none",
     height: "29",
     view_box: "0 0 29 29",
     width: "29",
     xmlns: "http://www.w3.org/2000/svg",
packages/main-ui/src/components/icons/logos/x.rs (1)

1-21: Well-structured X (Twitter) icon component

The X icon component follows the correct Dioxus component pattern and properly renders the logo.

Consider adding accessibility attributes to improve screen reader support:

 svg {
+    aria_label: "X logo",
+    role: "img",
     fill: "none",
     height: "29",
     view_box: "0 0 29 29",
     width: "29",
     xmlns: "http://www.w3.org/2000/svg",
packages/main-ui/src/components/icons/bsky.rs (2)

7-8: Remove unnecessary blank line

There's an extra blank line after the opening of the div element that should be removed for consistency with other icon components.

 rsx! {
     div {..attributes,
-
         svg {

1-34: Consider organizing Bsky with other logos

The Bsky component is defined directly in the icons directory while other social media logos (Telegram, X) are in a logos subdirectory.

Consider moving this file to packages/main-ui/src/components/icons/logos/bsky.rs for better organization and consistency with other logo components.

Additionally, add accessibility attributes to improve screen reader support:

 svg {
+    aria_label: "BlueSky logo",
+    role: "img",
     fill: "none",
     height: "29",
     view_box: "0 0 29 29",
     width: "29",
     xmlns: "http://www.w3.org/2000/svg",
packages/main-ui/src/route.rs (1)

13-14: Consider adding explanatory comment for commented-out routes

You've commented out several routes including the PoliticianStatusPage, Topics, and Patrons sections. Since this is a significant change to the application's navigation, it would be helpful to add a comment explaining why these routes are currently disabled and whether they'll be reintroduced later.

packages/main-ui/public/input.css (1)

5-12: Good start on theme variables

Adding theme variables is a good practice for maintaining consistent styling. The dark theme with gold/yellow accents looks appropriate for the landing page.

Consider expanding the theme with additional variables for:

  • More granular color variations (e.g., primary-light, primary-dark)
  • Additional spacing scales rather than a single value
  • Typography variables (font sizes, weights, line heights)
  • Border radiuses and shadows

This would make the theme more comprehensive and flexible for future UI development.

packages/main-ui/src/pages/components/politician_stance.rs (1)

1-32: Component structure looks good, but the translations need improvement.

The component follows the Dioxus framework conventions and properly handles i18n. However, the Korean and English translations for the title are identical, which doesn't provide proper localization for Korean users.

Consider updating the Korean translation to provide a proper localized title rather than using the English term "PoliticianStance":

title: {
-    ko: "PoliticianStance",
+    ko: "정치인 입장",
    en: "PoliticianStance",
},
packages/main-ui/src/pages/components/support.rs (1)

1-32: Component structure looks good, but the translations need improvement.

The component follows the Dioxus framework conventions and properly handles i18n. However, the Korean and English translations for the title are identical, which doesn't provide proper localization for Korean users.

Consider updating the Korean translation to provide a proper localized title rather than using the English term "Support":

title: {
-    ko: "Support",
+    ko: "지원",
    en: "Support",
},
packages/main-ui/src/pages/components/community.rs (1)

1-32: Component structure looks good, but the translations need improvement.

The component follows the Dioxus framework conventions and properly handles i18n. However, the Korean and English translations for the title are identical, which doesn't provide proper localization for Korean users.

Consider updating the Korean translation to provide a proper localized title rather than using the English term "Community":

title: {
-    ko: "Community",
+    ko: "커뮤니티",
    en: "Community",
},
packages/main-ui/src/pages/components/mod.rs (1)

1-16: Module organization is clean, but consider using a more explicit approach for exports.

The module organization is clean, using submodules for each component. However, using wildcard imports (*) can make it harder to track which components are actually being exported and could lead to unintended exports if a component file exports additional items in the future.

Consider explicitly naming the components you want to export:

mod about;
mod bottom_sheet;
mod community;
mod header;
mod politician_stance;
mod support;
mod top;

- pub use about::*;
- pub use bottom_sheet::*;
- pub use community::*;
- pub use header::*;
- pub use politician_stance::*;
- pub use support::*;
- pub use top::*;
+ pub use about::About;
+ pub use bottom_sheet::BottomSheet;
+ pub use community::Community;
+ pub use header::Header;
+ pub use politician_stance::PoliticianStance;
+ pub use support::Support;
+ pub use top::Top;
packages/main-ui/src/pages/page.rs (1)

4-4: Consider using explicit imports instead of wildcard

Using wildcard imports (*) makes it less clear which components are actually being used in the file and can potentially lead to name conflicts.

-use super::components::*;
+use super::components::{Top, About, PoliticianStance, Community, Support};
packages/main-ui/src/pages/components/header.rs (2)

15-40: Consider a DRY approach to building the menu links.
Reuse a small helper or data array to define each link’s href, label, and selected-state styling, to reduce repetitive code blocks and ensure better maintainability.

-                nav { class: "grow flex flex-row gap-[10px] text-secondary font-bold text-[15px]",
-                    a {
-                        class: "p-10 hover:text-white",
-                        href: "#about",
-                        color: if selected == 1 { "var(--color-primary)" },
-                        {tr.menu_about}
-                    }
-                    ...
-                }
+                let links = [
+                    (tr.menu_about, "#about", 1),
+                    (tr.menu_stance, "#politician-stance", 2),
+                    (tr.menu_community, "#community", 3),
+                    (tr.menu_support, "#support", 4),
+                ];
+                nav { class: "grow flex flex-row gap-[10px] text-secondary font-bold text-[15px]",
+                    links.iter().map(|(label, href, idx)| rsx! {
+                        a {
+                            class: "p-10 hover:text-white",
+                            href: "{href}",
+                            color: if selected == *idx { "var(--color-primary)" } else { "inherit" },
+                            "{label}"
+                        }
+                    })
+                }

56-93: Remove or utilize the unused 'reward' translation key.
The reward key is defined in the translation but not referenced in the component. Consider removing it or adding corresponding UI elements if needed.

-    reward: {
-        ko: "나의 보상",
-        en: "My Rewards",
-    }
packages/main-ui/src/pages/components/bottom_sheet.rs (1)

15-25: Improve accessibility with ARIA attributes.
The clickable SVG lacks a label, potentially impacting screen readers. Add an aria-label or similar attribute to improve accessibility.

 div { class: "w-full fixed bottom-0 left-0 flex flex-row items-center justify-center py-30 cursor-pointer z-11",
     svg {
+        aria-label: "Bottom sheet toggle",
         ...
     }
 }
packages/main-ui/src/pages/layout.rs (1)

14-48: Consider a more scalable approach for scroll-based section detection.
Storing thresholds in an array or mapping positions to indices could simplify future updates and logic expansions.

packages/main-ui/src/pages/mod.rs (2)

1-12: Consider removing commented code instead of commenting it out.

Many modules have been commented out rather than deleted. While this approach may be useful during transitional phases, it can lead to code clutter over time. Consider removing these commented lines if they're no longer needed, or add comments explaining why they're being kept.


20-25: Document the restructuring rationale.

The codebase appears to be undergoing significant restructuring. Consider adding documentation explaining the overall architecture changes and the reasoning behind them, which would help future developers understand the design decisions.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between be9818e and 3a35eb9.

⛔ Files ignored due to path filters (48)
  • Cargo.lock is excluded by !**/*.lock
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/100.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/102.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/1024.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/114.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/120.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/128.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/144.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/152.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/16.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/167.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/172.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/180.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/196.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/20.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/216.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/256.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/29.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/32.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/40.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/48.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/50.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/512.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/55.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/57.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/58.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/60.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/64.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/66.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/72.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/76.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/80.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/87.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/88.png is excluded by !**/*.png
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/92.png is excluded by !**/*.png
  • packages/main-ui/public/logos/android/mipmap-hdpi/ic_launcher.png is excluded by !**/*.png
  • packages/main-ui/public/logos/android/mipmap-mdpi/ic_launcher.png is excluded by !**/*.png
  • packages/main-ui/public/logos/android/mipmap-xhdpi/ic_launcher.png is excluded by !**/*.png
  • packages/main-ui/public/logos/android/mipmap-xxhdpi/ic_launcher.png is excluded by !**/*.png
  • packages/main-ui/public/logos/android/mipmap-xxxhdpi/ic_launcher.png is excluded by !**/*.png
  • packages/main-ui/public/logos/apple-touch-icon.png is excluded by !**/*.png
  • packages/main-ui/public/logos/appstore.png is excluded by !**/*.png
  • packages/main-ui/public/logos/favicon-96x96.png is excluded by !**/*.png
  • packages/main-ui/public/logos/favicon.ico is excluded by !**/*.ico
  • packages/main-ui/public/logos/favicon.svg is excluded by !**/*.svg
  • packages/main-ui/public/logos/playstore.png is excluded by !**/*.png
  • packages/main-ui/public/logos/web-app-manifest-192x192.png is excluded by !**/*.png
  • packages/main-ui/public/logos/web-app-manifest-512x512.png is excluded by !**/*.png
📒 Files selected for processing (32)
  • Cargo.toml (2 hunks)
  • deps/rust-sdk (1 hunks)
  • packages/main-ui/Cargo.toml (1 hunks)
  • packages/main-ui/Makefile (2 hunks)
  • packages/main-ui/public/input.css (1 hunks)
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/Contents.json (0 hunks)
  • packages/main-ui/public/main.css (1 hunks)
  • packages/main-ui/src/components/footer/mod.rs (0 hunks)
  • packages/main-ui/src/components/icons/bsky.rs (1 hunks)
  • packages/main-ui/src/components/icons/logos/bsky.rs (1 hunks)
  • packages/main-ui/src/components/icons/logos/telegram.rs (1 hunks)
  • packages/main-ui/src/components/icons/logos/x.rs (1 hunks)
  • packages/main-ui/src/components/icons/mod.rs (2 hunks)
  • packages/main-ui/src/components/icons/telegram.rs (1 hunks)
  • packages/main-ui/src/components/icons/x.rs (1 hunks)
  • packages/main-ui/src/components/logo/mod.rs (0 hunks)
  • packages/main-ui/src/components/mod.rs (1 hunks)
  • packages/main-ui/src/main.rs (3 hunks)
  • packages/main-ui/src/pages/components/about.rs (1 hunks)
  • packages/main-ui/src/pages/components/bottom_sheet.rs (1 hunks)
  • packages/main-ui/src/pages/components/community.rs (1 hunks)
  • packages/main-ui/src/pages/components/header.rs (1 hunks)
  • packages/main-ui/src/pages/components/mod.rs (1 hunks)
  • packages/main-ui/src/pages/components/politician_stance.rs (1 hunks)
  • packages/main-ui/src/pages/components/support.rs (1 hunks)
  • packages/main-ui/src/pages/components/top.rs (1 hunks)
  • packages/main-ui/src/pages/header.rs (0 hunks)
  • packages/main-ui/src/pages/i18n.rs (0 hunks)
  • packages/main-ui/src/pages/layout.rs (1 hunks)
  • packages/main-ui/src/pages/mod.rs (1 hunks)
  • packages/main-ui/src/pages/page.rs (1 hunks)
  • packages/main-ui/src/route.rs (1 hunks)
💤 Files with no reviewable changes (5)
  • packages/main-ui/src/components/footer/mod.rs
  • packages/main-ui/src/components/logo/mod.rs
  • packages/main-ui/src/pages/i18n.rs
  • packages/main-ui/public/logos/Assets.xcassets/AppIcon.appiconset/Contents.json
  • packages/main-ui/src/pages/header.rs
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: test-with-server
  • GitHub Check: test
  • GitHub Check: main-api
🔇 Additional comments (19)
deps/rust-sdk (1)

1-1: Subproject Commit Reference Updated

The commit reference has been updated to a1f3417846eb8ef842e25d129f79d424fc2da4f6. Please ensure that the changes included in this commit are fully compatible with the landing page implementation and that any dependent functionality in the Rust SDK is properly verified.

packages/main-ui/src/components/mod.rs (1)

4-4:

Details

✅ Verification successful

Added footer module looks good

The addition of the footer module aligns with the landing page implementation.


🏁 Script executed:

#!/bin/bash
# Verify that the footer module exists and is properly implemented
if [ -f "packages/main-ui/src/components/footer/mod.rs" ]; then
  echo "Footer module exists:"
  cat "packages/main-ui/src/components/footer/mod.rs" | head -n 20
else
  echo "Footer module file does not exist"
fi

Length of output: 797


Footer module is correctly integrated

The verification confirms that the file packages/main-ui/src/components/footer/mod.rs exists and includes the expected implementation for the Footer component. The addition aligns with the landing page update, and the earlier removal of the logo module appears intentional.

  • Verified file: packages/main-ui/src/components/footer/mod.rs
  • Confirmed presence of the component implementation using appropriate imports and structure

Everything looks good.

packages/main-ui/public/main.css (2)

7-9: LGTM - Good browser compatibility approach.

The added CSS properties for hiding scrollbars across different browsers (IE/Edge, Firefox) and adding smooth scrolling create a consistent user experience.


12-14: LGTM - Completes the scrollbar hiding approach.

This WebKit-specific rule complements the other browser-specific rules to ensure scrollbars are hidden across all major browsers.

packages/main-ui/src/components/icons/x.rs (1)

1-21: LGTM - Well-structured icon component.

The X icon component is properly implemented as a Dioxus component. It correctly accepts customizable attributes and renders an SVG with appropriate dimensions and path data.

packages/main-ui/src/main.rs (5)

28-28: LGTM - CSS inclusion.

Including the input.css content for use with Tailwind is a good approach for managing styles.


45-61: LGTM - Improved favicon support.

The addition of multiple favicon formats and sizes improves cross-browser and cross-device compatibility, which is a good practice for web applications.


70-71: LGTM - Updated Tailwind integration.

The new Tailwind script source and the addition of the style element properly set up Tailwind CSS for the application.


24-26:

Details

❓ Verification inconclusive

Verify the impact of commented service initializations.

These service initializations have been commented out, which might cause the application to behave unexpectedly if other components depend on these services being initialized.


🏁 Script executed:

#!/bin/bash
# Check if these services are initialized elsewhere
echo "Checking for other initializations of Theme..."
rg "Theme::init" --type rust --glob "!src/main.rs"

echo "Checking for other initializations of UserService..."
rg "UserService::init" --type rust --glob "!src/main.rs"

echo "Checking for other initializations of PopupService..."
rg "PopupService::init" --type rust --glob "!src/main.rs"

Length of output: 785


Ensure Service Dependencies Are Explicitly Managed

  • Theme & PopupService: The search confirms that both Theme::init() and PopupService::init() only appear as commented lines in packages/main-ui/src/main.rs and are not initialized elsewhere in the codebase. This raises concerns if other components depend on these services.
  • UserService: While UserService::init() is also commented out in main.rs, a debug log referencing it appears in packages/main-ui/src/services/user_service.rs. Please verify if this debug output indicates that the service is effectively initialized elsewhere or if an explicit initialization call is still required.

Please review and confirm that the commented-out initializations are intentional and that all dependent components function correctly without these explicit service calls.


9-12:

Details

✅ Verification successful

Verify the impact of commented service imports.

The service imports have been commented out, which may affect functionality if these services are still being used elsewhere in the application.


🏁 Script executed:

#!/bin/bash
# Search for usages of the commented services in the codebase
echo "Searching for Theme usage..."
rg "Theme::" --type rust -A 2 -B 2 --glob "!src/main.rs"

echo "Searching for UserService usage..."
rg "UserService::" --type rust -A 2 -B 2 --glob "!src/main.rs"

echo "Searching for PopupService usage..."
rg "PopupService::" --type rust -A 2 -B 2 --glob "!src/main.rs"

Length of output: 11671


Review Verification: Confirming Intentional Removal of Service Initialization in main.rs

After searching the codebase, I found the following:

  • Theme: Although references to Theme exist in packages/main-ui/src/theme.rs, the commented call to Theme::init() in packages/main-ui/src/main.rs does not appear elsewhere. This suggests that explicit initialization here is no longer required.
  • UserService: The code in packages/main-ui/src/services/user_service.rs actively uses UserService methods. The commented UserService::init() in main is not interfering with these calls, indicating that its initialization is likely handled internally or deemed unnecessary in the main entry point.
  • PopupService: Aside from the commented PopupService::init() in packages/main-ui/src/main.rs, there are no active usages found. Its removal appears safe.

Please confirm that these changes are intentional and that alternative initialization (if needed) is managed elsewhere in the application.

packages/main-ui/src/pages/components/about.rs (1)

1-22: LGTM - Well-structured component.

The About component follows Dioxus best practices with proper handling of language, attributes, and children elements.

packages/main-ui/src/components/icons/logos/bsky.rs (1)

5-34: Well-structured SVG component implementation

The Bsky logo component follows Dioxus best practices with proper props definition using the #[props(extends = GlobalAttributes)] pattern, allowing for flexible customization. The SVG structure is clean with appropriate dimensions, viewBox, and clipping path definition.

Cargo.toml (1)

9-9:

Details

✅ Verification successful

Verify Rust edition 2024 compatibility

Rust edition 2024 is not yet officially released as of early 2024. This might cause compatibility issues with build tools and dependencies.


🌐 Web query:

Is Rust edition 2024 available for stable Rust yet?

💡 Result:

Yes, the Rust 2024 Edition became available on the stable channel with the release of Rust 1.85.0 on February 20, 2025 [2][5][7]. This marks the fourth edition of Rust, following the 2015, 2018, and 2021 editions, and introduces several language, tooling, and ecosystem improvements while maintaining backward compatibility.

Key Details

  • Release Timeline
    • Entered beta testing on January 9, 2025 [4]
    • Stabilized and shipped with Rust 1.85.0 on February 20, 2025 [5][7]
  • Major Features
    • Async closures (async || {}) for simplified asynchronous programming [2][7]
    • Improved lifetime capture rules for impl Trait and RPIT (return-position impl Trait) [1][7]
    • Temporary scope adjustments for if let and tail expressions [1][7]
    • Reserved keywords (e.g., gen) for future language features [1][5]
    • Diagnostic control via #[diagnostic::do_not_recommend] to suppress misleading compiler suggestions [2][5]
  • Migration
    • Automated via cargo fix --edition [3][6]
    • Requires setting edition = "2024" in Cargo.toml [3][7]
    • Allows incremental adoption with compatibility lints [6]

Ecosystem Impact

  • Cargo now considers rust-version during dependency resolution [5][7].
  • Rustfmt introduces "style editions" for independent formatting rules [5][7].
  • The standard library adds Future/IntoFuture to the prelude and supports FromIterator/Extend for tuples [5][7].

For projects upgrading, the Rust team recommends testing on nightly/beta first and addressing warnings incrementally [6]. While most changes are automated, some manual adjustments (e.g., macro expansions) may be needed [6][7].

Citations:


Validated: Rust 2024 Edition is stable

The Rust 2024 Edition is now officially available on the stable channel (Rust 1.85.0, released on February 20, 2025). Specifying edition = "2024" in your Cargo.toml is correct and should not cause any compatibility issues.

packages/main-ui/src/components/icons/mod.rs (1)

23-25: LGTM: Clean extension of icon component modules

The addition of new icon modules (bsky, telegram, x) and their public exports follows the established pattern of the file, maintaining consistency with the existing structure.

Also applies to: 28-28, 43-43, 46-46

packages/main-ui/src/pages/page.rs (1)

11-16: Streamlined page structure with new landing page components

The new HomePage implementation uses a clean, vertical flex layout with distinct section components that create a better landing page experience.

packages/main-ui/src/pages/layout.rs (1)

71-72: Confirm that the layout incorporates the new header design.
Ensure that all updated header props, including changed translation keys or styling, are correctly applied and tested.

packages/main-ui/Makefile (2)

30-30: Improved build process by adding clean step.

Adding the clean target as a prerequisite ensures that previous build artifacts are removed before building, preventing potential issues with stale files. This is a good practice for maintaining consistent build outputs.


39-40:

Details

❓ Verification inconclusive

Enabled Tailwind CSS generation.

You've activated the Tailwind CSS generation that was previously disabled. This suggests that the CSS reading bug mentioned in the previous commented code has been resolved, which will provide proper styling for the application.


🏁 Script executed:

#!/bin/bash
# Check if tailwindcss is available and its version
command -v tailwindcss && tailwindcss --version

Length of output: 24


Attention: Manual Verification Required for Tailwind CSS Environment

The change in the Makefile to enable Tailwind CSS generation (lines 39–40) appears correct. However, the verification command (command -v tailwindcss && tailwindcss --version) produced no output, which means we cannot confirm from this test alone that Tailwind CSS is installed and returning its version correctly.

  • Please manually verify (or re-run diagnostic commands) to ensure that:
    • The tailwindcss binary is installed and accessible in the environment.
    • Running tailwindcss --version produces the expected version output.
  • Once you confirm the Tailwind CSS installation, it will ensure that the CSS generation works as intended and that the previous CSS-related issues are resolved.
packages/main-ui/src/pages/mod.rs (1)

2-2: Added new components module.

The addition of the components module indicates a good step toward better code organization. This likely contains UI components used across multiple pages.

Comment on lines +1 to +35
#![allow(non_snake_case)]
use dioxus::prelude::*;

#[component]
pub fn Telegram(#[props(extends = GlobalAttributes)] attributes: Vec<Attribute>) -> Element {
rsx! {
div {..attributes,
svg {
fill: "none",
height: "29",
view_box: "0 0 29 29",
width: "29",
xmlns: "http://www.w3.org/2000/svg",
g { clip_path: "url(#clip0_218_854)",
path {
clip_rule: "evenodd",
d: "M28.25 14.0183C28.25 21.7503 21.982 28.0183 14.25 28.0183C6.51801 28.0183 0.25 21.7503 0.25 14.0183C0.25 6.28632 6.51801 0.0183105 14.25 0.0183105C21.982 0.0183105 28.25 6.28632 28.25 14.0183ZM14.7517 10.3537C13.39 10.9201 10.6685 12.0924 6.58721 13.8705C5.92447 14.1341 5.5773 14.3919 5.5457 14.644C5.49228 15.0701 6.02583 15.2378 6.75238 15.4663C6.85121 15.4974 6.95361 15.5296 7.05859 15.5637C7.77341 15.796 8.73496 16.0679 9.23484 16.0787C9.68827 16.0885 10.1943 15.9015 10.7531 15.5179C14.5664 12.9438 16.5348 11.6428 16.6584 11.6147C16.7455 11.5949 16.8664 11.57 16.9482 11.6428C17.0301 11.7156 17.022 11.8533 17.0134 11.8903C16.9605 12.1156 14.8661 14.0628 13.7823 15.0704C13.4444 15.3845 13.2048 15.6073 13.1558 15.6582C13.046 15.7722 12.9341 15.88 12.8266 15.9837C12.1626 16.6239 11.6646 17.1039 12.8542 17.8879C13.4259 18.2646 13.8834 18.5762 14.3398 18.887C14.8382 19.2264 15.3353 19.565 15.9785 19.9866C16.1424 20.094 16.2989 20.2056 16.4514 20.3143C17.0314 20.7278 17.5525 21.0993 18.1964 21.04C18.5704 21.0056 18.9569 20.6539 19.1531 19.6047C19.6169 17.1253 20.5286 11.7532 20.7393 9.53945C20.7577 9.3455 20.7345 9.09728 20.7158 8.98831C20.6972 8.87935 20.6582 8.7241 20.5166 8.60918C20.3489 8.47307 20.0899 8.44437 19.9741 8.44641C19.4475 8.45568 18.6396 8.7366 14.7517 10.3537Z",
fill: "white",
fill_rule: "evenodd",
}
}
defs {
clipPath { id: "clip0_218_854",
rect {
fill: "white",
height: "28",
transform: "translate(0.25 0.0183105)",
width: "28",
}
}
}
}
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Duplicate Telegram component

This Telegram component is identical to the one in packages/main-ui/src/components/icons/logos/telegram.rs, which creates potential maintenance issues.

Having the same component in two different locations can cause confusion and maintenance problems. Consider:

  1. Keeping only one implementation (preferably in the logos directory for consistency)
  2. If both are needed, refactor to have one implementation that's imported by the other
# Option 1: Remove this file and use only the one in logos/

# Option 2: If both locations are needed for backward compatibility
#![allow(non_snake_case)]
use dioxus::prelude::*;
- // Current implementation
+ // Re-export from logos
+ pub use super::logos::telegram::Telegram;

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +16 to +23
// #[nest("/topics")]
// #[route("/")]
// TopicsPage { lang: Language },
// #[route("/new?:step&:legislation_id")]
// NewTopicPage { lang: Language, step: NewTopicStep, legislation_id: QueryParam<String> },
// #[route("/:id")]
// TopicsByIdPage { id: String, lang: Language },
// #[end_nest]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify that removed routes won't cause issues elsewhere in the codebase

Multiple route sections have been commented out rather than deleted. While this approach helps preserve the code for future use, ensure that there are no references to these routes elsewhere in the codebase that might cause runtime errors or broken navigation.

Also applies to: 25-34


🏁 Script executed:

#!/bin/bash
# Look for potential references to the commented-out routes in the codebase
echo "Searching for references to commented-out routes..."
rg -i "PoliticianStatusPage|TopicsPage|NewTopicPage|TopicsByIdPage|PatronsPage|NewPatronPage|PatronsLoginPage|PatronsByIdPage" --type rust

Length of output: 2473


Attention: Inconsistent Route Removal Impacting Navigation

The commented-out routes in packages/main-ui/src/route.rs (lines 16–23 and 25–34) are still being referenced across the codebase—for example, in pages/topics/page.rs and pages/menus.rs. This discrepancy could lead to runtime errors or broken navigation if these route variants are expected at runtime.

  • Verify if the routes (e.g., TopicsPage, NewTopicPage, TopicsByIdPage) should indeed be removed.
  • If they are being intentionally deprecated, update or remove all corresponding references (e.g., in pages/menus.rs, pages/topics/page.rs, etc.) to ensure consistency and prevent runtime failures.

by-types.workspace = true
by-components.workspace = true
wallet-adapter = "1.0.4-beta"
wallet-adapter = "=1.0.4-beta"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify the need for strict version pinning

You've changed the wallet-adapter version from "1.0.4-beta" to "=1.0.4-beta", enforcing an exact version match. While this improves build reproducibility, it also means you won't automatically get compatible bugfixes. Consider documenting the reason for this strict version requirement.


🌐 Web query:

Is Rust edition 2024 officially released?

💡 Result:

Yes, the Rust 2024 Edition was officially released on February 20, 2025, alongside Rust version 1.85.0[7][19]. This marks the fourth major edition of Rust, following the 2015, 2018, and 2021 editions. Key highlights include:

Key Features

  • Async closures (async || {}) for seamless concurrency[3][7][13].
  • Improved temporary variable handling in if let and match expressions[7][15].
  • Stricter safety rules for unsafe blocks and attributes[3][7].
  • Enhanced standard library with traits like Future and IntoFuture in the prelude[3][7].
  • Rustfmt style editions for independent control of formatting rules[3][7].

Migration

  • Automated via cargo fix --edition, though manual adjustments may be needed for semantic changes[7][15].
  • Projects can opt in by setting edition = "2024" in Cargo.toml[10][15].

Release Timeline

  • Beta channel: January 9, 2025[10].
  • Stabilization: February 20, 2025[7][10].

This edition focuses on ergonomic improvements, safety, and tooling enhancements while maintaining backward compatibility[3][5][7]. For full details, see the Edition Guide[19].

Citations:


Action Required: Document the Rationale for Strict Version Pinning

You've updated the wallet-adapter dependency to use an exact version ("=1.0.4-beta") which guarantees build reproducibility but prevents automatic adoption of compatible bugfixes. Please add an inline comment in packages/main-ui/Cargo.toml explaining why this strict version requirement is necessary.

Additionally, note that Rust edition 2024 is officially released (February 20, 2025) and its usage here is valid.

Comment on lines +4 to +5
font-family: Railway, sans-serif !important;
background-color: var(--color-background);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

❓ Verification inconclusive

Font inconsistency detected.

The font-family has been changed to "Railway, sans-serif" but the NanumSquare import statement at line 1 is still present. Additionally, there's no visible import for the Railway font. The font name might also be misspelled - did you mean "Raleway" which is a common web font?

-  font-family: Railway, sans-serif !important;
+  font-family: Raleway, sans-serif !important;

Also consider adding the Raleway font import:

@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@300;400;500;600;700&display=swap');

Action: Resolve Font Import Inconsistencies in main.css

The font-family is currently set to "Railway, sans-serif", which appears to be a typo and should likely be "Raleway, sans-serif". Additionally, the file still includes the NanumSquare import at line 1, even though it isn’t used. Please address the following:

  • Correct the Font Family:
    Replace:
    -  font-family: Railway, sans-serif !important;
    +  font-family: Raleway, sans-serif !important;
  • Update / Remove Font Imports:
    • Remove the unused NanumSquare import (if Raleway is the intended font).
    • Add the appropriate Raleway font import, for example:
    @import url('https://fonts.googleapis.com/css2?family=Raleway:wght@300;400;500;600;700&display=swap');

These changes will ensure the correct font is imported and applied across the UI.

Comment on lines +24 to +31
translate! {
AboutTranslate;

title: {
ko: "About",
en: "About",
},
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify Korean translation.

The Korean translation for "About" is currently identical to the English version. Verify if this is intentional or if it should be translated to Korean.


🌐 Web query:

How to say "About" in Korean?

💡 Result:

When expressing "about" in Korean, the translation depends on the context—whether discussing a topic, conversation, or approximation. Here are the primary methods:

1. Using "~에 대해(서)" for General Topics

This structure is used to indicate "about" or "regarding" a subject. It’s formal and commonly used in writing or formal speech.

  • Example:
    • 고구마에 대해서 말했어요. ("I talked about sweet potatoes.") [2]
    • 한국 역사에 대해 공부했어요. ("I studied about Korean history.") [11]

2. Using "이야기/얘기" (Story/Conversation)

For casual conversations, 이야기 (or its shortened form 얘기) is often used to mean "about." It’s more natural in spoken Korean.

  • Example:
    • 한국에서 사는 이야기를 했어요. ("We talked about living in Korea.") [1]
    • 고구마 먹는 얘기 했어요. ("We talked about eating sweet potatoes.") [2]

3. Using "내용" (Content) with Adjectives

내용 (meaning "content") pairs with adjectives to describe what something is about.

  • Example:
    • 영화 내용이 뭐예요? ("What is the movie about?") [1]
    • 이 책 내용은 어려워요. ("This book’s content is hard" → "This book is about something complex.") [1]

4. Approximation with "정도" or "쯤"

For quantities or time, use 정도 or to mean "about" or "approximately."

  • Example:
    • 10분 정도 걸려요. ("It takes about 10 minutes.") [4]
    • 3시 쯤 만나요. ("Let’s meet around 3 o’clock.") [4]

Key Differences

  • Formality:
    • ~에 대해(서) is formal and textbook-style.
    • 이야기/내용 is colloquial and preferred in everyday speech.
  • Context:
    • Use 이야기 for conversations (e.g., "talking about X").
    • Use ~에 대해 for broader topics (e.g., "a book about science").

For instance, saying "우리 고구마 먹는 얘기했어" (casual) vs. "고구마에 대해 논의했어요" (formal) changes tone but not meaning[1][2].

By choosing the right structure based on context and formality, you can accurately convey "about" in Korean.

Citations:


Action Required: Update Korean Translation for the "About" Page

The current translation keeps both versions as "About." In typical web UI contexts, the "About" page is rendered in Korean as "소개." Please update the code accordingly unless there's a specific reason to retain the English term. Consider modifying the Korean entry in the translation block (located in packages/main-ui/src/pages/components/about.rs, lines 24–31) from "About" to "소개".

Comment thread Cargo.toml
Comment on lines +40 to +41
dioxus = { version = "0.6.3", git = "https://github.com/hackartists/dioxus.git" }
dioxus-web = { version = "0.6.3", git = "https://github.com/hackartists/dioxus.git" }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Dependency sourced from fork instead of official repository

The project is using a fork of Dioxus rather than the official repository. This introduces potential maintenance and compatibility risks:

  1. No specific branch or commit is specified, meaning it will use the default branch's latest commit
  2. Any changes in the fork that diverge from official Dioxus may lead to upgrade difficulties

🏁 Script executed:

#!/bin/bash
# Check the status of the fork compared to upstream
echo "Checking fork status compared to official Dioxus repo..."
git ls-remote https://github.com/hackartists/dioxus.git | grep HEAD
git ls-remote https://github.com/dioxuslabs/dioxus.git | grep HEAD

# Check version specified in the package's Cargo.toml
if [ -f "packages/main-ui/Cargo.toml" ]; then
  echo "Checking Dioxus version in main-ui package:"
  grep -A 3 "dioxus.*=" packages/main-ui/Cargo.toml
fi

Length of output: 957


Action Required: Resolve Dependency Source and Version Pinning

The Dioxus dependency in lines 40–41 of Cargo.toml is being sourced from a fork (hackartists/dioxus) rather than the official repository (dioxuslabs/dioxus). This setup poses the following risks:

  • Unpinned Reference: No specific branch or commit is specified. As a result, it automatically tracks the fork's default branch (currently at commit 4838a4412d9c7f445f34baeca78e0585dd8ada7a), which may introduce unreviewed changes over time.
  • Maintenance and Compatibility Issues: Divergences between the fork and the official repository (HEAD in the official repo is 8b4ccb7817a98379eff2f348f55bbd84f9f12ea3) could lead to upgrade difficulties and compatibility issues.

Recommendations:

  • Explicitly Pin a Commit/Branch: Specify a specific commit or branch in your dependency declaration to ensure reproducible builds.
  • Consider Using the Official Repository: If possible, switch to the official Dioxus repository to reduce potential maintenance risks.

Comment on lines +41 to +45
button {
class: "bg-white hover:bg-secondary px-40 py-20 gap-10 flex items-center justify-center text-black font-bold text-base rounded-[10px]",
onclick: |_| {},
{tr.btn_learn}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Use the 'btn_join' translation for the second button.
Both buttons currently display {tr.btn_learn}. According to the translation keys, the second button should use {tr.btn_join} to match its intended functionality.

-    {tr.btn_learn}
+    {tr.btn_join}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
button {
class: "bg-white hover:bg-secondary px-40 py-20 gap-10 flex items-center justify-center text-black font-bold text-base rounded-[10px]",
onclick: |_| {},
{tr.btn_learn}
}
button {
class: "bg-white hover:bg-secondary px-40 py-20 gap-10 flex items-center justify-center text-black font-bold text-base rounded-[10px]",
onclick: |_| {},
{tr.btn_join}
}

Comment on lines +7 to +8
children: Element,
onclick: EventHandler<()>,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Parameter 'children' is never rendered.
The component takes a children: Element prop but doesn’t use it in rsx!. Embed or remove it to maintain clarity.

 pub fn BottomSheet(
     #[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
-    children: Element,
     onclick: EventHandler<()>,
 ) -> Element {
     ...
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
children: Element,
onclick: EventHandler<()>,
pub fn BottomSheet(
#[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
onclick: EventHandler<()>,
) -> Element {
...
}

Comment on lines +16 to +18
// pub use patrons::*;
// pub use politicians::*;
// pub use topics::*;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Review public API changes for potential breaking changes.

Commenting out these public exports may break existing code that depends on these modules. Ensure that all code that previously used these exported items has been updated to use the new structure.


🏁 Script executed:

#!/bin/bash
# Search for usage of previously public modules that are now commented out
echo "Searching for usages of previously public modules:"
rg -l "patrons::|politicians::|topics::" --type rust

Length of output: 282


Action Required: Update Public API Exports

It appears that the previously public modules are still in use in several parts of the codebase:

  • packages/main-ui/src/pages/patrons/_id/login_page.rs
  • packages/main-ui/src/pages/mod.rs
  • packages/main-api/src/main.rs

Commenting out these re-exports without updating the dependent code will likely lead to breaking changes. Please verify that all references to these modules in the listed files (and any other affected areas) have been updated to the new structure. If these modules are still needed as part of the public API, consider either restoring the exports or providing an alternative and deprecating the old usage correctly.

+ Introduced ~Indicator~ component for displaying indicators.
+ Added ~MissionCard~ component to showcase mission details.
+ Updated ~About~ page to include new components.
+ Enhanced ~RootLayout~ with ~MetaSeoTemplate~ for SEO improvements.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (10)
packages/main-ui/src/pages/components/mission_card.rs (2)

14-14: Consider extracting hardcoded values to CSS variables or constants.

The component uses multiple hardcoded values for styling like colors (bg-[#1A1A1A], text-[#DEE1E6]) and spacing (px-30, py-40). For better maintainability and consistency, consider extracting these to CSS variables or Rust constants.

- div { class: "px-30 py-40 bg-[#1A1A1A] w-full h-full flex flex-col items-start justify-between text-[#DEE1E6] rounded-[15px]",
+ div { class: "px-30 py-40 bg-card w-full h-full flex flex-col items-start justify-between text-card-text rounded-[15px]",

1-24: Add documentation for the component.

This component lacks documentation. Consider adding a doc comment to explain its purpose, parameters, and usage examples.

#![allow(non_snake_case)]
use dioxus::prelude::*;

+/// A card component that displays mission information.
+/// 
+/// # Parameters
+/// - `no`: The mission number (e.g., "01.")
+/// - `title`: The mission title
+/// - `description`: The mission description
+/// - `attributes`: Additional HTML attributes to apply to the outer div
+/// 
+/// # Example
+/// ```
+/// MissionCard {
+///     class: "col-span-1",
+///     no: "01.",
+///     title: "Mission Title",
+///     description: "Mission description goes here",
+/// }
+/// ```
#[component]
pub fn MissionCard(
    no: String,
    title: String,
    description: String,

    #[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
) -> Element {
packages/main-ui/src/components/indicators/mod.rs (2)

1-12: Add documentation for the Indicator component.

The component lacks documentation explaining its purpose and usage. Consider adding a doc comment to improve code maintainability.

#![allow(non_snake_case)]
use dioxus::prelude::*;

+/// A component that displays a circular indicator followed by content.
+/// 
+/// # Parameters
+/// - `children`: The content to display after the indicator
+/// 
+/// # Example
+/// ```
+/// Indicator { "Section Title" }
+/// ```
#[component]
pub fn Indicator(children: Element) -> Element {

8-8: Consider making indicator size configurable.

The indicator has hardcoded dimensions (w-12 h-12). To improve reusability, consider making the size configurable through an optional parameter.

#[component]
-pub fn Indicator(children: Element) -> Element {
+pub fn Indicator(
+    children: Element,
+    #[props(default = "12")] size: &'static str,
+) -> Element {
    rsx! {
        div { class: "flex flex-row items-center gap-5 text-primary font-bold text-sm",
-            div { class: "w-12 h-12 bg-primary rounded-full" }
+            div { class: "w-{size} h-{size} bg-primary rounded-full" }
            {children}
        }
    }
}
packages/main-ui/src/pages/components/mod.rs (1)

10-16: Use wildcard imports selectively.

The current approach of using pub use module::* for all modules makes it difficult to track which components come from which modules. Consider being more explicit about which components you're re-exporting.

-pub use about::*;
-pub use bottom_sheet::*;
-pub use community::*;
-pub use header::*;
-pub use mission_card::*;
-pub use politician_stance::*;
-pub use support::*;
-pub use top::*;
+pub use about::About;
+pub use bottom_sheet::BottomSheet;
+pub use community::Community;
+pub use header::Header;
+pub use mission_card::MissionCard;
+pub use politician_stance::PoliticianStance;
+pub use support::Support;
+pub use top::Top;

Alternatively, if you need to export multiple items from each module, consider using more specific import syntax:

pub use about::{About, AboutTranslate};
packages/main-ui/src/pages/layout.rs (5)

3-3: Verify if PopupZone is still needed.

The import for PopupZone is commented out rather than removed. If this component is no longer used, consider removing the commented import for cleaner code.

-// use dioxus_popup::PopupZone;

12-48: Replace magic numbers with named constants.

The scroll position threshold calculation uses magic numbers (0.7, 1.7, 2.7, etc.) which makes the code less maintainable and harder to understand. Consider defining these as named constants with descriptive names.

pub fn RootLayout(lang: Language) -> Element {
+    const SECTION_1_THRESHOLD: f64 = 0.7;
+    const SECTION_2_THRESHOLD: f64 = 1.7;
+    const SECTION_3_THRESHOLD: f64 = 2.7;
+    const SECTION_4_THRESHOLD: f64 = 3.7;
+    const SECTION_5_THRESHOLD: f64 = 4.1;

    #[cfg(feature = "web")]
    let mut scroll_position = use_signal(|| 0.0);
    let selected = use_memo(move || {
        // Rest of the code...
        
-        let i = if y < height * 0.7 {
+        let i = if y < height * SECTION_1_THRESHOLD {
             0
-        } else if y < height * 1.7 {
+        } else if y < height * SECTION_2_THRESHOLD {
             1
-        } else if y < height * 2.7 {
+        } else if y < height * SECTION_3_THRESHOLD {
             2
-        } else if y < height * 3.7 {
+        } else if y < height * SECTION_4_THRESHOLD {
             3
-        } else if y <= height * 4.1 {
+        } else if y <= height * SECTION_5_THRESHOLD {
             4
         } else {
             5
         };

70-79: SEO keywords could be optimized.

The current list of keywords is quite long and contains comma-separated phrases. For better SEO, consider using fewer, more targeted keywords.

MetaSeoTemplate {
    lang,
    title: "Ratel",
-    keywords: "ratel, crypto, policy, south korea, ecosystem, politicians, supportive policies, track, crypto stances, vote, legislation, propose, DAO-driven improvements, shape, thriving future, industry, democracy",
+    keywords: "ratel, crypto policy, ecosystem, blockchain governance, DAO, legislation tracking",
    author: "Ratel Foundation",
    url: "https://ratel.foundation",
    canonical: "https://ratel.foundation",
    logo_url: asset!("/public/logos/favicon-96x96.png"),
}

98-114: Consider adding reduced motion support.

The smooth scrolling implementation doesn't respect user preferences for reduced motion, which may cause accessibility issues for users who are sensitive to motion.

let script = format!(
-    "window.scrollTo({{ top: {next_position}, behavior: 'smooth' }});",
+    "window.scrollTo({{ top: {next_position}, behavior: window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth' }});",
);

98-114: Hardcoded section count should be a constant.

The value 5 is hardcoded in the condition selected() != 5, which makes the code less maintainable. Consider defining this as a named constant.

pub fn RootLayout(lang: Language) -> Element {
+    const TOTAL_SECTIONS: i32 = 5;

    // Rest of the code...
    
-    if selected() != 5 {
+    if selected() != TOTAL_SECTIONS {
        BottomSheet {
            // Implementation...
        }
    }
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a35eb9 and 77e50b9.

📒 Files selected for processing (7)
  • packages/main-ui/src/components/indicators/mod.rs (1 hunks)
  • packages/main-ui/src/components/mod.rs (1 hunks)
  • packages/main-ui/src/pages/components/about.rs (1 hunks)
  • packages/main-ui/src/pages/components/mission_card.rs (1 hunks)
  • packages/main-ui/src/pages/components/mod.rs (1 hunks)
  • packages/main-ui/src/pages/layout.rs (1 hunks)
  • packages/main-ui/src/pages/page.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/main-ui/src/components/mod.rs
  • packages/main-ui/src/pages/page.rs
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: main-api
🔇 Additional comments (3)
packages/main-ui/src/pages/components/about.rs (1)

64-65: Action Required: Update Korean Translation for the "About" Page

The current translation keeps both versions as "About." In typical web UI contexts, the "About" page is rendered in Korean as "소개." Please update the code accordingly unless there's a specific reason to retain the English term.

title: {
-    ko: "About",
+    ko: "소개",
    en: "About",
},
packages/main-ui/src/pages/layout.rs (2)

6-8: Imports structure looks good.

The imports are properly organized by component category and crate.


80-82: Good usage of selected value in header.

The Header component now receives the selected value, which will help with navigation highlighting.

Comment on lines +99 to +106
ko: "",
en:"Community-Driven Advocacy",
}

mission3_description: {
ko: "",
en:"Ratel funds initiatives that support regulatory clarity and industry-friendly policies.",
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add Korean translations for mission3.

The Korean translations for mission3 and its description are empty. This will lead to blank content for Korean users.

mission3: {
-    ko: "",
+    ko: "커뮤니티 주도 옹호활동",
    en:"Community-Driven Advocacy",
}

mission3_description: {
-    ko: "",
+    ko: "Ratel은 규제 명확성과 산업 친화적 정책을 지원하는 이니셔티브에 자금을 지원합니다.",
    en:"Ratel funds initiatives that support regulatory clarity and industry-friendly policies.",
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ko: "",
en:"Community-Driven Advocacy",
}
mission3_description: {
ko: "",
en:"Ratel funds initiatives that support regulatory clarity and industry-friendly policies.",
}
mission3: {
- ko: "",
+ ko: "커뮤니티 주도 옹호활동",
en:"Community-Driven Advocacy",
}
mission3_description: {
- ko: "",
+ ko: "Ratel은 규제 명확성과 산업 친화적 정책을 지원하는 이니셔티브에 자금을 지원합니다.",
en:"Ratel funds initiatives that support regulatory clarity and industry-friendly policies.",
}

Comment on lines +30 to +55
div { class: "w-full grid grid-cols-4 gap-24",
MissionCard {
class: "col-span-1 w-full h-352",
no: "01.",
title: tr.mission1,
description: tr.mission1_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "02.",
title: tr.mission2,
description: tr.mission2_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "03.",
title: tr.mission3,
description: tr.mission3_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "04.",
title: tr.mission4,
description: tr.mission4_description,
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve responsiveness for mobile screens.

The mission cards are laid out in a 4-column grid, which would stack poorly on mobile devices. Consider adding responsive design classes to adjust the layout on smaller screens.

-div { class: "w-full grid grid-cols-4 gap-24",
+div { class: "w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-24",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
div { class: "w-full grid grid-cols-4 gap-24",
MissionCard {
class: "col-span-1 w-full h-352",
no: "01.",
title: tr.mission1,
description: tr.mission1_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "02.",
title: tr.mission2,
description: tr.mission2_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "03.",
title: tr.mission3,
description: tr.mission3_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "04.",
title: tr.mission4,
description: tr.mission4_description,
}
}
div { class: "w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-24",
MissionCard {
class: "col-span-1 w-full h-352",
no: "01.",
title: tr.mission1,
description: tr.mission1_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "02.",
title: tr.mission2,
description: tr.mission2_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "03.",
title: tr.mission3,
description: tr.mission3_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "04.",
title: tr.mission4,
description: tr.mission4_description,
}
}

Comment on lines +89 to +96
ko: "",
en:"Politician Stance Tracking",
}

mission2_description: {
ko: "",
en:"We analyze lawmakers' positions on crypto and ensure accountability.",
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add Korean translations for mission2.

The Korean translations for mission2 and its description are empty. This will lead to blank content for Korean users.

mission2: {
-    ko: "",
+    ko: "정치인 입장 추적",
    en:"Politician Stance Tracking",
}

mission2_description: {
-    ko: "",
+    ko: "우리는 입법자들의 암호화폐에 대한 입장을 분석하고 책임을 보장합니다.",
    en:"We analyze lawmakers' positions on crypto and ensure accountability.",
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ko: "",
en:"Politician Stance Tracking",
}
mission2_description: {
ko: "",
en:"We analyze lawmakers' positions on crypto and ensure accountability.",
}
ko: "정치인 입장 추적",
en:"Politician Stance Tracking",
}
mission2_description: {
ko: "우리는 입법자들의 암호화폐에 대한 입장을 분석하고 책임을 보장합니다.",
en:"We analyze lawmakers' positions on crypto and ensure accountability.",
}

Comment on lines +79 to +85
ko: "",
en:"Decentralized Governance (DAO)",
}
mission1_description: {
ko: "",
en:"The Ratel DAO enables anyone to propose and vote on crypto policy initiatives.",
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add Korean translations for mission1.

The Korean translations for mission1 and its description are empty. This will lead to blank content for Korean users.

mission1: {
-    ko: "",
+    ko: "탈중앙화 거버넌스 (DAO)",
    en:"Decentralized Governance (DAO)",
}
mission1_description: {
-    ko: "",
+    ko: "Ratel DAO는 누구나 암호화폐 정책 이니셔티브를 제안하고 투표할 수 있게 합니다.",
    en:"The Ratel DAO enables anyone to propose and vote on crypto policy initiatives.",
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ko: "",
en:"Decentralized Governance (DAO)",
}
mission1_description: {
ko: "",
en:"The Ratel DAO enables anyone to propose and vote on crypto policy initiatives.",
}
mission1: {
- ko: "",
+ ko: "탈중앙화 거버넌스 (DAO)",
en:"Decentralized Governance (DAO)",
}
mission1_description: {
- ko: "",
+ ko: "Ratel DAO는 누구나 암호화폐 정책 이니셔티브를 제안하고 투표할 수 있게 합니다.",
en:"The Ratel DAO enables anyone to propose and vote on crypto policy initiatives.",
}

Comment on lines +109 to +116
ko: "",
en:"Community Participation-Based Token Distribution",
}

mission4_description: {
ko: "",
en:"Supporters receive RATEL tokens in return for their contributions, allowing them to participate in governance.",
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add Korean translations for mission4.

The Korean translations for mission4 and its description are empty. This will lead to blank content for Korean users.

mission4: {
-    ko: "",
+    ko: "커뮤니티 참여 기반 토큰 분배",
    en:"Community Participation-Based Token Distribution",
}

mission4_description: {
-    ko: "",
+    ko: "지지자들은 그들의 기여에 대한 보상으로 RATEL 토큰을 받아 거버넌스에 참여할 수 있습니다.",
    en:"Supporters receive RATEL tokens in return for their contributions, allowing them to participate in governance.",
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ko: "",
en:"Community Participation-Based Token Distribution",
}
mission4_description: {
ko: "",
en:"Supporters receive RATEL tokens in return for their contributions, allowing them to participate in governance.",
}
mission4: {
- ko: "",
+ ko: "커뮤니티 참여 기반 토큰 분배",
en:"Community Participation-Based Token Distribution",
}
mission4_description: {
- ko: "",
+ ko: "지지자들은 그들의 기여에 대한 보상으로 RATEL 토큰을 받아 거버넌스에 참여할 수 있습니다.",
en:"Supporters receive RATEL tokens in return for their contributions, allowing them to participate in governance.",
}

Comment on lines +1 to +58
#![allow(non_snake_case)]
use dioxus::prelude::*;
use dioxus_translate::*;

use crate::{components::indicators::Indicator, pages::components::mission_card::MissionCard};

#[component]
pub fn About(lang: Language) -> Element {
let tr: AboutTranslate = translate(&lang);

rsx! {
div {
id: "about",
class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
div { class: "w-full flex flex-col justify-start items-start gap-20",
Indicator { {tr.title} }
div { class: "w-full grid grid-cols-2 gap-24",
h1 { class: "w-full col-span-1 text-[32px] font-bold text-white",
{tr.mission}
}
div { class: "col-span-1 w-full h-full flex flex-col items-center justify-center",
div { class: "w-full h-1 bg-[#464646]" }
}
p { class: "col-span-1 w-full text-white font-normal text-[15px]/22 text-[#AEAEAE] whitespace-pre-line",
{tr.description}
}
}
}

div { class: "w-full grid grid-cols-4 gap-24",
MissionCard {
class: "col-span-1 w-full h-352",
no: "01.",
title: tr.mission1,
description: tr.mission1_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "02.",
title: tr.mission2,
description: tr.mission2_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "03.",
title: tr.mission3,
description: tr.mission3_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "04.",
title: tr.mission4,
description: tr.mission4_description,
}
}
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for incomplete translations.

The component doesn't handle the case where translations are missing (as is currently the case for Korean mission translations). Consider adding fallback logic to prevent displaying empty content.

#![allow(non_snake_case)]
use dioxus::prelude::*;
use dioxus_translate::*;

use crate::{components::indicators::Indicator, pages::components::mission_card::MissionCard};

#[component]
pub fn About(lang: Language) -> Element {
    let tr: AboutTranslate = translate(&lang);
+   
+   // Helper function to use English fallback when a translation is empty
+   let t = |ko: &str, en: &str| -> &str {
+       if lang == Language::Ko && ko.is_empty() {
+           en
+       } else if ko.is_empty() && en.is_empty() {
+           "Translation missing"
+       } else {
+           match lang {
+               Language::Ko => ko,
+               _ => en,
+           }
+       }
+   };

    rsx! {
        // ... existing code ...
        
        div { class: "w-full grid grid-cols-4 gap-24",
            MissionCard {
                class: "col-span-1 w-full h-352",
                no: "01.",
-               title: tr.mission1,
-               description: tr.mission1_description,
+               title: t(&tr.mission1.ko, &tr.mission1.en),
+               description: t(&tr.mission1_description.ko, &tr.mission1_description.en),
            }
            // Apply similar changes to other MissionCard instances
        }
    }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#![allow(non_snake_case)]
use dioxus::prelude::*;
use dioxus_translate::*;
use crate::{components::indicators::Indicator, pages::components::mission_card::MissionCard};
#[component]
pub fn About(lang: Language) -> Element {
let tr: AboutTranslate = translate(&lang);
rsx! {
div {
id: "about",
class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
div { class: "w-full flex flex-col justify-start items-start gap-20",
Indicator { {tr.title} }
div { class: "w-full grid grid-cols-2 gap-24",
h1 { class: "w-full col-span-1 text-[32px] font-bold text-white",
{tr.mission}
}
div { class: "col-span-1 w-full h-full flex flex-col items-center justify-center",
div { class: "w-full h-1 bg-[#464646]" }
}
p { class: "col-span-1 w-full text-white font-normal text-[15px]/22 text-[#AEAEAE] whitespace-pre-line",
{tr.description}
}
}
}
div { class: "w-full grid grid-cols-4 gap-24",
MissionCard {
class: "col-span-1 w-full h-352",
no: "01.",
title: tr.mission1,
description: tr.mission1_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "02.",
title: tr.mission2,
description: tr.mission2_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "03.",
title: tr.mission3,
description: tr.mission3_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "04.",
title: tr.mission4,
description: tr.mission4_description,
}
}
}
}
}
#![allow(non_snake_case)]
use dioxus::prelude::*;
use dioxus_translate::*;
use crate::{components::indicators::Indicator, pages::components::mission_card::MissionCard};
#[component]
pub fn About(lang: Language) -> Element {
let tr: AboutTranslate = translate(&lang);
// Helper function to use English fallback when a translation is empty
let t = |ko: &str, en: &str| -> &str {
if lang == Language::Ko && ko.is_empty() {
en
} else if ko.is_empty() && en.is_empty() {
"Translation missing"
} else {
match lang {
Language::Ko => ko,
_ => en,
}
}
};
rsx! {
div {
id: "about",
class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
div { class: "w-full flex flex-col justify-start items-start gap-20",
Indicator { {tr.title} }
div { class: "w-full grid grid-cols-2 gap-24",
h1 { class: "w-full col-span-1 text-[32px] font-bold text-white",
{tr.mission}
}
div { class: "col-span-1 w-full h-full flex flex-col items-center justify-center",
div { class: "w-full h-1 bg-[#464646]" }
}
p { class: "col-span-1 w-full text-white font-normal text-[15px]/22 text-[#AEAEAE] whitespace-pre-line",
{tr.description}
}
}
}
div { class: "w-full grid grid-cols-4 gap-24",
MissionCard {
class: "col-span-1 w-full h-352",
no: "01.",
title: t(&tr.mission1.ko, &tr.mission1.en),
description: t(&tr.mission1_description.ko, &tr.mission1_description.en),
}
// Apply similar changes to the remaining MissionCard instances as needed:
MissionCard {
class: "col-span-1 w-full h-352",
no: "02.",
title: tr.mission2,
description: tr.mission2_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "03.",
title: tr.mission3,
description: tr.mission3_description,
}
MissionCard {
class: "col-span-1 w-full h-352",
no: "04.",
title: tr.mission4,
description: tr.mission4_description,
}
}
}
}
}

Comment on lines +50 to +68
#[cfg(feature = "web")]
let _ = use_coroutine(move |_: UnboundedReceiver<()>| async move {
let script = r#"
window.addEventListener('scroll', () => {
dioxus.send(`${window.scrollY}`);
});
"#;
let mut eval = document::eval(script);

loop {
let y = eval
.recv::<String>()
.await
.unwrap_or_default()
.parse::<f64>()
.unwrap_or_default();
scroll_position.set(y);
}
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add cleanup for scroll event listener.

The current implementation adds an event listener but doesn't remove it when the component is unmounted, which could lead to memory leaks. Consider adding a cleanup mechanism.

#[cfg(feature = "web")]
let _ = use_coroutine(move |_: UnboundedReceiver<()>| async move {
    let script = r#"
        let scrollHandler = () => {
            dioxus.send(`${window.scrollY}`);
        };
        window.addEventListener('scroll', scrollHandler);
        
        // Return the handler for cleanup
        scrollHandler;
    "#;
    let mut eval = document::eval(script);
+   
+   // When coroutine drops, cleanup the event listener
+   defer! {
+       let cleanup_script = r#"
+           window.removeEventListener('scroll', LAST_EVAL_RESULT);
+       "#;
+       let _ = document::eval(cleanup_script);
+   }

    loop {
        let y = eval
            .recv::<String>()
            .await
            .unwrap_or_default()
            .parse::<f64>()
            .unwrap_or_default();
        scroll_position.set(y);
    }
});

Committable suggestion skipped: line range outside the PR's diff.

…omponents

Refactored ~About~, ~Community~, ~PoliticianStance~, and ~Support~ components to use the new ~SectionHeader~ component for consistent section headers. Updated translations and imports accordingly.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (10)
packages/main-ui/src/pages/components/support.rs (2)

8-23: Implement responsive design for mobile devices.

The component uses h-screen for height, which can cause issues on mobile devices when the content exceeds the viewport height. Additionally, the layout doesn't adjust well for very small screens.

- class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
+ class: "w-full max-w-1177 min-h-screen py-16 flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10 max-[640px]:gap-30",

25-42: Consider using translation constants instead of hardcoded strings.

Instead of using hardcoded strings like "Support" for translations, it's better to use constants defined in a central location. This makes it easier to maintain and update translations.

packages/main-ui/src/pages/components/section_header.rs (1)

20-34: Extract color values to theme variables.

Hard-coded color values like "#464646" and "#AEAEAE" make it difficult to maintain consistent styling. Consider using theme variables instead.

- div { class: "w-full h-1 bg-[#464646]" }
+ div { class: "w-full h-1 bg-divider" }

- p { class: "col-span-1 w-full text-white font-normal text-[15px]/22 text-[#AEAEAE] whitespace-pre-line",
+ p { class: "col-span-1 w-full text-white font-normal text-[15px]/22 text-secondary whitespace-pre-line",
packages/main-ui/src/pages/components/politician_stance.rs (1)

18-18: Implement responsive design for mobile devices.

Similar to the Support component, using h-screen can cause issues on mobile devices with limited viewport height.

- class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
+ class: "w-full max-w-1177 min-h-screen py-16 flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10 max-[640px]:gap-30",
packages/main-ui/src/pages/components/about.rs (1)

14-14: Implement responsive design for mobile devices.

Similar to other components, using h-screen might cause issues on mobile devices when content exceeds the viewport height.

- class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
+ class: "w-full max-w-1177 min-h-screen py-16 flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10 max-[640px]:gap-30",
packages/main-ui/src/pages/components/community.rs (3)

8-12: Component accepts unused children parameter.

The Community component accepts children: Element as a parameter but doesn't use it anywhere in the implementation. This could be misleading for developers trying to use this component.

Either remove the unused parameter:

pub fn Community(
    lang: Language,
    #[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
-    children: Element,
) -> Element {

Or incorporate the children into the component:

div {
    id: "community",
    class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
    SectionHeader {
        section_name: tr.title,
        title: tr.mission,
        description: tr.description,
    }

-    "Form"
+    {children}
}

10-10: Unused attributes parameter.

The component accepts attributes parameter but doesn't apply it to any element in the component.

Apply the attributes to the root element:

div {
    id: "community",
    class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
+    attributes: attributes,
    SectionHeader {

18-18: Consider breaking down long class string.

The class string is quite long which can make it difficult to read and maintain. Consider extracting it to a constant or using a class composition utility.

+const COMMUNITY_CONTAINER_CLASS: &str = "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10";

#[component]
pub fn Community(
    // ...
) -> Element {
    // ...
    rsx! {
        div {
            id: "community",
-            class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
+            class: COMMUNITY_CONTAINER_CLASS,
packages/main-ui/src/pages/components/mod.rs (2)

11-19: Consider more explicit imports instead of wildcard imports.

Using wildcard imports (pub use module::*) can lead to namespace pollution, especially as the number of components grows. Consider being more explicit about which components are being re-exported.

-pub use about::*;
-pub use bottom_sheet::*;
-pub use community::*;
-pub use header::*;
-pub use mission_card::*;
-pub use politician_stance::*;
-pub use section_header::*;
-pub use support::*;
-pub use top::*;
+pub use about::About;
+pub use bottom_sheet::BottomSheet;
+pub use community::Community;
+pub use header::Header;
+pub use mission_card::MissionCard;
+pub use politician_stance::PoliticianStance;
+pub use section_header::SectionHeader;
+pub use support::Support;
+pub use top::Top;

This approach makes it clearer which components are available and helps prevent unexpected conflicts.


1-9: Add module documentation.

Adding documentation comments to the module would help developers understand the purpose and organization of these components.

+//! Components for the landing page.
+//!
+//! This module contains all the components used to build the landing page sections.
+//! Each component is responsible for rendering a specific section of the landing page.
+
mod about;
mod bottom_sheet;
mod community;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 77e50b9 and 87a4bdf.

📒 Files selected for processing (6)
  • packages/main-ui/src/pages/components/about.rs (1 hunks)
  • packages/main-ui/src/pages/components/community.rs (1 hunks)
  • packages/main-ui/src/pages/components/mod.rs (1 hunks)
  • packages/main-ui/src/pages/components/politician_stance.rs (1 hunks)
  • packages/main-ui/src/pages/components/section_header.rs (1 hunks)
  • packages/main-ui/src/pages/components/support.rs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: main-api
🔇 Additional comments (5)
packages/main-ui/src/pages/components/about.rs (4)

21-46: Improve responsiveness for mobile screens.

The mission cards are laid out in a 4-column grid, which would stack poorly on mobile devices. Consider adding responsive design classes to adjust the layout on smaller screens.

-div { class: "w-full grid grid-cols-4 gap-24",
+div { class: "w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-24",

54-57: Update Korean Translation for the "About" Page.

The current translation keeps both versions as "About." In typical web UI contexts, the "About" page is rendered in Korean as "소개."

title: {
-    ko: "About",
+    ko: "소개",
    en: "About",
},

69-107: Add Korean translations for all missions.

The Korean translations for all four missions and their descriptions are empty. This will lead to blank content for Korean users.

mission1: {
-    ko: "",
+    ko: "탈중앙화 거버넌스 (DAO)",
    en:"Decentralized Governance (DAO)",
}
mission1_description: {
-    ko: "",
+    ko: "Ratel DAO는 누구나 암호화폐 정책 이니셔티브를 제안하고 투표할 수 있게 합니다.",
    en:"The Ratel DAO enables anyone to propose and vote on crypto policy initiatives.",
}

mission2: {
-    ko: "",
+    ko: "정치인 입장 추적",
    en:"Politician Stance Tracking",
}

mission2_description: {
-    ko: "",
+    ko: "우리는 입법자들의 암호화폐에 대한 입장을 분석하고 책임을 보장합니다.",
    en:"We analyze lawmakers' positions on crypto and ensure accountability.",
}

mission3: {
-    ko: "",
+    ko: "커뮤니티 주도 옹호활동",
    en:"Community-Driven Advocacy",
}

mission3_description: {
-    ko: "",
+    ko: "Ratel은 규제 명확성과 산업 친화적 정책을 지원하는 이니셔티브에 자금을 지원합니다.",
    en:"Ratel funds initiatives that support regulatory clarity and industry-friendly policies.",
}

mission4: {
-    ko: "",
+    ko: "커뮤니티 참여 기반 토큰 분배",
    en:"Community Participation-Based Token Distribution",
}

mission4_description: {
-    ko: "",
+    ko: "지지자들은 그들의 기여에 대한 보상으로 RATEL 토큰을 받아 거버넌스에 참여할 수 있습니다.",
    en:"Supporters receive RATEL tokens in return for their contributions, allowing them to participate in governance.",
}

8-49: Add error handling for incomplete translations.

The component doesn't handle the case where translations are missing (as is currently the case for Korean mission translations). Consider adding fallback logic to prevent displaying empty content.

#![allow(non_snake_case)]
use dioxus::prelude::*;
use dioxus_translate::*;

use super::*;

#[component]
pub fn About(lang: Language) -> Element {
    let tr: AboutTranslate = translate(&lang);
+   
+   // Helper function to use English fallback when a translation is empty
+   let t = |ko: &str, en: &str| -> &str {
+       if lang == Language::Ko && ko.is_empty() {
+           en
+       } else if ko.is_empty() && en.is_empty() {
+           "Translation missing"
+       } else {
+           match lang {
+               Language::Ko => ko,
+               _ => en,
+           }
+       }
+   };

    rsx! {
        // ... existing code ...
        
        div { class: "w-full grid grid-cols-4 gap-24",
            MissionCard {
                class: "col-span-1 w-full h-352",
                no: "01.",
-               title: tr.mission1,
-               description: tr.mission1_description,
+               title: t(&tr.mission1.ko, &tr.mission1.en),
+               description: t(&tr.mission1_description.ko, &tr.mission1_description.en),
            }
            // Apply similar changes to other MissionCard instances
        }
    }
}
packages/main-ui/src/pages/components/mod.rs (1)

1-19: LGTM - Good module organization.

The module structure follows good Rust practices for organizing components, making them easily accessible through the parent module.

Comment on lines +6 to +13
#[component]
pub fn SectionHeader(
section_name: String,
title: String,
description: String,
#[props(default = true)] with_line: bool,
children: Element,
) -> Element {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Unused children parameter.

The children parameter is defined but never used in the component implementation.

Either remove the unused parameter or use it in the component implementation:

#[component]
pub fn SectionHeader(
    section_name: String,
    title: String,
    description: String,
    #[props(default = true)] with_line: bool,
-    children: Element,
) -> Element {
    // ...
}

Or if you intended to use it, add it to the template.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#[component]
pub fn SectionHeader(
section_name: String,
title: String,
description: String,
#[props(default = true)] with_line: bool,
children: Element,
) -> Element {
#[component]
pub fn SectionHeader(
section_name: String,
title: String,
description: String,
#[props(default = true)] with_line: bool,
) -> Element {
// ...
}

Comment on lines +8 to +26
pub fn PoliticianStance(
lang: Language,
#[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
children: Element,
) -> Element {
let tr: PoliticianStanceTranslate = translate(&lang);

rsx! {
div {
id: "politician-stance",
class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
SectionHeader {
section_name: tr.title,
title: tr.mission,
description: tr.description,
}
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Unused children and attributes parameters.

The component defines children and attributes parameters but doesn't use them in the implementation.

Either remove the unused parameters or incorporate them into the component implementation:

#[component]
pub fn PoliticianStance(
    lang: Language,
-   #[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
-   children: Element,
) -> Element {
    let tr: PoliticianStanceTranslate = translate(&lang);

    rsx! {
        div {
            id: "politician-stance",
            class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
            SectionHeader {
                section_name: tr.title,
                title: tr.mission,
                description: tr.description,
            }
        }
    }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn PoliticianStance(
lang: Language,
#[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
children: Element,
) -> Element {
let tr: PoliticianStanceTranslate = translate(&lang);
rsx! {
div {
id: "politician-stance",
class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
SectionHeader {
section_name: tr.title,
title: tr.mission,
description: tr.description,
}
}
}
}
#[component]
pub fn PoliticianStance(
lang: Language,
) -> Element {
let tr: PoliticianStanceTranslate = translate(&lang);
rsx! {
div {
id: "politician-stance",
class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
SectionHeader {
section_name: tr.title,
title: tr.mission,
description: tr.description,
}
}
}
}

Comment on lines +15 to +27
rsx! {
div {
id: "community",
class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
SectionHeader {
section_name: tr.title,
title: tr.mission,
description: tr.description,
}

"Form"
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Placeholder text needs to be replaced.

The string "Form" appears to be a placeholder that should be replaced with the actual form implementation or content.

Replace the placeholder with the intended form component or content:

div {
    id: "community",
    class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
    SectionHeader {
        section_name: tr.title,
        title: tr.mission,
        description: tr.description,
    }

-    "Form"
+    // Implement the actual form component here
+    form {
+        // Form fields and submission logic
+    }
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
rsx! {
div {
id: "community",
class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
SectionHeader {
section_name: tr.title,
title: tr.mission,
description: tr.description,
}
"Form"
}
}
rsx! {
div {
id: "community",
class: "w-full max-w-1177 h-screen flex flex-col items-start justify-center gap-50 max-[1177px]:mx-10",
SectionHeader {
section_name: tr.title,
title: tr.mission,
description: tr.description,
}
// Implement the actual form component here
form {
// Form fields and submission logic
}
}
}

- Added btracing package to dependencies.
- Introduced EmailInput component for email subscriptions.
- Removed old Footer component and integrated new Footer with EmailInput.
- Updated Cargo.toml files to include btracing package.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
packages/main-ui/src/pages/layout.rs (1)

50-68: ⚠️ Potential issue

Add cleanup for scroll event listener

The current implementation adds an event listener but doesn't remove it when the component is unmounted, which could lead to memory leaks. Consider adding a cleanup mechanism.

#[cfg(feature = "web")]
let _ = use_coroutine(move |_: UnboundedReceiver<()>| async move {
    let script = r#"
        let scrollHandler = () => {
            dioxus.send(`${window.scrollY}`);
        };
        window.addEventListener('scroll', scrollHandler);
        
        // Return the handler for cleanup
        scrollHandler;
    "#;
    let mut eval = document::eval(script);
+   
+   // When coroutine drops, cleanup the event listener
+   defer! {
+       let cleanup_script = r#"
+           window.removeEventListener('scroll', LAST_EVAL_RESULT);
+       "#;
+       let _ = document::eval(cleanup_script);
+   }

    loop {
        let y = eval
            .recv::<String>()
            .await
            .unwrap_or_default()
            .parse::<f64>()
            .unwrap_or_default();
        scroll_position.set(y);
    }
});
🧹 Nitpick comments (5)
packages/main-ui/src/pages/components/footer.rs (2)

7-9: Unused translation variable in Footer component

The _tr variable is defined but never used in the rendering of the component, despite having translation strings defined below. Consider either:

  1. Removing the underscore prefix if you plan to use the translations
  2. Adding translation text to the footer content
-    let _tr: FooterTranslate = translate(&lang);
+    let tr: FooterTranslate = translate(&lang);

10-12: Incomplete CSS class for flexbox layout

The class "items-start" is used which is a flexbox alignment property, but there's no flex or display class to enable flexbox behavior for the container.

-        footer { class: "w-full items-start", EmailInput {} }
+        footer { class: "w-full flex items-start", EmailInput {} }
packages/main-ui/src/pages/components/mod.rs (2)

13-23: Consider more explicit imports rather than wildcard re-exports

Using wildcard re-exports (pub use module::*) makes all public items from these modules available, which is convenient but could potentially lead to name conflicts if multiple modules define items with the same name. Consider using more explicit re-exports for better maintainability and to avoid potential naming collisions.

-pub use about::*;
-pub use bottom_sheet::*;
+pub use about::{About, AboutProps};
+pub use bottom_sheet::{BottomSheet, BottomSheetProps};

This approach would make it clearer which components are available and reduce the risk of unexpected name conflicts.


24-24: Remove empty line at end of file

There appears to be an empty line (24) at the end of the file. Consider removing it for consistency.

packages/main-ui/src/pages/layout.rs (1)

3-3: Clean up commented-out code

If PopupZone is no longer needed, it's better to remove the commented-out import entirely rather than leaving it as a comment.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87a4bdf and 5e1fe57.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • Cargo.toml (3 hunks)
  • packages/main-ui/Cargo.toml (1 hunks)
  • packages/main-ui/src/components/footer/mod.rs (0 hunks)
  • packages/main-ui/src/components/mod.rs (1 hunks)
  • packages/main-ui/src/pages/components/email_input.rs (1 hunks)
  • packages/main-ui/src/pages/components/footer.rs (1 hunks)
  • packages/main-ui/src/pages/components/mod.rs (1 hunks)
  • packages/main-ui/src/pages/layout.rs (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/main-ui/src/components/footer/mod.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/main-ui/src/components/mod.rs
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: main-api
🔇 Additional comments (9)
packages/main-ui/Cargo.toml (2)

38-38: Document the rationale for strict version pinning

You've changed the wallet-adapter version from "1.0.4-beta" to "=1.0.4-beta", enforcing an exact version match. This improves build reproducibility but prevents automatic adoption of compatible bugfixes.

Please add an inline comment explaining why this strict version requirement is necessary.


40-40: LGTM: Adding the btracing workspace dependency

The addition of the btracing workspace dependency is appropriate as it's being used in the new EmailInput component for logging functionality.

Cargo.toml (3)

9-9: Verify Rust 2024 Edition compatibility

Updating to Rust edition 2024 adopts the latest language features, which is good, but ensure your toolchain is compatible and that all code has been migrated properly.


26-26: LGTM: Addition of btracing dependency

The addition of the btracing dependency is appropriate as it's being used in the new EmailInput component for logging.


41-42: Resolve dependency source and version pinning issues

The Dioxus dependencies are being sourced from a fork rather than the official repository, and no specific commit is pinned.

  1. Pin a specific commit to ensure build reproducibility:
-dioxus = { version = "0.6.3", git = "https://github.com/hackartists/dioxus.git" }
-dioxus-web = { version = "0.6.3", git = "https://github.com/hackartists/dioxus.git" }
+dioxus = { version = "0.6.3", git = "https://github.com/hackartists/dioxus.git", rev = "specific-commit-hash" }
+dioxus-web = { version = "0.6.3", git = "https://github.com/hackartists/dioxus.git", rev = "specific-commit-hash" }
  1. Consider switching to the official Dioxus repository to reduce maintenance risks.
#!/bin/bash
# Check the status of the fork compared to upstream
echo "Checking fork status compared to official Dioxus repo..."
git ls-remote https://github.com/hackartists/dioxus.git | grep HEAD
git ls-remote https://github.com/dioxuslabs/dioxus.git | grep HEAD
packages/main-ui/src/pages/components/mod.rs (1)

1-11: Well-organized module structure for UI components

The module organization looks clean and logical, setting up a clear structure for all the landing page UI components.

packages/main-ui/src/pages/layout.rs (3)

12-48: Good implementation of section detection based on scroll position

The section detection logic based on scroll position and window height is well-implemented. The use of use_signal and use_memo is appropriate for tracking and computing the active section.


71-79: Good use of MetaSeoTemplate for SEO optimization

The MetaSeoTemplate is well configured with appropriate metadata for SEO, including title, keywords, author, and canonical URL.


98-114: Nice implementation of BottomSheet for smooth scrolling

The BottomSheet component provides a good user experience by enabling smooth scrolling to the next section. The condition to hide it on the last section (when selected = 5) is appropriate.

Comment on lines +20 to +25
class: "bg-white text-black font-medium px-3 py-1 rounded-r-lg hover:bg-gray-200 focus:outline-none",
onclick: move |_| {
btracing::info!("Subscribed by {}", email());
},
"Subscribe"
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Incomplete subscription functionality

The subscribe button only logs the email address but doesn't actually submit it to any API or service. There's also no validation or user feedback after clicking.

Consider adding:

  1. Email validation before submission
  2. API call to submit the email to a subscription service
  3. User feedback (success/error messages)
  4. Loading state during submission
button {
    class: "bg-white text-black font-medium px-3 py-1 rounded-r-lg hover:bg-gray-200 focus:outline-none",
    onclick: move |_| {
+       if email().is_empty() || !email().contains('@') {
+           // Show validation error
+           return;
+       }
+       
+       // Set loading state
+       
        btracing::info!("Subscribed by {}", email());
+       
+       // Add API call to submit email
+       // e.g., subscribe_email(&email()).await;
+       
+       // Show success message
+       // Reset form or show confirmation
    },
    "Subscribe"
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class: "bg-white text-black font-medium px-3 py-1 rounded-r-lg hover:bg-gray-200 focus:outline-none",
onclick: move |_| {
btracing::info!("Subscribed by {}", email());
},
"Subscribe"
}
class: "bg-white text-black font-medium px-3 py-1 rounded-r-lg hover:bg-gray-200 focus:outline-none",
onclick: move |_| {
if email().is_empty() || !email().contains('@') {
// Show validation error
return;
}
// Set loading state
btracing::info!("Subscribed by {}", email());
// Add API call to submit email
// e.g., subscribe_email(&email()).await;
// Show success message
// Reset form or show confirmation
},
"Subscribe"
}

…omponent

+ Added new colors to ~input.css~
+ Removed ~EmailInput~ component
+ Updated ~Footer~ component to use ~InputWithButton~ and ~Socials~ components
+ Added new ~InputWithButton~ component
+ Added new ~Socials~ component
+ Updated module exports in ~mod.rs~
+ Updated ~Top~ component to use ~Socials~ component
+ Minor layout adjustments in ~RootLayout~ component
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
packages/main-ui/src/pages/components/top.rs (1)

39-43: ⚠️ Potential issue

Use the 'btn_join' translation for the second button.

Both buttons currently display {tr.btn_learn}. According to the translation keys, the second button should use {tr.btn_join} to match its intended functionality.

-    {tr.btn_learn}
+    {tr.btn_join}
packages/main-ui/src/pages/layout.rs (1)

50-68: ⚠️ Potential issue

Add cleanup for scroll event listener.

The current implementation adds an event listener but doesn't remove it when the component is unmounted, which could lead to memory leaks. Consider adding a cleanup mechanism.

#[cfg(feature = "web")]
let _ = use_coroutine(move |_: UnboundedReceiver<()>| async move {
    let script = r#"
-       window.addEventListener('scroll', () => {
+       let scrollHandler = () => {
            dioxus.send(`${window.scrollY}`);
-       });
+       };
+       window.addEventListener('scroll', scrollHandler);
+       
+       // Return the handler for cleanup
+       scrollHandler;
    "#;
    let mut eval = document::eval(script);
+   
+   // When coroutine drops, cleanup the event listener
+   defer! {
+       let cleanup_script = r#"
+           window.removeEventListener('scroll', LAST_EVAL_RESULT);
+       "#;
+       let _ = document::eval(cleanup_script);
+   }

    loop {
        let y = eval
            .recv::<String>()
            .await
            .unwrap_or_default()
            .parse::<f64>()
            .unwrap_or_default();
        scroll_position.set(y);
    }
});
🧹 Nitpick comments (13)
packages/main-ui/public/input.css (1)

5-18: Clarify and Verify Custom Theme Block

The new @theme static { ... } block cleanly defines a centralized set of CSS custom properties for your theme. Please verify that your Tailwind CSS build and configuration support this custom at-rule since it isn’t part of standard CSS. Also, consider adding an inline comment to explain its purpose and usage for maintainability in a team environment.

packages/main-ui/src/pages/components/socials.rs (1)

21-21: Consider implementing or removing the commented Telegram link

There's a commented-out Telegram link that appears to be incomplete. Either implement it with proper href and alt text or remove the comment to avoid confusion.

packages/main-ui/src/pages/components/footer.rs (1)

59-62: Future copyright year

The copyright year is set to 2025, which is in the future. Consider changing it to the current year or using a dynamic year that updates automatically.

- copyright: {
-     ko: "© 2025 Ratel Foundation.",
-     en: "© 2025 Ratel Foundation.",
- }
+ copyright: {
+     ko: "© 2024 Ratel Foundation.",
+     en: "© 2024 Ratel Foundation.",
+ }
packages/main-ui/src/pages/components/input_with_button.rs (2)

15-33: Add keyboard support for form submission

The component currently only submits when the button is clicked. Consider adding keyboard support to allow users to submit by pressing Enter when the input is focused.

 input {
     class: "outline-none h-full grow px-20 text-white text-base placeholder-c-wg-30 border border-c-wg-70 border rounded-l-lg flex flex-row items-center justify-start",
     r#type,
     value: value(),
     placeholder,
     oninput: move |e| value.set(e.value()),
+    onkeydown: move |e| {
+        if e.key() == "Enter" {
+            onsubmit(value());
+        }
+    },
 }

16-17: Consider adding basic input validation

Depending on the input type (especially for email), it might be beneficial to add basic validation before submitting.

pub fn InputWithButton(
    #[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
    placeholder: String,
    btn_name: String,
    #[props(default = "text".to_string())] r#type: String,

    onsubmit: EventHandler<String>,
) -> Element {
    let mut value = use_signal(|| "".to_string());
+   let mut is_valid = use_signal(|| true);
+   
+   let validate = move |val: &str| {
+       if r#type == "email" {
+           is_valid.set(val.contains('@') && val.contains('.'));
+       } else {
+           is_valid.set(!val.is_empty());
+       }
+   };

Then update the button click handler:

button {
-   class: "h-full bg-white text-black text-sm font-bold px-23 hover:bg-gray-200 focus:outline-none rounded-r-lg flex items-center justify-center",
+   class: "h-full bg-white text-black text-sm font-bold px-23 hover:bg-gray-200 focus:outline-none rounded-r-lg flex items-center justify-center disabled:bg-gray-300 disabled:cursor-not-allowed",
+   disabled: !is_valid(),
    onclick: move |_| {
+       validate(&value());
+       if is_valid() {
            onsubmit(value());
+       }
    },
    {btn_name}
}
packages/main-ui/src/pages/components/top.rs (3)

25-25: Fix conflicting text color styles.

There are conflicting text color specifications in the paragraph element: text-white and text-[#AEAEAE]. The latter will override the former, making the text-white class redundant.

-p { class: "text-[18px] text-center text-white font-normal text-[#AEAEAE] whitespace-pre-line",
+p { class: "text-[18px] text-center font-normal text-[#AEAEAE] whitespace-pre-line",

18-18: Consider using relative sizing for better responsiveness.

Using w-screen h-screen could cause overflow issues on some devices or when nested within certain containers. Consider using relative sizing like percentages or viewport units with additional constraints.

-class: "w-screen h-screen flex flex-col items-center justify-center gap-100",
+class: "w-full min-h-screen flex flex-col items-center justify-center gap-100",

41-41: Implement the onclick handler for the join button.

The onClick handler is currently empty. Consider implementing the functionality according to the TODO comment or add a more descriptive placeholder if implementation is pending.

-onclick: |_| {},
+onclick: |_| {
+    // TODO: Implement sign in logic
+    log::info!("Sign in button clicked");
+},
packages/main-ui/src/pages/layout.rs (5)

3-3: Consider removing commented code instead of commenting it out.

It's better to remove unused imports rather than commenting them out, especially in production code. If you need to keep track of this import for future reference, consider adding it to documentation instead.

-// use dioxus_popup::PopupZone;

14-48: Improve code readability with named constants for scroll thresholds.

The scroll threshold calculations use magic numbers (0.7, 1.7, etc.) without explaining their significance, making the code harder to understand and maintain.

let selected = use_memo(move || {
    #[cfg(feature = "web")]
    {
        let y = scroll_position();
        let height = match web_sys::window() {
            Some(window) => window
                .inner_height()
                .unwrap_or_default()
                .as_f64()
                .unwrap_or_default(),
            None => 0.0,
        };

+       // Define section thresholds as multiples of viewport height
+       const SECTION_1_THRESHOLD: f64 = 0.7;
+       const SECTION_2_THRESHOLD: f64 = 1.7;
+       const SECTION_3_THRESHOLD: f64 = 2.7;
+       const SECTION_4_THRESHOLD: f64 = 3.7;
+       const SECTION_5_THRESHOLD: f64 = 4.0;

-       let i = if y < height * 0.7 {
+       let i = if y < height * SECTION_1_THRESHOLD {
            0
-       } else if y < height * 1.7 {
+       } else if y < height * SECTION_2_THRESHOLD {
            1
-       } else if y < height * 2.7 {
+       } else if y < height * SECTION_3_THRESHOLD {
            2
-       } else if y < height * 3.7 {
+       } else if y < height * SECTION_4_THRESHOLD {
            3
-       } else if y <= height * 4.0 {
+       } else if y <= height * SECTION_5_THRESHOLD {
            4
        } else {
            5
        };

        return i;
    }
    #[cfg(not(feature = "web"))]
    0
});

98-109: Add error handling for the window scroll script.

The current implementation doesn't handle potential errors when executing the scroll script, which could lead to unhandled exceptions.

onclick: move |_| {
    let height = match web_sys::window() {
        Some(window) => {
            window.inner_height().unwrap_or_default().as_f64().unwrap_or_default()
        }
        None => 0.0,
    };
    let next_position = height * (selected() + 1) as f64;
    let script = format!(
        "window.scrollTo({{ top: {next_position}, behavior: 'smooth' }});",
    );
-   let _ = document::eval(&script);
+   if let Err(e) = document::eval(&script) {
+       log::error!("Failed to execute scroll script: {:?}", e);
+   }
},

17-25: Add error handling for window height retrieval.

The current implementation uses unwrap_or_default() for handling potential errors, which is good, but the code could be more readable by extracting the window height retrieval into a helper function.

+   #[cfg(feature = "web")]
+   fn get_window_height() -> f64 {
+       web_sys::window()
+           .and_then(|window| {
+               window
+                   .inner_height()
+                   .ok()
+                   .and_then(|height| height.as_f64())
+           })
+           .unwrap_or_default()
+   }

    let selected = use_memo(move || {
        #[cfg(feature = "web")]
        {
            let y = scroll_position();
-           let height = match web_sys::window() {
-               Some(window) => window
-                   .inner_height()
-                   .unwrap_or_default()
-                   .as_f64()
-                   .unwrap_or_default(),
-               None => 0.0,
-           };
+           let height = get_window_height();

98-103: Reuse the window height retrieval function.

The same window height retrieval logic is duplicated here. Consider reusing the helper function suggested earlier.

onclick: move |_| {
-   let height = match web_sys::window() {
-       Some(window) => {
-           window.inner_height().unwrap_or_default().as_f64().unwrap_or_default()
-       }
-       None => 0.0,
-   };
+   let height = get_window_height();
    let next_position = height * (selected() + 1) as f64;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5e1fe57 and 64c2e84.

📒 Files selected for processing (7)
  • packages/main-ui/public/input.css (1 hunks)
  • packages/main-ui/src/pages/components/footer.rs (1 hunks)
  • packages/main-ui/src/pages/components/input_with_button.rs (1 hunks)
  • packages/main-ui/src/pages/components/mod.rs (1 hunks)
  • packages/main-ui/src/pages/components/socials.rs (1 hunks)
  • packages/main-ui/src/pages/components/top.rs (1 hunks)
  • packages/main-ui/src/pages/layout.rs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: main-api
🔇 Additional comments (6)
packages/main-ui/src/pages/components/socials.rs (1)

1-24: Social media component looks good

The Socials component is well-structured and properly implements social media links with appropriate accessibility attributes (alt text) and security measures (target="_blank"). The component accepts global attributes, making it flexible for styling and positioning.

packages/main-ui/src/pages/components/footer.rs (2)

22-24: Email subscription functionality is incomplete

The onsubmit handler only logs the email but doesn't actually subscribe the user or validate the email. Consider implementing proper email validation and submission to a backend service.

Are there plans to implement the actual subscription functionality in a future PR, or should this be completed now?


1-78: Footer component is well-structured

The Footer component is well-organized with proper internationalization support and a clean layout. The use of translation macros for multilingual support is a good practice.

packages/main-ui/src/pages/components/input_with_button.rs (1)

1-33: Component is well-structured

The InputWithButton component is well-designed with appropriate props and styling. The use of signals for state management is a good practice.

packages/main-ui/src/pages/components/mod.rs (1)

1-25: Module organization looks good

The module structure is clean and well-organized, with proper declarations and re-exports of all components. This approach provides a good balance between organization and usability.

packages/main-ui/src/pages/components/top.rs (1)

1-71: Overall component structure looks good.

The Top component is well-structured with clear separation of UI elements and translations. The use of the translate macro for internationalization is a good practice. Make sure to implement the TODOs before finalizing the feature.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
packages/main-ui/src/pages/components/footer.rs (3)

11-24: Consider extracting the SVG into a separate component.

The SVG wave element is directly included in the component. For better maintainability and potential reuse, consider extracting it into a separate component.

- div { class: "w-full",
-     svg {
-         fill: "none",
-         view_box: "0 0 1921 146",
-         width: "100%",
-         xmlns: "http://www.w3.org/2000/svg",
-         path {
-             d: "M0.25 73.7684L1920.25 0V146H0.25V73.7684Z",
-             fill: "#191919",
-         }
-     }
- }
+ div { class: "w-full",
+     FooterWave {}
+ }

73-76: Make copyright year dynamic.

The year "2025" is hardcoded in the copyright text. To avoid annual updates, consider using a dynamic year calculation.

copyright: {
-   ko: "© 2025 Ratel Foundation.",
-   en: "© 2025 Ratel Foundation.",
+   ko: "© {current_year} Ratel Foundation.",
+   en: "© {current_year} Ratel Foundation.",
}

You would need to add JavaScript interop to get the current year or implement it in Rust if this is a server-rendered component.


44-49: Enhance accessibility for footer links.

The footer links lack accessibility attributes. Consider adding title attributes and aria roles for better screen reader support.

- a { class: "hover:text-white", href: "/privacy", {tr.privacy} }
- a { class: "hover:text-white", href: "/terms", {tr.terms} }
- a { class: "hover:text-white", href: "/sitemap", {tr.sitemap} }
+ a { 
+   class: "hover:text-white", 
+   href: "/privacy", 
+   title: "Privacy Policy",
+   aria_label: "Privacy Policy",
+   {tr.privacy} 
+ }
+ a { 
+   class: "hover:text-white", 
+   href: "/terms", 
+   title: "Terms of Service",
+   aria_label: "Terms of Service",
+   {tr.terms} 
+ }
+ a { 
+   class: "hover:text-white", 
+   href: "/sitemap", 
+   title: "Sitemap",
+   aria_label: "Sitemap",
+   {tr.sitemap} 
+ }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64c2e84 and a660a0d.

📒 Files selected for processing (1)
  • packages/main-ui/src/pages/components/footer.rs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: main-api
🔇 Additional comments (3)
packages/main-ui/src/pages/components/footer.rs (3)

1-6: Component imports and attributes look well structured.

The use of #![allow(non_snake_case)] is appropriate for UI components following React-like naming conventions. All necessary imports are present for the component to function.


7-10: Component declaration follows good Dioxus practices.

The Footer component is properly defined with the #[component] attribute and takes a Language parameter for internationalization support.


56-92: Well-organized translations with good coverage.

The translations are well-structured with good coverage for both Korean and English languages. The organization of the translation blocks is clean and readable.

Comment on lines +34 to +38
r#type: "email",
onsubmit: |email| {
btracing::info!("Subscribed by {}", email);
},
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Implement proper email subscription handling.

The current implementation only logs the email address without providing user feedback or actual subscription functionality. Consider adding error handling and success messaging.

onsubmit: |email| {
-   btracing::info!("Subscribed by {}", email);
+   btracing::info!("Processing subscription for {}", email);
+   // Add actual subscription logic here
+   // For example: subscribe_to_newsletter(email).await;
+   // Show success message to user
},
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
r#type: "email",
onsubmit: |email| {
btracing::info!("Subscribed by {}", email);
},
}
r#type: "email",
onsubmit: |email| {
btracing::info!("Processing subscription for {}", email);
// Add actual subscription logic here
// For example: subscribe_to_newsletter(email).await;
// Show success message to user
},

+ Added new primary and secondary button components with customizable styles and states.
+ Updated CSS variables for button colors.
+ Integrated new button components into existing pages and components.
+ Added labeled input component for form fields in the support section.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (1)
packages/main-ui/src/pages/components/top.rs (1)

36-41: ⚠️ Potential issue

Use the 'btn_join' translation for the second button.

Both buttons currently display {tr.btn_learn}. According to the translation keys, the second button should use {tr.btn_join} to match its intended functionality.

-    SecondaryButton { onclick: |_| {}, {tr.btn_learn} }
+    SecondaryButton { onclick: |_| {}, {tr.btn_join} }
🧹 Nitpick comments (15)
packages/main-ui/public/input.css (3)

5-35: Custom Theme Block Implementation
The new @theme static { ... } block introduces a well-organized set of custom CSS variables covering overall theme colors and detailed button styling for both primary and secondary variants. Please ensure that your build process (e.g., Tailwind/PostCSS) is configured to recognize the non-standard @theme static at-rule. Additionally, adding a brief comment inside or above this block to explain its purpose and processing would enhance maintainability.


11-11: Verify --color-black Value
The custom property --color-black is set to #000203, which is slightly off from the typical pure black (#000000). Please double-check that this subtle color difference is intentional and aligns with your design guidelines.


19-33: Button Color Variables Review
The definitions for primary and secondary button colors are neatly segmented and clearly commented. Verify that the chosen colors for text, hover, and disabled states meet your project's accessibility and branding standards, especially in terms of contrast.

packages/main-ui/src/components/button/primary_button.rs (1)

1-34: Well-structured component with good separation of concerns

The PrimaryButton component is well implemented with appropriate conditional styling based on disabled state and size handling.

Consider adding more size variants

Currently, the component only supports a Normal size. Consider adding more size variants (like Small, Large) to make the component more flexible and reusable across different UI contexts.

 let padding = match size {
     ButtonSize::Normal => "px-40 py-20",
+    ButtonSize::Small => "px-20 py-10",
+    ButtonSize::Large => "px-60 py-30",
 };
packages/main-ui/src/pages/components/labeled_input.rs (2)

18-20: Fix redundant CSS class and use Tailwind for height

There are two issues with the styling:

  1. The border class is duplicated in the class list
  2. Height is set using inline styles instead of Tailwind classes
-                    class: "w-full outline-none h-full grow px-20 text-white text-base placeholder-c-wg-30 border border-c-wg-70 border rounded-lg flex flex-row items-center justify-start",
-                    style: "height: {height};",
+                    class: "w-full outline-none h-full grow px-20 text-white text-base placeholder-c-wg-30 border-c-wg-70 border rounded-lg flex flex-row items-center justify-start h-[{height}]",

4-28: Consider adding support for validation and error states

The input component could be enhanced with validation support and error state display for better user experience.

 pub fn LabeledInput(
     #[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
     label_name: String,
     placeholder: String,
     #[props(default = "50px".to_string())] height: String,
     #[props(default = "text".to_string())] r#type: String,
+    #[props(default = false)] has_error: bool,
+    #[props(default = "".to_string())] error_message: String,
 
     oninput: EventHandler<String>,
 ) -> Element {
+    let border_class = if has_error {
+        "border-red-500"
+    } else {
+        "border-c-wg-70"
+    };
     rsx! {
         div {..attributes,
             div { class: "w-full flex flex-col items-start gap-5",
                 p { class: "text-c-cg-30 font-bold text-base/28", {label_name} }
                 input {
-                    class: "w-full outline-none h-full grow px-20 text-white text-base placeholder-c-wg-30 border border-c-wg-70 border rounded-lg flex flex-row items-center justify-start",
+                    class: "w-full outline-none h-full grow px-20 text-white text-base placeholder-c-wg-30 border {border_class} rounded-lg flex flex-row items-center justify-start",
                     style: "height: {height};",
                     r#type,
                     placeholder,
                     oninput: move |e| oninput(e.value()),
                 }
+                {has_error && rsx!(
+                    p { class: "text-red-500 text-sm mt-1", {error_message} }
+                )}
             }
         }
     }
 }
packages/main-ui/src/components/button/secondary_botton.rs (1)

13-20: Consider adding more size variants

Similar to PrimaryButton, this component only supports a Normal size. Consider adding more size variants for better flexibility.

 let padding = match size {
     ButtonSize::Normal => "px-40 py-20",
+    ButtonSize::Small => "px-20 py-10",
+    ButtonSize::Large => "px-60 py-30",
 };
packages/main-ui/src/pages/components/support.rs (3)

39-41: Fix incorrect debug message

The debug message for last name incorrectly logs "First name" instead of "Last name".

-                                btracing::debug!("First name: {}", e);
+                                btracing::debug!("Last name: {}", e);

63-71: Implement dropdown box instead of input

There's a FIXME comment indicating that this should be a dropdown box, not a regular input.

Would you like me to implement a dropdown component to replace this input field? The current implementation uses a regular input field where a dropdown select would be more appropriate.


67-68: Fix identical label and placeholder

The label and placeholder for the "needs" input are identical, which is inconsistent with other fields where they differ.

-                        placeholder: tr.label_needs,
+                        placeholder: tr.placeholder_needs,

You should also add a placeholder translation:

+    placeholder_needs: {
+        ko: "주제를 선택하세요",
+        en: "Select a topic",
+    }
packages/main-ui/src/pages/components/mod.rs (1)

15-27: Consider explicit imports instead of wildcard re-exports.

While using pub use module_name::* is a common pattern in Rust for component libraries, it can lead to namespace pollution if multiple modules export items with the same name. For improved maintainability as the codebase grows, consider explicitly re-exporting specific components:

-pub use about::*;
+pub use about::About;

This approach provides better clarity about which components are available from each module.

packages/main-ui/src/pages/components/top.rs (4)

32-32: Provide more descriptive props to the Socials component.

The Socials component is used with minimal properties. Consider providing more descriptive props such as specific social networks to display or configuration settings that might be needed.


36-37: Add more specific TODOs with issue references.

The TODO comments would be more helpful if they included specific issue references or more detailed information about the planned implementation:

-    // TODO: implement downloading whitepaper
+    // TODO: implement downloading whitepaper functionality (#ISSUE_NUMBER)
-    // TODO: implement Sign in
+    // TODO: implement Sign in flow with authentication service (#ISSUE_NUMBER)

Also applies to: 39-40


21-21: Extract Tailwind classes into reusable components or variables.

The component has long, complex Tailwind class strings that reduce readability. Consider extracting common patterns into reusable components or CSS variables for better maintainability:

// Example approach:
const SECTION_CONTAINER = "w-screen h-screen flex flex-col items-center justify-center gap-100";
const HEADING_STYLE = "text-[48px] text-center font-bold leading-[56px] text-white whitespace-pre-line";

Then use these constants in your JSX:

div { 
    class: SECTION_CONTAINER,
    // ...
}

Also applies to: 25-25, 28-28


11-44: Consider handling loading states and accessibility.

The component lacks handling for loading states or accessibility attributes. Consider:

  1. Adding ARIA attributes for better screen reader support
  2. Ensuring proper tab navigation between interactive elements
  3. Including loading states for buttons when actions are pending
 PrimaryButton { 
     onclick: |_| {}, 
+    aria_label: "Learn more about RATEL",
     {tr.btn_learn} 
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a660a0d and b7f3943.

📒 Files selected for processing (8)
  • packages/main-ui/public/input.css (1 hunks)
  • packages/main-ui/src/components/button/mod.rs (1 hunks)
  • packages/main-ui/src/components/button/primary_button.rs (1 hunks)
  • packages/main-ui/src/components/button/secondary_botton.rs (1 hunks)
  • packages/main-ui/src/pages/components/labeled_input.rs (1 hunks)
  • packages/main-ui/src/pages/components/mod.rs (1 hunks)
  • packages/main-ui/src/pages/components/support.rs (1 hunks)
  • packages/main-ui/src/pages/components/top.rs (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/main-ui/src/components/button/mod.rs
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: main-api
🔇 Additional comments (1)
packages/main-ui/src/pages/components/mod.rs (1)

1-13: Module organization looks clean and well-structured.

The file properly declares all necessary component modules that are part of the landing page implementation.

Comment on lines +1 to +34
#![allow(non_snake_case)]
use super::ButtonSize;
use dioxus::prelude::*;

#[component]
pub fn SecondaryButton(
#[props(default = Default::default())] size: ButtonSize,
#[props(default = false)] disabled: bool,
children: Element,

onclick: Option<EventHandler<MouseEvent>>,
) -> Element {
let bg = if !disabled {
"bg-btn-s hover:bg-btn-s-hover text-btn-s-text hover:text-btn-s-hover-text cursor-pointer"
} else {
"bg-btn-s-disabled text-btn-s-disabled cursor-not-allowed"
};
let padding = match size {
ButtonSize::Normal => "px-40 py-20",
};

rsx! {
button {
class: "font-bold gap-10 flex items-center justify-center text-base rounded-[10px] {bg} {padding}",
disabled,
onclick: move |evt| {
if let Some(onclick) = onclick {
onclick(evt);
}
},
{children}
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix filename typo: "secondary_botton.rs" should be "secondary_button.rs"

The filename contains a typo which will cause import issues. The file should be renamed from "secondary_botton.rs" to "secondary_button.rs". This is already causing an issue in the support.rs file where it's being imported.

The file needs to be renamed from "secondary_botton.rs" to "secondary_button.rs" and all imports updated accordingly.

use dioxus::prelude::*;
use dioxus_translate::*;

use crate::components::button::secondary_botton::SecondaryButton;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix import path with typo

The import path contains a typo: "secondary_botton" should be "secondary_button". This matches the filename typo identified in the button component file.

-use crate::components::button::secondary_botton::SecondaryButton;
+use crate::components::button::secondary_button::SecondaryButton;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
use crate::components::button::secondary_botton::SecondaryButton;
use crate::components::button::secondary_button::SecondaryButton;

}
} // end of form

SecondaryButton { onclick: |_| {}, {tr.btn_submit} }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add form submission feedback

The submit button has an empty onclick handler with no feedback to the user. Consider adding form validation and submission logic.

-                SecondaryButton { onclick: |_| {}, {tr.btn_submit} }
+                SecondaryButton { 
+                    onclick: move |_| {
+                        // Validate form fields
+                        // Submit form data
+                        btracing::debug!("Form submitted");
+                    }, 
+                    {tr.btn_submit} 
+                }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
SecondaryButton { onclick: |_| {}, {tr.btn_submit} }
SecondaryButton {
onclick: move |_| {
// Validate form fields
// Submit form data
btracing::debug!("Form submitted");
},
{tr.btn_submit}
}

use dioxus_translate::*;

use crate::components::{
button::{primary_button::PrimaryButton, secondary_botton::SecondaryButton},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix typo in module path: "secondary_botton".

There's a typo in the import path for the SecondaryButton component.

-    button::{primary_button::PrimaryButton, secondary_botton::SecondaryButton},
+    button::{primary_button::PrimaryButton, secondary_button::SecondaryButton},
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
button::{primary_button::PrimaryButton, secondary_botton::SecondaryButton},
button::{primary_button::PrimaryButton, secondary_button::SecondaryButton},

Reorganized CSS variables for better readability and added backdrop blur effect to the header component.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (6)
packages/main-ui/public/input.css (3)

5-11: Static Theme Block Initialization
The static theme block is introduced with @theme static { ... } and is well-organized into sections. Confirm that your build system processes the @theme static directive as expected, since it is not a standard Tailwind directive.


6-10: Tailwind CSS Variables Section
This section defines essential variables such as --spacing, --color-black, --color-primary, and --color-secondary. The naming is consistent. However, verify that the value set for --spacing (1px) meets the intended design requirements, as it is unusually small for spacing.


31-39: App-Specific Color Definitions
The app-specific color section extends the theme with additional variables like --color-hover, --color-c-wg-*, and --color-footer. The grouping is comprehensive and clear. Consider adding inline documentation if these variables have specific usage contexts within the app to aid future maintenance.

packages/main-ui/src/pages/components/header.rs (3)

56-93: Unused translation in the translations table.

The "reward" translation (lines 79-82) is defined but not used anywhere in the component. This could lead to confusion and maintenance issues.

Consider removing unused translations to keep the code clean:

translate! {
    HeaderTranslate;

    menu_about: {
        ko: "About",
        en: "About",
    }

    menu_stance: {
        ko: "Politician stance",
        en: "Politician stance",
    }

    menu_community: {
        ko: "Community",
        en: "Community",
    }

    menu_support: {
        ko: "Support",
        en: "Support",
    }

-    reward: {
-        ko: "나의 보상",
-        en: "My Rewards",
-    }

    login: {
        ko: "로그인",
        en: "Sign in",
    }

    get_ratel: {
        ko: "$RATEL 받기",
        en: "GET $RATEL",
    }
}

11-12: Consider using design tokens for magic numbers in layout.

The design uses several hard-coded values like "gap-59" and "max-w-[1176px]" which might make future design system adjustments more difficult.

Consider defining these values as design tokens or Tailwind theme variables for better maintainability:

- div { class: "w-full flex flex-row items-center justify-between gap-59 max-w-[1176px] mx-10",
+ div { class: "w-full flex flex-row items-center justify-between gap-header-nav max-w-content mx-10",

This assumes you've added these custom values to your Tailwind configuration.


19-20: Avoid inline style attributes for conditional highlighting.

Using the color attribute directly isn't a best practice in component frameworks - it adds an inline style which overrides CSS precedence.

Consider using conditional classes instead of inline color styles:

- a {
-     class: "p-10 hover:text-white",
-     href: "#about",
-     color: if selected == 1 { "var(--color-primary)" },
-     {tr.menu_about}
- }
+ a {
+     class: "p-10 hover:text-white {if selected == 1 { "text-primary" } else { "" }}",
+     href: "#about",
+     {tr.menu_about}
+ }

Apply this pattern to all menu items for consistency.

Also applies to: 25-26, 31-32, 37-38

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b7f3943 and 9e0fcb9.

📒 Files selected for processing (2)
  • packages/main-ui/public/input.css (1 hunks)
  • packages/main-ui/src/pages/components/header.rs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: main-api
  • GitHub Check: test
🔇 Additional comments (11)
packages/main-ui/public/input.css (6)

1-3: Tailwind Directives Integration
The inclusion of Tailwind’s base, components, and utilities layers is correctly implemented, ensuring the foundational styles are loaded.


4-4: Formatting Check
This line (line 4) appears to be a spacer or an intentional blank line. Ensure it adheres to your project’s formatting guidelines.


12-14: Background Colors Setup
The background color is clearly defined with --color-background: #1E1E1E;, which supports a dark theme. This should integrate nicely with the overall UI.


15-22: Primary Button Colors Configuration
The primary button colors are comprehensively defined, covering normal, hover, text, and disabled states. This detailed configuration will help ensure a consistent button appearance across various UI states.


23-30: Secondary Button Colors Configuration
Similarly, the secondary button colors have been defined with attention to hover and disabled states. The approach mirrors the primary button setup and maintains design consistency.


40-40: File Termination Verification
The file correctly concludes after closing the { ... } block. Ensure no trailing whitespace or extraneous characters are present that might affect the CSS processing.

packages/main-ui/src/pages/components/header.rs (5)

1-5: Import and directive setup looks good.

The import setup properly includes necessary dependencies for the Dioxus framework and translation functionality. Using #![allow(non_snake_case)] is appropriate for React-style components that follow PascalCase naming convention.


6-9: Component declaration with proper signature and translation initialization.

The Header component is correctly defined with appropriate parameters - language for localization and selected index for highlighting the active menu item. The translation lookup is properly initialized.


10-14: Fixed header implementation looks good.

The header's positioning and styling using Tailwind CSS classes creates an appropriate fixed header with backdrop blur effect. The logo placement and navigation to the top of the page are well implemented.


15-40: Navigation menu implementation is well structured.

The navigation menu items are consistently formatted with appropriate hover effects and conditional styling based on the selected parameter. Each menu item correctly links to the corresponding section on the page.


42-49: Action buttons look well-implemented.

The login and GET $RATEL buttons have appropriate styling and use translated text correctly. The primary button has a distinct visual style with proper hover effects.

Comment on lines +59 to +62
menu_about: {
ko: "About",
en: "About",
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consider more distinct Korean translations for menu items.

The Korean translations for menu items (About, Politician stance, Community, Support) are identical to English, which might not provide a proper localized experience.


🌐 Web query:

What are appropriate Korean translations for website navigation items like "About", "Community", and "Support"?

💡 Result:

To translate website navigation items like "About," "Community," and "Support" into Korean, consider both direct translations and culturally adapted terms based on context. Here’s a breakdown of common translations and usage notes:

1. "About"

  • Standard translation: "소개" (Sogae)
    • Used for general introductions (e.g., "회사 소개" for "About Us" in corporate contexts).
  • Alternative: "정보" (Jeongbo, "Information") for broader informational sections.
    • Best for informal or community-focused sites.

2. "Community"

  • Direct loanword: "커뮤니티" (Keomyuniti)
    • Widely understood and used in digital platforms.
  • Formal alternative: "공동체" (Gongdongche)
    • Emphasizes collective identity, suitable for NGOs or forums.

3. "Support"

  • Common translation: "고객 지원" (Gogaek Jiwon, "Customer Support")
    • Standard for business/corporate sites.
  • Simplified: "지원" (Jiwon)
    • General-purpose (e.g., technical support).
  • Casual option: "도움말" (Doummal, "Help")
    • Friendly tone for user assistance.

Considerations for Localization

  • Cultural Nuances: Honorifics and formality levels matter. For formal websites, use "회사 소개" (About Us) and "고객 지원" (Customer Support). For informal/community sites, "커뮤니티" and "도움말" are more approachable [2][11].
  • SEO and Clarity: Loanwords like "커뮤니티" are SEO-friendly for younger audiences, while "공동체" may align better with traditional or nonprofit contexts [5][7].
  • Professional Tools: Services like Papago or Linguise provide context-aware translations and live editing to refine terms directly on the website [1][2].

Example Navigation Bar

English Korean (Formal) Korean (Informal)
About 회사 소개 소개
Community 공동체 커뮤니티
Support 고객 지원 도움말

For accuracy, combine machine translation tools like Papago (noted for slang/honorifics [2][12]) with human review, especially for culturally sensitive terms. Professional services like Cultures Connection or Responsive Translation ensure localization aligns with Korean linguistic norms [5][13].

Citations:


Action: Update the Korean menu item translations for better localization

  • File: packages/main-ui/src/pages/components/header.rs, Lines 59-62
  • Suggestion: Currently, the Korean translation for the "About" menu item is identical to the English text (“About”). Based on localization best practices, please update the translations as follows:
    • About: Change from "About" to "소개" (or "회사 소개" if a more formal tone is desired).
    • Community: If applicable, update from "Community" to "커뮤니티" (or "공동체" for a formal version).
    • Support: Change from "Support" to "고객 지원" (alternatively, "도움말" can be used for a friendlier tone).
    • Politician stance: Although not shown in the snippet, if present in the codebase, consider a distinct translation such as "정치 입장" to clearly differentiate it from the English version.

Please ensure these updates align with the intended tone of the website and consult with any localization guidelines or stakeholders if necessary.

Added a new logo image to the public assets and integrated the MetaPage component in the HomePage. The MetaPage component sets the page title, description, and image.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/main-ui/src/pages/page.rs (1)

5-5: Consider more specific imports instead of wildcard imports.

Using wildcard imports (*) makes it harder to track which components are actually being used and can lead to namespace pollution. This might also impact code readability for new developers joining the project.

-use super::components::*;
+use super::components::{Top, About, PoliticianStance, Community, Support};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e0fcb9 and c5e3760.

⛔ Files ignored due to path filters (1)
  • packages/main-ui/public/logos/logo.png is excluded by !**/*.png
📒 Files selected for processing (1)
  • packages/main-ui/src/pages/page.rs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: main-api
🔇 Additional comments (4)
packages/main-ui/src/pages/page.rs (4)

2-2: Good addition of the MetaPage component for SEO optimization.

The inclusion of the MetaPage component improves SEO by providing title, description and image metadata for the page. This is a best practice for web applications.


7-7: Good use of localization.

Implementing the dioxus_translate crate for internationalization is a good approach for supporting multiple languages in the application.


16-21: Good modular structure with clear component separation.

The updated layout with dedicated components for different sections (Top, About, PoliticianStance, Community, Support) improves code organization and maintainability. Each component now has a specific responsibility following the single responsibility principle.

However, consider adding some spacing between components to improve visual separation on the page:

 div { class: "flex flex-col w-full justify-start items-center",
     Top { lang }
+    div { class: "my-8" }
     About { lang }
+    div { class: "my-8" }
     PoliticianStance { lang }
+    div { class: "my-8" }
     Community { lang }
+    div { class: "my-8" }
     Support { lang }
 }

11-12:

Details

❓ Verification inconclusive

Ensure translation keys are consistent with component expectations.

The code imports TopTranslate for the main page translations. Make sure all required translation keys for the description are defined in the translation files and that the component correctly handles missing translations.


🏁 Script executed:

#!/bin/bash
# Check if TopTranslate includes a description field
rg -A 5 "TopTranslate" --glob "*.rs"

Length of output: 1377


Translation Key Consistency Verification

The code now clearly references tr.description within the MetaPage (see packages/main-ui/src/pages/page.rs: lines 11–12), confirming that TopTranslate provides a description field. Please ensure that:

  • All translation files contain the required description key.
  • The MetaPage component (and any related components) gracefully handles cases where a translation might be missing.

lang,
}
}
MetaPage { title: "Ratel", description: tr.description, image: "{image}" }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Check if the image path is correct.

Verify that the image path "/public/logos/logo.png" is correctly referenced and the file exists. The current string interpolation "{image}" might not work as expected - the variable is already a string.


🏁 Script executed:

#!/bin/bash
# Check if the logo file exists
fd "logo.png" --glob "*/public/logos/*"

# Also check how asset! macro is used elsewhere
rg "asset!" --glob "*.rs" -A 1 -B 1

Length of output: 4002


Image Path Reference Correction – Update String Interpolation

  • In packages/main-ui/src/pages/page.rs, the asset! macro is correctly used to assign the image path with let image = asset!("/public/logos/logo.png");.

  • However, when constructing the MetaPage, the current code uses a literal string "{image}". Since image is already a string containing the correctly resolved path, it should be passed directly rather than wrapped in quotes.

  • Recommendation: Replace

    MetaPage { title: "Ratel", description: tr.description, image: "{image}" }

    with

    MetaPage { title: "Ratel", description: tr.description, image }

Please verify that the file at /public/logos/logo.png exists (as seen in similar asset references elsewhere in the codebase) and update as needed.

+ Added environment variable check to conditionally load Tailwind CSS and script in local environment.
+ Changed stylesheet links to preload for improved performance.
+ Deferred loading of main script to optimize page load time.
@hackartists hackartists merged commit 7bb3d6d into biyard:main Mar 9, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Mar 19, 2025
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants