작업중

This commit is contained in:
focp212@naver.com
2025-09-29 16:59:26 +09:00
parent 74ab29f80a
commit 0a747469a6
18 changed files with 313 additions and 111 deletions

View File

@@ -33,4 +33,66 @@ export const BottomSheetMotionVaiants = {
}; };
export const BottomSheetMotionDuration = { export const BottomSheetMotionDuration = {
duration: 0.3 duration: 0.3
}; };
export const MenuItems = [
{menuId: '30', parent: '30', menuName: '거래조회', subMenu:
[
{menuId: '31', parent: '30', menuName: '거래내역조회'},
{menuId: '32', parent: '30', menuName: '현금영수증 발행'},
{menuId: '33', parent: '30', menuName: '에스크로'},
{menuId: '34', parent: '30', menuName: '빌링'}
]
},
{menuId: '35', parent: '35', menuName: '정산조회', subMenu:
[
{menuId: '36', parent: '35', menuName: '정산달력'},
{menuId: '37', parent: '35', menuName: '정산내역'},
]
},
{menuId: '38', parent: '38', menuName: '가맹점 관리', subMenu:
[
{menuId: '39', parent: '38', menuName: '가맹점 정보'},
{menuId: '40', parent: '38', menuName: '등록 현황'},
]
},
{menuId: '41', parent: '41', menuName: '결제 관리', subMenu:
[
{menuId: '42', parent: '41', menuName: '결제 정보'},
{menuId: '43', parent: '41', menuName: '결제데이터통보'},
]
},
{menuId: '44', parent: '44', menuName: '계정관리', subMenu:
[
{menuId: '45', parent: '44', menuName: '사용자관리'},
{menuId: '46', parent: '44', menuName: '비밀번호관리'},
]
},
{menuId: '47', parent: '47', menuName: '부가세신고자료', subMenu:
[
{menuId: '48', parent: '47', menuName: '부가세신고자료'},
{menuId: '49', parent: '47', menuName: '부가세참고'},
]
},
{menuId: '50', parent: '50', menuName: '부가서비스', subMenu:
[
{menuId: '51', parent: '50', menuName: '부가서비스소개'},
{menuId: '52', parent: '50', menuName: '신용카드ARS카드결제'},
{menuId: '53', parent: '50', menuName: '계좌이체ARS카드결제'},
{menuId: '54', parent: '50', menuName: '가상계좌ARS카드결제'},
{menuId: '55', parent: '50', menuName: '휴대폰ARS카드결제'},
{menuId: '56', parent: '50', menuName: '계좌간편결제ARS카드결제'},
{menuId: '57', parent: '50', menuName: 'SSG머니ARS카드결제'},
{menuId: '58', parent: '50', menuName: 'SSG은행계좌ARS카드결제'},
{menuId: '59', parent: '50', menuName: '문화상품권ARS카드결제'},
{menuId: '60', parent: '50', menuName: '티머니페이ARS카드결제'},
]
},
{menuId: '61', parent: '61', menuName: '고객지원', subMenu:
[
{menuId: '62', parent: '61', menuName: '공지사항'},
{menuId: '63', parent: '61', menuName: '자주묻는질문'},
{menuId: '64', parent: '61', menuName: '1:1문의'},
]
},
]

View File

