Skip to content

Conversation

@hamo-o
Copy link
Contributor

@hamo-o hamo-o commented Apr 12, 2025

#️⃣ 연관된 이슈>

📝 작업 내용> 이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능)

논의 주도자의 경우, 논의 수정과 삭제를 할 수 있도록 합니다.

🙏 여기는 꼭 봐주세요! > 리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

Summary by CodeRabbit

  • New Features

    • Added buttons for editing and deleting discussions, including confirmation modals for deletion.
    • Introduced a dedicated button for accessing the discussion edit page, visible only to discussion hosts.
  • Enhancements

    • Discussion editing and deletion now update and invalidate relevant data automatically, ensuring up-to-date information throughout the app.
    • The discussion edit page now loads existing discussion data dynamically based on the URL.
  • Bug Fixes

    • Improved loading state handling by switching from isLoading to isPending for a smoother user experience.
  • Refactor

    • Simplified form and button logic for discussion creation, editing, and deletion, making components more modular and maintainable.
  • Style

    • Adjusted layout and alignment in discussion title and form components for improved readability and usability.

@hamo-o hamo-o added the 🖥️ FE Frontend label Apr 12, 2025
@hamo-o hamo-o added this to the 😉 9차 스프린트 milestone Apr 12, 2025
@coderabbitai
Copy link

coderabbitai bot commented Apr 12, 2025

Walkthrough

This update introduces new API methods for editing and deleting discussions, adds corresponding React hooks for mutation operations, and refactors UI components to support discussion editing and deletion. The form logic is modularized, and the edit page is now data-driven, fetching discussion details dynamically. Several components are updated for state management and improved structure.

Changes

File(s) Change Summary
.../api/index.ts Added putDiscussion and deleteDiscussion methods to the API client for updating and deleting discussions.
.../api/mutations.ts Refactored useDiscussionMutation to remove callback, added useDiscussionEditMutation and useDiscussionDeleteMutation hooks for editing and deleting discussions, updated cache invalidation and navigation logic.
.../api/queries.ts Changed useDiscussionQuery to use and return isPending instead of isLoading.
.../ui/DiscussionEditButton/index.tsx Introduced new DiscussionEditButton component, conditionally rendering an edit button for discussion hosts.
.../ui/DiscussionForm/EnrollButton.tsx Added AddButton, EditButton, and DeleteButton components for modular discussion form actions, including modal confirmation for deletion.
.../ui/DiscussionForm/FormButton.tsx Refactored FormButton to be stateless, delegating all logic to imported button components, and removed all internal mutation, navigation, and state logic.
.../ui/DiscussionForm/index.tsx Reformatted the DiscussionForm props type annotation for readability; no logic changes.
.../ui/DiscussionTitle/index.tsx Updated layout and replaced isLoading with isPending; added DiscussionEditButton to the title component.
.../DiscussionEditPage/index.tsx Refactored edit page to fetch discussion data based on route parameter, using hooks and conditional rendering; form is now populated dynamically.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DiscussionForm
    participant API
    participant Router
    participant Modal

    User->>DiscussionForm: Clicks Edit or Delete Button
    alt Edit
        DiscussionForm->>API: PUT /api/v1/discussion/{id}
        API-->>DiscussionForm: Updated discussion data
        DiscussionForm->>Router: Navigate to /discussion/{id}
    else Delete
        DiscussionForm->>Modal: Show confirmation modal
        Modal->>User: User confirms
        DiscussionForm->>API: DELETE /api/v1/discussion/{id}
        API-->>DiscussionForm: Success
        DiscussionForm->>Router: Navigate to home
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Possibly related PRs

  • #190: Introduced initial discussion creation and retrieval API methods and UI markup; both PRs modify the discussion API module, focusing on different HTTP methods and mutation hooks.

Suggested reviewers

  • dioo1461

Poem

