test
This commit is contained in:
@@ -227,7 +227,7 @@ export const FundAccountTransferListWrap = () => {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="transaction-list">
|
<section className="transaction-list pb-86">
|
||||||
{ getListDateGroup() }
|
{ getListDateGroup() }
|
||||||
</section>
|
</section>
|
||||||
<div className="apply-row">
|
<div className="apply-row">
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ interface UseAppBridgeReturn {
|
|||||||
|
|
||||||
// 토큰 요청
|
// 토큰 요청
|
||||||
requestToken: () => Promise<any>;
|
requestToken: () => Promise<any>;
|
||||||
|
requestRefreshToken: () => Promise<any>;
|
||||||
|
|
||||||
// 간편 인증 등록
|
// 간편 인증 등록
|
||||||
registerBiometric: () => Promise<void>;
|
registerBiometric: () => Promise<void>;
|
||||||
@@ -146,15 +147,6 @@ export const useAppBridge = (): UseAppBridgeReturn => {
|
|||||||
return appBridge.safeCall(() => appBridge.setStorage(key, value));
|
return appBridge.safeCall(() => appBridge.setStorage(key, value));
|
||||||
}, [isNativeEnvironment]);
|
}, [isNativeEnvironment]);
|
||||||
|
|
||||||
/*
|
|
||||||
const getStorage = useCallback(async <T = unknown>(key: string): Promise<T | null> => {
|
|
||||||
if (!isNativeEnvironment) {
|
|
||||||
const item = localStorage.getItem(key);
|
|
||||||
return item ? JSON.parse(item) : null;
|
|
||||||
}
|
|
||||||
return appBridge.safeCall(() => appBridge.getStorage(key), null);
|
|
||||||
}, [isNativeEnvironment]);
|
|
||||||
*/
|
|
||||||
const removeStorage = useCallback(async (key: string): Promise<void> => {
|
const removeStorage = useCallback(async (key: string): Promise<void> => {
|
||||||
if (!isNativeEnvironment) {
|
if (!isNativeEnvironment) {
|
||||||
localStorage.removeItem(key);
|
localStorage.removeItem(key);
|
||||||
@@ -177,6 +169,13 @@ export const useAppBridge = (): UseAppBridgeReturn => {
|
|||||||
return appBridge.safeCall(() => appBridge.requestToken());
|
return appBridge.safeCall(() => appBridge.requestToken());
|
||||||
}, [isNativeEnvironment]);
|
}, [isNativeEnvironment]);
|
||||||
|
|
||||||
|
const requestRefreshToken = useCallback(async (): Promise<any> => {
|
||||||
|
if (!isNativeEnvironment) {
|
||||||
|
throw new Error('Token refresh request is only available in native environment');
|
||||||
|
}
|
||||||
|
return appBridge.safeCall(() => appBridge.requestRefreshToken());
|
||||||
|
}, [isNativeEnvironment]);
|
||||||
|
|
||||||
const registerBiometric = useCallback(async (): Promise<void> => {
|
const registerBiometric = useCallback(async (): Promise<void> => {
|
||||||
if (!isNativeEnvironment) {
|
if (!isNativeEnvironment) {
|
||||||
throw new Error('Biometric auth is only available in native environment');
|
throw new Error('Biometric auth is only available in native environment');
|
||||||
@@ -198,72 +197,7 @@ export const useAppBridge = (): UseAppBridgeReturn => {
|
|||||||
}
|
}
|
||||||
return appBridge.safeCall(() => appBridge.closeBiometricRegistrationPopup());
|
return appBridge.safeCall(() => appBridge.closeBiometricRegistrationPopup());
|
||||||
}, [isNativeEnvironment]);
|
}, [isNativeEnvironment]);
|
||||||
|
|
||||||
/*
|
|
||||||
const openCamera = useCallback(async (
|
|
||||||
options?: { quality?: number; allowEdit?: boolean }
|
|
||||||
): Promise<string> => {
|
|
||||||
if (!isNativeEnvironment) {
|
|
||||||
throw new Error('Camera access is only available in native environment');
|
|
||||||
}
|
|
||||||
const result = await appBridge.safeCall(() => appBridge.openCamera(options), '');
|
|
||||||
return result || '';
|
|
||||||
}, [isNativeEnvironment]);
|
|
||||||
|
|
||||||
const openGallery = useCallback(async (
|
|
||||||
options?: { multiple?: boolean; maxCount?: number }
|
|
||||||
): Promise<string[]> => {
|
|
||||||
if (!isNativeEnvironment) {
|
|
||||||
throw new Error('Gallery access is only available in native environment');
|
|
||||||
}
|
|
||||||
const result = await appBridge.safeCall(() => appBridge.openGallery(options), []);
|
|
||||||
return result || [];
|
|
||||||
}, [isNativeEnvironment]);
|
|
||||||
|
|
||||||
const getLocation = useCallback(async (
|
|
||||||
options?: { enableHighAccuracy?: boolean; timeout?: number }
|
|
||||||
): Promise<LocationInfo> => {
|
|
||||||
if (!isNativeEnvironment) {
|
|
||||||
// 웹 환경에서는 HTML5 Geolocation API 사용
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (!navigator.geolocation) {
|
|
||||||
reject(new Error('Geolocation is not supported'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
navigator.geolocation.getCurrentPosition(
|
|
||||||
(position) => {
|
|
||||||
resolve({
|
|
||||||
latitude: position.coords.latitude,
|
|
||||||
longitude: position.coords.longitude,
|
|
||||||
accuracy: position.coords.accuracy,
|
|
||||||
timestamp: position.timestamp
|
|
||||||
});
|
|
||||||
},
|
|
||||||
(error) => reject(error),
|
|
||||||
{
|
|
||||||
enableHighAccuracy: options?.enableHighAccuracy || false,
|
|
||||||
timeout: options?.timeout || 10000
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await appBridge.safeCall(() => appBridge.getLocation(options));
|
|
||||||
if (!result) {
|
|
||||||
throw new Error('Failed to get location');
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}, [isNativeEnvironment]);
|
|
||||||
|
|
||||||
const getContacts = useCallback(async (): Promise<ContactInfo[]> => {
|
|
||||||
if (!isNativeEnvironment) {
|
|
||||||
throw new Error('Contact access is only available in native environment');
|
|
||||||
}
|
|
||||||
const result = await appBridge.safeCall(() => appBridge.getContacts(), []);
|
|
||||||
return result || [];
|
|
||||||
}, [isNativeEnvironment]);
|
|
||||||
*/
|
|
||||||
const shareContent = useCallback(async (content: ShareContent): Promise<void> => {
|
const shareContent = useCallback(async (content: ShareContent): Promise<void> => {
|
||||||
if (!isNativeEnvironment) {
|
if (!isNativeEnvironment) {
|
||||||
// 웹 환경에서는 Web Share API 사용 (지원되는 경우)
|
// 웹 환경에서는 Web Share API 사용 (지원되는 경우)
|
||||||
@@ -318,6 +252,7 @@ export const useAppBridge = (): UseAppBridgeReturn => {
|
|||||||
shareContent,
|
shareContent,
|
||||||
logout,
|
logout,
|
||||||
requestToken,
|
requestToken,
|
||||||
|
requestRefreshToken,
|
||||||
registerBiometric,
|
registerBiometric,
|
||||||
openBiometricRegistrationPopup,
|
openBiometricRegistrationPopup,
|
||||||
closeBiometricRegistrationPopup
|
closeBiometricRegistrationPopup
|
||||||
|
|||||||
@@ -130,4 +130,10 @@ main.home-main{
|
|||||||
}
|
}
|
||||||
.menu-category{
|
.menu-category{
|
||||||
position: relative;
|
position: relative;
|
||||||
|
}
|
||||||
|
.date-group{
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.pb-86{
|
||||||
|
padding-bottom: 86px;
|
||||||
}
|
}
|
||||||
@@ -37,6 +37,7 @@ export enum BridgeMessageType {
|
|||||||
|
|
||||||
// 토큰 요청
|
// 토큰 요청
|
||||||
REQUEST_TOKEN = 'requestToken',
|
REQUEST_TOKEN = 'requestToken',
|
||||||
|
REQUEST_REFRESH_TOKEN = 'requestRefreshToken',
|
||||||
|
|
||||||
// 카메라/갤러리
|
// 카메라/갤러리
|
||||||
OPEN_CAMERA = 'openCamera',
|
OPEN_CAMERA = 'openCamera',
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import axios, { AxiosInstance, AxiosResponse, AxiosError, AxiosRequestConfig } f
|
|||||||
import { ApiResponse, ApiErrorResponse, FileUploadProgress, FileUploadResponse } from '@/types';
|
import { ApiResponse, ApiErrorResponse, FileUploadProgress, FileUploadResponse } from '@/types';
|
||||||
import { tokenManager } from './tokenManager';
|
import { tokenManager } from './tokenManager';
|
||||||
import config from '@/config';
|
import config from '@/config';
|
||||||
|
import { useAppBridge } from '@/hooks';
|
||||||
|
|
||||||
class ApiClient {
|
class ApiClient {
|
||||||
private instance: AxiosInstance;
|
private instance: AxiosInstance;
|
||||||
@@ -11,6 +12,9 @@ class ApiClient {
|
|||||||
reject: (error?: unknown) => void;
|
reject: (error?: unknown) => void;
|
||||||
}> = [];
|
}> = [];
|
||||||
|
|
||||||
|
private isNativeEnvironment: boolean;
|
||||||
|
private requestRefreshToken: () => Promise<any>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.instance = axios.create({
|
this.instance = axios.create({
|
||||||
baseURL: config.api.baseURL,
|
baseURL: config.api.baseURL,
|
||||||
@@ -21,7 +25,19 @@ class ApiClient {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
const {
|
||||||
|
isNativeEnvironment,
|
||||||
|
openBiometricRegistrationPopup,
|
||||||
|
requestRefreshToken,
|
||||||
|
logout
|
||||||
|
} = useAppBridge();
|
||||||
|
this.isNativeEnvironment = isNativeEnvironment;
|
||||||
|
this.requestRefreshToken = requestRefreshToken;
|
||||||
|
|
||||||
this.setupInterceptors();
|
this.setupInterceptors();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupInterceptors(): void {
|
private setupInterceptors(): void {
|
||||||
@@ -57,7 +73,14 @@ class ApiClient {
|
|||||||
|
|
||||||
originalRequest._retry = true;
|
originalRequest._retry = true;
|
||||||
this.isRefreshing = true;
|
this.isRefreshing = true;
|
||||||
|
|
||||||
|
console.log('refreshToken!!');
|
||||||
|
/*
|
||||||
|
this.requestRefreshToken().then((token) => {
|
||||||
|
console.log('requestRefreshToken +[' + JSON.stringify(token) + ']' );
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const newToken = await this.refreshAccessToken();
|
const newToken = await this.refreshAccessToken();
|
||||||
this.processQueue(null, newToken);
|
this.processQueue(null, newToken);
|
||||||
@@ -72,6 +95,7 @@ class ApiClient {
|
|||||||
} finally {
|
} finally {
|
||||||
this.isRefreshing = false;
|
this.isRefreshing = false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(this.handleError(error));
|
return Promise.reject(this.handleError(error));
|
||||||
|
|||||||
@@ -157,6 +157,10 @@ class AppBridge {
|
|||||||
return this.sendMessage(BridgeMessageType.REQUEST_TOKEN);
|
return this.sendMessage(BridgeMessageType.REQUEST_TOKEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async requestRefreshToken(): Promise<any> {
|
||||||
|
return this.sendMessage(BridgeMessageType.REQUEST_REFRESH_TOKEN);
|
||||||
|
}
|
||||||
|
|
||||||
// 공유 관련
|
// 공유 관련
|
||||||
async shareContent(content: ShareContent): Promise<void> {
|
async shareContent(content: ShareContent): Promise<void> {
|
||||||
return this.sendMessage(BridgeMessageType.SHARE_CONTENT, content);
|
return this.sendMessage(BridgeMessageType.SHARE_CONTENT, content);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
FooterItemActiveKey
|
FooterItemActiveKey
|
||||||
} from '@/entities/common/model/types';
|
} from '@/entities/common/model/types';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { useAppBridge } from '@/hooks';
|
||||||
|
|
||||||
export const FooterNavigation = ({
|
export const FooterNavigation = ({
|
||||||
setMenuOn,
|
setMenuOn,
|
||||||
@@ -14,16 +15,34 @@ export const FooterNavigation = ({
|
|||||||
}: FooterProps) => {
|
}: FooterProps) => {
|
||||||
const { navigate } = useNavigate();
|
const { navigate } = useNavigate();
|
||||||
const [isFooterOn, setIsFooterOn] = useState<boolean>(false);
|
const [isFooterOn, setIsFooterOn] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const {
|
||||||
|
isNativeEnvironment,
|
||||||
|
openBiometricRegistrationPopup,
|
||||||
|
requestRefreshToken,
|
||||||
|
logout
|
||||||
|
} = useAppBridge();
|
||||||
|
|
||||||
const onClickToNavigate = (path?: string) => {
|
const onClickToNavigate = (path?: string) => {
|
||||||
if(!!path){
|
if(!!path){
|
||||||
navigate(path);
|
if(path === PATHS.settlement.list){
|
||||||
|
callRefresh();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
navigate(path);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const onClickToOpenMenu = () => {
|
const onClickToOpenMenu = () => {
|
||||||
setFavoriteEdit(false);
|
setFavoriteEdit(false);
|
||||||
setMenuOn(true);
|
setMenuOn(true);
|
||||||
};
|
};
|
||||||
|
const callRefresh = () => {
|
||||||
|
requestRefreshToken().then((token) => {
|
||||||
|
console.log('requestRefreshToken +[' + JSON.stringify(token) + ']' );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const buttonItems = [
|
const buttonItems = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -119,9 +119,27 @@ export const SubLayout = () => {
|
|||||||
}
|
}
|
||||||
setLoginSuccess(true);
|
setLoginSuccess(true);
|
||||||
setHeaderNavigationKey(headerNavigationKey + 1);
|
setHeaderNavigationKey(headerNavigationKey + 1);
|
||||||
|
|
||||||
|
reLogin();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const reLogin = () => {
|
||||||
|
console.log('reLogin');
|
||||||
|
let userInfo = useStore.getState().UserStore.userInfo;
|
||||||
|
if(userInfo.accessTokenExpiresIn){
|
||||||
|
let accessTokenExpiresIn = userInfo.accessTokenExpiresIn;
|
||||||
|
let timer = setTimeout(() => {
|
||||||
|
if(isNativeEnvironment){
|
||||||
|
handleRequestToken();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
handleLogin();
|
||||||
|
}
|
||||||
|
}, accessTokenExpiresIn * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
const handleLogin = useCallback(async () => {
|
const handleLogin = useCallback(async () => {
|
||||||
const userParmas = {
|
const userParmas = {
|
||||||
|
|||||||
Reference in New Issue
Block a user