diff --git a/src/app/app.tsx b/src/app/app.tsx index 90d4562..5d6d87f 100644 --- a/src/app/app.tsx +++ b/src/app/app.tsx @@ -1,9 +1,7 @@ import '@/bridge'; import { router } from '@/shared/configs/sentry'; import { Toasts } from '@/shared/ui/toasts/toasts'; -import { TopButton } from '@/widgets/top-button'; import { useInitTheme } from './hooks'; -import { IOSStatusBar } from '@/widgets/ios-status-bar'; import { RouterProvider } from 'react-router-dom'; export const App = () => { diff --git a/src/app/hooks/use-noti-bar.ts b/src/app/hooks/use-noti-bar.ts deleted file mode 100644 index 20dc492..0000000 --- a/src/app/hooks/use-noti-bar.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { notiBar } from '@/shared/lib'; -import { useStore } from '@/shared/model/store'; -import { useEffect } from 'react'; -import { useShallow } from 'zustand/react/shallow'; - -export const useNotiBar = () => { - const [notiBarMessage, setNotiBarMessage] = useStore( - useShallow((state: any) => [ - state.utilEventSlice.notiBarMessage, - state.utilEventSlice.setNotiBarMessage - ]) - ); - - useEffect(() => { - if(notiBarMessage) { - notiBar(notiBarMessage); - setNotiBarMessage(''); - } - }, [notiBarMessage]); -}; diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 1b686f0..f560d8d 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,7 +1,6 @@ import React, { useState } from 'react'; import { Link, useRouterState } from '@tanstack/react-router'; import { Toasts } from '@/shared/ui/toasts/toasts'; -import { notiBar, snackBar } from '@/shared/lib/toast'; import { ToastContainer,toast } from 'react-toastify'; diff --git a/src/entities/account/ui/user-login-auth-info-wrap.tsx b/src/entities/account/ui/user-login-auth-info-wrap.tsx index edb5b8e..d60c777 100644 --- a/src/entities/account/ui/user-login-auth-info-wrap.tsx +++ b/src/entities/account/ui/user-login-auth-info-wrap.tsx @@ -3,7 +3,6 @@ import { useUserFindAuthMethodMutation } from '@/entities/user/api/use-user-find import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant'; import { useEffect, useState } from 'react'; import { useUserModifyAuthMethodMutation } from '@/entities/user/api/use-user-modify-authmethod-mutation'; -import { snackBar } from '@/shared/lib/toast'; import { PATHS } from '@/shared/constants/paths'; import { useNavigate } from '@/shared/lib/hooks/use-navigate'; @@ -26,7 +25,7 @@ export const UserLoginAuthInfoWrap = ({ const { mutateAsync: userFindAuthMethod } = useUserFindAuthMethodMutation(); const { mutateAsync: userModifyAuthMethod } = useUserModifyAuthMethodMutation({ onSuccess: () => { - snackBar('사용자 정보가 성공적으로 저장되었습니다.'); + // snackBar('사용자 정보가 성공적으로 저장되었습니다.'); navigate(PATHS.account.user.manage, { state: { mid: mid, @@ -34,7 +33,7 @@ export const UserLoginAuthInfoWrap = ({ }); }, onError: (error) => { - snackBar(error?.response?.data?.message || '사용자 정보 저장에 실패했습니다.'); + // snackBar(error?.response?.data?.message || '사용자 정보 저장에 실패했습니다.'); } }); diff --git a/src/entities/transaction/api/use-billing-charge-mutation.ts b/src/entities/transaction/api/use-billing-charge-mutation.ts index beea4a1..041505e 100644 --- a/src/entities/transaction/api/use-billing-charge-mutation.ts +++ b/src/entities/transaction/api/use-billing-charge-mutation.ts @@ -13,7 +13,7 @@ import { export const billingCharge = (params: BillingChargeParams) => { return resultify( - axios.post(API_URL_TRANSACTION.billingDetail(), params), + axios.post(API_URL_TRANSACTION.billingCharge(), params), ); }; diff --git a/src/entities/transaction/ui/billing-list.tsx b/src/entities/transaction/ui/billing-list.tsx index 4a112b8..a3f9020 100644 --- a/src/entities/transaction/ui/billing-list.tsx +++ b/src/entities/transaction/ui/billing-list.tsx @@ -59,14 +59,14 @@ export const BillingList = ({ return ( <>
- { getListDateGroup() } -
- -
+ { getListDateGroup() }
+
+ +
); }; \ No newline at end of file diff --git a/src/pages/account/password/modify-cancel-password-page.tsx b/src/pages/account/password/modify-cancel-password-page.tsx index b066045..4e29ab5 100644 --- a/src/pages/account/password/modify-cancel-password-page.tsx +++ b/src/pages/account/password/modify-cancel-password-page.tsx @@ -9,7 +9,6 @@ import { useSetOnBack } from '@/widgets/sub-layout/use-sub-layout'; import { useUserChangeCancelPasswordMutation } from '@/entities/user/api/use-user-change-cancel-password-mutation'; -import { snackBar } from '@/shared/lib/toast'; import { useStore } from '@/shared/model/store'; import { XKeypad, XKeypadManager, createPasswordKeypad } from '@/utils/xkeypad'; @@ -37,7 +36,7 @@ export const PasswordModifyCancelPasswordPage = () => { const changeCancelPasswordMutation = useUserChangeCancelPasswordMutation({ onSuccess: () => { - snackBar('비밀번호가 성공적으로 변경되었습니다.'); + // snackBar('비밀번호가 성공적으로 변경되었습니다.'); // Clear form and keypads setPassword(''); setConfirmPassword(''); @@ -49,7 +48,7 @@ export const PasswordModifyCancelPasswordPage = () => { navigate(PATHS.account.password.manage); }, onError: (error) => { - snackBar(error?.response?.data?.message || '비밀번호 변경에 실패했습니다.'); + // snackBar(error?.response?.data?.message || '비밀번호 변경에 실패했습니다.'); } }); diff --git a/src/pages/account/password/modify-login-password-page.tsx b/src/pages/account/password/modify-login-password-page.tsx index 7ef4e0e..6619d7a 100644 --- a/src/pages/account/password/modify-login-password-page.tsx +++ b/src/pages/account/password/modify-login-password-page.tsx @@ -9,7 +9,6 @@ import { useSetOnBack } from '@/widgets/sub-layout/use-sub-layout'; import { useUserChangePasswordMutation } from '@/entities/user/api/use-user-change-password-mutation'; -import { snackBar } from '@/shared/lib/toast'; export const PasswordModifyLoginPasswordPage = () => { const { navigate } = useNavigate(); @@ -20,7 +19,7 @@ export const PasswordModifyLoginPasswordPage = () => { const changePasswordMutation = useUserChangePasswordMutation({ onSuccess: () => { - snackBar('비밀번호가 성공적으로 변경되었습니다.'); + // snackBar('비밀번호가 성공적으로 변경되었습니다.'); // Clear form setCurrentPassword(''); setNewPassword(''); @@ -29,7 +28,7 @@ export const PasswordModifyLoginPasswordPage = () => { navigate(PATHS.account.password.manage); }, onError: (error) => { - snackBar(error?.response?.data?.message || '비밀번호 변경에 실패했습니다.'); + // snackBar(error?.response?.data?.message || '비밀번호 변경에 실패했습니다.'); } }); diff --git a/src/pages/account/user/add-account-page.tsx b/src/pages/account/user/add-account-page.tsx index bcf32d4..c6a8842 100644 --- a/src/pages/account/user/add-account-page.tsx +++ b/src/pages/account/user/add-account-page.tsx @@ -12,7 +12,6 @@ import { VerificationItem } from '@/entities/account/model/types'; import { useUserCreateMutation } from '@/entities/user/api/use-user-create-mutation'; import { useUserExistsUseridQuery } from '@/entities/user/api/use-user-exists-userid-query'; import { useLocation } from 'react-router'; -import { snackBar } from '@/shared/lib/toast'; export const UserAddAccountPage = () => { const { navigate } = useNavigate(); @@ -21,10 +20,10 @@ export const UserAddAccountPage = () => { const { mutateAsync: userCreate, isPending } = useUserCreateMutation({ onSuccess: () => { - snackBar('사용자가 성공적으로 추가되었습니다.'); + // snackBar('사용자가 성공적으로 추가되었습니다.'); }, onError: (error) => { - snackBar(error?.response?.data?.message || '사용자 추가에 실패했습니다.'); + // snackBar(error?.response?.data?.message || '사용자 추가에 실패했습니다.'); } }); @@ -382,7 +381,7 @@ export const UserAddAccountPage = () => { if (response.status) { // 성공 시 사용자 관리 페이지로 이동 - snackBar('사용자가 성공적으로 추가되었습니다.'); + // snackBar('사용자가 성공적으로 추가되었습니다.'); navigate(PATHS.account.user.manage); } else if (response.error) { // 에러 처리 diff --git a/src/pages/account/user/menu-auth-page.tsx b/src/pages/account/user/menu-auth-page.tsx index 6d7e000..6639e32 100644 --- a/src/pages/account/user/menu-auth-page.tsx +++ b/src/pages/account/user/menu-auth-page.tsx @@ -12,7 +12,7 @@ import { useLocation } from 'react-router'; import { useUserMenuPermissionsSaveMutation } from '@/entities/user/api/use-user-menu-permission-save-mutation'; // import { useUserMenuPermissionsMutation } from '@/entities/user/api/use-user-menu-permission-mutation'; import { UserMenuPermissionData } from '@/entities/user/model/types'; -import { snackBar } from '@/shared/lib/toast'; +//import { snackBar } from '@/shared/lib/toast'; // 권한 비트 플래그 (실제 API 데이터 기준) const PERMISSION = { @@ -35,7 +35,7 @@ export const UserMenuAuthPage = () => { const [isInitialLoad, setIsInitialLoad] = useState(true); const savePermissionsMutation = useUserMenuPermissionsSaveMutation({ onSuccess: () => { - snackBar('권한이 성공적으로 저장되었습니다.'); + //snackBar('권한이 성공적으로 저장되었습니다.'); navigate(PATHS.account.user.accountAuth, { state: { mid, @@ -46,7 +46,7 @@ export const UserMenuAuthPage = () => { }); }, onError: (error) => { - snackBar(error?.response?.data?.message || '권한 저장에 실패했습니다.'); + // snackBar(error?.response?.data?.message || '권한 저장에 실패했습니다.'); } }); diff --git a/src/pages/transaction/billing/charge-page.tsx b/src/pages/transaction/billing/charge-page.tsx index 119673a..846911b 100644 --- a/src/pages/transaction/billing/charge-page.tsx +++ b/src/pages/transaction/billing/charge-page.tsx @@ -2,7 +2,7 @@ import { ChangeEvent, useState } from 'react'; import { PATHS } from '@/shared/constants/paths'; import { IMAGE_ROOT } from '@/shared/constants/common'; import { useNavigate } from '@/shared/lib/hooks/use-navigate'; -import { HeaderType } from '@/entities/common/model/types'; +import { CalendarType, HeaderType } from '@/entities/common/model/types'; import { useBillingChargeMutation } from '@/entities/transaction/api/use-billing-charge-mutation'; import { useSetOnBack, @@ -10,18 +10,26 @@ import { useSetHeaderType, useSetFooterMode } from '@/widgets/sub-layout/use-sub-layout'; +import { NumericFormat, PatternFormat } from 'react-number-format'; +import { showAlert } from '@/widgets/show-alert'; +import moment from 'moment'; +import NiceCalendar from '@/shared/ui/calendar/nice-calendar'; +import { notiBar, snackBar } from '@/shared/lib'; export const BillingChargePage = () => { const { navigate } = useNavigate(); - const [billKey, setBillKey] = useState('BIKYvattest01m'); - const [productName, setProductName] = useState('테스트상품123'); - const [productAmount, setProductAmount] = useState(1000000); - const [orderNumber, setOrderNumber] = useState('P146733723'); - const [buyerName, setBuyerName] = useState('김테스트'); - const [paymentRequestDate, setPaymentRequestDate] = useState('2025-06-08'); + const [billKey, setBillKey] = useState(''); + const [productName, setProductName] = useState(''); + const [productAmount, setProductAmount] = useState(0); + const [orderNumber, setOrderNumber] = useState(''); + const [buyerName, setBuyerName] = useState(''); + const [paymentRequestDate, setPaymentRequestDate] = useState(moment().format('YYYY.MM.DD')); const [installmentMonth, setInstallmentMonth] = useState('00'); + const [calendarOpen, setCalendarOpen] = useState(false); + + useSetHeaderTitle('빌링 결제 신청'); useSetHeaderType(HeaderType.RightClose); useSetOnBack(() => { @@ -31,23 +39,64 @@ export const BillingChargePage = () => { const { mutateAsync: billingCharge } = useBillingChargeMutation(); + const setNewDate = (date: string) => { + setPaymentRequestDate(moment(date).format('YYYY.MM.DD')); + setCalendarOpen(false); + }; + const onClickToOpenCalendar = () => { + setCalendarOpen(true); + }; + const onClickToBillingCharge = () => { + if(!billKey){ + showAlert('빌키는 필수 입력 항목입니다.'); + return; + } + else if(!productName){ + showAlert('상품명은 필수 입력 항목입니다.'); + } + else if(!productAmount){ + showAlert('상품금액은 필수 입력 항목입니다.'); + } + else if(productAmount <= 0){ + showAlert('상품금액은 0보다 커야 합니다.'); + } + else if(!orderNumber){ + showAlert('주문번호는 필수 입력 항목입니다.'); + } + else if(!buyerName){ + showAlert('구매자명은 필수 입력 항목입니다.'); + } + let params = { billKey: billKey, productName: productName, productAmount: productAmount, orderNumber: orderNumber, buyerName: buyerName, - paymentRequestDate: paymentRequestDate, + paymentRequestDate: moment(paymentRequestDate).format('YYYYMMDD'), installmentMonth: installmentMonth }; billingCharge(params).then((rs) => { console.log(rs); - alert('성공') navigate(PATHS.transaction.billing.list); + }).catch((e: any) => { + /* + if(e.response?.data?.message){ + showAlert(e.response?.data?.message); + return; + } + */ }); }; + const onChangeBillKey = (value: string) => { + const pattern = /^[A-Za-z0-9]+$/; + if(pattern.test(value) || value === ''){ + setBillKey(value); + } + }; + const makeInstallmentMonthSelect = () => { let rs = []; @@ -88,8 +137,8 @@ export const BillingChargePage = () => {
) => onChangeBillKey(e.target.value) } />
@@ -106,11 +155,12 @@ export const BillingChargePage = () => {
상품금액 *
- ) => setProductAmount(parseInt(e.target.value)) } - /> + >
@@ -140,13 +190,14 @@ export const BillingChargePage = () => {
+ ); }; \ No newline at end of file diff --git a/src/pages/transaction/billing/list-page.tsx b/src/pages/transaction/billing/list-page.tsx index e8a5d91..b5a7140 100644 --- a/src/pages/transaction/billing/list-page.tsx +++ b/src/pages/transaction/billing/list-page.tsx @@ -32,9 +32,9 @@ export const BillingListPage = () => { const [mid, setMid] = useState(userMid); const [searchType, setSearchType] = useState(BillingSearchType.ALL); const [searchKeyword, setSearchKeyword] = useState(''); - // const [startDate, setStartDate] = useState(moment().subtract(1, 'month').format('YYYY-MM-DD')); - const [startDate, setStartDate] = useState(moment().format('YYYY-MM-DD')); - const [endDate, setEndDate] = useState(moment().format('YYYY-MM-DD')); + const [startDate, setStartDate] = useState(moment().subtract(1, 'month').format('YYYYMMDD')); + //const [startDate, setStartDate] = useState(moment().format('YYYYMMDD')); + const [endDate, setEndDate] = useState(moment().format('YYYYMMDD')); const [requestStatus, setRequestStatus] = useState(BillingRequestStatus.ALL); const [processResult, setProcessResult] = useState(BillingProcessResult.ALL); const [paymentMethod, setPaymentMethod] = useState(BillingPaymentMethod.ALL); @@ -76,8 +76,9 @@ export const BillingListPage = () => { maxAmount: newMaxAmount, page: pageParam }; + if(listParams.page){ - listParams.page.sortType = (option?.sortType)? option.sortType: sortType; + listParams.page.sortType = option?.sortType || sortType; setPageParam(listParams.page); } @@ -114,6 +115,14 @@ export const BillingListPage = () => { useEffect(() => { callList(); }, []); + useEffect(() => { + callList(); + }, [ + mid, searchType, searchKeyword, + startDate, endDate, + requestStatus, processResult, paymentMethod, + minAmount, maxAmount + ]); return ( <> diff --git a/src/pages/transaction/cash-receipt/list-page.tsx b/src/pages/transaction/cash-receipt/list-page.tsx index 47c5145..e402796 100644 --- a/src/pages/transaction/cash-receipt/list-page.tsx +++ b/src/pages/transaction/cash-receipt/list-page.tsx @@ -5,7 +5,18 @@ import { IMAGE_ROOT } from '@/shared/constants/common'; import { PATHS } from '@/shared/constants/paths'; import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { CashReceiptList } from '@/entities/transaction/ui/cash-receipt-list'; -import { CashReceiptListItem, TransactionCategory, CashReceiptPurposeType, CashReceiptProcessResult, ListItemProps, CashReceiptListParams, CashReceiptTransactionType, CashReceiptSearchNumberType, CashReceiptSummaryParams, CashReceiptListResponse, CashReceiptSummaryResponse } from '@/entities/transaction/model/types'; +import { + TransactionCategory, + CashReceiptPurposeType, + CashReceiptProcessResult, + ListItemProps, + CashReceiptListParams, + CashReceiptTransactionType, + CashReceiptSearchNumberType, + CashReceiptSummaryParams, + CashReceiptListResponse, + CashReceiptSummaryResponse +} from '@/entities/transaction/model/types'; import { useCashReceiptListMutation } from '@/entities/transaction/api/use-cash-receipt-list-mutation'; import { useDownloadExcelMutation } from '@/entities/transaction/api/use-download-excel-mutation'; import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant'; @@ -127,9 +138,8 @@ export const CashReceiptListPage = () => { callList(); }, [ mid, startDate, endDate, - purposeType, transactionType, - processResult, searchNumberType, - searchNumber + purposeType, transactionType, processResult, + searchNumberType, searchNumber ]); return ( diff --git a/src/pages/transaction/escrow/list-page.tsx b/src/pages/transaction/escrow/list-page.tsx index efa449f..15a0e2d 100644 --- a/src/pages/transaction/escrow/list-page.tsx +++ b/src/pages/transaction/escrow/list-page.tsx @@ -5,7 +5,15 @@ import { IMAGE_ROOT } from '@/shared/constants/common'; import { PATHS } from '@/shared/constants/paths'; import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { EscrowList } from '@/entities/transaction/ui/escrow-list'; -import { EscrowListItem, TransactionCategory, EscrowDeliveryStatus, EscrowSearchType, EscrowSettlementStatus, ListItemProps } from '@/entities/transaction/model/types'; +import { + TransactionCategory, + EscrowDeliveryStatus, + EscrowSearchType, + EscrowSettlementStatus, + ListItemProps, + EscrowListParams, + EscrowListResponse +} from '@/entities/transaction/model/types'; import { useEscrowListMutation } from '@/entities/transaction/api/use-escrow-list-mutation'; import { useDownloadExcelMutation } from '@/entities/transaction/api/use-download-excel-mutation'; import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant'; @@ -32,9 +40,9 @@ export const EscrowListPage = () => { const [mid, setMid] = useState(userMid); const [searchType, setSearchType] = useState(EscrowSearchType.ALL); const [searchKeyword, setSearchKeyword] = useState(''); - //const [startDate, setStartDate] = useState(moment().subtract(1, 'month').format('YYYY-MM-DD')); - const [startDate, setStartDate] = useState(moment().format('YYYY-MM-DD')); - const [endDate, setEndDate] = useState(moment().format('YYYY-MM-DD')); + const [startDate, setStartDate] = useState(moment().subtract(1, 'month').format('YYYYMMDD')); + // const [startDate, setStartDate] = useState(moment().format('YYYYMMDD')); + const [endDate, setEndDate] = useState(moment().format('YYYYMMDD')); const [deliveryStatus, setDeliveryStatus] = useState(EscrowDeliveryStatus.ALL); const [settlementStatus, setSettlementStatus] = useState(EscrowSettlementStatus.ALL); const [minAmount, setMinAmount] = useState(); @@ -62,7 +70,7 @@ export const EscrowListPage = () => { if(!!maxAmount && typeof(maxAmount) === 'string'){ newMaxAmount = parseInt(maxAmount); } - let listParams = { + let listParams: EscrowListParams = { mid: mid, searchType: 'ORDER_NUMBER', searchKeyword: searchKeyword, @@ -74,12 +82,13 @@ export const EscrowListPage = () => { maxAmount: newMaxAmount, page: pageParam }; + if(listParams.page){ - listParams.page.sortType = (option?.sortType)? option.sortType: sortType; + listParams.page.sortType = option?.sortType || sortType; setPageParam(listParams.page); } - escrowList(listParams).then((rs) => { + escrowList(listParams).then((rs: EscrowListResponse) => { setListItems(rs.content); }); }; @@ -112,6 +121,14 @@ export const EscrowListPage = () => { useEffect(() => { callList(); }, []); + useEffect(() => { + callList(); + }, [ + mid, searchType, searchKeyword, + startDate, endDate, + deliveryStatus, settlementStatus, + minAmount, maxAmount + ]); return ( <> diff --git a/src/shared/configs/axios/index.ts b/src/shared/configs/axios/index.ts index 53996ee..cbd8f53 100644 --- a/src/shared/configs/axios/index.ts +++ b/src/shared/configs/axios/index.ts @@ -3,7 +3,7 @@ import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'ax import { WHITE_LIST_URLS } from '@/shared/api/urls'; import { StorageKeys } from '@/shared/constants/local-storage'; import { checkIsAxiosError, getLocalStorage, setLocalStorage } from '@/shared/lib'; -import { finalizeConfig, extractAccessToken, extractRequestId } from './utils'; +import { finalizeConfig } from './utils'; import { HEADER_USER_AGENT } from '@/shared/constants/url'; import { appBridge } from '@/utils/appBridge'; import { useAppBridge } from '@/hooks'; @@ -30,22 +30,10 @@ const onRequestFulfilled = (config: InternalAxiosRequestConfig) => { }; const onRequestRejected = (error: any) => { - const { method, url, params, data, headers } = error.config; - /* - Sentry.setContext('API Request Detail', { - method, - url, - params, - data, - headers, - }); - */ return Promise.reject(error); }; const onResponseFulfilled = (response: AxiosResponse) => { - extractAccessToken(response); - extractRequestId(response); return { ...response, data: response.data.data || response.data, @@ -73,22 +61,13 @@ const onResponseRejected = (error: AxiosError) => { }); } - /* - else if (error?.response) { - const { data, status } = error.response; - extractRequestId(error?.response); - Sentry.setContext('API Response Detail', { - status, - data, - }); - } - */ return new Promise((_resolve, reject) => { - if (checkIsAxiosError(error)) { + if(checkIsAxiosError(error)){ // iOS의 경우 window에서 unload event가 일어날때 네트워크 에러가 발생하곤 해서 이런 케이스를 방지하기 위해 지연시킴 // location.href, location.reload 등으로 unload event가 일어나면 자바스크립트 런타임이 초기화되므로 settimeout으로 인한 네트워크 에러가 트리거 x setTimeout(() => reject(error), 300); - } else { + } + else{ reject(error); } }); diff --git a/src/shared/configs/axios/utils.ts b/src/shared/configs/axios/utils.ts index fc1365c..e97fcbf 100644 --- a/src/shared/configs/axios/utils.ts +++ b/src/shared/configs/axios/utils.ts @@ -1,6 +1,4 @@ -import { InternalAxiosRequestConfig, AxiosResponse } from 'axios'; -import { StorageKeys } from '@/shared/constants/local-storage'; -import { setLocalStorage } from '@/shared/lib'; +import { InternalAxiosRequestConfig } from 'axios'; export const finalizeConfig = (config: InternalAxiosRequestConfig) => { const { params, data } = config; @@ -9,21 +7,4 @@ export const finalizeConfig = (config: InternalAxiosRequestConfig) => { params, data, }; -}; - -export const extractAccessToken = (response: AxiosResponse): void => { - const authHeader = response?.headers?.['authorization']; - if (authHeader) { - const accessToken = authHeader.substring(7); - setLocalStorage(StorageKeys.Jwt, accessToken); - } -}; - -export const extractRequestId = (response: AxiosResponse): void => { - const requestIdHeader = response?.headers?.['x-request-id']; - if (requestIdHeader) { - const requestId = requestIdHeader.replaceAll(', *', ''); - console.log('requestId --> ', requestId); - setLocalStorage(StorageKeys.RequestId, requestId); - } -}; +}; \ No newline at end of file diff --git a/src/shared/lib/hooks/use-navigate.ts b/src/shared/lib/hooks/use-navigate.ts index 5302970..4a599cd 100644 --- a/src/shared/lib/hooks/use-navigate.ts +++ b/src/shared/lib/hooks/use-navigate.ts @@ -8,15 +8,15 @@ import { export type NavigateTo = PathType | -1 | 0; export const goBackWebview = (goBack: () => void) => { - if (!window.ReactNativeWebView) { - if (window.history.state?.idx > 0) { - goBack(); - return; - } else { - window.close(); - } + if(window.history.state?.idx > 0){ + goBack(); return; } + else{ + window.close(); + } + return; + }; export const useNavigate = () => { diff --git a/src/shared/lib/toast.tsx b/src/shared/lib/toast.ts similarity index 69% rename from src/shared/lib/toast.tsx rename to src/shared/lib/toast.ts index c1732bd..a77e6e9 100644 --- a/src/shared/lib/toast.tsx +++ b/src/shared/lib/toast.ts @@ -1,5 +1,5 @@ -/* eslint-disable @cspell/spellchecker */ -import { toast } from 'react-toastify'; +import { toast } from "react-toastify"; + export const snackBar = (text: string) => { toast.dismiss({ containerId: 'snackbar' }); toast(text, { containerId: 'snackbar' }); @@ -7,5 +7,5 @@ export const snackBar = (text: string) => { export const notiBar = (text: string) => { toast.dismiss({ containerId: 'notibar' }); - toast(text); -}; + toast(text, { containerId: 'notibar' }); +}; \ No newline at end of file diff --git a/src/shared/ui/toasts/noti-bar.tsx b/src/shared/ui/toasts/noti-bar.tsx index 20286b0..b8e275b 100644 --- a/src/shared/ui/toasts/noti-bar.tsx +++ b/src/shared/ui/toasts/noti-bar.tsx @@ -1,21 +1,22 @@ /* eslint-disable @cspell/spellchecker */ -import { Slide, ToastContainer } from 'react-toastify'; +import { ToastContainer } from 'react-toastify'; import styled from 'styled-components'; const StyledNotiBar = styled(ToastContainer)` // https://styled-components.com/docs/faqs#how-can-i-override-styles-with-higher-specificity &&&.Toastify__toast-container { - transform: translateX(2.5%); + } .Toastify__toast { min-height: auto; - width: 95%; + width: calc(100% - 32px); height: auto; - - background-color: #262d42; + margin-top: 20px; + background-color: rgba(45, 52, 54, 0.8); box-sizing: border-box; + color: #ffffff; - border-radius: 0px 0px 20px 20px; + border-radius: 20px 20px 20px 20px; text-align: center; -webkit-box-shadow: 1px 1px 10px 0px rgba(43, 38, 38, 0.5); -moz-box-shadow: 1px 1px 10px 0px rgba(43, 38, 38, 0.5); @@ -23,7 +24,7 @@ const StyledNotiBar = styled(ToastContainer)` display: flex; align-items: center; justify-content: center; - padding: 0; + padding: 6px 0 9px 0; } .Toastify__toast-body { padding: 0; diff --git a/src/shared/ui/toasts/snack-bar.tsx b/src/shared/ui/toasts/snack-bar.tsx index 9b59c09..132cbfa 100644 --- a/src/shared/ui/toasts/snack-bar.tsx +++ b/src/shared/ui/toasts/snack-bar.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @cspell/spellchecker */ import { cssTransition, ToastContainer } from 'react-toastify'; import styled from 'styled-components'; @@ -8,12 +7,14 @@ const StyledSnackBar = styled(ToastContainer)` display: flex; align-items: center; justify-content: center; - bottom: 20px; + bottom: 30px; pointer-events: none; margin-bottom: calc(env(safe-area-inset-top) / 3); + z-index: 1000; } .Toastify__toast { pointer-events: none; + calc(100% - 32px); height: auto; padding: 0; display: flex; @@ -23,8 +24,9 @@ const StyledSnackBar = styled(ToastContainer)` min-height: auto; border-radius: 50px; padding: 10px 20px; - background-color: rgba(34, 37, 56, 0.555); + background-color: rgba(45, 52, 54, 0.8); width: 85%; + color: #ffffff } .Toastify__toast-body { padding: 0; @@ -53,7 +55,7 @@ export const SnackBar = () => { return ( { pauseOnFocusLoss={false} draggable={false} pauseOnHover={false} - transition={fade} containerId={'snackbar'} draggablePercent={10} closeButton={false} diff --git a/src/widgets/fallbacks/api-error.tsx b/src/widgets/fallbacks/api-error.tsx index 5bc90e4..1c27b19 100644 --- a/src/widgets/fallbacks/api-error.tsx +++ b/src/widgets/fallbacks/api-error.tsx @@ -8,7 +8,7 @@ type CommonErrorProps = FallbackProps & { height?: number; }; export const APIError = ({ error, resetErrorBoundary }: CommonErrorProps) => { - const { navigateBack } = useNavigate(); + const { reload } = useNavigate(); const msg = useMemo(() => { let message: Partial = { title: '일시적인 오류가 발생하였습니다.', @@ -21,7 +21,7 @@ export const APIError = ({ error, resetErrorBoundary }: CommonErrorProps) => { }, [error]); const handleCancel = () => { - navigateBack(); + reload(); resetErrorBoundary(); }; @@ -30,8 +30,8 @@ export const APIError = ({ error, resetErrorBoundary }: CommonErrorProps) => { afterLeave={() => null} open={true} onClose={() => null} - onConfirmClick={resetErrorBoundary} - onCancelClick={handleCancel} + onConfirmClick={ resetErrorBoundary } + onCancelClick={ handleCancel } message={msg.message} buttonLabel={['취소', '재시도']} /> diff --git a/src/widgets/ios-status-bar/index.tsx b/src/widgets/ios-status-bar/index.tsx deleted file mode 100644 index b598d92..0000000 --- a/src/widgets/ios-status-bar/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Fragment } from 'react/jsx-runtime'; -import { useAppColor } from '@/shared/lib/hooks/use-change-bg-color'; - -export const IOSStatusBar = () => { - const [appColor] = useAppColor(); - const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent); - - if(!isIOS){ - return ; - } - - return ( -
- ); -}; diff --git a/src/widgets/top-button/handle-event-listeners.ts b/src/widgets/top-button/handle-event-listeners.ts deleted file mode 100644 index ecc17de..0000000 --- a/src/widgets/top-button/handle-event-listeners.ts +++ /dev/null @@ -1,21 +0,0 @@ -interface EventListeners { - element: HTMLElement | null; - onScroll: () => void; - onTouchStart: () => void; - onTouchMove: () => void; - onTouchEnd: () => void; -} - -export const addEventListeners = ({ element, onScroll, onTouchStart, onTouchMove, onTouchEnd }: EventListeners) => { - element?.addEventListener('scroll', onScroll); - element?.addEventListener('touchstart', onTouchStart, { passive: true }); - element?.addEventListener('touchmove', onTouchMove, { passive: true }); - element?.addEventListener('touchend', onTouchEnd, { passive: true }); -}; - -export const removeEventListeners = ({ element, onScroll, onTouchStart, onTouchMove, onTouchEnd }: EventListeners) => { - element?.removeEventListener('scroll', onScroll); - element?.removeEventListener('touchstart', onTouchStart); - element?.removeEventListener('touchmove', onTouchMove); - element?.removeEventListener('touchend', onTouchEnd); -}; diff --git a/src/widgets/top-button/index.tsx b/src/widgets/top-button/index.tsx deleted file mode 100644 index 314807f..0000000 --- a/src/widgets/top-button/index.tsx +++ /dev/null @@ -1,103 +0,0 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -import { AnimatePresence, motion, useMotionValue } from 'framer-motion'; -import { useCallback, useRef, useState } from 'react'; - -import { useRouteChangeEffect } from './use-route-change-effect'; -import { useScrollEventListeners } from './use-scroll-event-listeners'; -import { useScrollTarget } from './use-scroll-target'; - -const TIME_OUT = 5000; -const THRASH_HOLD = 30; - -let isScrollingBackToTop = false; -let lastScrollY = 0; -let isTouching = false; - -export const TopButton = () => { - const scrollTarget = useScrollTarget(); - const scrollY = useMotionValue(scrollTarget.current?.scrollTop ?? 0); - - const scrollTimeOutRef = useRef(undefined); - const [showButton, setShowButton] = useState(); - - const reset = useCallback(() => { - setShowButton(false); - isScrollingBackToTop = false; - isTouching = false; - if (scrollTarget.current) { - scrollTarget.current.scrollTop = 0; - } - clearTimeout(scrollTimeOutRef.current); - }, []); - - const initialize = useCallback(() => { - reset(); - lastScrollY = 0; - }, []); - - const scrollBackToTop = useCallback(() => { - reset(); - }, []); - - const onScroll = () => { - if (isTouching) return; - const currentScrollY = scrollTarget.current?.scrollTop ?? 0; - const direction = currentScrollY > lastScrollY ? 'down' : 'up'; - lastScrollY = currentScrollY <= 0 ? 0 : currentScrollY; - - scrollY.set(currentScrollY); - clearTimeout(scrollTimeOutRef.current); - - setShowButton(direction === 'down' ? false : currentScrollY > THRASH_HOLD); - - if (!isScrollingBackToTop && direction === 'down') { - scrollTimeOutRef.current = setTimeout(() => { - setShowButton(true); - }, TIME_OUT); - } - if (currentScrollY === 0) { - isScrollingBackToTop = false; - } - }; - - const onTouchStart = useCallback(() => { - isTouching = true; - }, []); - const onTouchMove = useCallback(() => { - isTouching = true; - }, []); - const onTouchEnd = useCallback(() => { - isTouching = false; - }, []); - - useScrollEventListeners({ - scrollTarget, - onScroll, - onTouchStart, - onTouchMove, - onTouchEnd, - }); - - useRouteChangeEffect({ - scrollTarget, - onScroll, - onTouchStart, - onTouchMove, - onTouchEnd, - callback: initialize, - }); - return ( - - {showButton && ( - - 위로 - - )} - - ); -}; diff --git a/src/widgets/top-button/use-route-change-effect.ts b/src/widgets/top-button/use-route-change-effect.ts deleted file mode 100644 index 7d4acd3..0000000 --- a/src/widgets/top-button/use-route-change-effect.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -import { useIsFetching, useIsMutating } from '@tanstack/react-query'; -import { useCallback, useEffect } from 'react'; - -import { useRouterListener } from '@/shared/lib/hooks'; -import { addEventListeners, removeEventListeners } from './handle-event-listeners'; - -interface RouteChangeEffect { - scrollTarget: React.MutableRefObject; - onScroll: () => void; - onTouchStart: () => void; - onTouchMove: () => void; - onTouchEnd: () => void; - callback: () => void; -} - -export const useRouteChangeEffect = ({ - scrollTarget, - onScroll, - onTouchStart, - onTouchMove, - onTouchEnd, - callback, -}: RouteChangeEffect) => { - const isFetching = useIsFetching(); - const isMutating = useIsMutating(); - const isLoading = isFetching > 0 || isMutating > 0; - - const resetScrollTarget = useCallback(() => { - const rootEl = document.getElementById('root') as HTMLElement; - const pullToRefreshEl = document.getElementsByClassName('ptr__children')[0] as HTMLElement; - - scrollTarget.current = rootEl; - if (pullToRefreshEl?.scrollHeight > window.innerHeight) { - scrollTarget.current = pullToRefreshEl; - addEventListeners({ element: pullToRefreshEl, onScroll, onTouchStart, onTouchMove, onTouchEnd }); - removeEventListeners({ element: rootEl, onScroll, onTouchStart, onTouchMove, onTouchEnd }); - } else { - addEventListeners({ element: rootEl, onScroll, onTouchStart, onTouchMove, onTouchEnd }); - removeEventListeners({ element: pullToRefreshEl, onScroll, onTouchStart, onTouchMove, onTouchEnd }); - } - }, []); - useEffect(() => { - if (isLoading) return; - resetScrollTarget(); - }, [isLoading]); - - useRouterListener(() => { - setTimeout(() => { - callback?.(); - }, 0); - }); -}; diff --git a/src/widgets/top-button/use-scroll-event-listeners.ts b/src/widgets/top-button/use-scroll-event-listeners.ts deleted file mode 100644 index e64ab52..0000000 --- a/src/widgets/top-button/use-scroll-event-listeners.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -import { MutableRefObject, useEffect } from 'react'; - -import { addEventListeners, removeEventListeners } from './handle-event-listeners'; - -interface EventListeners { - scrollTarget: MutableRefObject; - onScroll: () => void; - onTouchStart: () => void; - onTouchMove: () => void; - onTouchEnd: () => void; -} -export const useScrollEventListeners = ({ - scrollTarget, - onScroll, - onTouchStart, - onTouchMove, - onTouchEnd, -}: EventListeners) => { - useEffect(() => { - if(!scrollTarget.current){ - return () => {}; - } - addEventListeners({ element: scrollTarget.current, onScroll, onTouchStart, onTouchMove, onTouchEnd }); - - return () => { - const rootEl = document.getElementById('root') as HTMLElement; - const pullToRefreshEl = document.getElementsByClassName('ptr__children')[0] as HTMLElement; - removeEventListeners({ element: rootEl, onScroll, onTouchStart, onTouchMove, onTouchEnd }); - removeEventListeners({ element: pullToRefreshEl, onScroll, onTouchStart, onTouchMove, onTouchEnd }); - }; - }, []); -}; diff --git a/src/widgets/top-button/use-scroll-target.ts b/src/widgets/top-button/use-scroll-target.ts deleted file mode 100644 index 5aa6afb..0000000 --- a/src/widgets/top-button/use-scroll-target.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { useEffect, useRef } from 'react'; - -export const useScrollTarget = () => { - const scrollTarget = useRef(null); - - useEffect(() => { - const rootEl = document.getElementById('root') as HTMLElement; - const pullToRefreshEl = document.getElementsByClassName('ptr__children')[0] as HTMLElement; - - let target: HTMLElement | null = rootEl; - if (pullToRefreshEl?.scrollHeight > window.innerHeight) { - target = pullToRefreshEl; - } - scrollTarget.current = target; - - return () => { - scrollTarget.current = null; - }; - }, []); - - return scrollTarget; -};