Skip to content

Conversation

@ff1451
Copy link
Collaborator

@ff1451 ff1451 commented Jan 17, 2026

No description provided.

@ff1451 ff1451 requested a review from Copilot January 17, 2026 06:10
@ff1451 ff1451 self-assigned this Jan 17, 2026
@ff1451 ff1451 linked an issue Jan 17, 2026 that may be closed by this pull request
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces reusable bottom sheet and bottom modal components to improve UI consistency and adds confirmation dialogs for destructive actions (logout and account withdrawal). The refactoring extracts bottom sheet logic into a dedicated component with configurable behavior.

Changes:

  • Added new BottomSheet and BottomModal reusable components
  • Enhanced useBottomSheet hook with configuration options and callback support
  • Replaced direct modal usage with new components across Profile, MyPage, and Timer pages

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/utils/hooks/useBottomSheet.ts Enhanced with options object pattern, default position, and position change callback
src/components/common/BottomSheet.tsx New resizable bottom sheet component with render prop support
src/components/common/BottomModal.tsx New bottom modal component for confirmation dialogs
src/pages/Timer/index.tsx Refactored to use new BottomSheet component, removing inline implementation
src/pages/User/Profile/index.tsx Added withdrawal confirmation using BottomModal
src/pages/User/MyPage/index.tsx Added logout confirmation using BottomModal
src/pages/Council/CouncilNotice/index.tsx Added bottom padding for better content spacing
src/pages/Auth/SignUp/components/StepLayout.tsx Updated margin calculation to use safe area insets
src/pages/Chat/index.tsx Updated empty state text to be more conversational
src/components/layout/Header/routeTitles.ts Added chat route title mapping

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +41 to +43
if (newPosition !== position) {
setPosition(newPosition);
onPositionChange?.(newPosition);
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

The onPositionChange callback should be wrapped in useCallback or the callback ref pattern to prevent unnecessary re-renders when the callback reference changes. Currently, if the parent component passes a new function reference on each render, it could cause the hook to behave unexpectedly.

Copilot uses AI. Check for mistakes.
<div className="mt-2 text-xs leading-3.5 text-indigo-300">{councilNoticeDetail.updatedAt}</div>
</div>
<div className="bg-indigo-0 flex-1 px-5 py-4 text-[13px] leading-4.5 whitespace-pre-line text-indigo-700">
<div className="bg-indigo-0 flex-1 px-5 py-4 pb-20 text-[13px] leading-4.5 whitespace-pre-line text-indigo-700">
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

The CSS classes contain conflicting padding declarations. The class 'py-4' sets both top and bottom padding, but 'pb-20' overrides the bottom padding. This makes the 'py-4' bottom padding redundant. Consider using 'pt-4 pb-20' instead for clarity and to avoid confusion about which padding value is actually applied.

Suggested change
<div className="bg-indigo-0 flex-1 px-5 py-4 pb-20 text-[13px] leading-4.5 whitespace-pre-line text-indigo-700">
<div className="bg-indigo-0 flex-1 px-5 pt-4 pb-20 text-[13px] leading-4.5 whitespace-pre-line text-indigo-700">

Copilot uses AI. Check for mistakes.
Comment on lines 54 to 70
return (
<div
ref={sheetRef}
className={clsx(
'fixed inset-x-0 z-20 flex flex-col rounded-t-3xl bg-white transition-transform duration-300 ease-out',
resizable && isDragging && 'transition-none',
className
)}
style={{
bottom: `${bottomOffset}px`,
height:
effectivePosition === 'full'
? `calc(100% - ${fullTopOffset}px - ${bottomOffset}px)`
: `calc(100% - ${halfTopOffset}px - ${bottomOffset}px)`,
transform: getTransform(),
}}
>
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

The BottomSheet component is missing accessibility attributes. It should include role, aria-modal, and aria-label/aria-labelledby attributes to properly identify it as a sheet/dialog for screen readers. Consider adding role="region" or role="dialog" and appropriate ARIA attributes.

Copilot uses AI. Check for mistakes.
>
탈퇴하기
</button>
<button onClick={closeModal} className="text-h3 w-full rounded-lg py-3.5 text-center text-indigo-400">
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

The cancel button lacks semantic importance and could benefit from clearer styling. Currently the cancel button appears as plain text with only color differentiation, which may have insufficient contrast and could be easily missed. Consider adding a border or background to make it more visually distinct as an interactive element.

Suggested change
<button onClick={closeModal} className="text-h3 w-full rounded-lg py-3.5 text-center text-indigo-400">
<button
onClick={closeModal}
className="text-h3 w-full rounded-lg py-3.5 text-center text-indigo-400 bg-indigo-50 border border-indigo-200"
>

Copilot uses AI. Check for mistakes.
Comment on lines +79 to 89
<div>
<button
onClick={() => withdraw()}
className="w-full rounded-lg bg-indigo-700 py-3.5 text-center text-lg leading-7 font-bold text-white"
className="bg-primary text-h3 w-full rounded-lg py-3.5 text-center text-white"
>
탈퇴하기
</button>
<button onClick={closeModal} className="text-h3 w-full rounded-lg py-3.5 text-center text-indigo-400">
취소
</button>
</div>
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

The button ordering places the destructive primary action (탈퇴하기/withdraw) above the cancel action. This is contrary to common UX patterns where destructive actions should typically be placed in a less prominent position to prevent accidental clicks. Consider placing the cancel button above or making the destructive action less prominent visually.

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +39
const { position, isDragging, currentTranslate, sheetRef, handlers } = useBottomSheet({
defaultPosition,
onPositionChange,
});
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

When resizable is false, the hook still runs and manages state unnecessarily. The handlers are created but never used, which wastes resources. Consider adding a condition to skip hook initialization when resizable is false, or create a simpler version of the component for non-resizable cases.

Copilot uses AI. Check for mistakes.
Comment on lines 24 to 25
export type { SheetPosition };

Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

The exported SheetPosition type on line 3 is also re-exported on line 24 in the component file. This creates redundant exports. Consider removing one of these exports or adding a comment explaining why both are needed.

Suggested change
export type { SheetPosition };

Copilot uses AI. Check for mistakes.
}}
>
{resizable && (
<div className="flex h-5 shrink-0 cursor-grab items-center justify-center active:cursor-grabbing" {...handlers}>
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

The draggable handle element is missing keyboard accessibility. Users who cannot use touch gestures should be able to control the sheet expansion/collapse using keyboard controls. Consider making the handle focusable and adding keyboard event handlers for arrow keys or Enter/Space keys.

Suggested change
<div className="flex h-5 shrink-0 cursor-grab items-center justify-center active:cursor-grabbing" {...handlers}>
<div
className="flex h-5 shrink-0 cursor-grab items-center justify-center active:cursor-grabbing"
{...handlers}
role="button"
tabIndex={0}
aria-label="Resize bottom sheet"
onKeyDown={(event) => {
if (event.key === 'Enter' || event.key === ' ' || event.key === 'Spacebar') {
event.preventDefault();
const anyHandlers = handlers as any;
if (typeof anyHandlers.onMouseDown === 'function') {
anyHandlers.onMouseDown(event);
} else if (typeof anyHandlers.onPointerDown === 'function') {
anyHandlers.onPointerDown(event);
}
}
}}
>

Copilot uses AI. Check for mistakes.
>
로그아웃
</button>
<button onClick={closeModal} className="text-h3 w-full rounded-lg py-3.5 text-center text-indigo-400">
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

The cancel button lacks semantic importance and could benefit from clearer styling. Currently the cancel button appears as plain text with only color differentiation, which may have insufficient contrast and could be easily missed. Consider adding a border or background to make it more visually distinct as an interactive element.

Suggested change
<button onClick={closeModal} className="text-h3 w-full rounded-lg py-3.5 text-center text-indigo-400">
<button
type="button"
onClick={closeModal}
className="text-h3 w-full rounded-lg border border-indigo-200 bg-white py-3.5 text-center text-indigo-500"
>

Copilot uses AI. Check for mistakes.
@ff1451 ff1451 merged commit 3b487f7 into develop Jan 18, 2026
1 check 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.

[feat] 바텀시트 모달 추가 및 UI 수정

2 participants