즐겨찾기 추가/삭제 로직 개선 및 스크롤 위치 수정
- 즐겨찾기 삭제 시 최소 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 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import { useFavoriteEditOnStore, useMenuIds, useMenuOnStore, useStore } from '@/
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { showAlert } from '@/widgets/show-alert';
|
import { showAlert } from '@/widgets/show-alert';
|
||||||
import { checkGrant } from '@/shared/lib/check-grant';
|
import { checkGrant } from '@/shared/lib/check-grant';
|
||||||
|
import { snackBar } from '@/shared/lib';
|
||||||
|
|
||||||
export interface FavoriteWrapperProps {
|
export interface FavoriteWrapperProps {
|
||||||
usingType: 'home' | 'menu',
|
usingType: 'home' | 'menu',
|
||||||
@@ -27,6 +28,7 @@ export const FavoriteWrapper = ({
|
|||||||
const { menuIds, setMenuIds, deleteMenuId} = useMenuIds();
|
const { menuIds, setMenuIds, deleteMenuId} = useMenuIds();
|
||||||
const [isFirst, setIsFirst] = useState<boolean>(true);
|
const [isFirst, setIsFirst] = useState<boolean>(true);
|
||||||
const [favoriteItems, setFavoriteItems] = useState<Array<UserFavorite>>([]);
|
const [favoriteItems, setFavoriteItems] = useState<Array<UserFavorite>>([]);
|
||||||
|
const [prevMenuOn, setPrevMenuOn] = useState<boolean>(false);
|
||||||
|
|
||||||
const itemAdd: UserFavorite = {
|
const itemAdd: UserFavorite = {
|
||||||
menuId: -1,
|
menuId: -1,
|
||||||
@@ -73,6 +75,12 @@ export const FavoriteWrapper = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onClickToRemoveItem = (item?: UserFavorite) => {
|
const onClickToRemoveItem = (item?: UserFavorite) => {
|
||||||
|
// 삭제 전에 먼저 개수 체크
|
||||||
|
if(menuIds.length === 1){
|
||||||
|
snackBar(t('favorite.cannotDeleteLastItem'));
|
||||||
|
return; // 삭제 중단
|
||||||
|
}
|
||||||
|
|
||||||
let idx = -1;
|
let idx = -1;
|
||||||
let newFavorite: Array<UserFavorite> = favoriteItems.filter((value, index) => {
|
let newFavorite: Array<UserFavorite> = favoriteItems.filter((value, index) => {
|
||||||
if(value.menuId === item?.menuId){
|
if(value.menuId === item?.menuId){
|
||||||
@@ -80,18 +88,16 @@ export const FavoriteWrapper = ({
|
|||||||
}
|
}
|
||||||
return value.menuId !== item?.menuId;
|
return value.menuId !== item?.menuId;
|
||||||
});
|
});
|
||||||
|
|
||||||
useStore.getState().UserStore.setUserFavorite(newFavorite);
|
useStore.getState().UserStore.setUserFavorite(newFavorite);
|
||||||
setFavoriteItems(newFavorite);
|
setFavoriteItems(newFavorite);
|
||||||
|
|
||||||
if(idx > -1){
|
if(idx > -1){
|
||||||
goToSlide(idx);
|
goToSlide(idx);
|
||||||
}
|
}
|
||||||
if(menuIds.length <= 1){
|
|
||||||
showAlert('바로가기는 1개이상 설정 필요 합니다.') ;
|
if(item?.menuId){
|
||||||
}
|
deleteMenuId(item?.menuId);
|
||||||
else{
|
|
||||||
if(item?.menuId){
|
|
||||||
deleteMenuId(item?.menuId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -162,16 +168,31 @@ export const FavoriteWrapper = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getFavoriteList();
|
getFavoriteList();
|
||||||
|
|
||||||
if(usingType === 'home'){
|
if(usingType === 'home'){
|
||||||
goToSlide('first');
|
goToSlide('first');
|
||||||
}
|
}
|
||||||
else if(usingType === 'menu' && !isFirst){
|
else if(usingType === 'menu'){
|
||||||
setTimeout(() => {
|
// 메뉴가 새로 열렸는지 확인 (prevMenuOn: false -> menuOn: true)
|
||||||
goToSlide('last');
|
const isMenuJustOpened = !prevMenuOn && menuOn;
|
||||||
}, 100);
|
|
||||||
|
if(isMenuJustOpened || isFirst){
|
||||||
|
// 메뉴가 새로 열렸거나 처음 렌더링 시 맨 앞으로
|
||||||
|
setTimeout(() => {
|
||||||
|
goToSlide('first');
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
else if(changeMenuId){
|
||||||
|
// 즐겨찾기 아이템 추가/삭제 시 마지막으로 (변경된 항목 보여주기)
|
||||||
|
setTimeout(() => {
|
||||||
|
goToSlide('last');
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsFirst(false);
|
setIsFirst(false);
|
||||||
}, [changeMenuId, favoriteEditOn]);
|
setPrevMenuOn(menuOn);
|
||||||
|
}, [changeMenuId, favoriteEditOn, menuOn]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { MenuItems } from '@/entities/common/model/constant';
|
import { MenuItems } from '@/entities/common/model/constant';
|
||||||
import { showAlert } from '@/widgets/show-alert';
|
import { showAlert } from '@/widgets/show-alert';
|
||||||
import { checkGrant } from '@/shared/lib/check-grant';
|
import { checkGrant } from '@/shared/lib/check-grant';
|
||||||
|
import { snackBar } from '@/shared/lib';
|
||||||
|
|
||||||
export interface MenuCategoryProps {
|
export interface MenuCategoryProps {
|
||||||
menuId?: number;
|
menuId?: number;
|
||||||
@@ -60,34 +61,41 @@ export const MenuCategory = ({
|
|||||||
programPath?: string,
|
programPath?: string,
|
||||||
) => {
|
) => {
|
||||||
let userFavorite = useStore.getState().UserStore.userFavorite;
|
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{
|
else{
|
||||||
if(checked){
|
userFavorite = userFavorite.filter((value, _) => {
|
||||||
userFavorite = [
|
return value.menuId !== menuId
|
||||||
...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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useStore.getState().UserStore.setUserFavorite(userFavorite);
|
||||||
|
setChangeMenuId(`${menuId}-${checked}`);
|
||||||
|
callFavoiteItems();
|
||||||
};
|
};
|
||||||
|
|
||||||
const callFavoiteItems = () => {
|
const callFavoiteItems = () => {
|
||||||
|
|||||||
@@ -357,7 +357,9 @@
|
|||||||
"menuPermissions": "Menu Permissions"
|
"menuPermissions": "Menu Permissions"
|
||||||
},
|
},
|
||||||
"favorite": {
|
"favorite": {
|
||||||
"edit": "Edit"
|
"edit": "Edit",
|
||||||
|
"cannotDeleteLastItem": "At least one shortcut must be set.",
|
||||||
|
"cannotAddMoreThan10": "You can set up to 10 shortcuts."
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"home": "Home",
|
"home": "Home",
|
||||||
|
|||||||
@@ -357,7 +357,9 @@
|
|||||||
"menuPermissions": "메뉴별 권한 설정"
|
"menuPermissions": "메뉴별 권한 설정"
|
||||||
},
|
},
|
||||||
"favorite": {
|
"favorite": {
|
||||||
"edit": "편집하기"
|
"edit": "편집하기",
|
||||||
|
"cannotDeleteLastItem": "바로가기는 1개 이상 설정 필요합니다.",
|
||||||
|
"cannotAddMoreThan10": "바로가기는 최대 10개 설정 가능합니다."
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"home": "홈",
|
"home": "홈",
|
||||||
|
|||||||
Reference in New Issue
Block a user