Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implemented responsive landing page for helm-inspect #12

Merged
merged 3 commits into from
Mar 9, 2025

Conversation

niyasrad
Copy link
Member

@niyasrad niyasrad commented Mar 9, 2025

Description

  • Designed a clean, modern, and minimalistic landing page for Helm Inspect in Figma.
  • Ensured full responsiveness across desktop, tablet, and mobile devices.
  • Used Styled Components for modular and maintainable styling.
  • Set-up prettier for linted, formatted code.
  • Implemented Framer Motion techniques for smooth animations and transitions.
  • Linked documentation and Qreater GitHub page to the website, and hosting it in vercel.

Related Issue

Type of Change

  • Bugfix
  • New Feature
  • Documentation

Checklist

  • Code follows the project style guidelines
  • Tests have been added/updated
  • All tests pass

Summary by CodeRabbit

  • New Features

    • Launched a dynamic landing experience for HelmInspect with an engaging hero section, clear navigation, and prominent call-to-action.
    • Introduced interactive elements including an animated scenario display and a command box offering one-click copy functionality.
    • Enhanced styling and responsiveness ensure a seamless, visually appealing experience across all devices.
    • Added automation for synchronizing forked repositories with upstream sources.
  • Configuration Updates

    • Introduced new configuration files for TypeScript, ESLint, Prettier, and Vite to streamline development and ensure code quality.
    • Added a .gitignore file to manage ignored files and directories effectively.
  • Styling Enhancements

    • Implemented a comprehensive set of styled components for various sections and elements of the landing page, improving layout and visual appeal.

@niyasrad niyasrad added documentation Improvements or additions to documentation enhancement New feature or request labels Mar 9, 2025
@niyasrad niyasrad requested a review from Vaish24navi March 9, 2025 14:42
@niyasrad niyasrad self-assigned this Mar 9, 2025
Copy link

coderabbitai bot commented Mar 9, 2025

Walkthrough

This pull request introduces a comprehensive set of new files and configurations. A GitHub Actions workflow automates the synchronization of a forked repository with its upstream source. Several configuration files for linting, formatting, TypeScript, and Vite are added alongside new HTML, CSS, and package management files. The project now includes a fully fledged landing page with new React components for layout, navigation, call-to-action sections, and interactive elements such as a command box and animated scenario box. Additional files support deployment (Vercel), Python packaging, and enhanced TypeScript project management.

Changes

File(s) Change Summary
.github/workflows/sync-fork.yaml New GitHub Actions workflow to auto-sync a fork with upstream changes on selected branches.
landing/.gitignore, landing/.prettierrc, landing/eslint.config.js, landing/package.json, landing/vite.config.ts, landing/tsconfig.app.json, landing/tsconfig.json, landing/tsconfig.node.json, landing/vercel.json, landing/src/vite-env.d.ts, pyproject.toml New configuration files for ignoring files, code formatting, linting, dependency management, Vite setup, TypeScript settings, deployment routing, and Python packaging directives.
landing/index.html, landing/src/assets/styles/index.css New landing page HTML and global CSS assets defining structure, fonts, and layout styles.
landing/src/app.tsx, landing/src/main.tsx Introduction of the main React application entry points – the primary App component and its DOM rendering in main.tsx.
landing/src/components/commandbox/*.ts*, landing/src/components/ctabox/*.ts*, landing/src/components/index.styles.ts, landing/src/components/layout/*.ts*, landing/src/components/navbar/*.ts*, landing/src/components/scenariobox/scenariobox.tsx New React UI components with styled-components for command boxes (with copy functionality), CTA boxes, landing layouts, navigation bars, and animated scenario displays.
landing/src/containers/how/*.ts*, landing/src/containers/landing/*.ts*, landing/src/containers/why/*.ts* New container components for different landing page sections: How It Works, Landing, and Why Helm Inspect, integrating the previously defined UI components and interactions.

Sequence Diagram(s)

sequenceDiagram
    participant Runner as GitHub Actions Runner
    participant Fork as Forked Repository
    participant Upstream as Upstream Repository
    Runner->>Fork: Checkout forked repository
    Runner->>Fork: Add upstream remote
    Runner->>Upstream: Fetch changes
    Runner->>Fork: Force merge upstream changes
    Runner->>Fork: Push merged changes (log success/error)
Loading
sequenceDiagram
    participant User as User
    participant CB as CommandBox Component
    participant Clipboard as Navigator.clipboard
    User->>CB: Clicks command box
    CB->>Clipboard: Call writeText(copyText)
    alt Copy Success
        CB->>User: Display "Copied" animation
        note right of CB: State 'copied' true for 1.5 sec then resets
    else Copy Failure
        CB->>User: Log error message
    end
Loading

Poem

Hop, hop, hop—I’m your coding bunny,
Syncing forks and styling with flair so sunny.
Command boxes that copy with a flick of a paw,
Landing pages that dazzle without a flaw.
In code’s vast garden, every change is fun—
Hopping through updates till the work is done!
🥕🐰


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9e18f5c and 598768e.

⛔ Files ignored due to path filters (3)
  • landing/package-lock.json is excluded by !**/package-lock.json
  • landing/public/logo.svg is excluded by !**/*.svg
  • landing/src/assets/logo/helm_inspect.svg is excluded by !**/*.svg
