Files
nice-app-web/src/widgets/sub-layout/index.tsx
focp212@naver.com 72e57a9250 추가
2025-11-20 09:36:26 +09:00

482 lines
15 KiB
TypeScript

import * as _ from 'lodash-es';
import {
Fragment,
useCallback,
useEffect,
useState
} from 'react';
import { Outlet, useLocation } from 'react-router-dom';
import { HeaderNavigation } from '@/widgets/navigation/header';
import { FooterNavigation } from '@/widgets/navigation/footer';
import { PullToRefresh } from '@/widgets/pull-to-refresh/pull-to-refresh';
import {
CodeListItem,
CodesSelectParams,
CodesSelectPostResponse,
HeaderType
} from '@/entities/common/model/types';
import { useHomeGroupsMutation } from '@/entities/home/api/use-home-groups-mutation';
import { useUserInfo } from '@/entities/user/lib/use-user-info';
import { useAppBridge } from '@/hooks';
import { useDetailOnStore, useFavoriteEditOnStore, useMenuOnStore, useStore } from '@/shared/model/store';
import { HomeGroupsParams, HomeGroupsResponse } from '@/entities/home/model/types';
import {
BusinessPropertyParams,
BusinessPropertyResponse,
LoginResponse,
MenuGrantsItem,
ShortcutUserParams,
ShortcutUserResponse,
UserFindAuthMethodParams
} from '@/entities/user/model/types';
import { useShortcutUserMutation } from '@/entities/user/api/use-shortcut-user-mutation';
import { useShortcutDefaultMutation } from '@/entities/user/api/use-shortcut-detault-mutation';
import { useBusinessPropertyMutation } from '@/entities/user/api/use-business-property-mutation';
import { useUserFindAuthMethodMutation } from '@/entities/user/api/use-user-find-authmethod-mutation';
import { useCodesSelectMutation } from '@/entities/common/api/use-codes-select-mutation';
import { MenuItems } from '@/entities/common/model/constant';
import { AlarmLinkOptions } from '@/entities/alarm/model/types';
import { AlarmRoutes } from '@/entities/alarm/ui/alarm-routes';
import { useNavigate } from '@/shared/lib/hooks';
export interface ContextType {
setOnBack: (onBack: () => void) => void;
setOnRightClick: (onRightClick: () => void) => void;
setHeaderTitle: (title: string) => void;
setIsPullToRefreshEnabled: (enabled: boolean) => void;
setMenuOn: (menuOn: boolean) => void;
setHeaderType: (headerType: HeaderType) => void;
setFooterMode: (footerMode: boolean) => void;
setFooterCurrentPage: (footerCurrentPage?: string | null) => void;
setFavoriteEdit: (favoriteEdit?: boolean) => void;
};
export interface CallCodesSelectProps {
codeCl: string;
code1Filter?: Array<any>;
};
export interface OnSetCommonCodesProps {
data: Array<CodeListItem>;
codeCl: string;
code1Filter?: Array<any>;
};
export const SubLayout = () => {
const {
callLogin,
updateUserData
} = useUserInfo();
const { reload, navigateBack } = useNavigate();
const { menuOn, setMenuOn } = useMenuOnStore();
const { favoriteEditOn, setFavoriteEditOn } = useFavoriteEditOnStore();
const { detailOn, setDetailOn } = useDetailOnStore();
const location = useLocation();
console.log(location)
const [isPullToRefreshEnabled, setIsPullToRefreshEnabled] = useState(false);
const [onBack, setOnBack] = useState(undefined);
const [onRightClick, setOnRightClick] = useState(undefined);
const [headerTitle, setHeaderTitle] = useState<string>('');
const [headerType, setHeaderType] = useState<HeaderType>(HeaderType.NoHeader);
const [footerMode, setFooterMode] = useState<boolean>(false);
const [footerCurrentPage, setFooterCurrentPage] = useState<undefined | string | null>(undefined);
const [headerNavigationKey, setHeaderNavigationKey] = useState<number>(1);
const [loginSuccess, setLoginSuccess] = useState<boolean>(false);
const [mid, setMid] = useState<string>();
const [alarmRoutesOn, setAlarmRoutesOn] = useState<boolean>(false);
const [alarmOptions, setAlarmOptions] = useState<AlarmLinkOptions>();
const { isNativeEnvironment } = useAppBridge();
const { mutateAsync: homeGroups } = useHomeGroupsMutation();
const { mutateAsync: codesSelect} = useCodesSelectMutation();
const { mutateAsync: shortcutUser } = useShortcutUserMutation();
const { mutateAsync: shortcutDefault } = useShortcutDefaultMutation();
const { mutateAsync: businessProperty } = useBusinessPropertyMutation();
const { mutateAsync: findAuthMethod } = useUserFindAuthMethodMutation();
const wrapperClassName = 'wrapper';
const callHomeGroups = () => {
let userInfo = useStore.getState().UserStore.userInfo;
let params: HomeGroupsParams = {
userid: userInfo.usrid
};
homeGroups(params).then((rs: HomeGroupsResponse) => {
useStore.getState().UserStore.setUserMids(rs.mids);
if(!!rs.mids[0]){
useStore.getState().UserStore.setMid(rs.mids[0]);
setMid(rs.mids[0]);
}
let options: Array<Record<string, string>> = rs.mids.map((value, index) => {
return {
name: value,
value: value
};
});
useStore.getState().UserStore.setSelectOptionsMids(options);
let options2 = _.cloneDeep(options);
options2.sort((a: Record<string, any>, b: Record<string, any>) => {
if(a.value.toLowerCase() > b.value.toLowerCase()) return 1;
else if(a.value.toLowerCase() < b.value.toLowerCase()) return -1;
else return 0;
});
let optionsWithoutGids = options2.filter((value: Record<string, any>, index: number) => {
let last = value.value.slice(-1);
return last.toLowerCase() !== 'g';
});
useStore.getState().UserStore.setSelectOptionsMidsWithoutGids(optionsWithoutGids);
setLoginSuccess(true);
setHeaderNavigationKey(headerNavigationKey + 1);
}).catch((e: any) => {
console.error(e);
});
};
const callBusinessProperty = () => {
if(!!mid){
let params: BusinessPropertyParams = {
mid: mid
};
businessProperty(params).then((rs: BusinessPropertyResponse) => {
useStore.getState().UserStore.setBusinessInfo(rs);
}).catch((e: any) => {
console.error(e);
});
}
};
const callSortcutDefault = () => {
let userInfo = useStore.getState().UserStore.userInfo;
if(userInfo.usrid){
let params: ShortcutUserParams = {
usrid: userInfo.usrid,
};
shortcutDefault(params).then((rs: ShortcutUserResponse) => {
const modifiedShortcuts = rs.shortcuts.map(shortcut => ({
...shortcut,
iconFilePath: `/images/menu_icon_${shortcut.menuId}.svg`,
programPath: getProgramPath(shortcut.menuId)
}));
useStore.getState().UserStore.setUserFavorite(modifiedShortcuts);
}).catch((e: any) => {
console.error(e);
});
}
};
// 맵 형태로 상수로 만들어 놓을 필요가 있다. 무의미한 반복문 너무 많이 사용
const getProgramPath = (menuId: number) => {
let programPath: string = '';
Loop1:
for(let i=0;i<MenuItems.length;i++){
let menuItem = MenuItems[i];
if(menuItem){
let subMenu = menuItem.subMenu;
if(subMenu){
Loop2:
for(let j=0;j<subMenu.length;j++){
let subMenuItem = subMenu[j];
if(subMenuItem){
if(subMenuItem.menuId === menuId){
programPath = subMenuItem.programPath;
break Loop1;
}
}
}
}
}
}
return programPath;
};
const callShortcutUser = () => {
let userInfo = useStore.getState().UserStore.userInfo;
if(userInfo.usrid){
let params: ShortcutUserParams = {
usrid: userInfo.usrid
};
shortcutUser(params).then((rs: ShortcutUserResponse) => {
if(!rs.usingDefault && rs.shortcuts){
if(rs.shortcuts.length > 0){
const modifiedShortcuts = rs.shortcuts.map(shortcut => ({
...shortcut,
iconFilePath: `/images/menu_icon_${shortcut.menuId}.svg`,
programPath: getProgramPath(shortcut.menuId)
}));
useStore.getState().UserStore.setUserFavorite(modifiedShortcuts);
}
else if(!!rs.usingDefault){
callSortcutDefault();
}
}
}).catch((e: any) => {
console.error(e);
});
}
};
const callFindAuthMethod = () => {
let userInfo = useStore.getState().UserStore.userInfo;
if(!!userInfo.usrid && !! mid){
let params: UserFindAuthMethodParams = {
usrid: userInfo.usrid,
mid: mid
};
findAuthMethod(params).then((rs: any) => {
let emails = rs.emails.map((value: any, index: any) => {
return value.content;
});
useStore.getState().UserStore.setUserEmails(emails);
let options: Array<Record<string, string>> = emails.map((value: any, index: any) => {
return {
name: value,
value: value
};
});
useStore.getState().UserStore.setSelectOptionsEmails(options);
if(!!emails[0]){
useStore.getState().UserStore.setEmail(emails[0]);
}
}).catch((e: any) => {
console.error(e);
});
}
};
const handleLogin = useCallback(async () => {
let userParmas;
if(!isNativeEnvironment){
userParmas = {
id: 'nictest00',
password: 'nictest00'
};
// userParmas = {
// id: 'woowahan5',
// password: 'nictest00'
// };
}
callLogin(userParmas).then(() => {
callHomeGroups();
callShortcutUser();
callCodesSelect({ codeCl: '0001' });
callCodesSelect({ codeCl: '0002' });
let filter0022: Array<string> = ['01', '02', '03', '05', '14', '21', '24', '26', '31'];
callCodesSelect({
codeCl: '0022',
code1Filter: filter0022
});
callCodesSelect({ codeCl: '0325' });
callCodesSelect({ codeCl: '0074' });
onSetGrant();
}).catch((error: any) => {
setLoginSuccess(false);
});
}, []);
const callCodesSelect = ({
codeCl,
code1Filter
}: CallCodesSelectProps) => {
let params: CodesSelectParams = {
codeCl: codeCl,
useCl: 0,
method: 'post'
};
codesSelect(params).then((rs: CodesSelectPostResponse) => {
if(rs){
onSetCommonCodes({
data: rs.codeList,
codeCl: codeCl,
code1Filter: code1Filter
});
}
}).catch((e: any) => {
console.error(e);
});
};
const onSetGrant = () => {
let userInfo = useStore.getState().UserStore.userInfo;
const menuGrants = userInfo.menuGrants;
let grantObj: Record<string, Array<string>> = {};
let grantKeys = [8, 4, 2, 1];
if(!!menuGrants){
for(let i=0;i<menuGrants.length;i++){
let menuGrantItem = menuGrants[i];
if(menuGrantItem){
let menuId: number = menuGrantItem.menuId;
let grant: number = menuGrantItem.grant;
if(!grantObj.hasOwnProperty(''+menuId)){
grantObj[''+menuId] = [];
}
for(let j=0;j<grantKeys.length;j++){
let grantKey = grantKeys[j];
if(!!grantKey){
//grant = grant - grantKey;
if((grant - grantKey) >= 0){
grant = grant - grantKey;
if(j === 0){
grantObj[''+menuId]?.push('D');
}
else if(j === 1){
grantObj[''+menuId]?.push('X');
}
else if(j === 2){
grantObj[''+menuId]?.push('W');
}
else if(j === 3){
grantObj[''+menuId]?.push('R');
}
}
else{
continue;
}
}
}
}
}
}
useStore.getState().UserStore.setMenuGrantsByKey(grantObj);
};
const onSetCommonCodes = ({
data,
codeCl,
code1Filter
}: OnSetCommonCodesProps) => {
if(codeCl === '0001'){
useStore.getState().CommonStore.setBankList(data);
}
else if(codeCl === '0002'){
useStore.getState().CommonStore.setCreditCardList(data);
}
else if(codeCl === '0022'){
let options = [];
options = data.map((value, index) => {
return {
name: value.desc1,
value: value.code1
}
});
if(!!code1Filter){
options = options.filter((value, index) => {
return code1Filter.includes(value.value);
});
}
options = options.sort((a, b) => {
if(a > b) return 1;
else if(a < b) return -1;
else return 0;
});
options.unshift({
name: '전체', value: ''
});
useStore.getState().CommonStore.setServiceCodes(options);
}
else if(codeCl === '0325'){
useStore.getState().CommonStore.setAppNotificationCategories(data);
}
else if(codeCl === '0074'){
useStore.getState().CommonStore.setVirtualBankList(data);
}
};
const saveToken = (token: LoginResponse) => {
updateUserData(token);
};
const alarmLink = (options: AlarmLinkOptions) => {
if(options?.linkUrl){
setAlarmRoutesOn(true);
setAlarmOptions(options);
}
};
const onPressBackKey = () => {
let pathname = location.pathname;
console.log('pathname = [' + pathname + ']');
if(menuOn){
setMenuOn(false);
setFavoriteEditOn(false);
}
else if(detailOn){
setDetailOn(false);
}
else{
navigateBack();
}
};
window.saveToken = saveToken;
window.alarmLink = alarmLink;
window.onPressBackKey = onPressBackKey;
useEffect(() => {
handleLogin();
}, []);
useEffect(() => {
if(!!mid){
callBusinessProperty();
callFindAuthMethod();
}
}, [mid]);
return (
<PullToRefresh onRefresh={reload} isPullable={isPullToRefreshEnabled}>
<div className={ wrapperClassName }>
<div
className="header-empty-block"
style={{ width: '100%', height: '50px' }}
></div>
<Fragment>
<HeaderNavigation
onBack={ onBack }
onRightClick={ onRightClick }
headerTitle={ headerTitle }
headerType={ headerType }
key={ headerNavigationKey }
loginSuccess={ loginSuccess }
mid={ mid }
setMid={ setMid }
/>
{ loginSuccess &&
<Outlet
context={{
setOnBack,
setOnRightClick,
setHeaderTitle,
setHeaderType,
setFooterMode,
setFooterCurrentPage,
setIsPullToRefreshEnabled,
}}
/>
}
{
footerMode &&
<FooterNavigation
footerCurrentPage={ footerCurrentPage }
></FooterNavigation>
}
{ alarmRoutesOn &&
<AlarmRoutes
options={ alarmOptions }
></AlarmRoutes>
}
</Fragment>
</div>
</PullToRefresh>
);
};