From 8fbc7d2f743c104f5357be9036ea7136a835fcd1 Mon Sep 17 00:00:00 2001 From: Jay Sheen Date: Thu, 13 Nov 2025 17:24:29 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A6=90=EA=B2=A8=EC=B0=BE=EA=B8=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80/=EC=82=AD=EC=A0=9C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 즐겨찾기 삭제 시 최소 1개 유지 검증 추가 (favorite-wrapper.tsx) - 즐겨찾기 추가/삭제 로직 분리 및 개선 (menu-category.tsx) - 추가 시: 최대 10개만 체크 - 삭제 시: 최소 1개 유지 체크 - 각 조건에서 early return으로 명확한 흐름 구성 - 메뉴 오픈 시 즐겨찾기 목록 스크롤을 맨 앞으로 초기화 - prevMenuOn 상태로 메뉴 오픈 감지 - 추가/삭제 시에만 마지막 아이템으로 스크롤 - 로컬라이제이션 키 추가 - cannotDeleteLastItem: 최소 1개 유지 메시지 - cannotAddMoreThan10: 최대 10개 제한 메시지 - snackBar import 추가 및 showAlert에서 snackBar로 변경 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/entities/home/ui/favorite-wrapper.tsx | 45 +++++++++++++----- src/entities/menu/ui/menu-category.tsx | 56 +++++++++++++---------- src/locales/en.json | 4 +- src/locales/ko.json | 4 +- 4 files changed, 71 insertions(+), 38 deletions(-) diff --git a/src/entities/home/ui/favorite-wrapper.tsx b/src/entities/home/ui/favorite-wrapper.tsx index 72c1f65..2ca2c03 100644 --- a/src/entities/home/ui/favorite-wrapper.tsx +++ b/src/entities/home/ui/favorite-wrapper.tsx @@ -8,6 +8,7 @@ import { useFavoriteEditOnStore, useMenuIds, useMenuOnStore, useStore } from '@/ import { useTranslation } from 'react-i18next'; import { showAlert } from '@/widgets/show-alert'; import { checkGrant } from '@/shared/lib/check-grant'; +import { snackBar } from '@/shared/lib'; export interface FavoriteWrapperProps { usingType: 'home' | 'menu', @@ -27,6 +28,7 @@ export const FavoriteWrapper = ({ const { menuIds, setMenuIds, deleteMenuId} = useMenuIds(); const [isFirst, setIsFirst] = useState(true); const [favoriteItems, setFavoriteItems] = useState>([]); + const [prevMenuOn, setPrevMenuOn] = useState(false); const itemAdd: UserFavorite = { menuId: -1, @@ -73,6 +75,12 @@ export const FavoriteWrapper = ({ }; const onClickToRemoveItem = (item?: UserFavorite) => { + // 삭제 전에 먼저 개수 체크 + if(menuIds.length === 1){ + snackBar(t('favorite.cannotDeleteLastItem')); + return; // 삭제 중단 + } + let idx = -1; let newFavorite: Array = favoriteItems.filter((value, index) => { if(value.menuId === item?.menuId){ @@ -80,18 +88,16 @@ export const FavoriteWrapper = ({ } return value.menuId !== item?.menuId; }); + useStore.getState().UserStore.setUserFavorite(newFavorite); setFavoriteItems(newFavorite); + if(idx > -1){ goToSlide(idx); } - if(menuIds.length <= 1){ - showAlert('바로가기는 1개이상 설정 필요 합니다.') ; - } - else{ - if(item?.menuId){ - deleteMenuId(item?.menuId); - } + + if(item?.menuId){ + deleteMenuId(item?.menuId); } }; @@ -162,16 +168,31 @@ export const FavoriteWrapper = ({ useEffect(() => { getFavoriteList(); + if(usingType === 'home'){ goToSlide('first'); } - else if(usingType === 'menu' && !isFirst){ - setTimeout(() => { - goToSlide('last'); - }, 100); + else if(usingType === 'menu'){ + // 메뉴가 새로 열렸는지 확인 (prevMenuOn: false -> menuOn: true) + const isMenuJustOpened = !prevMenuOn && menuOn; + + if(isMenuJustOpened || isFirst){ + // 메뉴가 새로 열렸거나 처음 렌더링 시 맨 앞으로 + setTimeout(() => { + goToSlide('first'); + }, 100); + } + else if(changeMenuId){ + // 즐겨찾기 아이템 추가/삭제 시 마지막으로 (변경된 항목 보여주기) + setTimeout(() => { + goToSlide('last'); + }, 100); + } } + setIsFirst(false); - }, [changeMenuId, favoriteEditOn]); + setPrevMenuOn(menuOn); + }, [changeMenuId, favoriteEditOn, menuOn]); return ( <> diff --git a/src/entities/menu/ui/menu-category.tsx b/src/entities/menu/ui/menu-category.tsx index 5179353..558a2ba 100644 --- a/src/entities/menu/ui/menu-category.tsx +++ b/src/entities/menu/ui/menu-category.tsx @@ -7,6 +7,7 @@ import { useTranslation } from 'react-i18next'; import { MenuItems } from '@/entities/common/model/constant'; import { showAlert } from '@/widgets/show-alert'; import { checkGrant } from '@/shared/lib/check-grant'; +import { snackBar } from '@/shared/lib'; export interface MenuCategoryProps { menuId?: number; @@ -60,34 +61,41 @@ export const MenuCategory = ({ programPath?: string, ) => { let userFavorite = useStore.getState().UserStore.userFavorite; - if(userFavorite.length >= 10){ - showAlert('즐겨찾기는 10개까지만 추가 할수 있습니다.'); + + // 추가 시: 최대 10개 체크 + if(checked && userFavorite.length >= 10){ + snackBar(t('favorite.cannotAddMoreThan10')); + return; } - else if(userFavorite.length <= 1){ - showAlert('바로가기는 1개이상 설정 필요 합니다.'); + + // 삭제 시: 최소 1개 체크 + if(!checked && userFavorite.length <= 1){ + snackBar(t('favorite.cannotDeleteLastItem')); + return; + } + + // 추가 또는 삭제 실행 + if(checked){ + userFavorite = [ + ...userFavorite, + { + menuId: menuId, + menuName: menuName, + menuNameEng: menuNameEng, + iconFilePath: iconFilePath, + programPath: programPath + } + ]; } else{ - if(checked){ - userFavorite = [ - ...userFavorite, - { - menuId: menuId, - menuName: menuName, - menuNameEng: menuNameEng, - iconFilePath: iconFilePath, - programPath: programPath - } - ]; - } - else{ - userFavorite = userFavorite.filter((value, _) => { - return value.menuId !== menuId - }); - } - useStore.getState().UserStore.setUserFavorite(userFavorite); - setChangeMenuId(`${menuId}-${checked}`); - callFavoiteItems(); + userFavorite = userFavorite.filter((value, _) => { + return value.menuId !== menuId + }); } + + useStore.getState().UserStore.setUserFavorite(userFavorite); + setChangeMenuId(`${menuId}-${checked}`); + callFavoiteItems(); }; const callFavoiteItems = () => { diff --git a/src/locales/en.json b/src/locales/en.json index c200db7..7998fe6 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -357,7 +357,9 @@ "menuPermissions": "Menu Permissions" }, "favorite": { - "edit": "Edit" + "edit": "Edit", + "cannotDeleteLastItem": "At least one shortcut must be set.", + "cannotAddMoreThan10": "You can set up to 10 shortcuts." }, "footer": { "home": "Home", diff --git a/src/locales/ko.json b/src/locales/ko.json index cc1885c..1c89ea5 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -357,7 +357,9 @@ "menuPermissions": "메뉴별 권한 설정" }, "favorite": { - "edit": "편집하기" + "edit": "편집하기", + "cannotDeleteLastItem": "바로가기는 1개 이상 설정 필요합니다.", + "cannotAddMoreThan10": "바로가기는 최대 10개 설정 가능합니다." }, "footer": { "home": "홈",