📒 Files selected for processing (32)
  • .github/workflows/sync-fork.yaml (1 hunks)
  • landing/.gitignore (1 hunks)
  • landing/.prettierrc (1 hunks)
  • landing/eslint.config.js (1 hunks)
  • landing/index.html (1 hunks)
  • landing/package.json (1 hunks)
  • landing/src/app.tsx (1 hunks)
  • landing/src/assets/styles/index.css (1 hunks)
  • landing/src/components/commandbox/commandbox.styles.ts (1 hunks)
  • landing/src/components/commandbox/commandbox.tsx (1 hunks)
  • landing/src/components/ctabox/ctabox.styles.ts (1 hunks)
  • landing/src/components/ctabox/ctabox.tsx (1 hunks)
  • landing/src/components/index.styles.ts (1 hunks)
  • landing/src/components/layout/layout.styles.ts (1 hunks)
  • landing/src/components/layout/layout.tsx (1 hunks)
  • landing/src/components/navbar/navbar.styles.ts (1 hunks)
  • landing/src/components/navbar/navbar.tsx (1 hunks)
  • landing/src/components/scenariobox/scenariobox.tsx (1 hunks)
  • landing/src/containers/how/how.styles.ts (1 hunks)
  • landing/src/containers/how/how.tsx (1 hunks)
  • landing/src/containers/landing/landing.styles.ts (1 hunks)
  • landing/src/containers/landing/landing.tsx (1 hunks)
  • landing/src/containers/why/why.styles.ts (1 hunks)
  • landing/src/containers/why/why.tsx (1 hunks)
  • landing/src/main.tsx (1 hunks)
  • landing/src/vite-env.d.ts (1 hunks)
  • landing/tsconfig.app.json (1 hunks)
  • landing/tsconfig.json (1 hunks)
  • landing/tsconfig.node.json (1 hunks)
  • landing/vercel.json (1 hunks)
  • landing/vite.config.ts (1 hunks)
  • pyproject.toml (1 hunks)

🪧 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 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.

@niyasrad niyasrad linked an issue Mar 9, 2025 that may be closed by this pull request
Copy link

@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: 2

🔭 Outside diff range comments (1)
landing/tsconfig.node.json (1)

1-25: 🛠️ Refactor suggestion

⚠️ Potential issue

JSON Config Format Compliance Issue:
The configuration settings are well defined for your Node environment; however, please note that standard JSON does not support comments. The inline comments (e.g., on line 9 and line 16) may trigger errors in JSON parsers that enforce strict JSON syntax.

Suggested Change: Remove the inline comments or switch to a JSONC configuration if your toolchain supports it. For example:

-    /* Bundler mode */
+    
-    /* Linting */
+    
🧰 Tools
🪛 Biome (1.9.4)

[error] 9-9: JSON standard does not allow comments.

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-16: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-16: JSON standard does not allow comments.

(parse)


[error] 17-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 17-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 17-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 17-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-24: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

🧹 Nitpick comments (34)
.github/workflows/sync-fork.yaml (2)

1-47: Consider a more cautious approach to fork synchronization.

While this workflow achieves the goal of syncing a fork with its upstream repository, the merge strategy is quite aggressive and could potentially overwrite important fork-specific changes.

The --strategy-option=theirs combined with --force push will always favor upstream changes and overwrite any conflicting changes in the fork. This might be intentional, but could lead to unexpected loss of work if contributors are making changes to the same files.

Consider a more cautious approach:

- git merge upstream/${{ github.ref_name }} --allow-unrelated-histories --strategy-option=theirs --no-edit
+ git merge upstream/${{ github.ref_name }} --allow-unrelated-histories --no-edit || {
+   echo "::warning::Merge conflicts detected. Please resolve manually."
+   exit 1
+ }
- if ! git push origin ${{ github.ref_name }} --force; then
+ if ! git push origin ${{ github.ref_name }}; then
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 47-47: no new line character at the end of file

(new-line-at-end-of-file)


47-47: Add newline at end of file.

Add a newline character at the end of the file to conform to standard YAML formatting practices.

  echo "::notice::Successfully synced fork with upstream"
+
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 47-47: no new line character at the end of file

(new-line-at-end-of-file)

landing/vite.config.ts (1)

1-7: Vite configuration looks good, but documentation URL may be incorrect.

The React plugin is correctly configured, but the documentation URL should be https://vitejs.dev/config/ instead of https://vite.dev/config/.

- // https://vite.dev/config/
+ // https://vitejs.dev/config/
landing/src/components/layout/layout.tsx (1)

1-3: Consider adding React import for clarity.

While modern React (17+) doesn't require explicit React imports for JSX, it's still a good practice to include it for clarity, especially since you're using React types.

+import React from 'react'
 import Navbar from '../navbar/navbar'
 import { LayoutWrapper, LayoutContent } from './layout.styles'
landing/src/main.tsx (1)

1-7: Overall Entry Point Setup is Solid:
The file correctly imports the required modules, loads the stylesheet, and renders the <App /> component into the DOM using createRoot. The use of the non-null assertion operator (!) is acceptable if you’re confident the element with the ID root always exists. For enhanced robustness, consider adding a check to handle a potential null value (e.g., logging an error if the element isn’t found).

landing/src/containers/landing/landing.styles.ts (1)

1-22: Responsive and Clear Landing Styles:
The LandingContent styled component is well crafted with a clear, responsive design. The use of the CSS min() function for the margin-bottom property is modern; just ensure it meets compatibility requirements for your target browsers.

landing/tsconfig.app.json (1)

1-26: Strong TypeScript configuration with modern settings

The TypeScript configuration is well set up with modern features and strict type checking, which will help catch errors early in development.

Consider adding the following options to further enhance developer experience:

{
  "compilerOptions": {
    // ... existing options
+   "forceConsistentCasingInFileNames": true,
+   "resolveJsonModule": true,
+   "baseUrl": ".",
+   "paths": {
+     "@/*": ["./src/*"]
+   }
  },
  "include": ["src"]
}

These additions would improve import management and prevent case-sensitivity issues across different operating systems.