A bunny hops through code so bright,
With edit, delete, and buttons light.
Discussions now can change or fade,
With hooks and forms all smartly made.
A modal pops—"Are you sure?"—
And off you go, your path secure!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/fe/discussion-edit-delete

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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests 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.

@hamo-o hamo-o force-pushed the feature/fe/discussion-edit-delete branch from f19acc5 to 6e2406d Compare May 12, 2025 01:03
@hamo-o hamo-o marked this pull request as ready for review May 12, 2025 01:15
@hamo-o hamo-o requested a review from dioo1461 as a code owner May 12, 2025 01:15
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: 0

🧹 Nitpick comments (6)
frontend/src/pages/DiscussionPage/DiscussionEditPage/index.tsx (1)

12-14: Consider adding error handling

While the loading state is handled appropriately, there's no specific handling for query errors. Consider adding error handling to provide feedback to users when the discussion data cannot be fetched.

-  const { discussion, isPending } = useDiscussionQuery(id);
+  const { discussion, isPending, isError } = useDiscussionQuery(id);

-  if (isPending || !discussion) return null;
+  if (isPending) return <LoadingSpinner />; // Or your loading component
+  if (isError || !discussion) return <ErrorMessage message="토론을 불러오는 데 실패했습니다." />; // Or your error component
frontend/src/features/discussion/ui/DiscussionForm/EnrollButton.tsx (2)

55-57: Consider adding loading state for deletion

The delete operation might take some time to complete. Consider adding a loading state to provide feedback to the user during the deletion process and prevent multiple clicks.

  const { createModal, onModalClose } = useGlobalModal();
-  const { mutate } = useDiscussionDeleteMutation(onModalClose);
+  const { mutate, isPending } = useDiscussionDeleteMutation(onModalClose);

  const handleClickDeleteDiscussion = () => {
    createModal({
      // ... existing code ...
      children: (
        <Flex
          align='flex-end'
          height='100%'
          justify='flex-end'
        >
          <Button
-            onClick={() => mutate()}
+            onClick={() => mutate()}
+            disabled={isPending}
+            isLoading={isPending}
            size='xl'
            variant='re'
          >
            삭제하기
          </Button>
        </Flex>
      ),
    });
  };

6-10: Consider organizing imports alphabetically

For better readability and easier maintenance, consider organizing your imports alphabetically within each import section.

-import { 
-  useDiscussionDeleteMutation, 
-  useDiscussionEditMutation, 
-  useDiscussionMutation,
-} from '../../api/mutations';
+import { 
+  useDiscussionDeleteMutation, 
+  useDiscussionEditMutation, 
+  useDiscussionMutation,
+} from '../../api/mutations';
frontend/src/features/discussion/api/mutations.ts (3)

32-51: Consider adding error handling to the edit mutation.

The implementation of useDiscussionEditMutation follows good practices by extracting parameters from the route and invalidating relevant caches, including the specific discussion detail cache. However, there's no error handling in case the API call fails.