@@ -7,18 +7,22 @@ export interface BannerInfoState {
setBannerInfo: (update: SetStateAction<Partial<BannerInfo>>) => void; setBannerInfo: (update: SetStateAction<Partial<BannerInfo>>) => void;
}; };
const initialState = { const initialBannerInfoState = {
bannerInfo: {} as BannerInfo, bannerInfo: {} as BannerInfo,
} as BannerInfoState; } as BannerInfoState;
export const createBannerInfoStore = lens<BannerInfoState>((set, get) => ({ export const createBannerInfoStore = lens<BannerInfoState>((set, get) => ({
...initialState, ...initialBannerInfoState,
setBannerInfo: (update) => { setBannerInfo: (update) => {
set((state: BannerInfoState) => { set((state: BannerInfoState) => {
const newBannerInfo = typeof update === 'function' ? update(state.bannerInfo) : update; const newBannerInfo = (typeof update === 'function')
? update(state.bannerInfo): update;
return { return {
...state, ...state,
bannerInfo: { ...state.bannerInfo, ...newBannerInfo }, bannerInfo: {
...state.bannerInfo,
...newBannerInfo
},
}; };
}); });
}, },

View File

@@ -69,11 +69,13 @@ export interface HeaderNavigationProps {
menuOn: boolean; menuOn: boolean;
headerType: HeaderType; headerType: HeaderType;
setMenuOn: (menuOn: boolean) => void; setMenuOn: (menuOn: boolean) => void;
favoriteEdit?: boolean;
}; };
export interface FooterProps { export interface FooterProps {
setMenuOn: (menuOn: boolean) => void; setMenuOn: (menuOn: boolean) => void;
footerCurrentPage?: string | null; footerCurrentPage?: string | null;
setFavoriteEdit: (favoriteEdit: boolean) => void;
}; };
export enum FooterItemActiveKey { export enum FooterItemActiveKey {
Home = 'Home', Home = 'Home',

View File

@@ -3,10 +3,6 @@ import {
NoticeListResponse NoticeListResponse
} from '@/entities/support/model/types'; } from '@/entities/support/model/types';
export interface FavoriteItemProps {
img?: string,
text?: string
};
export interface HomeBottomBannerProps { export interface HomeBottomBannerProps {
setBottomBannerOn: (bottomBannerOn: boolean) => void; setBottomBannerOn: (bottomBannerOn: boolean) => void;
bottomBannerOn: boolean; bottomBannerOn: boolean;

View File

@@ -1,17 +0,0 @@
import { FavoriteItemProps } from '../model/types';
export const FavoriteItem = ({
img,
text
}: FavoriteItemProps) => {
return (
<>
<div className="swiper-item">
<div className="swiper-icon coin-icon">
<img src={ img } alt={ text } />
</div>
<span className="swiper-text">{ text }</span>
</div>
</>
);
};

View File

@@ -1,56 +1,98 @@
import { useEffect, useState } from 'react';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { Swiper, SwiperSlide } from 'swiper/react'; import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css'; import 'swiper/css';
import { IMAGE_ROOT } from '@/shared/constants/common'; import { IMAGE_ROOT } from '@/shared/constants/common';
import { FavoriteItem } from './favorite-item'; import { UserFavorite } from '@/entities/user/model/types';
import { FavoriteItemProps } from '../model/types' import { useStore } from '@/shared/model/store';
/*
const items: Array<UserFavorite> = [
{img: IMAGE_ROOT + '/ico_menu_01.svg', title: '지급대행'},
{img: IMAGE_ROOT + '/ico_menu_02.svg', title: '거래내역조회'},
{img: IMAGE_ROOT + '/ico_menu_03.svg', title: '정산달력'},
{img: IMAGE_ROOT + '/ico_menu_02.svg', title: '거래내역조회'},
{img: IMAGE_ROOT + '/ico_menu_03.svg', title: '정산달력'}
];
*/
export interface FavoriteWrapperProps {
usingType: 'home' | 'menu'
};
export const FavoriteWrapper = () => { export const FavoriteWrapper = ({
const items: Array<FavoriteItemProps> = [ usingType
{img: IMAGE_ROOT + '/ico_menu_01.svg', text: '지급대행'}, }: FavoriteWrapperProps) => {
{img: IMAGE_ROOT + '/ico_menu_02.svg', text: '거래내역조회'}, const { navigate } = useNavigate();
{img: IMAGE_ROOT + '/ico_menu_03.svg', text: '정산달력'},
{img: IMAGE_ROOT + '/ico_menu_02.svg', text: '거래내역조회'},
{img: IMAGE_ROOT + '/ico_menu_03.svg', text: '정산달력'}
];
const itemAdd = { const [edit, setEdit] = useState<boolean>(false);
const [favoriteItems, setFavoriteItems] = useState<Array<UserFavorite>>([]);
const itemAdd: UserFavorite = {
img: IMAGE_ROOT + '/ico_menu_plus.svg', img: IMAGE_ROOT + '/ico_menu_plus.svg',
text: '편집하기' title: '편집하기'
};
const onClickToFavoriteEdit = () => {
setEdit(true);
}; };
const getItems = () => { //useSetFavoriteEdit(true);
//useSetMenuOn(true);
const onClickToNavigate = (path?: string) => {
if(!!path){
navigate(path);
}
};
const getFavoriteItems = () => {
let rs = []; let rs = [];
for(let i=0;i<items.length;i++){ for(let i=0;i<favoriteItems.length;i++){
rs.push( rs.push(
<SwiperSlide <SwiperSlide key={ `favorite-slide-key-${i}` }>
key={ 'slide-key-'+i } <div
> className="swiper-item"
<FavoriteItem onClick={ () => onClickToNavigate(favoriteItems[i]?.path) }
img={ items[i]?.img } >
text={ items[i]?.text } <div className="swiper-icon coin-icon">
></FavoriteItem> <img
src={ favoriteItems[i]?.img }
alt={ favoriteItems[i]?.title }
/>
</div>
<span className="swiper-text">{ favoriteItems[i]?.title }</span>
</div>
</SwiperSlide> </SwiperSlide>
); );
} }
rs.push(
<SwiperSlide key={ `favorite-item-add-slide-key` }>
<div
className="swiper-item"
onClick={ onClickToFavoriteEdit }
>
<div className="swiper-icon coin-icon">
<img
src={ itemAdd.img }
alt={ itemAdd.title }
/>
</div>
<span className="swiper-text">{ itemAdd.title }</span>
</div>
</SwiperSlide>
);
return rs; return rs;
}; };
return ( return (
<> <>
<Swiper <Swiper
spaceBetween={9} spaceBetween={ 9 }
slidesPerView={4} slidesPerView={ 4 }
> >{ getFavoriteItems() }</Swiper>
{ getItems() }
<SwiperSlide>
<FavoriteItem
img={ itemAdd.img }
text={ itemAdd.text }
></FavoriteItem>
</SwiperSlide>
</Swiper>
</> </>
); );
}; };

View File

@@ -3,8 +3,10 @@ export interface MenuCategoryItem {
path: string; path: string;
}; };
export interface MenuCategoryProps { export interface MenuCategoryProps {
key: string;
category: string; category: string;
categoryIcon?: string; categoryIcon?: string;
items: Array<MenuCategoryItem>; items: Array<MenuCategoryItem>;
setMenuOn: (menuOn: boolean) => void; setMenuOn: (menuOn: boolean) => void;
favoriteEdit?: boolean;
}; };

View File

@@ -1,35 +1,70 @@
import { PATHS } from '@/shared/constants/paths';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { MenuCategoryProps } from '../model/types'; import { MenuCategoryProps } from '../model/types';
import { useStore } from '@/shared/model/store';
import { IMAGE_ROOT } from '@/shared/constants/common';
export const MenuCategory = ({ export const MenuCategory = ({
category, category,
categoryIcon, categoryIcon,
items, items,
setMenuOn setMenuOn,
favoriteEdit
}: MenuCategoryProps) => { }: MenuCategoryProps) => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const onClickToNavigate = (path?: string) => { const onClickToNavigate = (path?: string) => {
if(!!path){ if(!!path && !favoriteEdit){
setMenuOn(false); setMenuOn(false);
navigate(path); navigate(path);
} }
}; };
const favoriteSetting = (
checked: boolean,
title?: string,
path?: string
) => {
useStore.getState().UserStore.setUserFavorite([{
title: title,
img: IMAGE_ROOT + '/ico_menu_01.svg',
path: path,
}]);
};
const getMenuItems = () => { const getMenuItems = () => {
let rs = []; let rs = [];
for(let i=0;i<items.length;i++){ for(let i=0;i<items.length;i++){
let title = items[i]?.title; if(!!favoriteEdit){
let path = items[i]?.path; rs.push(
let key = 'menu-item-key-'+i; <li
rs.push( key={ `menu-item-key-${category}-${i}` }
<li onClick={ () => onClickToNavigate(items[i]?.path) }
key={ key } >
onClick={ () => onClickToNavigate(path) } <span>{ items[i]?.title }</span>
>{ title }</li> <div className="check_box_scrap">
); <input
id={ `menu-item-checkbox-${category}-${i}` }
className="checkbox"
type="checkbox"
onChange={ (e) => favoriteSetting(e.target.checked, items[i]?.title, items[i]?.path) }
/>
<label
className="gtr"
htmlFor={ `menu-item-checkbox-${category}-${i}` }
></label>
</div>
</li>
);
}
else{
rs.push(
<li
key={ `menu-item-key-${i}` }
onClick={ () => onClickToNavigate(items[i]?.path) }
>{ items[i]?.title }</li>
);
}
} }
return rs; return rs;
}; };

View File

@@ -1,26 +1,33 @@
import { lens } from '@dhmk/zustand-lens'; import { lens } from '@dhmk/zustand-lens';
import { SetStateAction } from 'react'; import { SetStateAction } from 'react';
import { UserInfo } from './types'; import { UserFavorite, UserInfo } from './types';
import { StorageKeys } from '@/shared/constants/local-storage'; import { StorageKeys } from '@/shared/constants/local-storage';
export interface UserInfoState { export interface UserInfoState {
userInfo: UserInfo; userInfo: UserInfo;
setUserInfo: (update: SetStateAction<Partial<UserInfo>>) => void; setUserInfo: (update: SetStateAction<Partial<UserInfo>>) => void;
resetUserInfo: () => void; resetUserInfo: () => void;
userFavorite: Array<UserFavorite>;
setUserFavorite: (update: SetStateAction<Array<UserFavorite>>) => void;
}; };
const initialState = { const initialUserInfoState = {
userInfo: {} as UserInfo, userInfo: {} as UserInfo,
userFavorite: [] as Array<UserFavorite>
} as UserInfoState; } as UserInfoState;
export const createUserInfoStore = lens<UserInfoState>((set, get) => ({ export const createUserInfoStore = lens<UserInfoState>((set, get) => ({
...initialState, ...initialUserInfoState,
setUserInfo: (update) => { setUserInfo: (update) => {
set((state: UserInfoState) => { set((state: UserInfoState) => {
const newUserInfo = typeof update === 'function' ? update(state.userInfo) : update; const newUserInfo = (typeof update === 'function')
? update(state.userInfo): update;
return { return {
...state, ...state,
userInfo: { ...state.userInfo, ...newUserInfo }, userInfo: {
...state.userInfo,
...newUserInfo
},
}; };
}); });
}, },
@@ -34,6 +41,19 @@ export const createUserInfoStore = lens<UserInfoState>((set, get) => ({
window.localStorage.removeItem(StorageKeys.Usrid); window.localStorage.removeItem(StorageKeys.Usrid);
// window.localStorage.removeItem(StorageKeys.ClientAddressIP); // window.localStorage.removeItem(StorageKeys.ClientAddressIP);
// window.localStorage.removeItem(StorageKeys.Requires2FA); // window.localStorage.removeItem(StorageKeys.Requires2FA);
set(initialState); set(initialUserInfoState);
},
setUserFavorite: (update) => {
set((state: UserInfoState) => {
const newUserFavorite = (typeof update === 'function')
? update(state.userFavorite): update;
return {
...state,
userFavorite: {
...state.userFavorite,
...newUserFavorite
},
};
});
}, },
})); }));

View File

@@ -28,6 +28,11 @@ export interface LoginResponse {
requires2FA?: boolean; requires2FA?: boolean;
}; };
export interface UserFavorite {
title?: string;
img?: string;
path?: string;
};
export interface UserInfo extends LoginResponse { export interface UserInfo extends LoginResponse {
status: boolean; status: boolean;
error?: ErrorResponse; error?: ErrorResponse;

View File

@@ -15,16 +15,25 @@ import {
useSetHeaderTitle, useSetHeaderTitle,
useSetHeaderType, useSetHeaderType,
useSetFooterMode, useSetFooterMode,
useSetFooterCurrentPage useSetFooterCurrentPage,
useSetFavoriteEdit,
useSetMenuOn
} from '@/widgets/sub-layout/use-sub-layout'; } from '@/widgets/sub-layout/use-sub-layout';
export const HomePage = () => { export const HomePage = () => {
const { callLogin } = useUserInfo(); const { callLogin } = useUserInfo();
const { isNativeEnvironment, openBiometricRegistrationPopup, requestToken, logout } = useAppBridge(); const {
isNativeEnvironment,
openBiometricRegistrationPopup,
requestToken,
logout
} = useAppBridge();
useSetHeaderTitle(''); useSetHeaderTitle('');
useSetHeaderType(HeaderType.Home); useSetHeaderType(HeaderType.Home);
useSetFooterMode(true); useSetFooterMode(true);
useSetFooterCurrentPage(FooterItemActiveKey.Home); useSetFooterCurrentPage(FooterItemActiveKey.Home);
//useSetFavoriteEdit(true);
//useSetMenuOn(true);
const today = moment().format('YYYYMMDD').toString(); const today = moment().format('YYYYMMDD').toString();
let bannerToday = getLocalStorage(StorageKeys.BottomBannerClose); let bannerToday = getLocalStorage(StorageKeys.BottomBannerClose);
@@ -189,7 +198,9 @@ export const HomePage = () => {
<div className="tab-pane dashboard active"> <div className="tab-pane dashboard active">
{ loginSuccess && { loginSuccess &&
<> <>
<FavoriteWrapper></FavoriteWrapper> <FavoriteWrapper
usingType='home'
></FavoriteWrapper>
<DayStatusBox></DayStatusBox> <DayStatusBox></DayStatusBox>
</> </>
} }

View File

@@ -305,6 +305,13 @@ export const PATHS: RouteNamesType = {
ROUTE_NAMES.additionalService.payout.request, ROUTE_NAMES.additionalService.payout.request,
), ),
}, },
faceAuth: {
base: generatePath(`${ROUTE_NAMES.additionalService.base}${ROUTE_NAMES.additionalService.faceAuth.base}`),
list: generatePath(
`${ROUTE_NAMES.additionalService.base}${ROUTE_NAMES.additionalService.faceAuth.base}`,
ROUTE_NAMES.additionalService.faceAuth.list,
),
}
}, },
support: { support: {
base: generatePath(ROUTE_NAMES.support.base), base: generatePath(ROUTE_NAMES.support.base),

View File

@@ -131,6 +131,10 @@ export const ROUTE_NAMES = {
detail: 'detail', detail: 'detail',
request: 'request', request: 'request',
}, },
faceAuth: {
base: '/face-auth/*',
list: 'list',
}
}, },
support: { support: {

View File

@@ -10,10 +10,12 @@ import { FilterMotionDuration, FilterMotionStyle, FilterMotionVariants } from '@
export interface MenuProps { export interface MenuProps {
menuOn: boolean; menuOn: boolean;
setMenuOn: (menuOn: boolean) => void; setMenuOn: (menuOn: boolean) => void;
favoriteEdit?: boolean;
}; };
export const Menu = ({ export const Menu = ({
menuOn, menuOn,
setMenuOn setMenuOn,
favoriteEdit
}: MenuProps) => { }: MenuProps) => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const userInfo = useStore((state) => state.UserStore.userInfo); const userInfo = useStore((state) => state.UserStore.userInfo);
@@ -24,8 +26,7 @@ export const Menu = ({
}; };
const onClickToMenuClose = () => { const onClickToMenuClose = () => {
setMenuOn(false); setMenuOn(false);
}; };
const menuCategoryItems = { const menuCategoryItems = {
transaction: { transaction: {
@@ -93,6 +94,7 @@ export const Menu = ({
{title: '자금이체', path: PATHS.additionalService.fundAccount.transferList}, {title: '자금이체', path: PATHS.additionalService.fundAccount.transferList},
{title: '정산대행', path: PATHS.additionalService.settlementAgency.manage}, {title: '정산대행', path: PATHS.additionalService.settlementAgency.manage},
{title: '지급대행', path: PATHS.additionalService.payout.list}, {title: '지급대행', path: PATHS.additionalService.payout.list},
{title: '안면인증', path: PATHS.additionalService.faceAuth.list}
] ]
}, },
support: { support: {
@@ -105,12 +107,7 @@ export const Menu = ({
] ]
}, },
} }
const variants = {
hidden: { x: '100%' },
visible: { x: '0%' },
};
const getMenuCategory = () => { const getMenuCategory = () => {
let rs = []; let rs = [];
for (const [key, value] of Object.entries(menuCategoryItems)) { for (const [key, value] of Object.entries(menuCategoryItems)) {
@@ -121,6 +118,7 @@ export const Menu = ({
categoryIcon={ value.categoryIcon } categoryIcon={ value.categoryIcon }
items={ value.items } items={ value.items }
setMenuOn={ setMenuOn } setMenuOn={ setMenuOn }
favoriteEdit={ favoriteEdit }
/> />
); );
} }
@@ -139,25 +137,38 @@ export const Menu = ({
> >
<div className="full-menu-container"> <div className="full-menu-container">
<div className="full-menu-header"> <div className="full-menu-header">
<div className="full-menu-title">{ 'nictest001m' } <span>(madzoneviper)</span></div> <div className="full-menu-title">
{ 'nictest001m' }
<span style={{marginLeft: '4px'}}>(madzoneviper)</span>
</div>
<div className="full-menu-actions"> <div className="full-menu-actions">
<button <button
className="full-menu-settings" className="full-menu-settings"
onClick={ () => onClickToNavigate(PATHS.setting) } onClick={ () => onClickToNavigate(PATHS.setting) }
> >
<img src={ IMAGE_ROOT + '/ico_set.svg' } alt="설정" /> <img
src={ IMAGE_ROOT + '/ico_set.svg' }
alt="설정"
/>
</button> </button>
<button <button
className="full-menu-close" className="full-menu-close"
onClick={ () => onClickToMenuClose() } onClick={ () => onClickToMenuClose() }
> >
<img src={ IMAGE_ROOT + '/ico_close.svg' } alt="설정" /> <img
src={ IMAGE_ROOT + '/ico_close.svg' }
alt="설정"
/>
</button> </button>
</div> </div>
</div> </div>
<div className="full-menu-top-nav"> <div className="full-menu-top-nav">
{ <FavoriteWrapper></FavoriteWrapper> } {
<FavoriteWrapper
usingType='menu'
></FavoriteWrapper>
}
</div> </div>
<div> <div>

View File

@@ -9,7 +9,8 @@ import { useEffect, useState } from 'react';
export const FooterNavigation = ({ export const FooterNavigation = ({
setMenuOn, setMenuOn,
footerCurrentPage footerCurrentPage,
setFavoriteEdit
}: FooterProps) => { }: FooterProps) => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const [isFooterOn, setIsFooterOn] = useState<boolean>(false); const [isFooterOn, setIsFooterOn] = useState<boolean>(false);
@@ -20,6 +21,7 @@ export const FooterNavigation = ({
} }
}; };
const onClickToOpenMenu = () => { const onClickToOpenMenu = () => {
setFavoriteEdit(false);
setMenuOn(true); setMenuOn(true);
}; };

View File

@@ -12,7 +12,8 @@ export const HeaderNavigation = ({
headerTitle, headerTitle,
menuOn, menuOn,
headerType, headerType,
setMenuOn setMenuOn,
favoriteEdit
}: HeaderNavigationProps) => { }: HeaderNavigationProps) => {
const { const {
navigate, navigate,
@@ -49,6 +50,7 @@ export const HeaderNavigation = ({
<Menu <Menu
menuOn={ menuOn } menuOn={ menuOn }
setMenuOn={ setMenuOn } setMenuOn={ setMenuOn }
favoriteEdit={ favoriteEdit }
></Menu> ></Menu>
} }
{ {

View File

@@ -9,14 +9,16 @@ import { PullToRefresh } from '@/widgets/pull-to-refresh/pull-to-refresh';
import { useNavigate } from '@/shared/lib/hooks'; import { useNavigate } from '@/shared/lib/hooks';
import { useScrollToTop } from '@/shared/lib/hooks/use-scroll-to-top'; import { useScrollToTop } from '@/shared/lib/hooks/use-scroll-to-top';
import { HeaderType } from '@/entities/common/model/types'; import { HeaderType } from '@/entities/common/model/types';
export interface ContextType { export interface ContextType {
setOnBack: (onBack: () => void) => void; setOnBack: (onBack: () => void) => void;
setHeaderTitle: (title: string) => void; setHeaderTitle: (title: string) => void;
setIsPullToRefreshEnabled: (enabled: boolean) => void; setIsPullToRefreshEnabled: (enabled: boolean) => void;
setMenuOn:(on: boolean) => void; setMenuOn: (menuOn: boolean) => void;
setHeaderType: (headerType: HeaderType) => void; setHeaderType: (headerType: HeaderType) => void;
setFooterMode:(footMode: boolean) => void; setFooterMode: (footerMode: boolean) => void;
setFooterCurrentPage:(currentPage?: string | null) => void; setFooterCurrentPage: (footerCurrentPage?: string | null) => void;
setFavoriteEdit: (favoriteEdit?: boolean) => void;
}; };
export const SubLayout = () => { export const SubLayout = () => {
@@ -29,7 +31,8 @@ export const SubLayout = () => {
const [headerType, setHeaderType] = useState<HeaderType>(HeaderType.NoHeader); const [headerType, setHeaderType] = useState<HeaderType>(HeaderType.NoHeader);
const [footerMode, setFooterMode] = useState<boolean>(false); const [footerMode, setFooterMode] = useState<boolean>(false);
const [footerCurrentPage, setFooterCurrentPage] = useState<undefined | string | null>(undefined); const [footerCurrentPage, setFooterCurrentPage] = useState<undefined | string | null>(undefined);
const [favoriteEdit, setFavoriteEdit] = useState<boolean>(false);
const wrapperClassName = 'wrapper'; const wrapperClassName = 'wrapper';
return ( return (
@@ -45,6 +48,7 @@ export const SubLayout = () => {
menuOn={ menuOn } menuOn={ menuOn }
setMenuOn={ setMenuOn } setMenuOn={ setMenuOn }
headerType={ headerType } headerType={ headerType }
favoriteEdit={ favoriteEdit }
/> />
<Outlet <Outlet
context={{ context={{
@@ -54,7 +58,8 @@ export const SubLayout = () => {
setMenuOn, setMenuOn,
setHeaderType, setHeaderType,
setFooterMode, setFooterMode,
setFooterCurrentPage setFooterCurrentPage,
setFavoriteEdit
}} }}
/> />
{ {
@@ -62,6 +67,7 @@ export const SubLayout = () => {
<FooterNavigation <FooterNavigation
setMenuOn={ setMenuOn } setMenuOn={ setMenuOn }
footerCurrentPage={ footerCurrentPage } footerCurrentPage={ footerCurrentPage }
setFavoriteEdit={ setFavoriteEdit }
></FooterNavigation> ></FooterNavigation>
} }

View File

@@ -1,9 +1,8 @@
/* eslint-disable react-hooks/exhaustive-deps */ import { useEffect } from 'react';
import { ReactNode, useEffect } from 'react';
import { useOutletContext } from 'react-router'; import { useOutletContext } from 'react-router';
import { ContextType } from '.';
import { FooterItemActiveKey } from '@/entities/common/model/types'; import { FooterItemActiveKey } from '@/entities/common/model/types';
import { HeaderType } from '@/entities/common/model/types'; import { HeaderType } from '@/entities/common/model/types';
import { ContextType } from '.';
export const useSubLayoutContext = () => { export const useSubLayoutContext = () => {
return useOutletContext<ContextType>(); return useOutletContext<ContextType>();
@@ -25,7 +24,7 @@ export const useSetHeaderTitle = (title: string) => {
useEffect(() => { useEffect(() => {
setHeaderTitle(title); setHeaderTitle(title);
return () => setHeaderTitle(''); return () => setHeaderTitle('');
}, [setHeaderTitle]); }, [title, setHeaderTitle]);
return { setHeaderTitle }; return { setHeaderTitle };
}; };
@@ -34,16 +33,16 @@ export const useSetIsPullToRefreshEnabled = (enabled: boolean) => {
useEffect(() => { useEffect(() => {
setIsPullToRefreshEnabled(enabled); setIsPullToRefreshEnabled(enabled);
return () => setIsPullToRefreshEnabled(false); return () => setIsPullToRefreshEnabled(false);
}, [setIsPullToRefreshEnabled, enabled]); }, [enabled, setIsPullToRefreshEnabled]);
return { setIsPullToRefreshEnabled }; return { setIsPullToRefreshEnabled };
}; };
export const useSetMenuOn = (on: boolean) => { export const useSetMenuOn = (menuOn: boolean) => {
const { setMenuOn } = useSubLayoutContext(); const { setMenuOn } = useSubLayoutContext();
useEffect(() => { useEffect(() => {
setMenuOn(on); setMenuOn(menuOn);
return () => setMenuOn(false); return () => setMenuOn(false);
}, [setMenuOn, on]); }, [menuOn, setMenuOn]);
return { setMenuOn }; return { setMenuOn };
}; };
@@ -52,16 +51,25 @@ export const useSetHeaderType = (headerType: HeaderType) => {
useEffect(() => { useEffect(() => {
setHeaderType(headerType); setHeaderType(headerType);
return () => setHeaderType(HeaderType.NoHeader); return () => setHeaderType(HeaderType.NoHeader);
}, [setHeaderType]); }, [headerType, setHeaderType]);
return { setHeaderType }; return { setHeaderType };
}; };
export const useSetFavoriteEdit = (favoriteEdit: boolean) => {
const { setFavoriteEdit } = useSubLayoutContext();
useEffect(() => {
setFavoriteEdit(favoriteEdit);
return () => setFavoriteEdit(false);
}, [favoriteEdit, setFavoriteEdit]);
return { setFavoriteEdit }
};
export const useSetFooterMode = (footerMode: boolean) => { export const useSetFooterMode = (footerMode: boolean) => {
const { setFooterMode } = useSubLayoutContext(); const { setFooterMode } = useSubLayoutContext();
useEffect(() => { useEffect(() => {
setFooterMode(footerMode); setFooterMode(footerMode);
return () => setFooterMode(false); return () => setFooterMode(false);
}, [setFooterMode, footerMode]); }, [footerMode, setFooterMode]);
return { setFooterMode }; return { setFooterMode };
}; };
@@ -70,6 +78,6 @@ export const useSetFooterCurrentPage = (footerCurrentPage?: FooterItemActiveKey
useEffect(() => { useEffect(() => {
setFooterCurrentPage(footerCurrentPage); setFooterCurrentPage(footerCurrentPage);
return () => setFooterCurrentPage(undefined); return () => setFooterCurrentPage(undefined);
}, [setFooterCurrentPage, footerCurrentPage]); }, [footerCurrentPage, setFooterCurrentPage]);
return { setFooterCurrentPage }; return { setFooterCurrentPage };
}; };