🧰 Tools
🪛 Biome (1.9.4)

[error] 10-10: JSON standard does not allow comments.

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-16: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-16: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-16: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-18: JSON standard does not allow comments.

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 24-24: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 25-25: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 25-25: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 25-25: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 25-26: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

landing/src/containers/how/how.tsx (2)

17-60: Consider moving scenarios inside the component or to a separate file

The scenarios array is currently defined outside of the component. For better organization and maintainability, consider either:

  1. Moving it inside the component (if it's only used there)
  2. Moving it to a separate file and importing it (better for reusability)
- const scenarios = [
+ // In a separate file: scenarios.tsx
+ export const scenarios = [
  // ...
]

export const How = () => {
+  // Or define scenarios here if only used in this component
+  // const scenarios = [ ... ]
  return (
    // ...
  )
}

134-137: Consider adding an accessible label to the AnimatedScenarioBox

For better accessibility, consider adding an aria-label or similar attribute to the AnimatedScenarioBox to describe its purpose to screen reader users.

<AnimatedScenarioBox
  scenarios={scenarios}
  intervalTime={4000}
+ aria-label="Command line examples of using HelmInspect"
/>
landing/src/components/ctabox/ctabox.tsx (1)

18-28: Consider adding error handling for the scroll functionality

The directOrScroll method handles smooth scrolling for anchor links, but it doesn't account for cases where the target element might not exist in the DOM. Consider adding error handling or a fallback mechanism.

if (CTALink.startsWith('#')) {
    e.preventDefault()
-   document.getElementById(CTALink.slice(1))?.scrollIntoView({
-       behavior: 'smooth',
-       block: 'start',
-   })
+   const targetElement = document.getElementById(CTALink.slice(1))
+   if (targetElement) {
+       targetElement.scrollIntoView({
+           behavior: 'smooth',
+           block: 'start',
+       })
+   } else {
+       console.warn(`Element with id '${CTALink.slice(1)}' not found`)
+   }
}
landing/src/containers/why/why.tsx (1)

18-66: Consider extracting scenarios to a separate file

The scenarios array is quite lengthy and could be moved to a separate file for better maintainability and separation of concerns. This would make the component file cleaner and more focused on rendering logic.

Consider creating a file like why.scenarios.ts with:

import React from 'react'
import { PrimaryHighlight, DullHighlight, AccentHighlight, MobileTrim } from '../../components/index.styles'

export const scenarios = [
  // Move the existing scenarios array here
]

Then import it in this file:

- const scenarios = [
-   // ...scenario definitions
- ]
+ import { scenarios } from './why.scenarios'
landing/src/components/navbar/navbar.tsx (3)

26-45: Improve accessibility with semantic HTML and ARIA attributes

The navigation component would benefit from proper semantic HTML for better accessibility. Consider wrapping your navbar content in a <nav> element and adding appropriate ARIA attributes.

 return (
-    <NavbarWrapper>
+    <NavbarWrapper as="nav" role="navigation">
         <NavbarDesktop>
             <NavbarLogo src={helmInspect} alt="Logo" />
             <NavbarLinks>
                 <ButtonLink
                     href="https://github.com/qreater/HelmInspect?tab=readme-ov-file#table-of-contents"
                     target="_blank"
+                    rel="noopener noreferrer"
                 >
                     Docs
                 </ButtonLink>
                 <ButtonLink
                     href="https://github.com/qreater"
                     target="_blank"
+                    rel="noopener noreferrer"
                 >
                     Qreater
                 </ButtonLink>
             </NavbarLinks>
-            <NavbarMobileOpen onClick={toggleMenu} />
+            <NavbarMobileOpen 
+                onClick={toggleMenu} 
+                aria-label="Open menu" 
+                aria-expanded={menuOpen} 
+                aria-controls="mobile-menu"
+            />
         </NavbarDesktop>

47-89: Add keyboard accessibility to mobile menu

The mobile menu lacks keyboard accessibility. Users should be able to open/close the menu using keyboard and navigate through the menu items.

 <AnimatePresence>
     {menuOpen && (
         <>
             <NavbarBackground
                 as={motion.div}
                 initial={{ opacity: 0 }}
                 animate={{ opacity: 1 }}
                 exit={{ opacity: 0 }}
                 transition={{ duration: 0.2 }}
                 onClick={toggleMenu}
             />
             <NavbarMobile
+                id="mobile-menu"
                 as={motion.div}
                 initial={{ x: '-100%', opacity: 0, scale: 0.9 }}
                 animate={{ x: 0, opacity: 1, scale: 1 }}
                 exit={{ x: '-100%', opacity: 0, scale: 0.95 }}
                 transition={{
                     duration: 0.3,
                     ease: [0.33, 1, 0.68, 1],
                 }}
             >
                 <NavbarMobileHeader>
                     <NavbarLogo src={helmInspect} alt="Logo" />
-                    <NavbarMobileClose onClick={toggleMenu} />
+                    <NavbarMobileClose 
+                        onClick={toggleMenu} 
+                        aria-label="Close menu" 
+                        tabIndex={0}
+                        onKeyDown={(e) => e.key === 'Enter' && toggleMenu()}
+                    />
                 </NavbarMobileHeader>
                 <NavbarLinks $mobileMenu>
                     <ButtonLink
                         href="https://github.com/qreater/HelmInspect?tab=readme-ov-file#table-of-contents"
                         target="_blank"
+                        rel="noopener noreferrer"
                     >
                         Docs
                     </ButtonLink>
                     <ButtonLink
                         href="https://github.com/qreater"
                         target="_blank"
+                        rel="noopener noreferrer"
                     >
                         Qreater
                     </ButtonLink>
                 </NavbarLinks>
             </NavbarMobile>
         </>
     )}
 </AnimatePresence>

1-18: Consider extracting URLs to constants

The URLs to documentation and GitHub are hardcoded in multiple places. Consider extracting them to constants for easier maintenance.

 import { AnimatePresence, motion } from 'framer-motion'
 import { useState } from 'react'
 
 import helmInspect from '../../assets/logo/helm_inspect.svg'
 
+// Extract URLs to constants for easier maintenance
+const DOCS_URL = "https://github.com/qreater/HelmInspect?tab=readme-ov-file#table-of-contents"
+const QREATER_URL = "https://github.com/qreater"
+
 import {
     NavbarBackground,
     NavbarDesktop,
     NavbarLinks,
     NavbarLogo,
     NavbarMobile,
     NavbarMobileClose,
     NavbarMobileHeader,
     NavbarMobileOpen,
     NavbarWrapper,

Then use these constants where the URLs are referenced.

landing/src/components/commandbox/commandbox.styles.ts (2)

38-44: Minor optimization - remove redundant cursor style

The cursor: pointer is already set on the parent CommandBoxWrapper, so it's redundant here.

export const CommandBoxCopy = styled(DocumentDuplicate)`
    width: 1.3rem;
    height: 1.3rem;

    color: var(--text-color);
-    cursor: pointer;
`

1-52: Consider extracting repeated values to variables

For better maintainability, consider extracting the repeated border-radius value to a variable.

You could define a CSS variable in your global styles:

:root {
  --border-radius-sm: 0.725rem;
}

Then use var(--border-radius-sm) instead of the hardcoded value in multiple places.

landing/src/components/commandbox/commandbox.tsx (3)

19-27: Add error handling and cleanup for setTimeout

The clipboard API might not be supported in all browsers, and the setTimeout could cause memory leaks if the component unmounts before it completes.

 const copyCommand = () => {
-    navigator.clipboard.writeText(copyText)
+    try {
+        navigator.clipboard.writeText(copyText)
+        
+        if (copied) return
+        setCopied(true)
+        setTimeout(() => {
+            setCopied(false)
+        }, 1500)
+    } catch (err) {
+        console.error('Failed to copy text: ', err)
+        // Fallback method for browsers that don't support clipboard API
+        const textArea = document.createElement('textarea')
+        textArea.value = copyText
+        document.body.appendChild(textArea)
+        textArea.select()
+        document.execCommand('copy')
+        document.body.removeChild(textArea)
+        
+        if (copied) return
+        setCopied(true)
+        setTimeout(() => {
+            setCopied(false)
+        }, 1500)
+    }
+}

And add a useEffect for cleanup:

useEffect(() => {
    let timeout: ReturnType<typeof setTimeout>
    
    const copyCommand = () => {
        // ... your implementation
        
        timeout = setTimeout(() => {
            setCopied(false)
        }, 1500)
    }
    
    return () => {
        if (timeout) clearTimeout(timeout)
    }
}, [copied, copyText])

29-57: Improve accessibility with keyboard support and ARIA attributes

The command box needs keyboard accessibility and ARIA attributes to be more accessible.

 return (
-    <CommandBoxWrapper onClick={copyCommand}>
+    <CommandBoxWrapper 
+        onClick={copyCommand}
+        onKeyDown={(e) => e.key === 'Enter' && copyCommand()}
+        tabIndex={0}
+        role="button"
+        aria-label={`Copy command: ${copyText}`}
+        aria-live="polite"
+    >
         <CodeParagraph>{children}</CodeParagraph>
         <CommandBoxIcon>
             <AnimatePresence mode="wait">
                 {copied ? (
                     <motion.div
                         key="copied"
                         initial={{ opacity: 0, scale: 0.8 }}
                         animate={{ opacity: 1, scale: 1 }}
                         exit={{ opacity: 0, scale: 0.8 }}
                         transition={{ duration: 0.1 }}
+                        aria-hidden="true"
                     >
                         <CommandBoxCopied />
+                        <span className="sr-only">Command copied to clipboard</span>
                     </motion.div>
                 ) : (
                     <motion.div
                         key="copy"
                         initial={{ opacity: 0, scale: 0.8 }}
                         animate={{ opacity: 1, scale: 1 }}
                         exit={{ opacity: 0, scale: 0.8 }}
                         transition={{ duration: 0.1 }}
+                        aria-hidden="true"
                     >
                         <CommandBoxCopy />
+                        <span className="sr-only">Click to copy command</span>
                     </motion.div>
                 )}

You'll need to add a screen-reader only class to your global styles:

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

16-28: Add visual feedback when the command is copied

Currently, only the icon changes when the text is copied. Consider adding more visual feedback for a better user experience.

You could briefly change the border color or add a subtle animation to the entire component:

const CommandBox = ({ children, copyText }: CommandBoxProps) => {
    const [copied, setCopied] = useState(false)

    const copyCommand = () => {
        navigator.clipboard.writeText(copyText)

        if (copied) return
        setCopied(true)
        setTimeout(() => {
            setCopied(false)
        }, 1500)
    }

    return (
        <CommandBoxWrapper 
            onClick={copyCommand}
+           style={{ 
+               borderColor: copied ? 'var(--secondary-color)' : 'var(--border-color)',
+               transition: 'border-color 0.2s ease' 
+           }}
        >
landing/src/assets/styles/index.css (3)

32-35: Consider using min-height instead of fixed positioning for the body

Using position: fixed with width: 100% and height: 100% for the body element might cause issues with content overflow and prevent natural scrolling behavior on some devices, especially when content exceeds the viewport height.

body {
  font-family: var(--font-primary);
  color: var(--text-color);

-  position: fixed;
-  width: 100%;
-  height: 100%;
+  min-height: 100vh;
+  overflow-x: hidden;

  -webkit-tap-highlight-color: transparent;
  background-color: var(--background-color);
  line-height: 1.6;
}

86-88: Use CSS variables for color consistency in hover states

The hover state color is hardcoded to #4338ca instead of using a CSS variable, which breaks the consistency of your design system. Consider adding a variable for hover states in the root.

:root {
    --primary-color: #505BFF;
    --secondary-color: #00F6FF;
    --accent-color: #FF0000;
    --text-color: #FFFFFF;
    --border-color: #000000;
    --background-color: #171717;
    --dull-color: #8C8C8C;
+   --primary-hover-color: #4338ca;
  
    --font-primary: "Special Elite", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
  
    --radius: 8px;
    --shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
  }

/* Then update the hover state: */
.btn-primary:hover {
-  background-color: #4338ca;
+  background-color: var(--primary-hover-color);
}

112-120: Consider adding more breakpoints for better responsiveness

The CSS only includes one breakpoint at 768px. For a truly responsive landing page as described in the PR objectives, consider adding additional breakpoints for different device sizes.

@media (max-width: 768px) {
  html {
    font-size: 14px;
  }

  .container {
    padding: 0 0.5rem;
  }
}

+@media (max-width: 480px) {
+  html {
+    font-size: 12px;
+  }
+
+  .container {
+    padding: 0 0.25rem;
+  }
+}
+
+@media (min-width: 1200px) {
+  .container {
+    padding: 0 2rem;
+  }
+}
landing/src/components/scenariobox/scenariobox.tsx (3)

44-44: Avoid using array index as React key for dynamic content

Using array indices as keys can lead to unexpected behavior when items are reordered or filtered. Consider using a unique identifier from each scenario object instead.

-key={index}
+key={`scenario-${index}-${JSON.stringify(scenario.command).substring(0, 20)}`}

41-72: Improve performance by conditionally rendering scenarios

Currently, all scenarios are rendered but controlled via opacity, which can be inefficient for many items. Consider rendering only the visible scenarios to improve performance.

<AnimatePresence mode="wait">
-  {scenarios.map((scenario, index) => (
+  {scenarios.map((scenario, index) => index <= currentIndex && (
     <motion.div
       key={index}
       style={{
         opacity: 1,
         marginBottom: '1rem',
       }}
       initial={{ opacity: 0, y: 20 }}
       animate={{
-        opacity: currentIndex >= index ? 1 : 0,
-        y: currentIndex >= index ? 0 : 20,
+        opacity: 1,
+        y: 0,
       }}
       exit={{
         opacity: 0,
         y: -20,
       }}
       transition={{ duration: 0.5 }}
     >
       <ScenarioItem>
         {scenario.time ? (
           <HeroText>
             {scenario.time} &gt; {scenario.command}
           </HeroText>
         ) : (
           <HeroText>&gt; {scenario.command}</HeroText>
         )}
         <HeroText>{scenario.message}</HeroText>
       </ScenarioItem>
     </motion.div>
   ))}
</AnimatePresence>

24-33: Add accessibility attributes for animated content

The animated scenario box lacks accessibility features that would make it usable for screen readers and keyboard navigation. Consider adding ARIA attributes and keyboard controls.

return (
    <ScenarioBox
        style={{
            position: 'relative',
        }}
+       role="region"
+       aria-label="Animated scenarios"
+       tabIndex={0}
    >
        <AnimatePresence mode="wait">
            {scenarios.map((scenario, index) => (
                <motion.div
                    key={index}
                    style={{
                        opacity: 1,
                        marginBottom: '1rem',
                    }}
+                   role="text"
+                   aria-hidden={currentIndex < index}
                    initial={{ opacity: 0, y: 20 }}
                    animate={{
                        opacity: currentIndex >= index ? 1 : 0,
                        y: currentIndex >= index ? 0 : 20,
                    }}
                    exit={{
                        opacity: 0,
                        y: -20,
                    }}
                    transition={{ duration: 0.5 }}
                >
landing/index.html (2)

3-8: Add meta description tag for SEO optimization

Adding a meta description tag would improve SEO for the landing page and provide a brief summary in search engine results.

<head>
  <meta charset="UTF-8" />
  <link rel="icon" type="image/svg+xml" href="/logo.svg" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta name="description" content="HelmInspect - A tool for detecting drift in Kubernetes Helm charts within seconds. Monitor and identify changes in your deployments efficiently." />
  <title>HelmInspect | Drift Detection In Seconds!</title>
</head>

1-13: Consider adding Open Graph meta tags for social media sharing

Adding Open Graph meta tags would improve the appearance when the landing page is shared on social media platforms.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/logo.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+   <meta property="og:title" content="HelmInspect | Drift Detection In Seconds!" />
+   <meta property="og:description" content="A tool for detecting drift in Kubernetes Helm charts within seconds." />
+   <meta property="og:image" content="/og-image.png" />
+   <meta property="og:url" content="https://helminspect.qreater.dev/" />
+   <meta property="og:type" content="website" />
    <title>HelmInspect | Drift Detection In Seconds!</title>
  </head>
landing/package.json (3)

8-8: Specify TypeScript configuration file in the build script

The build script uses tsc -b without specifying which configuration file to use. This might lead to unexpected behavior if there are multiple TypeScript projects or configuration files.

- "build": "tsc -b && vite build",
+ "build": "tsc -b tsconfig.json && vite build",

6-12: Add testing scripts to package.json

According to the PR description, tests were not added or updated. Consider adding a testing script to encourage test creation in the future.

"scripts": {
  "dev": "vite",
  "build": "tsc -b && vite build",
  "format": "eslint \"**/*.{js,ts}\" --fix && prettier --write \"**/*.{ts,tsx}\"",
  "lint": "eslint .",
- "preview": "vite preview"
+ "preview": "vite preview",
+ "test": "vitest run",
+ "test:watch": "vitest"
},

9-9: Format script is missing JSX files in ESLint pattern

The format script's ESLint pattern only includes .js and .ts files, but not .jsx and .tsx files, which might lead to inconsistent formatting.

- "format": "eslint \"**/*.{js,ts}\" --fix && prettier --write \"**/*.{ts,tsx}\"",
+ "format": "eslint \"**/*.{js,ts,jsx,tsx}\" --fix && prettier --write \"**/*.{ts,tsx,js,jsx}\"",
landing/src/components/navbar/navbar.styles.ts (3)

45-71: Review positioning in NavbarMobile component

The NavbarMobile component is positioned with all sides (top, right, bottom, left) set to 0, while also having a width of 80%. This creates an inconsistency - if it's meant to be a slide-in sidebar from the right, you should remove the left: 0 property or set appropriate positioning.

export const NavbarMobile = styled(motion.div)`
    display: none;

    @media screen and (max-width: 1024px) {
        display: flex;
        flex-direction: column;
        gap: 2rem;

        justify-content: flex-start;
        align-items: start;

        position: fixed;

        top: 0;
        right: 0;
        bottom: 0;
-       left: 0;

        width: 80%;
        height: 100%;

        background-color: var(--background-color);
        z-index: 1000;

        padding: 2rem;
    }
`

93-99: Consider adding a media query to NavbarMobileClose

The NavbarMobileOpen component has a media query to hide it on desktop, but NavbarMobileClose doesn't have similar logic. If this is intentional (because it's only rendered inside the mobile menu), that's fine - but if not, consider adding the same media query for consistency.

export const NavbarMobileClose = styled(XMark)`
    width: 2rem;
    height: 2rem;
    color: var(--text-color);

    cursor: pointer;
+
+   @media screen and (min-width: 1024px) {
+       display: none;
+   }
`

101-119: Simplify conditional display logic in NavbarLinks

The current conditional display logic is a bit confusing. On desktop, it shows when $mobileMenu is false, while on mobile it shows when $mobileMenu is true. Consider renaming the prop to make the intent clearer.

- export const NavbarLinks = styled.div<{ $mobileMenu?: boolean }>`
-     display: ${({ $mobileMenu }) => ($mobileMenu ? 'none' : 'flex')};
+ export const NavbarLinks = styled.div<{ $isDesktopView?: boolean }>`
+     display: ${({ $isDesktopView }) => ($isDesktopView ? 'flex' : 'none')};
      justify-content: space-between;
      align-items: center;

-     width: ${({ $mobileMenu }) => ($mobileMenu ? '100%' : 'auto')};
+     width: ${({ $isDesktopView }) => ($isDesktopView ? 'auto' : '100%')};

      gap: 1rem;

      @media screen and (max-width: 1024px) {
-         display: ${({ $mobileMenu }) => ($mobileMenu ? 'flex' : 'none')};
+         display: ${({ $isDesktopView }) => ($isDesktopView ? 'none' : 'flex')};

          height: 100%;

          flex-direction: column;
          justify-content: center;
          gap: 1rem;
      }
  `
landing/src/components/index.styles.ts (1)

115-131: Reconsider cursor style for ScenarioBox

The cursor: crosshair is an unusual choice for a UI container element. This cursor is typically used for precision selection (like in image editors) and might confuse users. Consider using a more standard cursor value like pointer if the element is clickable, or default if it's not.

export const ScenarioBox = styled.div`
    display: flex;
    flex-direction: column;

    width: 100%;
    height: 100%;

    gap: 1rem;
    padding: 3rem 2rem;

    background-color: var(--background-color);
    border-radius: 0.725rem;
    border: 2px solid var(--border-color);

-   cursor: crosshair;
+   cursor: pointer;
    user-select: none;
`
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9e18f5c and e97b8b0.

⛔ Files ignored due to path filters (3)
  • landing/package-lock.json is excluded by !**/package-lock.json
  • landing/public/logo.svg is excluded by !**/*.svg
  • landing/src/assets/logo/helm_inspect.svg is excluded by !**/*.svg
📒 Files selected for processing (32)
  • .github/workflows/sync-fork.yaml (1 hunks)
  • landing/.gitignore (1 hunks)
  • landing/.prettierrc (1 hunks)
  • landing/eslint.config.js (1 hunks)
  • landing/index.html (1 hunks)
  • landing/package.json (1 hunks)
  • landing/src/app.tsx (1 hunks)
  • landing/src/assets/styles/index.css (1 hunks)
  • landing/src/components/commandbox/commandbox.styles.ts (1 hunks)
  • landing/src/components/commandbox/commandbox.tsx (1 hunks)
  • landing/src/components/ctabox/ctabox.styles.ts (1 hunks)
  • landing/src/components/ctabox/ctabox.tsx (1 hunks)
  • landing/src/components/index.styles.ts (1 hunks)
  • landing/src/components/layout/layout.styles.ts (1 hunks)
  • landing/src/components/layout/layout.tsx (1 hunks)
  • landing/src/components/navbar/navbar.styles.ts (1 hunks)
  • landing/src/components/navbar/navbar.tsx (1 hunks)
  • landing/src/components/scenariobox/scenariobox.tsx (1 hunks)
  • landing/src/containers/how/how.styles.ts (1 hunks)
  • landing/src/containers/how/how.tsx (1 hunks)
  • landing/src/containers/landing/landing.styles.ts (1 hunks)
  • landing/src/containers/landing/landing.tsx (1 hunks)
  • landing/src/containers/why/why.styles.ts (1 hunks)
  • landing/src/containers/why/why.tsx (1 hunks)
  • landing/src/main.tsx (1 hunks)
  • landing/src/vite-env.d.ts (1 hunks)
  • landing/tsconfig.app.json (1 hunks)
  • landing/tsconfig.json (1 hunks)
  • landing/tsconfig.node.json (1 hunks)
  • landing/vercel.json (1 hunks)
  • landing/vite.config.ts (1 hunks)
  • pyproject.toml (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
landing/tsconfig.app.json

[error] 10-10: JSON standard does not allow comments.

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-16: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-16: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-16: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-18: JSON standard does not allow comments.

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 24-24: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 25-25: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 25-25: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 25-25: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 25-26: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

landing/tsconfig.node.json

[error] 9-9: JSON standard does not allow comments.

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-16: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 16-16: JSON standard does not allow comments.

(parse)


[error] 17-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 17-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 17-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 17-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 18-18: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 19-19: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 20-20: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 21-21: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 22-22: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-23: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 23-24: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

🪛 YAMLlint (1.35.1)
.github/workflows/sync-fork.yaml

[error] 47-47: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (27)
pyproject.toml (1)

15-15: Good addition for package inclusion.

This line ensures that all files within the helm_inspect directory are included in the package distribution, which is essential for proper packaging and distribution of the Python module.

landing/vercel.json (1)

1-3: Appropriate SPA routing configuration for Vercel deployment.

This configuration correctly handles client-side routing for a single-page application by redirecting all non-file requests to the root. This is essential for frameworks like React Router to function properly when deployed on Vercel.

landing/eslint.config.js (1)

1-28: Well-structured ESLint configuration for a modern React TypeScript project.

This configuration uses the recommended flat config format and includes appropriate plugins and rules for React and TypeScript development. The setup with React Hooks, React Refresh, and TypeScript ESLint provides a solid foundation for maintaining code quality in the landing page implementation.

landing/src/vite-env.d.ts (1)

1-1: LGTM: Correctly configured Vite TypeScript references.

The triple-slash directive properly references Vite client types, which enables TypeScript to recognize Vite-specific types and APIs.

landing/.prettierrc (1)

1-6: LGTM: Well-structured Prettier configuration.

The Prettier configuration is well-structured with clear formatting preferences. The choices for no semicolons, single quotes, 4-space tabs, and trailing commas will help maintain consistent code style throughout the project.

landing/tsconfig.json (1)

1-7: LGTM: TypeScript project references properly configured.

The configuration correctly sets up TypeScript project references, allowing for separation of app and Node.js configurations which is a best practice for Vite + React projects.

landing/src/components/layout/layout.tsx (2)

4-6: LGTM: Props interface is well-defined.

The LayoutProps interface properly types the children prop as React.ReactNode, which is the correct type for components that accept React elements as children.


8-15: LGTM: Layout component implementation is clean and follows best practices.

The component is well-structured with a clear separation of concerns - it provides a consistent layout wrapper with navigation while rendering children content in the appropriate container.

landing/src/containers/how/how.styles.ts (1)

1-29: Clean and Modular Styled Components:
The styled components HowWrapper and HowContent are defined clearly. They effectively use flex and grid layouts with responsive media queries to ensure a flexible design across devices. No issues found.

landing/.gitignore (1)

1-25: Well-Organized Git Ignore File:
The .gitignore file efficiently excludes log files, node modules, build outputs, and editor-specific files, which aligns with best practices.

landing/src/app.tsx (1)

1-35: LGTM! Well-structured React application with proper routing.

This is a well-organized React component using React Router for navigation. The code follows best practices by:

  • Using functional components with proper TypeScript typing
  • Implementing clean route structure with a fallback redirect
  • Organizing components with a logical layout hierarchy
  • Using fragments appropriately to avoid unnecessary DOM elements
landing/src/containers/landing/landing.tsx (2)

15-66: Clean implementation with smooth scrolling functionality!

The Landing component is well-implemented with a good user experience enhancement using smooth scrolling. The code is clean, follows React best practices, and properly handles the event to prevent default anchor behavior.


26-64: Well-structured hero section with responsive design considerations

The hero section is well-organized with clear content hierarchy and responsive design accommodations through the MobileTrim component. Good use of styled components for consistent styling and highlighting.

landing/tsconfig.app.json (1)

10-11:

✅ Verification successful

Comments in JSON configuration files

While TypeScript allows comments in configuration files for better documentation, note that these aren't standard JSON. This is perfectly fine for TypeScript configs, but may cause issues with some JSON parsing tools.

Also applies to: 18-19


🌐 Web query:

Does TypeScript officially support comments in tsconfig.json files?

💡 Result:

TypeScript officially supports comments in tsconfig.json files despite JSON's specifications prohibiting them. This exception is enabled by TypeScript's custom parsing logic, which interprets tsconfig.json as JSON with Comments (JSONC), allowing developers to include // and /* */ annotations for clarity[2][3][9][17].

Key Details:

  1. Practical Support:

    • TypeScript's compiler (tsc) and most IDEs (like VSCode, WebStorm) recognize comments in tsconfig.json without errors[3][9][17].
    • Example from a default tsconfig.json:
      {
        "compilerOptions": {
          // Enable strict type-checking
          "strict": true
        }
      }
  2. Tooling Integration:

    • VSCode automatically treats tsconfig.json as JSONC, eliminating syntax warnings[17].
    • Other tools (e.g., ESLint, Biome.js) may require configuration adjustments to handle comments in JSON files[1][17].
  3. Caveats:

    • Tools relying on strict JSON parsers (e.g., Node.js for package.json) will fail if comments are present[1][17].
    • JSONC support is specific to TypeScript’s ecosystem and not universally valid JSON[9][12].

For projects outside TypeScript, use .jsonc extensions or build steps to strip comments before processing[1][17].

Citations:


Action: Confirm JSONC Comments in tsconfig File

The use of comments (e.g., /* Bundler mode */) in this configuration is valid since TypeScript officially supports "JSON with Comments" in tsconfig files. Keep in mind that while this is perfectly acceptable in the TypeScript ecosystem (and supported by tools like VSCode), it may still cause issues with any tooling that strictly expects standard JSON. The same consideration applies to the comment at lines 18–19.

🧰 Tools
🪛 Biome (1.9.4)

[error] 10-10: JSON standard does not allow comments.

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

landing/src/containers/how/how.tsx (1)

62-143: Well-structured How component with clear information hierarchy

The How component effectively communicates the product's workflow using a combination of textual explanation and visual demonstration. The nested list structure clearly conveys the feature set, and the AnimatedScenarioBox provides an interactive element for better user engagement.

landing/src/containers/why/why.styles.ts (2)

3-15: Well-implemented responsive container with appropriate flexbox layout

The WhyWrapper component is well-structured with proper flexbox configuration and responsive design. The padding adjustment for smaller screens is a good practice for maintaining appropriate spacing across different devices.


17-27: Good responsive grid implementation

The WhyContent component effectively uses CSS Grid with a responsive layout that adapts from two columns to one column on smaller screens. This approach ensures content readability and proper spacing across different viewport sizes.

landing/src/components/ctabox/ctabox.tsx (2)

3-9: Well-defined props interface with appropriate optionals

The CTABoxProps interface is clearly defined with required and optional properties. Using TypeScript interfaces for props provides good type safety and self-documentation.


30-42: Clean component implementation with proper styled components usage

The component rendering is clean and well-structured. Good use of conditional props for target attribute and the transient prop syntax ($left) for styled-components.

landing/src/containers/why/why.tsx (1)

68-125: Effective use of components for responsive and interactive content

The Why component is well-structured with good use of:

  1. AnimatedScenarioBox for showcasing problem scenarios
  2. CTABox for directing users to related information
  3. Responsive components like MobileTrim
  4. Highlight components for emphasizing important terms

The component effectively explains the purpose of Helm Inspect by first illustrating a problem scenario and then explaining how the tool addresses it.

landing/src/components/layout/layout.styles.ts (2)

3-9: Well-structured layout with appropriate grid configuration

The LayoutWrapper component establishes a good foundation for the page layout with a grid structure and an appealing gradient background.


11-23: Good responsive content container implementation

The LayoutContent component effectively manages the content flow with appropriate spacing and responsive padding adjustments for different screen sizes.

landing/src/components/commandbox/commandbox.styles.ts (1)

4-22: LGTM - Clean styling with good structure

The component styling is well-organized and uses CSS variables effectively. This makes the styles more maintainable and enables theming.

landing/src/components/ctabox/ctabox.styles.ts (1)

1-31: LGTM - Well-structured styled components with responsive design

The styled components are well-structured, with good use of flexbox for layout and responsive design for different screen sizes. The use of TypeScript props with the correct transient prop syntax ($left) follows styled-components best practices.

landing/package.json (1)

16-19:

✅ Verification successful

Verify compatibility with React 19 and React Router 7

The package.json specifies React 19 and React Router 7, which are currently future versions not yet officially released. This might lead to compatibility issues or unexpected behavior.


🌐 Web query:

What is the latest stable version of React and React Router as of March 2025?

💡 Result:

As of March 2025, the latest stable versions are:

React
Latest: v19.0.0 (Released Dec 5, 2024)

  • Introduced Actions for async state management[4][6][8]
  • Added new hooks like useActionState and useOptimistic[4]
  • Removed deprecated APIs like propTypes and string refs[8][12]

React Router
Latest: v7.3.0 (Released March 2025)

  • Added split route modules for optimized code splitting[11][15]
  • Introduced framework mode with Remix-inspired features[15]
  • Includes new navigation APIs and TypeScript improvements[5][9][13]

Both libraries follow semantic versioning, with React 19 receiving active support and security updates[6], while React Router continues to evolve with performance-focused architectural changes[7][11]. Developers should check official documentation (react.dev[14] and reactrouter.com[9]) for migration guidance when upgrading.

Citations:


Compatibility Verified for React 19 and React Router 7

The web query confirms that as of March 2025 the versions specified in landing/package.json (React 19.0.0 and React Router 7.3.0) are the latest stable releases. There is no compatibility issue with using these versions.

landing/src/components/index.styles.ts (2)

41-72: Great job implementing responsive ButtonCSS

The ButtonCSS implementation is well-structured with appropriate transitions, hover states, and responsive adjustments. Good use of CSS variables for theming flexibility.


3-39: Well-structured responsive containers

The HeroSection and HeroContentWrapper components have well-defined media queries that ensure proper responsiveness across different device sizes. The max-width constraint on the content wrapper is a good practice for readability on larger screens.

Copy link
Contributor

@Vaish24navi Vaish24navi left a comment

Choose a reason for hiding this comment

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

This is the coolest landing page @niyasrad , amazing work! 🥂 🚀 💜

@Vaish24navi Vaish24navi merged commit 0e80b35 into main Mar 9, 2025
3 checks passed
@Vaish24navi Vaish24navi deleted the feature/landing-page branch March 9, 2025 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: implement responsive landing page for helm-inspect
2 participants