export const useDiscussionEditMutation = () => {
  const { id } = useParams({ from: '/_main/discussion/edit/$id' });
  const queryClient = useQueryClient();
  const navigate = useNavigate();

-  const { mutate } = useMutation({
+  const { mutate, isError, error } = useMutation({
    mutationFn: (body: DiscussionRequest) => discussionApi.putDiscussion(id, body),
    onSuccess: (_) => {
      queryClient.invalidateQueries({ queryKey: upcomingQueryKey });
      queryClient.invalidateQueries({ queryKey: ongoingQueryKey.all });
      queryClient.invalidateQueries({ queryKey: discussionKeys.detail(id) });
      navigate({
        to: '/discussion/$id',
        params: { id },
      });
    },
+    onError: (error) => {
+      // Handle error appropriately, maybe show a toast notification
+      console.error('Failed to update discussion:', error);
+    },
  });

-  return { mutate };
+  return { mutate, isError, error };
};

53-68: Consider harmonizing the callback pattern across mutation hooks.

The useDiscussionDeleteMutation hook takes a callback as a parameter, while the other hooks don't use this pattern. This inconsistency might make the API harder to understand. Consider either:

  1. Using a similar callback pattern for all hooks, or
  2. Using the onSuccess pattern consistently and letting components handle additional logic

Additionally, consider adding error handling to this hook as well.

Two possible approaches:

  1. Make the callback optional with a default empty function:
-export const useDiscussionDeleteMutation = (callback: () => void) => {
+export const useDiscussionDeleteMutation = (callback: () => void = () => {}) => {
  1. Alternatively, use options object for more flexibility:
-export const useDiscussionDeleteMutation = (callback: () => void) => {
+export const useDiscussionDeleteMutation = (options?: { onSuccess?: () => void }) => {
  const { id } = useParams({ from: '/_main/discussion/edit/$id' });
  const queryClient = useQueryClient();
  const navigate = useNavigate();

  const { mutate } = useMutation({
    mutationFn: () => discussionApi.deleteDiscussion(id),
    onSuccess: (_) => {
      queryClient.invalidateQueries({ queryKey: upcomingQueryKey });
      queryClient.invalidateQueries({ queryKey: ongoingQueryKey.all });
-      callback();
+      options?.onSuccess?.();
      navigate({ to: '/home' });
    },
  });

  return { mutate };
};

12-68: Consider reducing code duplication in cache invalidation.

There's a pattern of cache invalidation that's repeated across all three hooks. Consider extracting this into a utility function to reduce duplication and make it easier to maintain.

+// Add at the top of the file
+const invalidateDiscussionCaches = (queryClient: any, discussionId?: string) => {
+  queryClient.invalidateQueries({ queryKey: upcomingQueryKey });
+  queryClient.invalidateQueries({ queryKey: ongoingQueryKey.all });
+  queryClient.invalidateQueries({ queryKey: discussionKeys.all });
+  if (discussionId) {
+    queryClient.invalidateQueries({ queryKey: discussionKeys.detail(discussionId) });
+  }
+};

// Then in each hook, replace the multiple invalidateQueries calls with:
// useDiscussionMutation
-      queryClient.invalidateQueries({ queryKey: upcomingQueryKey });
-      queryClient.invalidateQueries({ queryKey: ongoingQueryKey.all });
-      queryClient.invalidateQueries({ queryKey: discussionKeys.all });
+      invalidateDiscussionCaches(queryClient);

// useDiscussionEditMutation
-      queryClient.invalidateQueries({ queryKey: upcomingQueryKey });
-      queryClient.invalidateQueries({ queryKey: ongoingQueryKey.all });
-      queryClient.invalidateQueries({ queryKey: discussionKeys.detail(id) });
+      invalidateDiscussionCaches(queryClient, id);

// useDiscussionDeleteMutation
-      queryClient.invalidateQueries({ queryKey: upcomingQueryKey });
-      queryClient.invalidateQueries({ queryKey: ongoingQueryKey.all });
+      invalidateDiscussionCaches(queryClient);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c391efc and 062962f8c5a38629dc08d1fd2fd789f43899658d.

📒 Files selected for processing (9)
  • frontend/src/features/discussion/api/index.ts (1 hunks)
  • frontend/src/features/discussion/api/mutations.ts (2 hunks)
  • frontend/src/features/discussion/api/queries.ts (1 hunks)
  • frontend/src/features/discussion/ui/DiscussionEditButton/index.tsx (1 hunks)
  • frontend/src/features/discussion/ui/DiscussionForm/EnrollButton.tsx (1 hunks)
  • frontend/src/features/discussion/ui/DiscussionForm/FormButton.tsx (1 hunks)
  • frontend/src/features/discussion/ui/DiscussionForm/index.tsx (1 hunks)
  • frontend/src/features/discussion/ui/DiscussionTitle/index.tsx (1 hunks)
  • frontend/src/pages/DiscussionPage/DiscussionEditPage/index.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
frontend/src/features/discussion/api/queries.ts (1)
frontend/src/features/discussion/model/index.ts (1)
  • DiscussionResponse (94-94)
frontend/src/features/discussion/ui/DiscussionForm/index.tsx (2)
frontend/src/features/discussion/ui/DiscussionForm/type.ts (1)
  • FormType (8-8)
frontend/src/features/discussion/model/index.ts (1)
  • DiscussionRequest (92-92)
frontend/src/features/discussion/ui/DiscussionTitle/index.tsx (6)
frontend/src/features/discussion/api/queries.ts (1)
  • useDiscussionQuery (62-67)
frontend/src/components/Flex/index.tsx (1)
  • Flex (20-59)
frontend/src/features/discussion/ui/DiscussionTitle/index.css.ts (1)
  • titleStyle (5-7)
frontend/src/components/Text/index.tsx (1)
  • Text (15-18)
frontend/src/theme/index.css.ts (1)
  • vars (10-15)
frontend/src/features/discussion/ui/DiscussionTitle/DiscussionBadges.tsx (1)
  • DiscussionBadges (8-38)
frontend/src/features/discussion/api/index.ts (2)
frontend/src/features/discussion/model/index.ts (2)
  • DiscussionRequest (92-92)
  • DiscussionResponse (94-94)
frontend/src/utils/fetch/index.ts (1)
  • request (19-30)
frontend/src/features/discussion/ui/DiscussionEditButton/index.tsx (2)
frontend/src/features/discussion/api/queries.ts (1)
  • useDiscussionHostQuery (105-110)
frontend/src/components/Icon/component/Pencil.tsx (1)
  • Pencil (4-16)
frontend/src/features/discussion/ui/DiscussionForm/FormButton.tsx (3)
frontend/src/features/discussion/ui/DiscussionForm/type.ts (1)
  • FormType (8-8)
frontend/src/features/discussion/ui/DiscussionForm/EnrollButton.tsx (3)
  • AddButton (14-32)
  • DeleteButton (54-92)
  • EditButton (34-52)
frontend/src/components/Flex/index.tsx (1)
  • Flex (20-59)
🔇 Additional comments (16)
frontend/src/features/discussion/api/queries.ts (1)

63-66: Property naming updated for consistency

The change from isLoading to isPending aligns with the React Query v4+ API, where isPending is the preferred flag for tracking loading state. This update ensures consistency across the codebase.

frontend/src/features/discussion/ui/DiscussionForm/index.tsx (1)

18-19: LGTM! Improved formatting for readability

The type annotation for component props has been reformatted across multiple lines for better readability without changing functionality.

frontend/src/features/discussion/ui/DiscussionTitle/index.tsx (3)

8-8: LGTM! New import for edit button functionality

The addition of the DiscussionEditButton import supports the discussion editing capability.


14-14: Updated loading state property name

Property updated from isLoading to isPending to match the changes in the query hook implementation.


16-39: Improved layout to accommodate edit button

The layout has been restructured to:

  1. Use space-between justification for the main container
  2. Add a full-width setting to the container
  3. Nest the title and badges in their own Flex container
  4. Add the new DiscussionEditButton component

This creates a clean UI with the edit button properly aligned to the right of the discussion information.

frontend/src/features/discussion/api/index.ts (1)

27-37: Added API methods for discussion editing and deletion

The new putDiscussion and deleteDiscussion methods correctly implement the API endpoints for updating and removing discussions. These additions complete the CRUD operations for the discussion feature.

Both methods follow consistent patterns with the existing API implementation:

  • Proper URL construction with the discussion ID
  • Appropriate HTTP methods (PUT for update, DELETE for removal)
  • Correct typing for request bodies and responses
frontend/src/features/discussion/ui/DiscussionEditButton/index.tsx (1)

1-28: Clean implementation of conditional edit button

This component is well-structured and follows good practices:

  • Correctly uses useParams to extract the discussion ID from the URL
  • Properly checks if the current user is the host using useDiscussionHostQuery
  • Handles loading state appropriately with isPending
  • Only renders the button when the user is authorized (is the host)
  • Uses appropriate styling and accessibility features
frontend/src/pages/DiscussionPage/DiscussionEditPage/index.tsx (2)

1-15: Good dynamic data fetching implementation

The page now properly fetches discussion data based on the URL parameter instead of using hardcoded values. The loading state handling is implemented correctly with the early return when data is still loading or unavailable.


16-40: Form initialization looks correct

The form is properly initialized with dynamic data from the fetched discussion object. All necessary fields are mapped correctly to the form's initialValues.

frontend/src/features/discussion/ui/DiscussionForm/FormButton.tsx (1)

3-19: Good separation of concerns

The refactoring of FormButton to a stateless component that delegates responsibilities to specialized button components is a good practice. This makes the component more focused and maintainable by following the single responsibility principle.

frontend/src/features/discussion/ui/DiscussionForm/EnrollButton.tsx (3)

14-32: AddButton implementation looks good

The AddButton component correctly:

  • Uses form context to access form state and validation
  • Disables the button when the form is invalid
  • Uses the appropriate mutation hook for creating discussions

34-52: EditButton implementation looks good

The EditButton component correctly:

  • Uses form context to access form state and validation
  • Disables the button when the form is invalid
  • Uses the appropriate mutation hook for editing discussions

54-92: DeleteButton implementation is well done

The DeleteButton component properly:

  • Integrates with the global modal system for confirmation
  • Provides clear warning messages about the irreversible action
  • Uses appropriate styling for a destructive action
  • Closes the modal after the mutation is completed
frontend/src/features/discussion/api/mutations.ts (3)

2-2: Good use of tanstack router imports for consistency.

Using useNavigate and useParams from the same library (@tanstack/react-router) makes sense for consistency with other tanstack tools like React Query that you're already using in this file.


12-30: Well-refactored mutation hook with improved cache invalidation.

The refactoring of useDiscussionMutation removes the callback parameter and instead handles navigation directly within the hook, which provides a more cohesive API and better encapsulation of related logic. The cache invalidation strategy for multiple queries is comprehensive.


32-51: Ensure type safety for the ID parameter.

The ID extracted from route parameters is used directly in API calls. It's good practice to ensure this value is properly validated or converted to the expected type before using it in critical operations.

For example, if the API expects a numeric ID but the route parameter is a string, you might need to convert it:

// In useDiscussionEditMutation
-    mutationFn: (body: DiscussionRequest) => discussionApi.putDiscussion(id, body),
+    mutationFn: (body: DiscussionRequest) => {
+      // Ensure id is in the expected format
+      const numericId = parseInt(id, 10);
+      if (isNaN(numericId)) {
+        throw new Error('Invalid discussion ID');
+      }
+      return discussionApi.putDiscussion(String(numericId), body);
+    },

// Similarly in useDiscussionDeleteMutation

Verify how the discussionApi methods are defined to ensure you're passing the correct types.

Also applies to: 59-60

@hamo-o hamo-o force-pushed the feature/fe/discussion-edit-delete branch from 062962f to 7ca4ea8 Compare July 27, 2025 10:10
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: 0

🧹 Nitpick comments (6)
frontend/apps/client/src/features/discussion/api/queries.ts (1)

82-86: Fix inconsistent loading state property usage.

The useDiscussionRankQuery hook still uses isLoading while other hooks in this file use isPending. This creates inconsistency in the codebase.

Apply this diff to maintain consistency:

-  const { data: rank, isLoading } = useQuery<DiscussionRankResponse>(
+  const { data: rank, isPending } = useQuery<DiscussionRankResponse>(
     discussionRankQuery(discussionId, body),
   );
   
-  return { rank, isLoading };
+  return { rank, isPending };
frontend/apps/client/src/features/discussion/ui/DiscussionForm/FormButton.tsx (1)

6-21: Well-structured presentational component!

The refactoring to a purely presentational component improves separation of concerns. The conditional rendering based on form type is clear and maintainable.

Consider adding a comment or using a more descriptive prop name than type to clarify what FormType values are expected (e.g., formAction or mode).

frontend/apps/client/src/features/discussion/ui/DiscussionForm/EnrollButton.tsx (2)

14-32: Consider renaming the event handler for consistency.

The component logic is sound, but the handler name handleClickEnrollButton doesn't match the component name AddButton.

-  const handleClickEnrollButton = () => {
+  const handleClickAddButton = () => {
     mutate(formState);
   };

34-52: Rename handler for consistency with component name.

-  const handleClickEnrollButton = () => {
+  const handleClickEditButton = () => {
     mutate(formState);
   };
frontend/apps/client/src/features/discussion/api/mutations.ts (2)

35-54: Consistent implementation with proper cache invalidation!

The edit mutation properly invalidates both list and detail queries.

-    onSuccess: (_) => {
+    onSuccess: () => {

56-72: Well-structured delete mutation with proper cleanup!

The callback execution before navigation ensures the modal is closed properly.

-    onSuccess: (_) => {
+    onSuccess: () => {
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 062962f8c5a38629dc08d1fd2fd789f43899658d and 7ca4ea8.

📒 Files selected for processing (9)
  • frontend/apps/client/src/features/discussion/api/index.ts (1 hunks)
  • frontend/apps/client/src/features/discussion/api/mutations.ts (2 hunks)
  • frontend/apps/client/src/features/discussion/api/queries.ts (1 hunks)
  • frontend/apps/client/src/features/discussion/ui/DiscussionEditButton/index.tsx (1 hunks)
  • frontend/apps/client/src/features/discussion/ui/DiscussionForm/EnrollButton.tsx (1 hunks)
  • frontend/apps/client/src/features/discussion/ui/DiscussionForm/FormButton.tsx (1 hunks)
  • frontend/apps/client/src/features/discussion/ui/DiscussionForm/index.tsx (1 hunks)
  • frontend/apps/client/src/features/discussion/ui/DiscussionTitle/index.tsx (1 hunks)
  • frontend/apps/client/src/pages/DiscussionPage/DiscussionEditPage/index.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • frontend/apps/client/src/features/discussion/ui/DiscussionForm/index.tsx
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: hamo-o
PR: softeer5th/Team4-enDolphin#169
File: frontend/src/features/my-calendar/ui/SchedulePopover/index.tsx:35-35
Timestamp: 2025-02-14T11:44:42.393Z
Learning: Error handling for mutations will be implemented comprehensively across the application in a future update, rather than handling it individually for each mutation.
frontend/apps/client/src/pages/DiscussionPage/DiscussionEditPage/index.tsx (2)

Learnt from: hamo-o
PR: #101
File: frontend/src/routes/my-schedule/@components/SchedulePopover/PopoverForm.tsx:10-35
Timestamp: 2025-02-06T05:14:12.328Z
Learning: Form state management and validation for the SchedulePopover component in frontend/src/routes/my-schedule/@components/SchedulePopover/PopoverForm.tsx will be implemented in a future PR.

Learnt from: hamo-o
PR: #100
File: frontend/src/utils/jsxUtils.tsx:1-2
Timestamp: 2025-02-06T02:50:41.604Z
Learning: @tanstack/react-router package focuses on routing-specific types and does not export ReactNode type. Always import ReactNode from 'react' package to avoid type compatibility issues.

frontend/apps/client/src/features/discussion/ui/DiscussionForm/FormButton.tsx (2)

Learnt from: hamo-o
PR: #267
File: frontend/src/features/discussion/ui/DiscussionForm/MeetingPassword.tsx:16-20
Timestamp: 2025-02-21T17:55:36.208Z
Learning: In the DiscussionForm component, the password field is optional and not required for form submission.

Learnt from: hamo-o
PR: #101
File: frontend/src/routes/my-schedule/@components/SchedulePopover/PopoverForm.tsx:10-35
Timestamp: 2025-02-06T05:14:12.328Z
Learning: Form state management and validation for the SchedulePopover component in frontend/src/routes/my-schedule/@components/SchedulePopover/PopoverForm.tsx will be implemented in a future PR.

frontend/apps/client/src/features/discussion/api/mutations.ts (2)

Learnt from: hamo-o
PR: #169
File: frontend/src/features/my-calendar/ui/SchedulePopover/index.tsx:35-35
Timestamp: 2025-02-14T11:44:42.393Z
Learning: Error handling for mutations will be implemented comprehensively across the application in a future update, rather than handling it individually for each mutation.

Learnt from: hamo-o
PR: #100
File: frontend/src/utils/jsxUtils.tsx:1-2
Timestamp: 2025-02-06T02:50:41.604Z
Learning: @tanstack/react-router package focuses on routing-specific types and does not export ReactNode type. Always import ReactNode from 'react' package to avoid type compatibility issues.

🔇 Additional comments (12)
frontend/apps/client/src/features/discussion/api/index.ts (1)

27-37: LGTM! Clean implementation of discussion update and delete operations.

The new API methods follow REST conventions and maintain consistency with the existing codebase patterns. The parameter types and endpoint structure are appropriate for the CRUD operations.

frontend/apps/client/src/features/discussion/api/queries.ts (1)

63-66: LGTM! Updated to use isPending for better alignment with React Query patterns.

The change from isLoading to isPending follows modern React Query conventions and maintains consistency with other hooks in the codebase.

frontend/apps/client/src/features/discussion/ui/DiscussionEditButton/index.tsx (1)

1-26: LGTM! Well-structured conditional rendering component.

The component properly handles loading states, authorization checks, and navigation. The implementation follows React best practices with appropriate conditional rendering and clean integration with the design system.

frontend/apps/client/src/features/discussion/ui/DiscussionTitle/index.tsx (2)

6-6: Good integration of the edit button component.

The import of DiscussionEditButton properly extends the title component with editing capabilities.


12-37: LGTM! Layout changes properly accommodate the edit button.

The changes successfully:

  • Update to use isPending for consistency with query updates
  • Restructure layout to horizontal with space-between for proper button positioning
  • Preserve original vertical layout and styling for title/badges content
  • Integrate the edit button while maintaining clean separation of concerns
frontend/apps/client/src/pages/DiscussionPage/DiscussionEditPage/index.tsx (2)

2-4: Good integration of route parameters and data fetching.

The addition of useParams and useDiscussionQuery properly transforms this into a data-driven edit page.


10-40: Mapping verified: initialValues align with DiscussionRequest schema.

All required fields—title, dateRangeStart, dateRangeEnd, timeRangeStart, timeRangeEnd, duration, meetingMethod, and deadline—are provided and match the zod‐inferred DiscussionRequest type. Optional fields (location, password) are correctly omitted. No mismatches found.

frontend/apps/client/src/features/discussion/ui/DiscussionForm/FormButton.tsx (1)

1-5: Clean import structure!

The imports are well-organized and follow a logical separation between UI components and business logic.

frontend/apps/client/src/features/discussion/ui/DiscussionForm/EnrollButton.tsx (2)

1-13: Well-organized imports!

The imports follow a logical structure with clear separation between external dependencies, internal modules, and local imports.


54-92: Excellent implementation of delete confirmation flow!

The use of a modal for delete confirmation is a good UX practice, and the error styling with descriptive text properly warns users about the irreversible action.

frontend/apps/client/src/features/discussion/api/mutations.ts (2)

1-13: Comprehensive imports for mutation management!

Good practice importing query keys from related features to ensure proper cache invalidation across the application.


15-33: Clean implementation of discussion creation mutation!

The simplified API without callback parameter and comprehensive cache invalidation ensures data consistency across the application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🖥️ FE Frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 논의 기본 정보 조회, 수정, 삭제 API 연결

2 participants