Skip to content

Conversation

@Cllaude99
Copy link
Member

@Cllaude99 Cllaude99 commented Apr 21, 2025

목적
  • 홈화면의 우측하단에 보일 플로팅 버튼을 구현해요.
작업 내용
  • app/home/floating

    • FloatingPanelLayout.tsx
    • FloatingWidgetLayout.tsx
    • FloatingWidget.tsx
    • FloatingPanel.tsx
    • FloatingButton.tsx
  • hooks/useToggle.ts

  • hooks/useTab.tsx

  • 플로팅 버튼에 대한 명칭을 FloatingWidget으로 하고 해당 위젯은 FloatingPanel.tsx과 FloatingButton.tsx를 포함하도록 하였습니다.

  • FloatingPanel.tsx의 경우에는 useTab훅을 사용하여 탭에 대한 로직을 추상화 하였습니다.

필수 리뷰어
이슈 번호
비고

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Introduced a floating widget on the Home page, accessible from the bottom-right corner.
    • The floating widget includes a tabbed panel with sections for AI chart analysis, AI recommendations, and function help.
    • Interactive floating button allows users to open and close the widget.
  • Style
    • Added new layouts and visual enhancements for the floating panel and widget.
  • Bug Fixes
    • Minor correction to button style formatting.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 21, 2025

Walkthrough

This change introduces a floating widget feature to the home page. It adds a new FloatingWidget component to the home page layout, which displays a floating button at the bottom-right corner. When the button is clicked, a floating panel appears, presenting a tabbed interface with three sections: AI chart analysis, AI chart recommendations, and function help. The implementation includes several new components for layout, tab management, and UI logic, as well as custom hooks for toggling state, detecting clicks outside the widget, and managing tab selection. No changes are made to the signatures of existing exported entities.

Changes

File(s) Change Summary
src/app/home/index.tsx Imports and renders the new FloatingWidget component in the home page layout; minor formatting fix in modal options; contains an erroneous import statement inside a CSS template literal (non-functional).
src/components/app/home/floating/AIChartAnalyze.tsx
AIChartRecommendation.tsx
FunctionHelp.tsx
Adds new simple React components that render placeholder divs for each tab's content: AI chart analysis, AI recommendations, and function help.
src/components/app/home/floating/FloatingButton.tsx Adds a button component that toggles the floating panel, displaying different SVG icons based on open/closed state.
src/components/app/home/floating/FloatingPanel.tsx Adds a tabbed panel component with three tabs, each showing different content components and using icons for active/inactive states; uses a custom useTab hook for tab state management.
src/components/app/home/floating/FloatingPanelLayout.tsx Adds a styled layout component for the floating panel, handling positioning, sizing, and decorative elements.
src/components/app/home/floating/FloatingWidgetLayout.tsx Adds a layout component for the floating widget with fixed positioning and ref forwarding for container reference; resets button styles inside.
src/components/app/home/floating/floatingWidget.tsx Introduces the main floating widget component, managing open/close state with useToggle, click-outside detection with useClickOutside, and rendering the floating button and panel conditionally.
src/hooks/useClickOutside.tsx Implements a custom hook to detect clicks outside a referenced element and trigger a handler function; sets up and cleans up event listeners for mousedown and touchstart.
src/hooks/useTab.tsx Implements a generic custom hook and associated components for managing tab state and rendering a tabbed interface with customizable triggers, icons, and content panels using Emotion CSS-in-JS for styling.
src/hooks/useToggle.ts Adds a custom hook for boolean state management with toggle and setter functions using React's useState.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant FloatingButton
    participant FloatingWidget
    participant FloatingPanel

    User->>FloatingButton: Clicks button
    FloatingButton->>FloatingWidget: onClick (toggle open)
    alt Panel is opened
        FloatingWidget->>FloatingPanel: Render panel with tabs
        User->>FloatingPanel: Interacts with tab triggers
        FloatingPanel->>FloatingPanel: Switches tab content
    end
    User->>FloatingWidget: Clicks outside widget
    FloatingWidget->>FloatingWidget: Detects click outside
    FloatingWidget->>FloatingPanel: Closes panel
Loading

Poem

🐇
A button floats, a panel glides,
With tabs for wisdom AI provides.
Click me open, click me closed,
Chart secrets and tips are now exposed.
In the corner, bright and neat—
A widget makes the home page sweet!


📜 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 2fc8d52 and 62eace4.

📒 Files selected for processing (3)
  • src/components/app/home/floating/FloatingPanel.tsx (1 hunks)
  • src/components/app/home/floating/FloatingPanelLayout.tsx (1 hunks)
  • src/components/app/home/floating/FloatingWidgetLayout.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/components/app/home/floating/FloatingWidgetLayout.tsx
  • src/components/app/home/floating/FloatingPanel.tsx
  • src/components/app/home/floating/FloatingPanelLayout.tsx

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 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
Contributor

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

🧹 Nitpick comments (12)
src/hooks/useClickOutside.tsx (1)

1-23: Well-structured hook for detecting outside clicks

The implementation correctly handles both mouse and touch events, properly cleans up event listeners, and has appropriate TypeScript typing. This is a common pattern for implementing modals, dropdowns, and other dismissible UI elements.

One minor suggestion: since this file doesn't contain JSX, consider using a .ts extension instead of .tsx.

src/components/app/home/floating/FloatingPanelLayout.tsx (2)

7-23: Consider improving responsiveness for different screen sizes

The component uses fixed dimensions that may not adapt well to all devices:

  • width: 390px could overflow on smaller mobile screens
  • Fixed positioning (bottom: 9rem; right: 1rem) may need adjustments on different viewports

Consider using responsive units (%, rem) or media queries for better adaptability across devices.

-        position: absolute;
-        bottom: 9rem;
-        right: 1rem;
+        position: absolute;
+        bottom: min(9rem, 15%);
+        right: min(1rem, 5%);
-          width: 390px;
+          width: min(390px, 90vw);

15-23: Add z-index to prevent potential stacking context issues

The floating panel might overlap with other elements on the page. Adding a z-index would ensure it appears above other content.

          background-color: white;
          padding: 1.5rem;
          border-radius: 24px;
          box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
          border: 1px solid #e5e7eb;
          position: relative;
+          z-index: 10;
src/hooks/useTab.tsx (2)

73-89: Consider extracting hardcoded colors to theme variables

The tab styling uses hardcoded color values (#3076d4, #8e8e8e) which might make it difficult to maintain consistent styling across the application. Consider extracting these to theme constants or CSS variables.

-          color: ${isActive ? "#3076d4" : "#8e8e8e"};
+          color: ${isActive ? "var(--color-primary)" : "var(--color-text-secondary)"};

// Later in the CSS
-            background-color: ${isActive ? "#3076d4" : "transparent"};
+            background-color: ${isActive ? "var(--color-primary)" : "transparent"};

45-59: Consider a more flexible tab distribution method

Using justify-content: space-around for tab distribution might not work optimally when there are many tabs. Consider using justify-content: space-between or a more flexible approach like CSS Grid for better space distribution.

-          justify-content: space-around;
+          justify-content: space-between;
src/app/home/index.tsx (3)

30-30: Fix import casing for consistency

The import statement uses a lowercase first letter for floatingWidget while React components should use PascalCase naming conventions.

-import FloatingWidget from "@/components/app/home/floating/floatingWidget";
+import FloatingWidget from "@/components/app/home/floating/FloatingWidget";

508-508: Add positioning or container for FloatingWidget

The FloatingWidget component is added directly to the section without any positioning context. This may cause layout issues depending on how the component is implemented.

Consider wrapping it in a positioned container:

-<FloatingWidget />
+<div
+  css={css`
+    position: relative;
+    width: 100%;
+  `}
+>
+  <FloatingWidget />
+</div>

115-124: JSDoc function documentation has a typo

The JSDoc comment for openSubscriptionModal has a spacing issue in "flowbit서비스" (should be "flowbit 서비스").

 /**
- * @description 구독버튼 클릭시 flowbit서비스에 대해 주기적으로 구독할 수 있는 함수입니다.
+ * @description 구독버튼 클릭시 flowbit 서비스에 대해 주기적으로 구독할 수 있는 함수입니다.
 */
src/components/app/home/floating/floatingWidget.tsx (1)

1-28: Well-structured component with clean implementation!

This floating widget implementation follows good React practices:

  • Uses functional components with hooks for state management
  • Employs custom hooks for toggle behavior and outside click detection
  • Properly passes props and refs to child components
  • Has clear separation of concerns between state management and rendering

Consider enhancing accessibility by adding ARIA attributes to help screen reader users understand this interactive element.

 return (
   <FloatingWidgetLayout containerRef={floatingRef}>
     {isOpen && <FloatingPanel />}
-    <FloatingButton isOpen={isOpen} onClick={toggleOpen} />
+    <FloatingButton 
+      isOpen={isOpen} 
+      onClick={toggleOpen}
+      aria-expanded={isOpen}
+      aria-haspopup="true"
+      aria-label={isOpen ? "닫기" : "기능 메뉴 열기"} 
+    />
   </FloatingWidgetLayout>
 );
src/components/app/home/floating/FloatingWidgetLayout.tsx (1)

1-42: Good layout component with proper ref handling.

The layout implementation uses proper techniques:

  • Correctly implements forwardRef for ref handling
  • Properly positions the floating widget
  • Sets a display name for debugging
  • Resets button styles to avoid browser defaults

Consider making the position more responsive for mobile devices, as fixed positioning with specific rem values might cause display issues on smaller screens.

 <div
   css={css`
     position: fixed;
     bottom: 5rem;
     right: 8rem;
+    @media (max-width: 768px) {
+      bottom: 2rem;
+      right: 2rem;
+    }
     button {
       background: transparent;
       border: none;
       padding: 0;
       margin: 0;
       outline: none;
     }
   `}
 >
src/components/app/home/floating/FloatingPanel.tsx (2)

14-18: Consider extracting tab keys to a constants file.

The tab key definitions would be more maintainable if extracted to a separate constants file, especially if they might be used elsewhere in the application.

Consider moving this to a separate constants file:

// src/constants/tabKeys.ts
export const FloatingPanelTabKey = {
  CHART_ANALYZE: "CHART_ANALYZE",
  CHART_RECOMMENDATION: "CHART_RECOMMENDATION",
  FUNCTION_HELP: "FUNCTION_HELP",
} as const;

export type FloatingPanelTabKeyType = keyof typeof FloatingPanelTabKey;

Then import and use it in this component.


1-12: Consider lazy-loading icon assets for performance.

The component imports multiple SVG icons that might increase the initial bundle size. Consider lazy-loading these assets, especially if the floating panel isn't immediately visible when the page loads.

You could use dynamic imports with React.lazy and Suspense to load these icons on demand:

import { lazy, Suspense } from 'react';
import FloatingPanelLayout from "./FloatingPanelLayout";
import { useTab } from "@/hooks/useTab";

const IconAIChartAnalyzeInactive = lazy(() => import('@/assets/IconAIChartAnalyzeInactive.svg?react'));
const IconAIChartAnalyzeActive = lazy(() => import('@/assets/IconAIChartAnalyzeActive.svg?react'));
// Same for other icons

// Then wrap icon usage in Suspense
<Suspense fallback={<div>Loading...</div>}>
  {isActive ? <IconAIChartAnalyzeActive /> : <IconAIChartAnalyzeInactive />}
</Suspense>

This approach would be especially beneficial if the SVG files are large or if there are many of them.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 06e57af and f47bbce.

⛔ Files ignored due to path filters (8)
  • src/assets/IconAIChartAnalyzeActive.svg is excluded by !**/*.svg
  • src/assets/IconAIChartAnalyzeInactive.svg is excluded by !**/*.svg
  • src/assets/IconAIChartRecommendActive.svg is excluded by !**/*.svg
  • src/assets/IconAIChartRecommendInactive.svg is excluded by !**/*.svg
  • src/assets/IconFloatingClose.svg is excluded by !**/*.svg
  • src/assets/IconFloatingOpen.svg is excluded by !**/*.svg
  • src/assets/IconFunctionHelpActive.svg is excluded by !**/*.svg
  • src/assets/IconFunctionHelpInactive.svg is excluded by !**/*.svg
📒 Files selected for processing (12)
  • src/app/home/index.tsx (3 hunks)
  • src/components/app/home/floating/AIChartAnalyze.tsx (1 hunks)
  • src/components/app/home/floating/AIChartRecommendation.tsx (1 hunks)
  • src/components/app/home/floating/FloatingButton.tsx (1 hunks)
  • src/components/app/home/floating/FloatingPanel.tsx (1 hunks)
  • src/components/app/home/floating/FloatingPanelLayout.tsx (1 hunks)
  • src/components/app/home/floating/FloatingWidgetLayout.tsx (1 hunks)
  • src/components/app/home/floating/FunctionHelp.tsx (1 hunks)
  • src/components/app/home/floating/floatingWidget.tsx (1 hunks)
  • src/hooks/useClickOutside.tsx (1 hunks)
  • src/hooks/useTab.tsx (1 hunks)
  • src/hooks/useToggle.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/components/app/home/floating/FloatingPanel.tsx (5)
src/hooks/useTab.tsx (1)
  • useTab (28-123)
src/components/app/home/floating/FloatingPanelLayout.tsx (1)
  • FloatingPanelLayout (4-41)
src/components/app/home/floating/AIChartAnalyze.tsx (1)
  • AIChartAnalyze (1-3)
src/components/app/home/floating/AIChartRecommendation.tsx (1)
  • AIChartRecommendation (1-3)
src/components/app/home/floating/FunctionHelp.tsx (1)
  • FunctionHelp (1-3)
src/components/app/home/floating/floatingWidget.tsx (4)
src/hooks/useToggle.ts (1)
  • useToggle (3-13)
src/hooks/useClickOutside.tsx (1)
  • useClickOutside (3-23)
src/components/app/home/floating/FloatingPanel.tsx (1)
  • FloatingPanel (13-62)
src/components/app/home/floating/FloatingButton.tsx (1)
  • FloatingButton (9-18)
🔇 Additional comments (3)
src/hooks/useToggle.ts (1)

1-13: Well-implemented toggle hook with clean API

This custom hook follows React best practices and provides a clean, type-safe API for managing toggle state. The three returned properties (value, toggleValue, and setValue) give the consumer complete control over the toggle state.

src/components/app/home/floating/FloatingPanelLayout.tsx (1)

26-37: Nice visual touch with the speech bubble pointer

The rotated square creates a nice visual cue pointing to the button that likely triggers this panel. Good attention to detail.

src/hooks/useTab.tsx (1)

28-123: Well-implemented compound component pattern for tabs

The hook provides a flexible, type-safe API for creating tabbed interfaces. The compound component pattern with static subcomponents (List, Trigger, Content, ContentWrapper) creates a clean, intuitive API for consumers.

Comment on lines +1 to +3
export default function FunctionHelp() {
return <div>FunctionHelp</div>;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Component implementation is a placeholder

This component is currently just a placeholder returning static text. As part of the floating panel's tabbed interface, it should be properly implemented with actual function help content.

Consider implementing the actual help content with proper styling and information about the application's features:

-export default function FunctionHelp() {
-  return <div>FunctionHelp</div>;
+export default function FunctionHelp() {
+  return (
+    <div className="function-help-container">
+      <h3>기능 도움말</h3>
+      <ul>
+        <li>
+          <strong>차트 분석:</strong> 코인 데이터를 분석하여 추세를 파악할 수 있습니다.
+        </li>
+        <li>
+          <strong>AI 추천:</strong> AI 기반 코인 투자 추천을 확인할 수 있습니다.
+        </li>
+        {/* Add more help items as needed */}
+      </ul>
+    </div>
+  );
}
📝 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
export default function FunctionHelp() {
return <div>FunctionHelp</div>;
}
export default function FunctionHelp() {
return (
<div className="function-help-container">
<h3>기능 도움말</h3>
<ul>
<li>
<strong>차트 분석:</strong> 코인 데이터를 분석하여 추세를 파악할 있습니다.
</li>
<li>
<strong>AI 추천:</strong> AI 기반 코인 투자 추천을 확인할 있습니다.
</li>
{/* Add more help items as needed */}
</ul>
</div>
);
}

Comment on lines +1 to +3
export default function AIChartAnalyze() {
return <div>AIChartAnalyze</div>;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Component implementation is a placeholder

This component is currently just a placeholder with static text. Since this is part of the main AI feature set (차트해석/Chart Analysis), it should contain the actual implementation for chart analysis functionality.

Consider implementing the actual AI chart analysis content with proper UI components:

-export default function AIChartAnalyze() {
-  return <div>AIChartAnalyze</div>;
+export default function AIChartAnalyze() {
+  return (
+    <div className="ai-chart-analyze">
+      <h3>AI 차트해석</h3>
+      <div className="chart-analysis-content">
+        {/* Implement the actual chart analysis UI here */}
+        <p>선택된 코인의 차트를 AI가 분석 중입니다...</p>
+        {/* Add loading state, analysis results, etc. */}
+      </div>
+    </div>
+  );
}
📝 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
export default function AIChartAnalyze() {
return <div>AIChartAnalyze</div>;
}
export default function AIChartAnalyze() {
return (
<div className="ai-chart-analyze">
<h3>AI 차트해석</h3>
<div className="chart-analysis-content">
{/* Implement the actual chart analysis UI here */}
<p>선택된 코인의 차트를 AI가 분석 중입니다...</p>
{/* Add loading state, analysis results, etc. */}
</div>
</div>
);
}

Comment on lines +1 to +3
export default function AIChartRecommendation() {
return <div>AIChartRecommendation</div>;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Component implementation is a placeholder

This component is currently just a placeholder with static text. Since this is part of the main AI feature set (AI 추천판단/Chart Recommendation), it should contain the actual implementation for AI-based recommendation functionality.

Consider implementing the actual AI recommendation content:

-export default function AIChartRecommendation() {
-  return <div>AIChartRecommendation</div>;
+export default function AIChartRecommendation() {
+  return (
+    <div className="ai-chart-recommendation">
+      <h3>AI 추천판단</h3>
+      <div className="recommendation-content">
+        {/* Implement the actual recommendation UI here */}
+        <p>현재 코인 시장에 대한 AI 추천을 분석 중입니다...</p>
+        {/* Add recommendation cards, analysis results, etc. */}
+      </div>
+    </div>
+  );
}
📝 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
export default function AIChartRecommendation() {
return <div>AIChartRecommendation</div>;
}
export default function AIChartRecommendation() {
return (
<div className="ai-chart-recommendation">
<h3>AI 추천판단</h3>
<div className="recommendation-content">
{/* Implement the actual recommendation UI here */}
<p>현재 코인 시장에 대한 AI 추천을 분석 중입니다...</p>
{/* Add recommendation cards, analysis results, etc. */}
</div>
</div>
);
}

Copy link
Contributor

@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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f47bbce and 79f6334.

📒 Files selected for processing (1)
  • src/app/home/index.tsx (4 hunks)
🧰 Additional context used
🪛 GitHub Check: build
src/app/home/index.tsx

[failure] 30-30:
Cannot find module '@/components/app/home/floating/FloatingWidget' or its corresponding type declarations.

🪛 GitHub Actions: Build Test
src/app/home/index.tsx

[error] 30-30: TypeScript error TS2307: Cannot find module '@/components/app/home/floating/FloatingWidget' or its corresponding type declarations.

🔇 Additional comments (2)
src/app/home/index.tsx (2)

122-122: LGTM! Good practice with trailing comma.

Adding a trailing comma in object literals is good practice as it makes future additions cleaner and reduces diff noise.


509-509: LGTM! Appropriate placement of FloatingWidget.

The FloatingWidget is properly placed as a direct child of the main section, which will allow it to appear at the bottom right corner of the home screen as intended.

Once the import issue is fixed, please verify that the floating button appears in the correct position and functions as expected.

Comment on lines +229 to +230
height: 4.5rem;import FloatingWidget from '../../components/app/home/floating/FloatingWidget';
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove erroneous import statement in CSS template literal.

There's an import statement incorrectly placed inside a CSS template literal for the button's height. This will cause styling issues and potentially runtime errors.

-                  height: 4.5rem;import FloatingWidget from '../../components/app/home/floating/FloatingWidget';
-
+                  height: 4.5rem;

import { loginState } from "@/store/user";
import { SubscriptionModalContent } from "@/components/common/modal/SubscriptionModalContent";

import FloatingWidget from "@/components/app/home/floating/FloatingWidget";
Copy link
Contributor

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 for FloatingWidget component.

The build is failing because the import path is incorrect. According to the PR objectives, the floating button components are created in the app/home/floating directory, but you're importing from components/app/home/floating.

-import FloatingWidget from "@/components/app/home/floating/FloatingWidget";
+import FloatingWidget from "@/app/home/floating/FloatingWidget";

Alternatively, if you've placed the component in the components directory instead of the app directory, make sure the file exists at that location.

📝 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
import FloatingWidget from "@/components/app/home/floating/FloatingWidget";
-import FloatingWidget from "@/components/app/home/floating/FloatingWidget";
+import FloatingWidget from "@/app/home/floating/FloatingWidget";
🧰 Tools
🪛 GitHub Check: build

[failure] 30-30:
Cannot find module '@/components/app/home/floating/FloatingWidget' or its corresponding type declarations.

🪛 GitHub Actions: Build Test

[error] 30-30: TypeScript error TS2307: Cannot find module '@/components/app/home/floating/FloatingWidget' or its corresponding type declarations.

Copy link
Collaborator

@klmhyeonwoo klmhyeonwoo left a comment

Choose a reason for hiding this comment

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

컴파운드 패턴이랑 추상화 너무너무 좋네요!
조금의 코멘트를 남겨보았습니다, 너무너무 고생하셨습니다!

CHART_RECOMMENDATION: "CHART_RECOMMENDATION",
FUNCTION_HELP: "FUNCTION_HELP",
} as const;

Copy link
Collaborator

@klmhyeonwoo klmhyeonwoo Apr 21, 2025

Choose a reason for hiding this comment

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

const tabItems = [
  {
    key: TabKey.CHART_ANALYZE,
    label: "AI 차트해석",
    activeIcon: <IconAIChartAnalyzeActive />,
    inactiveIcon: <IconAIChartAnalyzeInactive />,
    content: <AIChartAnalyze />,
  },
  {
    key: TabKey.CHART_RECOMMENDATION,
    label: "AI 추천판단",
    activeIcon: <IconAIChartRecommendActive />,
    inactiveIcon: <IconAIChartRecommendInactive />,
    content: <AIChartRecommendation />,
  },
  ...
];

이렇게 위와 같이 중복적으로 사용되는 값들을 변수로 구조화하게 된다면 추후 수정 사항이 발생했을 때 변수 구조 부분만 살짝 바꾸면서 관련 컴포넌트들을 Map 형태로 쉽게 나타낼 수 있을 것 같다는 생각이 드는데 어떻게 생각하시나영!

<FloatingPanelLayout>
  <Tabs>
    <Tabs.List>
        {tabItems.map(({ key, label, activeIcon, inactiveIcon }) => (
            <Tabs.Trigger
            key={key}
            value={key}
            activeIcon={activeIcon}
            inactiveIcon={inactiveIcon}>
                {label}
            </Tabs.Trigger>
        ))}
    </Tabs.List>

    <Tabs.ContentWrapper>
        {tabItems.map(({ key, content }) => (
            <Tabs.Content key={key} value={key}>
                {content}
            </Tabs.Content>
        ))}
    </Tabs.ContentWrapper>
  </Tabs>
</FloatingPanelLayout>

Copy link
Member Author

@Cllaude99 Cllaude99 Apr 22, 2025

Choose a reason for hiding this comment

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

넵! 말씀하신 코드 리뷰를 바탕으로 제가 작성한 코드를 다시 보니, 새로운 탭에 수정이 생기거나 삭제 또는 추가가 발생할 경우에 어려움이 있을 것 같다고 생각했어요!
따라서 코드리뷰를 반영하여 tabItems를 만들는 방식으로 코드를 리팩토링 하였습니다. 이렇게 수정해보니 결과적으로 전체 흐름을 이전보다 깔끔하게 볼 수 있어서 좋은 것 같고 수정이 발생할 때에도 변경이 쉬워질 것 같아서 좋은 것 같아요!


export default function FloatingPanelLayout({ children }: PropsWithChildren) {
return (
<div
Copy link
Collaborator

Choose a reason for hiding this comment

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

지금 플로우빗 기존 코드에서 느끼고 있는 아쉬운 점들은 모두 엘리먼트에 인라인으로 css props 형태로 스타일이 적용되고 있는 부분인데 이 부분을 새롭게 만드는 컴포넌트부터는 변수 처리하여 하단으로 영역 구분을 하는 것은 어떨까요?!

Copy link
Member Author

Choose a reason for hiding this comment

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

이 부분을 제가 놓치고 있었네요. FloatingPanelLayout.tsx 뿐만 아니라 FloatingWidgetLayout.tsx도 css 적용을 리팩토링 했습니다. 아래에 스타일 관련 코드를 변수명에 넣는 방식으로 수정했어요!

Copy link
Contributor

@joeunSong joeunSong left a comment

Choose a reason for hiding this comment

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

고생 많으셨습니다!!

@Cllaude99 Cllaude99 merged commit d1bcae3 into main May 7, 2025
2 checks passed
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.

4 participants