첫 커밋
This commit is contained in:
43
src/entities/account/model/types.ts
Normal file
43
src/entities/account/model/types.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
export enum AccountTabKeys {
|
||||
UserManage = 'UserManage',
|
||||
PasswordManage = 'PasswordManage',
|
||||
};
|
||||
export interface AccountTabProps {
|
||||
activeTab: AccountTabKeys;
|
||||
};
|
||||
export enum AccountUserTabKeys {
|
||||
LoginAuthInfo = 'LoginAuthInfo',
|
||||
AccountAuth = 'AccountAuth',
|
||||
};
|
||||
export interface AccountUserTabProps {
|
||||
activeTab: AccountUserTabKeys;
|
||||
tid: string;
|
||||
};
|
||||
export interface AuthItem {
|
||||
useYn?: boolean;
|
||||
authName?: string;
|
||||
tid?: string;
|
||||
};
|
||||
export interface UserManageAuthListProps {
|
||||
authItems: Array<AuthItem>
|
||||
};
|
||||
export interface UserManageAuthItemProps extends AuthItem {
|
||||
|
||||
};
|
||||
export interface UserLoginAuthInfoWrapProps {
|
||||
tid: string;
|
||||
};
|
||||
export interface UserAccountAuthWrapProps {
|
||||
tid: string;
|
||||
};
|
||||
export interface PermItem {
|
||||
menuId?: string;
|
||||
permName?: string;
|
||||
};
|
||||
export interface UserAccountAuthPermListProps {
|
||||
tid: string;
|
||||
permItems: Array<PermItem>;
|
||||
};
|
||||
export interface UserAccountAuthPermItemProps extends PermItem {
|
||||
tid: string;
|
||||
};
|
||||
37
src/entities/account/ui/account-tab.tsx
Normal file
37
src/entities/account/ui/account-tab.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import {
|
||||
AccountTabKeys,
|
||||
AccountTabProps
|
||||
} from '../model/types';
|
||||
|
||||
export const AccountTab = ({
|
||||
activeTab
|
||||
}: AccountTabProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigation = (tab: AccountTabKeys) => {
|
||||
if(activeTab !== tab){
|
||||
if(tab === AccountTabKeys.UserManage){
|
||||
navigate(PATHS.account.user.manage);
|
||||
}
|
||||
else if(tab === AccountTabKeys.PasswordManage){
|
||||
navigate(PATHS.account.password.manage);
|
||||
}
|
||||
}
|
||||
};
|
||||
return(
|
||||
<>
|
||||
<div className="subTab">
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === AccountTabKeys.UserManage)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(AccountTabKeys.UserManage) }
|
||||
>사용자 관리</button>
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === AccountTabKeys.PasswordManage)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(AccountTabKeys.PasswordManage) }
|
||||
>비밀번호 관리</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
46
src/entities/account/ui/account-user-tab.tsx
Normal file
46
src/entities/account/ui/account-user-tab.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import {
|
||||
AccountUserTabKeys,
|
||||
AccountUserTabProps
|
||||
} from '../model/types';
|
||||
|
||||
export const AccountUserTab = ({
|
||||
activeTab,
|
||||
tid
|
||||
}: AccountUserTabProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigation = (tab: AccountUserTabKeys) => {
|
||||
if(activeTab !== tab){
|
||||
if(tab === AccountUserTabKeys.LoginAuthInfo){
|
||||
navigate(PATHS.account.user.loginAuthInfo, {
|
||||
state: {
|
||||
tid: tid
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(tab === AccountUserTabKeys.AccountAuth){
|
||||
navigate(PATHS.account.user.accountAuth, {
|
||||
state: {
|
||||
tid: tid
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
return(
|
||||
<>
|
||||
<div className="subTab">
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === AccountUserTabKeys.LoginAuthInfo)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(AccountUserTabKeys.LoginAuthInfo) }
|
||||
>로그인 인증정보</button>
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === AccountUserTabKeys.AccountAuth)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation( AccountUserTabKeys.AccountAuth) }
|
||||
>계정권한</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
29
src/entities/account/ui/password-manage-wrap.tsx
Normal file
29
src/entities/account/ui/password-manage-wrap.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
|
||||
export const PasswordManageWrap = () => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickTonavigation = () => {
|
||||
navigate(PATHS.account.password.modifyLoginPassword);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div className="ing-list">
|
||||
<div className="pwd-manage mt-20">
|
||||
<div className="pwd-buttons">
|
||||
<button
|
||||
className="btn-44 btn-white pwd-btn"
|
||||
type="button"
|
||||
onClick={ () => onClickTonavigation() }
|
||||
>로그인 비밀번호 변경</button>
|
||||
<button
|
||||
className="btn-44 btn-white pwd-btn"
|
||||
type="button"
|
||||
>거래취소 비밀번호 변경</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
};
|
||||
31
src/entities/account/ui/user-account-auth-perm-item.tsx
Normal file
31
src/entities/account/ui/user-account-auth-perm-item.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { UserAccountAuthPermItemProps } from '../model/types';
|
||||
|
||||
export const UserAccountAuthPermItem = ({
|
||||
tid,
|
||||
menuId,
|
||||
permName
|
||||
}: UserAccountAuthPermItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigation = () => {
|
||||
navigate(PATHS.account.user.menuAuth, {
|
||||
state: {
|
||||
tid: tid,
|
||||
menuId: menuId
|
||||
}
|
||||
})
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="perm-item"
|
||||
onClick={ () => onClickToNavigation() }
|
||||
>
|
||||
<span className="perm-name">{ permName }</span>
|
||||
<span className="ic20 arrow-right"></span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
30
src/entities/account/ui/user-account-auth-perm-list.tsx
Normal file
30
src/entities/account/ui/user-account-auth-perm-list.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { UserAccountAuthPermListProps } from '../model/types';
|
||||
import { UserAccountAuthPermItem } from './user-account-auth-perm-item';
|
||||
export const UserAccountAuthPermList = ({
|
||||
tid,
|
||||
permItems
|
||||
}: UserAccountAuthPermListProps) => {
|
||||
|
||||
const getPermItems = () => {
|
||||
let rs = [];
|
||||
for(let i=0;i<permItems.length;i++){
|
||||
rs.push(
|
||||
<UserAccountAuthPermItem
|
||||
key={ 'key-perm-item-' + i }
|
||||
tid={ tid }
|
||||
menuId={ permItems[i]?.menuId }
|
||||
permName={ permItems[i]?.permName }
|
||||
></UserAccountAuthPermItem>
|
||||
);
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="perm-list">
|
||||
{ getPermItems() }
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
58
src/entities/account/ui/user-account-auth-wrap.tsx
Normal file
58
src/entities/account/ui/user-account-auth-wrap.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import { UserAccountAuthWrapProps } from '../model/types';
|
||||
import { UserAccountAuthPermList } from './user-account-auth-perm-list';
|
||||
|
||||
export const UserAccountAuthWrap = ({
|
||||
tid
|
||||
}: UserAccountAuthWrapProps) => {
|
||||
let menuItems = [
|
||||
{menuId: 'menu1', permName: '거래조회'},
|
||||
{menuId: 'menu2', permName: '정산조회'},
|
||||
{menuId: 'menu3', permName: '가맹점 관리'},
|
||||
{menuId: 'menu4', permName: '결제 관리'},
|
||||
{menuId: 'menu5', permName: '계정 관리'},
|
||||
{menuId: 'menu6', permName: '부가세 신고 자료'},
|
||||
{menuId: 'menu7', permName: '부가서비스'},
|
||||
{menuId: 'menu8', permName: '고객지원'},
|
||||
];
|
||||
return (
|
||||
<>
|
||||
<div className="ing-list pdtop">
|
||||
<div className="perm-form">
|
||||
<div className="perm-field">
|
||||
<div className="perm-label">계정 상태</div>
|
||||
<div className="perm-control">
|
||||
<select>
|
||||
<option selected>사용</option>
|
||||
<option>미사용</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="perm-field">
|
||||
<div className="perm-label">로그인 범위</div>
|
||||
<div className="perm-control">
|
||||
<select>
|
||||
<option>MID</option>
|
||||
<option>GID</option>
|
||||
<option selected>MID + GID</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="ing-title fs18">메뉴별 권한 설정</div>
|
||||
|
||||
<UserAccountAuthPermList
|
||||
tid={ tid }
|
||||
permItems={ menuItems }
|
||||
></UserAccountAuthPermList>
|
||||
|
||||
<div className="apply-row bottom-padding">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
type="button"
|
||||
>저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
100
src/entities/account/ui/user-login-auth-info-wrap.tsx
Normal file
100
src/entities/account/ui/user-login-auth-info-wrap.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
import { UserLoginAuthInfoWrapProps } from '../model/types';
|
||||
|
||||
export const UserLoginAuthInfoWrap = ({
|
||||
tid
|
||||
}: UserLoginAuthInfoWrapProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="ing-list pdtop">
|
||||
<div className="settings-login-auth">
|
||||
<div className="group">
|
||||
<div className="group-header">
|
||||
<div className="title">이메일 주소</div>
|
||||
<button
|
||||
className="ic20 plus"
|
||||
type="button"
|
||||
aria-label="추가"
|
||||
></button>
|
||||
</div>
|
||||
<div className="input-row">
|
||||
<input
|
||||
type="text"
|
||||
value="nicetest01@nicepay.co.kr"
|
||||
placeholder="example@domain.com"
|
||||
/>
|
||||
<button
|
||||
className="icon-btn minus"
|
||||
type="button"
|
||||
aria-label="삭제"
|
||||
></button>
|
||||
</div>
|
||||
<div className="input-row">
|
||||
<input
|
||||
type="text"
|
||||
value="nicetest01@nicepay.co.kr"
|
||||
placeholder="example@domain.com"
|
||||
/>
|
||||
<button
|
||||
className="icon-btn minus"
|
||||
type="button"
|
||||
aria-label="삭제"
|
||||
></button>
|
||||
</div>
|
||||
<div className="input-row">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="example@domain.com"
|
||||
/>
|
||||
<button
|
||||
className="icon-btn minus"
|
||||
type="button"
|
||||
aria-label="삭제"
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="group">
|
||||
<div className="group-header">
|
||||
<div className="title">휴대폰 번호</div>
|
||||
<button
|
||||
className="ic20 plus"
|
||||
type="button"
|
||||
aria-label="추가"
|
||||
></button>
|
||||
</div>
|
||||
<div className="input-row">
|
||||
<input
|
||||
type="text"
|
||||
value="01012345678"
|
||||
placeholder="휴대폰 번호 입력"
|
||||
/>
|
||||
<button
|
||||
className="icon-btn minus"
|
||||
type="button"
|
||||
aria-label="삭제"
|
||||
></button>
|
||||
</div>
|
||||
<div className="input-row">
|
||||
<input
|
||||
type="text"
|
||||
value="01012345678"
|
||||
placeholder="휴대폰 번호 입력"
|
||||
readOnly={ true }
|
||||
/>
|
||||
<button
|
||||
className="icon-btn minus"
|
||||
type="button"
|
||||
aria-label="삭제"
|
||||
></button>
|
||||
</div>
|
||||
<div className="notice-bar">※ 탭을 변경하면 미저장 내용은 초기화됩니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row bottom-padding">
|
||||
<button className="btn-50 btn-blue flex-1">저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
33
src/entities/account/ui/user-manage-auth-item.tsx
Normal file
33
src/entities/account/ui/user-manage-auth-item.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { UserManageAuthItemProps } from '../model/types';
|
||||
|
||||
export const UserManageAuthItem = ({
|
||||
useYn,
|
||||
authName,
|
||||
tid
|
||||
}: UserManageAuthItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigation = () => {
|
||||
navigate(PATHS.account.user.loginAuthInfo, {
|
||||
state: {
|
||||
tid: tid
|
||||
}
|
||||
});
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="auth-item"
|
||||
onClick={ () => onClickToNavigation() }
|
||||
>
|
||||
<div className="auth-item-left">
|
||||
<span className={ `tag-pill ${(!!useYn)? '': 'red'}` }>{ (!!useYn)? '사용': '미사용' }</span>
|
||||
<span className="auth-name">{ authName }</span>
|
||||
</div>
|
||||
<span className="ic20 arrow-right"></span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
29
src/entities/account/ui/user-manage-auth-list.tsx
Normal file
29
src/entities/account/ui/user-manage-auth-list.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { UserManageAuthItem } from './user-manage-auth-item';
|
||||
import { UserManageAuthListProps } from '../model/types';
|
||||
|
||||
export const UserManageAuthList = ({
|
||||
authItems
|
||||
}: UserManageAuthListProps) => {
|
||||
|
||||
const getUserManageAuthItems = () => {
|
||||
let rs = [];
|
||||
for(let i=0;i<authItems.length;i++){
|
||||
rs.push(
|
||||
<UserManageAuthItem
|
||||
key={ 'UserManageAuthItem-key-' + i }
|
||||
useYn={ authItems[i]?.useYn }
|
||||
authName= { authItems[i]?.authName }
|
||||
tid= { authItems[i]?.tid }
|
||||
></UserManageAuthItem>
|
||||
);
|
||||
}
|
||||
return rs;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<div className="auth-list">
|
||||
{ getUserManageAuthItems() }
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
53
src/entities/account/ui/user-manage-wrap.tsx
Normal file
53
src/entities/account/ui/user-manage-wrap.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { AuthItem } from '../model/types';
|
||||
import { UserManageAuthList } from './user-manage-auth-list';
|
||||
|
||||
export const UserManageWrap = () => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const [authItems, setAuthItems] = useState<Array<AuthItem>>([]);
|
||||
|
||||
const callAuthList = () => {
|
||||
setAuthItems([
|
||||
{useYn: true, authName: 'test01', tid: 'A12334556'},
|
||||
{useYn: true, authName: 'test02', tid: 'A33334556'},
|
||||
{useYn: true, authName: 'test03', tid: 'A12345556'},
|
||||
{useYn: true, authName: 'test04', tid: 'A12978676'},
|
||||
{useYn: false, authName: 'test05', tid: 'A12344444'},
|
||||
]);
|
||||
};
|
||||
|
||||
const onClickToNavigation = () => {
|
||||
navigate(PATHS.account.user.addAccount);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callAuthList();
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<div className="ing-list">
|
||||
<div className="input-wrapper top-select mt-16">
|
||||
<select>
|
||||
<option>nicetest00m</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="ing-title">등록 현황</div>
|
||||
{ (!!authItems && authItems.length > 0) &&
|
||||
<UserManageAuthList
|
||||
authItems={ authItems }
|
||||
></UserManageAuthList>
|
||||
}
|
||||
<div className="apply-row bottom-padding">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToNavigation() }
|
||||
>사용자 추가</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionAlimtalkDetailParams,
|
||||
ExtensionAlimtalkDetailResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionAlimtalkDetail = (params: ExtensionAlimtalkDetailParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionAlimtalkDetailResponse>(API_URL.extensionArsDetail(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionAlimtalkDetailMutation = (options?: UseMutationOptions<ExtensionAlimtalkDetailResponse, CBDCAxiosError, ExtensionAlimtalkDetailParams>) => {
|
||||
const mutation = useMutation<ExtensionAlimtalkDetailResponse, CBDCAxiosError, ExtensionAlimtalkDetailParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionAlimtalkDetailParams) => extensionAlimtalkDetail(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionAlimtalkDownloadExcelParams,
|
||||
ExtensionAlimtalkDownloadExcelResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionAlimtalkDownloadExcel = (params: ExtensionAlimtalkDownloadExcelParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionAlimtalkDownloadExcelResponse>(API_URL.extensionAlimtalkDownloadExcel(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionAlimtalkDownloadExcelMutation = (options?: UseMutationOptions<ExtensionAlimtalkDownloadExcelResponse, CBDCAxiosError, ExtensionAlimtalkDownloadExcelParams>) => {
|
||||
const mutation = useMutation<ExtensionAlimtalkDownloadExcelResponse, CBDCAxiosError, ExtensionAlimtalkDownloadExcelParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionAlimtalkDownloadExcelParams) => extensionAlimtalkDownloadExcel(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionAlimtalkListParams,
|
||||
ExtensionAlimtalkListResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionAlimtalkList = (params: ExtensionAlimtalkListParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionAlimtalkListResponse>(API_URL.extensionAlimtalkList(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionAlimtalkListMutation = (options?: UseMutationOptions<ExtensionAlimtalkListResponse, CBDCAxiosError, ExtensionAlimtalkListParams>) => {
|
||||
const mutation = useMutation<ExtensionAlimtalkListResponse, CBDCAxiosError, ExtensionAlimtalkListParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionAlimtalkListParams) => extensionAlimtalkList(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionAlimtalkSettingDetailParams,
|
||||
ExtensionAlimtalkSettingDetailResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionAlimtalkSettingDetail = (params: ExtensionAlimtalkSettingDetailParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionAlimtalkSettingDetailResponse>(API_URL.extensionAlimtalkSettingDetail(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionAlimtalkSettingSaveMutation = (options?: UseMutationOptions<ExtensionAlimtalkSettingDetailResponse, CBDCAxiosError, ExtensionAlimtalkSettingDetailParams>) => {
|
||||
const mutation = useMutation<ExtensionAlimtalkSettingDetailResponse, CBDCAxiosError, ExtensionAlimtalkSettingDetailParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionAlimtalkSettingDetailParams) => extensionAlimtalkSettingDetail(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionAlimtalkSettingSaveParams,
|
||||
ExtensionAlimtalkSettingSaveResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionAlimtalkSettingSave = (params: ExtensionAlimtalkSettingSaveParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionAlimtalkSettingSaveResponse>(API_URL.extensionAlimtalkSettingSave(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionAlimtalkSettingSaveMutation = (options?: UseMutationOptions<ExtensionAlimtalkSettingSaveResponse, CBDCAxiosError, ExtensionAlimtalkSettingSaveParams>) => {
|
||||
const mutation = useMutation<ExtensionAlimtalkSettingSaveResponse, CBDCAxiosError, ExtensionAlimtalkSettingSaveParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionAlimtalkSettingSaveParams) => extensionAlimtalkSettingSave(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionArsApplyParams,
|
||||
ExtensionArsApplyResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionArsApply = (params: ExtensionArsApplyParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionArsApplyResponse>(API_URL.extensionArsApply(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionArsApplyMutation = (options?: UseMutationOptions<ExtensionArsApplyResponse, CBDCAxiosError, ExtensionArsApplyParams>) => {
|
||||
const mutation = useMutation<ExtensionArsApplyResponse, CBDCAxiosError, ExtensionArsApplyParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionArsApplyParams) => extensionArsApply(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionArsDetailParams,
|
||||
ExtensionArsDetailResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionArsDetail = (params: ExtensionArsDetailParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionArsDetailResponse>(API_URL.extensionArsDetail(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionArsDetailMutation = (options?: UseMutationOptions<ExtensionArsDetailResponse, CBDCAxiosError, ExtensionArsDetailParams>) => {
|
||||
const mutation = useMutation<ExtensionArsDetailResponse, CBDCAxiosError, ExtensionArsDetailParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionArsDetailParams) => extensionArsDetail(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionArsDownloadExcelParams,
|
||||
ExtensionArsDownloadExcelResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionArsDownloadExcel = (params: ExtensionArsDownloadExcelParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionArsDownloadExcelResponse>(API_URL.extensionArsDownloadExcel(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionArsDownloadExcelMutation = (options?: UseMutationOptions<ExtensionArsDownloadExcelResponse, CBDCAxiosError, ExtensionArsDownloadExcelParams>) => {
|
||||
const mutation = useMutation<ExtensionArsDownloadExcelResponse, CBDCAxiosError, ExtensionArsDownloadExcelParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionArsDownloadExcelParams) => extensionArsDownloadExcel(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionArsListParams,
|
||||
ExtensionArsListResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionArsList = (params: ExtensionArsListParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionArsListResponse>(API_URL.extensionArsList(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionArsListMutation = (options?: UseMutationOptions<ExtensionArsListResponse, CBDCAxiosError, ExtensionArsListParams>) => {
|
||||
const mutation = useMutation<ExtensionArsListResponse, CBDCAxiosError, ExtensionArsListParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionArsListParams) => extensionArsList(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionArsResendParams,
|
||||
ExtensionArsResendResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionArsResend = (params: ExtensionArsResendParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionArsResendResponse>(API_URL.extensionArsResend(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionArsResendMutation = (options?: UseMutationOptions<ExtensionArsResendResponse, CBDCAxiosError, ExtensionArsResendParams>) => {
|
||||
const mutation = useMutation<ExtensionArsResendResponse, CBDCAxiosError, ExtensionArsResendParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionArsResendParams) => extensionArsResend(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionKeyinApplyParams,
|
||||
ExtensionKeyinApplyResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionKeyinApply = (params: ExtensionKeyinApplyParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionKeyinApplyResponse>(API_URL.extensionKeyinApply(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionKeyinListMutation = (options?: UseMutationOptions<ExtensionKeyinApplyResponse, CBDCAxiosError, ExtensionKeyinApplyParams>) => {
|
||||
const mutation = useMutation<ExtensionKeyinApplyResponse, CBDCAxiosError, ExtensionKeyinApplyParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionKeyinApplyParams) => extensionKeyinApply(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionKeyinDownloadExcelParams,
|
||||
ExtensionKeyinDownloadExcelResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionKeyinDownloadExcel = (params: ExtensionKeyinDownloadExcelParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionKeyinDownloadExcelResponse>(API_URL.extensionKeyinDownloadExcel(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionKeyinDownloadExcelMutation = (options?: UseMutationOptions<ExtensionKeyinDownloadExcelResponse, CBDCAxiosError, ExtensionKeyinDownloadExcelParams>) => {
|
||||
const mutation = useMutation<ExtensionKeyinDownloadExcelResponse, CBDCAxiosError, ExtensionKeyinDownloadExcelParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionKeyinDownloadExcelParams) => extensionKeyinDownloadExcel(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionKeyinListParams,
|
||||
ExtensionKeyinListResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionKeyinList = (params: ExtensionKeyinListParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionKeyinListResponse>(API_URL.extensionKeyinList(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionKeyinListMutation = (options?: UseMutationOptions<ExtensionKeyinListResponse, CBDCAxiosError, ExtensionKeyinListParams>) => {
|
||||
const mutation = useMutation<ExtensionKeyinListResponse, CBDCAxiosError, ExtensionKeyinListParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionKeyinListParams) => extensionKeyinList(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionListParams,
|
||||
ExtensionListResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionList = (params: ExtensionListParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionListResponse>(API_URL.extensionList(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionListMutation = (options?: UseMutationOptions<ExtensionListResponse, CBDCAxiosError, ExtensionListParams>) => {
|
||||
const mutation = useMutation<ExtensionListResponse, CBDCAxiosError, ExtensionListParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionListParams) => extensionList(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionSmsDetailParams,
|
||||
ExtensionSmsDetailResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionSmsDetail = (params: ExtensionSmsDetailParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionSmsDetailResponse>(API_URL.extensionSmsDetail(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionSmsListMutation = (options?: UseMutationOptions<ExtensionSmsDetailResponse, CBDCAxiosError, ExtensionSmsDetailParams>) => {
|
||||
const mutation = useMutation<ExtensionSmsDetailResponse, CBDCAxiosError, ExtensionSmsDetailParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionSmsDetailParams) => extensionSmsDetail(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionSmsDownloadExcelParams,
|
||||
ExtensionSmsDownloadExcelResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionSmsDownloadExcel = (params: ExtensionSmsDownloadExcelParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionSmsDownloadExcelResponse>(API_URL.extensionSmsDownloadExcel(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionSmsDownloadExcelMutation = (options?: UseMutationOptions<ExtensionSmsDownloadExcelResponse, CBDCAxiosError, ExtensionSmsDownloadExcelParams>) => {
|
||||
const mutation = useMutation<ExtensionSmsDownloadExcelResponse, CBDCAxiosError, ExtensionSmsDownloadExcelParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionSmsDownloadExcelParams) => extensionSmsDownloadExcel(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionSmsListParams,
|
||||
ExtensionSmsListResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionSmsList = (params: ExtensionSmsListParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionSmsListResponse>(API_URL.extensionSmsList(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionSmsListMutation = (options?: UseMutationOptions<ExtensionSmsListResponse, CBDCAxiosError, ExtensionSmsListParams>) => {
|
||||
const mutation = useMutation<ExtensionSmsListResponse, CBDCAxiosError, ExtensionSmsListParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionSmsListParams) => extensionSmsList(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
ExtensionSmsResendParams,
|
||||
ExtensionSmsResendResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const extensionSmsResend = (params: ExtensionSmsResendParams) => {
|
||||
return resultify(
|
||||
axios.post<ExtensionSmsResendResponse>(API_URL.extensionSmsResend(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useExtensionSmsResendMutation = (options?: UseMutationOptions<ExtensionSmsResendResponse, CBDCAxiosError, ExtensionSmsResendParams>) => {
|
||||
const mutation = useMutation<ExtensionSmsResendResponse, CBDCAxiosError, ExtensionSmsResendParams>({
|
||||
...options,
|
||||
mutationFn: (params: ExtensionSmsResendParams) => extensionSmsResend(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
279
src/entities/additional-service/model/types.ts
Normal file
279
src/entities/additional-service/model/types.ts
Normal file
@@ -0,0 +1,279 @@
|
||||
import { DefaulResponsePagination } from '@/entities/common/model/types';
|
||||
|
||||
export interface ExtensionRequestParams {
|
||||
mid: string;
|
||||
};
|
||||
export interface ExtensionSmsResendParams extends ExtensionRequestParams {
|
||||
tid: string;
|
||||
};
|
||||
export interface ExtensionSmsResendResponse {
|
||||
|
||||
};
|
||||
export interface ExtensionSmsListParams extends ExtensionRequestParams {
|
||||
tid: string;
|
||||
searchCl: string;
|
||||
searchValue: string;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
smsCl: string;
|
||||
};
|
||||
export interface ExtensionSmsListItemProps {
|
||||
mid: string;
|
||||
tid: string;
|
||||
paymentDate: string;
|
||||
paymentStatus: string;
|
||||
smsCl: string;
|
||||
};
|
||||
export interface ExtensionSmsListResponse extends DefaulResponsePagination {
|
||||
content: Array<ExtensionSmsListItemProps>
|
||||
};
|
||||
export interface ExtensionSmsDownloadExcelParams extends ExtensionRequestParams {
|
||||
searchCl: string;
|
||||
searchValue: string;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
smsCl: string;
|
||||
};
|
||||
export interface ExtensionSmsDownloadExcelResponse {
|
||||
|
||||
};
|
||||
export interface ExtensionSmsDetailParams extends ExtensionRequestParams {
|
||||
tid: string;
|
||||
};
|
||||
export interface ExtensionSmsDetailResponse {
|
||||
senderNumber: string;
|
||||
senderName: string;
|
||||
receiverNumber: string;
|
||||
receiverName: string;
|
||||
sendMessage: string;
|
||||
};
|
||||
export interface ExtensionListParams extends ExtensionRequestParams {
|
||||
|
||||
};
|
||||
export interface activeExtensionListItem {
|
||||
extensionCode: string;
|
||||
extensionName: string;
|
||||
extensionInformation: string;
|
||||
};
|
||||
export interface availableExtensionListItem {
|
||||
extensionCode: string;
|
||||
extensionName: string;
|
||||
extensionInformation: string;
|
||||
};
|
||||
export interface ExtensionListItemProps {
|
||||
activeExtensionList: Array<activeExtensionListItem>;
|
||||
availableExtensionList: Array<availableExtensionListItem>;
|
||||
};
|
||||
export interface ExtensionListResponse extends DefaulResponsePagination {
|
||||
content: Array<ExtensionListItemProps>
|
||||
};
|
||||
export interface ExtensionKeyinListParams extends ExtensionRequestParams {
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
paymentStatus: string;
|
||||
minAmount: number;
|
||||
maxAmount: number;
|
||||
};
|
||||
export interface ExtensionKeyinListItemProps {
|
||||
tid: string;
|
||||
paymentDate: string;
|
||||
paymentStatus: string;
|
||||
amount: number;
|
||||
};
|
||||
export interface ExtensionKeyinListResponse extends DefaulResponsePagination {
|
||||
content: Array<ExtensionKeyinListItemProps>
|
||||
};
|
||||
export interface ExtensionKeyinDownloadExcelParams extends ExtensionRequestParams {
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
paymentStatus: string;
|
||||
minAmount: number;
|
||||
maxAmount: number;
|
||||
};
|
||||
export interface ExtensionKeyinDownloadExcelResponse {
|
||||
|
||||
};
|
||||
export interface ExtensionKeyinApplyParams extends ExtensionRequestParams {
|
||||
goodsName: string;
|
||||
amount: number;
|
||||
buyerName: string;
|
||||
email: string;
|
||||
phoneNumber: string;
|
||||
cardNo: string;
|
||||
cardExpirationDate: string;
|
||||
instmntMonth: string;
|
||||
moid: string;
|
||||
};
|
||||
export interface ExtensionKeyinApplyResponse {
|
||||
|
||||
};
|
||||
export interface ExtensionArsResendParams extends ExtensionRequestParams {
|
||||
tid: string;
|
||||
};
|
||||
export interface ExtensionArsResendResponse {
|
||||
|
||||
};
|
||||
export interface ExtensionArsListParams extends ExtensionRequestParams {
|
||||
moid: string;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
paymentStatus: string;
|
||||
orderStatus: string;
|
||||
minAmount: number;
|
||||
maxAmount: number;
|
||||
};
|
||||
export interface ExtensionArsListItemProps {
|
||||
tid: string;
|
||||
paymentDate: string;
|
||||
paymentStatus: string;
|
||||
orderStatus: string;
|
||||
arsPaymentMethod: string;
|
||||
amount: number;
|
||||
};
|
||||
export interface ExtensionArsListResponse extends DefaulResponsePagination {
|
||||
content: Array<ExtensionArsListItemProps>
|
||||
};
|
||||
export interface ExtensionArsDownloadExcelParams extends ExtensionRequestParams {
|
||||
moid: string;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
paymentStatus: string;
|
||||
orderStatus: string;
|
||||
minAmount: number;
|
||||
maxAmount: number;
|
||||
};
|
||||
export interface ExtensionArsDownloadExcelResponse {
|
||||
|
||||
};
|
||||
export interface ExtensionArsDetailParams extends ExtensionRequestParams {
|
||||
tid: string;
|
||||
};
|
||||
export interface ExtensionArsDetailResponse {
|
||||
corpName: string;
|
||||
mid: string;
|
||||
arsPaymentMethod: string;
|
||||
paymentStatus: string;
|
||||
orderStatus: string;
|
||||
paymentDate: string;
|
||||
goodsName: string;
|
||||
tid: string;
|
||||
buyerName: string;
|
||||
phoneNumber: string;
|
||||
maskPhoneNumber: string;
|
||||
email: string;
|
||||
smsVerificationCode: string;
|
||||
};
|
||||
export interface ExtensionArsApplyParams extends ExtensionRequestParams {
|
||||
moid: string;
|
||||
goodsName: string;
|
||||
amount: number;
|
||||
instmntMonth: string;
|
||||
buyerName: string;
|
||||
phoneNumber: string;
|
||||
email: string;
|
||||
arsPaymentMethod: string;
|
||||
};
|
||||
export interface ExtensionArsApplyResponse {
|
||||
|
||||
};
|
||||
export interface SendMerchantInfoItem {
|
||||
cardApprovalFlag: boolean;
|
||||
cardCancelFlag: boolean;
|
||||
bankApprovalFlag: boolean;
|
||||
bankCancelFlag: boolean;
|
||||
virtureAccountDepositRequestFlag: boolean;
|
||||
virtureAccountDepositCompleteFlag: boolean;
|
||||
virtureAccountRefundFlag: boolean;
|
||||
};
|
||||
export interface SendUserInfoItem {
|
||||
cardApprovalFlag: boolean;
|
||||
cardCancelFlag: boolean;
|
||||
bankApprovalFlag: boolean;
|
||||
bankCancelFlag: boolean;
|
||||
virtureAccountDepositRequestFlag: boolean;
|
||||
virtureAccountDepositCompleteFlag: boolean;
|
||||
virtureAccountRefundFlag: boolean;
|
||||
};
|
||||
export interface ExtensionAlimtalkSettingSaveParams extends ExtensionRequestParams {
|
||||
sendMerchantInfo: SendMerchantInfoItem;
|
||||
sendUserInfo: SendUserInfoItem;
|
||||
};
|
||||
export interface ExtensionAlimtalkSettingSaveResponse {
|
||||
|
||||
};
|
||||
export interface ExtensionAlimtalkSettingDetailParams extends ExtensionRequestParams {
|
||||
|
||||
};
|
||||
export interface ExtensionAlimtalkSettingDetailItem {
|
||||
sendMerchantInfo: SendMerchantInfoItem;
|
||||
sendUserInfo: SendUserInfoItem;
|
||||
};
|
||||
export interface ExtensionAlimtalkSettingDetailResponse extends DefaulResponsePagination {
|
||||
content: Array<ExtensionAlimtalkSettingDetailItem>
|
||||
};
|
||||
export interface ExtensionAlimtalkListParams extends ExtensionRequestParams {
|
||||
searchCl: string;
|
||||
searchValue: string;
|
||||
paymentMethod: string;
|
||||
alimCl: string;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
sendType: string;
|
||||
sendCl: string;
|
||||
};
|
||||
export interface ExtensionAlimtalkListItem {
|
||||
tid: string;
|
||||
sendDate: string;
|
||||
alimCl: string;
|
||||
sendType: string;
|
||||
sendCl: string;
|
||||
paymentMethod: string;
|
||||
receiverName: string;
|
||||
};
|
||||
export interface ExtensionAlimtalkListResponse extends DefaulResponsePagination {
|
||||
content: Array<ExtensionAlimtalkListItem>
|
||||
};
|
||||
export interface ExtensionAlimtalkDownloadExcelParams extends ExtensionRequestParams {
|
||||
searchCl: string;
|
||||
searchValue: string;
|
||||
paymentMethod: string;
|
||||
alimCl: string;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
sendType: string;
|
||||
sendCl: string;
|
||||
};
|
||||
export interface ExtensionAlimtalkDownloadExcelResponse {
|
||||
|
||||
};
|
||||
export interface ExtensionAlimtalkDetailParams extends ExtensionRequestParams {
|
||||
tid: string;
|
||||
};
|
||||
export interface ExtensionAlimtalkDetailResponse {
|
||||
receiverName: string;
|
||||
merchantName: string;
|
||||
sendDate: string;
|
||||
mid: string;
|
||||
tid: string;
|
||||
serviceName: string;
|
||||
sendType: string;
|
||||
senderName: string;
|
||||
paymentMethod: string;
|
||||
alimCl: string;
|
||||
sendCl: string;
|
||||
};
|
||||
export interface IntroListItemProps {
|
||||
className?: string;
|
||||
serviceName?: string;
|
||||
serviceDesc?: string;
|
||||
icon?: string;
|
||||
path?: string;
|
||||
};
|
||||
export interface ArsCardPaymentFinishProps {
|
||||
requestSuccess: boolean;
|
||||
setRequestSuccess: (requestSuccess: boolean) => void;
|
||||
};
|
||||
export interface SmsPaymentDetailResendProps {
|
||||
bottomSmsPaymentDetailResendOn: boolean;
|
||||
setBottomSmsPaymentDetailResendOn: (bottomSmsPaymentDetailResendOn: boolean) => void;
|
||||
};
|
||||
35
src/entities/additional-service/ui/intro-list-item.tsx
Normal file
35
src/entities/additional-service/ui/intro-list-item.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { IntroListItemProps } from '../model/types';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
|
||||
export const IntroListItem = ({
|
||||
className,
|
||||
serviceName,
|
||||
serviceDesc,
|
||||
icon,
|
||||
path
|
||||
}: IntroListItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigate = () => {
|
||||
if(!!path){
|
||||
navigate(path);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={ className }
|
||||
onClick={ () => onClickToNavigate() }
|
||||
>
|
||||
<div>
|
||||
<div className="service-name">{ serviceName }</div>
|
||||
<p className="service-desc">{ serviceDesc }</p>
|
||||
</div>
|
||||
<img
|
||||
src={ icon }
|
||||
alt={ serviceName }
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { SmsPaymentDetailResendProps } from '../model/types';
|
||||
|
||||
export const SmsPaymentDetailResend = ({
|
||||
bottomSmsPaymentDetailResendOn,
|
||||
setBottomSmsPaymentDetailResendOn
|
||||
}: SmsPaymentDetailResendProps) => {
|
||||
|
||||
const variants = {
|
||||
hidden: { y: '100%' },
|
||||
visible: { y: '0%' },
|
||||
};
|
||||
const onClickToClose = () => {
|
||||
// close
|
||||
setBottomSmsPaymentDetailResendOn(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{ bottomSmsPaymentDetailResendOn &&
|
||||
<div className="bg-dim"></div>
|
||||
}
|
||||
<motion.div
|
||||
className="bottomsheet"
|
||||
initial="hidden"
|
||||
animate={ (bottomSmsPaymentDetailResendOn)? 'visible': 'hidden' }
|
||||
variants={ variants }
|
||||
transition={{ duration: 0.5 }}
|
||||
>
|
||||
<div className="bottomsheet-header">
|
||||
<div className="bottomsheet-title">
|
||||
<h2>SMS 상세 & 재발송</h2>
|
||||
<button
|
||||
className="close-btn"
|
||||
type="button"
|
||||
>
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/ico_close.svg' }
|
||||
alt="닫기"
|
||||
onClick={ () => onClickToClose() }
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="resend-info">
|
||||
<div className="resend-row">발신자(번호) : 유앤아이피부과(16610808)</div>
|
||||
<div className="resend-row">수신자(번호) : 김*환(010****7000)</div>
|
||||
</div>
|
||||
<div className="resend-box">
|
||||
<p className="resend-text">[유앤아이피부과]김*환님, 신한은행 110322141414 (300원 06/08 입금완료)</p>
|
||||
</div>
|
||||
<div className="bottomsheet-footer">
|
||||
<button className="btn-50 btn-blue flex-1" type="button">신청</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
5
src/entities/alarm/model/types.ts
Normal file
5
src/entities/alarm/model/types.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface AlarmItemProps {
|
||||
title?: string,
|
||||
category?: string,
|
||||
date?: string
|
||||
};
|
||||
37
src/entities/alarm/ui/alarm-item.tsx
Normal file
37
src/entities/alarm/ui/alarm-item.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { AlarmItemProps } from '../model/types';
|
||||
|
||||
export const AlarmItem = ({
|
||||
title,
|
||||
category,
|
||||
date
|
||||
}: AlarmItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
const onClickToNavigate = (alarmId: number) => {
|
||||
let path = PATHS.support.notice.detail + alarmId;
|
||||
navigate(path);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="notice-item">
|
||||
<div className="notice-content">
|
||||
<div className="notice-title">{ title }</div>
|
||||
<div className="notice-meta">
|
||||
<strong>{ category }</strong>
|
||||
<span>{ date }</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="notice-arrow"
|
||||
onClick={ () => onClickToNavigate(4) }
|
||||
>
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/Forward.svg' }
|
||||
alt={ category + '바로가기' }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
40
src/entities/alarm/ui/alarm-list.tsx
Normal file
40
src/entities/alarm/ui/alarm-list.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { AlarmItem } from './alarm-item';
|
||||
import { AlarmItemProps } from '../model/types';
|
||||
|
||||
|
||||
export const AlarmList = () => {
|
||||
|
||||
const alarmItems: Array<AlarmItemProps> = [
|
||||
{title: '시스템 안정화를 위한 정기 점검이 예정되어 있습니다.', category: '공지사항', date: '2025.06.01 10:00:00'},
|
||||
{title: '가맹점 관리 메뉴에 거래내역 엑셀 다운로드 기능이 추가 되었습니다.', category: '공지사항', date: '2025.06.01 10:00:00'},
|
||||
{title: '신규 가맹점을 대상으로 거래수수료 인하 혜택을 12월까지 제공합니다.', category: '공지사항', date: '2025.06.01 10:00:00'},
|
||||
{title: '앱의 안정성과 사용성을 개선한 버전 2.3.1이 출시되었습니다.', category: '공지사항', date: '2025.06.01 10:00:00'},
|
||||
{title: '점검 시간 동안 일부 서비스 이용이 제한될 수 있으니 미리 확인해주세요.', category: '공지사항', date: '2025.06.01 10:00:00'},
|
||||
{title: '가맹점 관리 메뉴에 거래내역 엑셀 다운로드 기능이 추가 되었습니다.', category: '공지사항', date: '2025.06.01 10:00:00'},
|
||||
{title: '신규 가맹점을 대상으로 거래수수료 인하 혜택을 12월까지 제공합니다.', category: '공지사항', date: '2025.06.01 10:00:00'},
|
||||
{title: '앱의 안정성과 사용성을 개선한 버전 2.3.1이 출시되었습니다.', category: '공지사항', date: '2025.06.01 10:00:00'},
|
||||
{title: '점검 시간 동안 일부 서비스 이용이 제한될 수 있으니 미리 확인해주세요.', category: '공지사항', date: '2025.06.01 10:00:00'},
|
||||
];
|
||||
const getAlarmItems = () => {
|
||||
let rs = [];
|
||||
for(let i=0;i<alarmItems.length;i++){
|
||||
rs.push(
|
||||
<AlarmItem
|
||||
title={ alarmItems[i]?.title }
|
||||
category={ alarmItems[i]?.category }
|
||||
date={ alarmItems[i]?.date }
|
||||
></AlarmItem>
|
||||
)
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div className="notice-box sub">
|
||||
{ getAlarmItems() }
|
||||
</div>
|
||||
<div className="notice-alert">※ 알림은 90일간 보관 후 삭제됩니다.</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
BusinessMemberInfoParams,
|
||||
BusinessMemberInfoResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const businessMemberInfo = (params: BusinessMemberInfoParams) => {
|
||||
return resultify(
|
||||
axios.post<BusinessMemberInfoResponse>(API_URL.businessMemberInfo(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useBusinessMemberInfoMutation = (options?: UseMutationOptions<BusinessMemberInfoResponse, CBDCAxiosError, BusinessMemberInfoParams>) => {
|
||||
const mutation = useMutation<BusinessMemberInfoResponse, CBDCAxiosError, BusinessMemberInfoParams>({
|
||||
...options,
|
||||
mutationFn: (params: BusinessMemberInfoParams) => businessMemberInfo(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
56
src/entities/business-member/model/types.ts
Normal file
56
src/entities/business-member/model/types.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
export enum BusinessMemberTabKeys {
|
||||
Info = 'Info',
|
||||
RegistrationStatus = 'RegistrationStatus',
|
||||
};
|
||||
export enum BusinessMemberInfoKeys {
|
||||
InfoContractManager = 'InfoContractManager',
|
||||
InfoTechnicalManager = 'InfoTechnicalManager',
|
||||
InfoSettlementManager = 'InfoSettlementManager',
|
||||
InfoSettlementAccount = 'InfoSettlementAccount'
|
||||
};
|
||||
export interface BusinessMemberTabProps {
|
||||
activeTab: BusinessMemberTabKeys;
|
||||
};
|
||||
export interface InfoArrowProps {
|
||||
show?: boolean;
|
||||
};
|
||||
export interface BusinessMemberRequestParams {
|
||||
tid?: string;
|
||||
};
|
||||
export interface InfoBasicInfoProps {
|
||||
|
||||
};
|
||||
export interface InfoOwnerInfoProps {
|
||||
|
||||
};
|
||||
export interface InfoCompanyInfoProps {
|
||||
|
||||
};
|
||||
export interface InfoContractManagerProps {
|
||||
|
||||
};
|
||||
export interface InfoTechnicalManagerProps {
|
||||
|
||||
};
|
||||
export interface InfoSettlementManagerProps {
|
||||
|
||||
};
|
||||
export interface InfoSettlementAccountProps {
|
||||
|
||||
};
|
||||
export interface BusinessMemberInfoResponse {
|
||||
InfoBasicInfo?: InfoBasicInfoProps;
|
||||
InfoOwnerInfo?: InfoOwnerInfoProps;
|
||||
InfoCompanyInfo?: InfoCompanyInfoProps;
|
||||
infoContractManager?: InfoContractManagerProps;
|
||||
infoTechnicalManager?: InfoTechnicalManagerProps;
|
||||
infoSettlementManager?: InfoSettlementManagerProps;
|
||||
infoSettlementAccount?: InfoSettlementAccountProps;
|
||||
};
|
||||
export interface InfoProps extends BusinessMemberInfoResponse{
|
||||
show?: boolean;
|
||||
onClickToShowInfo?: (info: BusinessMemberInfoKeys) => void;
|
||||
};
|
||||
export interface BusinessMemberInfoParams extends BusinessMemberRequestParams {
|
||||
svcCd: string;
|
||||
};
|
||||
37
src/entities/business-member/ui/business-member-tab.tsx
Normal file
37
src/entities/business-member/ui/business-member-tab.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import {
|
||||
BusinessMemberTabKeys,
|
||||
BusinessMemberTabProps
|
||||
} from '../model/types';
|
||||
|
||||
export const BusinessMemberTab = ({
|
||||
activeTab
|
||||
}: BusinessMemberTabProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigation = (tab: BusinessMemberTabKeys) => {
|
||||
if(activeTab !== tab){
|
||||
if(tab === BusinessMemberTabKeys.Info){
|
||||
navigate(PATHS.businessMember.info);
|
||||
}
|
||||
else if(tab === BusinessMemberTabKeys.RegistrationStatus){
|
||||
navigate(PATHS.businessMember.registrationStatus);
|
||||
}
|
||||
}
|
||||
};
|
||||
return(
|
||||
<>
|
||||
<div className="subTab">
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === BusinessMemberTabKeys.Info)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(BusinessMemberTabKeys.Info) }
|
||||
>가맹점 정보</button>
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === BusinessMemberTabKeys.RegistrationStatus)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(BusinessMemberTabKeys.RegistrationStatus) }
|
||||
>등록현황</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
23
src/entities/business-member/ui/info-arrow.tsx
Normal file
23
src/entities/business-member/ui/info-arrow.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { InfoArrowProps } from '../model/types';
|
||||
|
||||
export const InfoArrow = ({ show }: InfoArrowProps) => {
|
||||
const [altMsg, setAltMsg] = useState<'접기' | '펼치기'>('접기');
|
||||
const [className, setClassName] = useState<string>('ic20 rot-180');
|
||||
|
||||
useEffect(() => {
|
||||
setAltMsg((show)? '접기': '펼치기');
|
||||
setClassName(`ic20 ${(show)? 'rot-180': ''}`);
|
||||
}, [show]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<img
|
||||
className={ className }
|
||||
src={ IMAGE_ROOT + '/select_arrow.svg' }
|
||||
alt={ altMsg }
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
36
src/entities/business-member/ui/info-basic-info.tsx
Normal file
36
src/entities/business-member/ui/info-basic-info.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { InfoProps } from '../model/types';
|
||||
|
||||
export const InfoBasicInfo = ({
|
||||
InfoBasicInfo
|
||||
}: InfoProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="section">
|
||||
<div className="section-title">기본정보</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">상호</span>
|
||||
<span className="v">나이스테스트</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">사업자번호</span>
|
||||
<span className="v">123-45-16798</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">사업자속성</span>
|
||||
<span className="v">일반</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">업종</span>
|
||||
<span className="v">식품</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">업태</span>
|
||||
<span className="v">식품</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
23
src/entities/business-member/ui/info-company-info.tsx
Normal file
23
src/entities/business-member/ui/info-company-info.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import { InfoProps } from '../model/types';
|
||||
|
||||
export const InfoCompanyInfo = ({
|
||||
InfoCompanyInfo
|
||||
}: InfoProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="section">
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">사업장주소</span>
|
||||
<span className="v">서울특별시 마포구 마포대로 217(아현동)</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">홈페이지 주소</span>
|
||||
<span className="v">https://adm.dev-nicepay.co.kr:8011</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
53
src/entities/business-member/ui/info-contract-manager.tsx
Normal file
53
src/entities/business-member/ui/info-contract-manager.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { BusinessMemberInfoKeys, InfoProps } from '../model/types';
|
||||
import { InfoArrow } from './info-arrow';
|
||||
|
||||
export const InfoContractManager = ({
|
||||
infoContractManager,
|
||||
show,
|
||||
onClickToShowInfo
|
||||
}: InfoProps) => {
|
||||
|
||||
const variants = {
|
||||
hidden: { height: 0, padding: 0, display: 'none' },
|
||||
visible: { height: 'auto', paddingTop: '12px', display: 'block' },
|
||||
};
|
||||
|
||||
const onClickToSetShowInfo = () => {
|
||||
if(!!onClickToShowInfo){
|
||||
onClickToShowInfo(BusinessMemberInfoKeys.InfoContractManager);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="section">
|
||||
<div className="section-title"
|
||||
onClick={ () => onClickToSetShowInfo() }
|
||||
>
|
||||
계약 담당자 <InfoArrow show={ show }></InfoArrow>
|
||||
</div>
|
||||
<motion.ul
|
||||
className="kv-list"
|
||||
initial="hidden"
|
||||
animate={ (show)? 'visible': 'hidden' }
|
||||
variants={ variants }
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<li className="kv-row">
|
||||
<span className="k">김테스트</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">010-1234-****</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">testkim@nicepay.co.kr</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
</motion.ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
27
src/entities/business-member/ui/info-owner-info.tsx
Normal file
27
src/entities/business-member/ui/info-owner-info.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { InfoProps } from '../model/types';
|
||||
|
||||
export const InfoOwnerInfo = ({
|
||||
InfoOwnerInfo
|
||||
}: InfoProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="section">
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">대표자명</span>
|
||||
<span className="v">김테스트</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">대표 연락처</span>
|
||||
<span className="v">010-1234-1234</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">대표 이메일</span>
|
||||
<span className="v">testkim@nicepay.co.kr</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
53
src/entities/business-member/ui/info-settlement-account.tsx
Normal file
53
src/entities/business-member/ui/info-settlement-account.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { BusinessMemberInfoKeys, InfoProps } from '../model/types';
|
||||
import { InfoArrow } from './info-arrow';
|
||||
|
||||
export const InfoSettlementAccount = ({
|
||||
infoSettlementAccount,
|
||||
show,
|
||||
onClickToShowInfo
|
||||
}: InfoProps) => {
|
||||
|
||||
const variants = {
|
||||
hidden: { height: 0, padding: 0, display: 'none' },
|
||||
visible: { height: 'auto', paddingTop: '12px', display: 'block' },
|
||||
};
|
||||
|
||||
const onClickToSetShowInfo = () => {
|
||||
if(!!onClickToShowInfo){
|
||||
onClickToShowInfo(BusinessMemberInfoKeys.InfoSettlementAccount);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="section">
|
||||
<div className="section-title"
|
||||
onClick={ () => onClickToSetShowInfo() }
|
||||
>
|
||||
정산계좌 <InfoArrow show={ show }></InfoArrow>
|
||||
</div>
|
||||
<motion.ul
|
||||
className="kv-list"
|
||||
initial="hidden"
|
||||
animate={ (show)? 'visible': 'hidden' }
|
||||
variants={ variants }
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<li className="kv-row">
|
||||
<span className="k">은행</span>
|
||||
<span className="v">신한은행</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">계좌번호</span>
|
||||
<span className="v">123-45-16798</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">예금주</span>
|
||||
<span className="v">김테스트</span>
|
||||
</li>
|
||||
</motion.ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
53
src/entities/business-member/ui/info-settlement-manager.tsx
Normal file
53
src/entities/business-member/ui/info-settlement-manager.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { BusinessMemberInfoKeys, InfoProps } from '../model/types';
|
||||
import { InfoArrow } from './info-arrow';
|
||||
|
||||
export const InfoSettlementManager = ({
|
||||
infoSettlementManager,
|
||||
show,
|
||||
onClickToShowInfo
|
||||
}: InfoProps) => {
|
||||
|
||||
const variants = {
|
||||
hidden: { height: 0, padding: 0, display: 'none' },
|
||||
visible: { height: 'auto', paddingTop: '12px', display: 'block' },
|
||||
};
|
||||
|
||||
const onClickToSetShowInfo = () => {
|
||||
if(!!onClickToShowInfo){
|
||||
onClickToShowInfo(BusinessMemberInfoKeys.InfoSettlementManager);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="section">
|
||||
<div className="section-title"
|
||||
onClick={ () => onClickToSetShowInfo() }
|
||||
>
|
||||
정산 담당자 <InfoArrow show={ show }></InfoArrow>
|
||||
</div>
|
||||
<motion.ul
|
||||
className="kv-list"
|
||||
initial="hidden"
|
||||
animate={ (show)? 'visible': 'hidden' }
|
||||
variants={ variants }
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<li className="kv-row">
|
||||
<span className="k">김테스트</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">010-1234-****</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">testkim@nicepay.co.kr</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
</motion.ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
53
src/entities/business-member/ui/info-technical-manager.tsx
Normal file
53
src/entities/business-member/ui/info-technical-manager.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { BusinessMemberInfoKeys, InfoProps } from '../model/types';
|
||||
import { InfoArrow } from './info-arrow';
|
||||
|
||||
export const InfoTechnicalManager = ({
|
||||
infoTechnicalManager,
|
||||
show,
|
||||
onClickToShowInfo
|
||||
}: InfoProps) => {
|
||||
|
||||
const variants = {
|
||||
hidden: { height: 0, padding: 0, display: 'none' },
|
||||
visible: { height: 'auto', paddingTop: '12px', display: 'block' },
|
||||
};
|
||||
|
||||
const onClickToSetShowInfo = () => {
|
||||
if(!!onClickToShowInfo){
|
||||
onClickToShowInfo(BusinessMemberInfoKeys.InfoTechnicalManager);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="section">
|
||||
<div className="section-title"
|
||||
onClick={ () => onClickToSetShowInfo() }
|
||||
>
|
||||
기술 담당자 <InfoArrow show={ show }></InfoArrow>
|
||||
</div>
|
||||
<motion.ul
|
||||
className="kv-list"
|
||||
initial="hidden"
|
||||
animate={ (show)? 'visible': 'hidden' }
|
||||
variants={ variants }
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<li className="kv-row">
|
||||
<span className="k">김테스트</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">010-1234-****</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">testkim@nicepay.co.kr</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
</motion.ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
121
src/entities/business-member/ui/info-wrap.tsx
Normal file
121
src/entities/business-member/ui/info-wrap.tsx
Normal file
@@ -0,0 +1,121 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useBusinessMemberInfoMutation } from '../api/use-business-member-info-mutation';
|
||||
import { InfoBasicInfo } from './info-basic-info';
|
||||
import { InfoOwnerInfo } from './info-owner-info';
|
||||
import { InfoCompanyInfo } from './info-company-info';
|
||||
import { InfoContractManager } from './info-contract-manager';
|
||||
import { InfoTechnicalManager } from './info-technical-manager';
|
||||
import { InfoSettlementManager } from './info-settlement-manager';
|
||||
import { InfoSettlementAccount } from './info-settlement-account';
|
||||
import {
|
||||
BusinessMemberInfoParams,
|
||||
BusinessMemberInfoResponse,
|
||||
InfoContractManagerProps,
|
||||
InfoTechnicalManagerProps,
|
||||
InfoSettlementManagerProps,
|
||||
InfoSettlementAccountProps,
|
||||
BusinessMemberInfoKeys
|
||||
} from '../model/types';
|
||||
|
||||
export const InfoWrap = () => {
|
||||
const [infoContractManager, setInfoContractManager] = useState<InfoContractManagerProps>();
|
||||
const [infoTechnicalManager, setInfoTechnicalManager] = useState<InfoTechnicalManagerProps>();
|
||||
const [infoSettlementManager, setInfoSettlementManager] = useState<InfoSettlementManagerProps>();
|
||||
const [infoSettlementAccount, setInfoSettlementAccount] = useState<InfoSettlementAccountProps>();
|
||||
const [showInfoContractManager, setShowInfoContractManager] = useState<boolean>(false);
|
||||
const [showInfoTechnicalManager, setShowInfoTechnicalManager] = useState<boolean>(false);
|
||||
const [showInfoSettlementManager, setShowInfoSettlementManager] = useState<boolean>(false);
|
||||
const [showInfoSettlementAccount, setShowInfoSettlemenAccount] = useState<boolean>(false);
|
||||
|
||||
const { mutateAsync: businessMemberInfo } = useBusinessMemberInfoMutation();
|
||||
|
||||
const callInfo = () => {
|
||||
let businessMemberInfoParams: BusinessMemberInfoParams = {
|
||||
svcCd: 'st',
|
||||
};
|
||||
businessMemberInfo(businessMemberInfoParams).then((rs: BusinessMemberInfoResponse) => {
|
||||
setInfoContractManager(rs.infoContractManager);
|
||||
setInfoTechnicalManager(rs.infoTechnicalManager);
|
||||
setInfoSettlementManager(rs.infoSettlementManager);
|
||||
setInfoSettlementAccount(rs.infoSettlementAccount);
|
||||
});
|
||||
};
|
||||
|
||||
const onClickToShowInfo = (info: BusinessMemberInfoKeys) => {
|
||||
if(info === BusinessMemberInfoKeys.InfoContractManager){
|
||||
setShowInfoContractManager(!showInfoContractManager);
|
||||
}
|
||||
else if(info === BusinessMemberInfoKeys.InfoTechnicalManager){
|
||||
setShowInfoTechnicalManager(!showInfoTechnicalManager);
|
||||
}
|
||||
else if(info === BusinessMemberInfoKeys.InfoSettlementManager){
|
||||
setShowInfoSettlementManager(!showInfoSettlementManager);
|
||||
}
|
||||
else if(info === BusinessMemberInfoKeys.InfoSettlementAccount){
|
||||
setShowInfoSettlemenAccount(!showInfoSettlementAccount);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callInfo();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="input-wrapper top-select mt-30">
|
||||
<select>
|
||||
<option value="1">nicetest00g</option>
|
||||
<option value="2">nicetest00g</option>
|
||||
<option value="3">nicetest00g</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="merchant-info">
|
||||
<InfoBasicInfo></InfoBasicInfo>
|
||||
<div className="info-divider mb-16"></div>
|
||||
|
||||
<InfoOwnerInfo></InfoOwnerInfo>
|
||||
|
||||
<div className="info-divider mb-16"></div>
|
||||
|
||||
<InfoCompanyInfo></InfoCompanyInfo>
|
||||
|
||||
<div className="info-divider mb-16"></div>
|
||||
|
||||
<InfoContractManager
|
||||
infoContractManager={ infoContractManager }
|
||||
show={ showInfoContractManager }
|
||||
onClickToShowInfo={ (info) => onClickToShowInfo(info) }
|
||||
></InfoContractManager>
|
||||
|
||||
<div className="info-divider mb-16"></div>
|
||||
|
||||
<InfoTechnicalManager
|
||||
infoTechnicalManager={ infoTechnicalManager }
|
||||
show={ showInfoTechnicalManager }
|
||||
onClickToShowInfo={ (info) => onClickToShowInfo(info) }
|
||||
></InfoTechnicalManager>
|
||||
|
||||
<div className="info-divider mb-16"></div>
|
||||
|
||||
<InfoSettlementManager
|
||||
infoSettlementManager={ infoSettlementManager }
|
||||
show={ showInfoSettlementManager }
|
||||
onClickToShowInfo={ (info) => onClickToShowInfo(info) }
|
||||
></InfoSettlementManager>
|
||||
|
||||
<div className="info-divider mb-16"></div>
|
||||
|
||||
<InfoSettlementAccount
|
||||
infoSettlementManager={ infoSettlementAccount }
|
||||
show={ showInfoSettlementAccount }
|
||||
onClickToShowInfo={ (info) => onClickToShowInfo(info) }
|
||||
></InfoSettlementAccount>
|
||||
|
||||
<div className="notice-bottom left-align">
|
||||
<p className="notice-tip">※ 가맹점 정보는 앱에서 수정할 수 없습니다.<br/>PC 가맹점 관리자에서 설정해 주세요.</p>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export const RegistrationStatusWrap = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
CodesCacheRefreshByCodeClParams,
|
||||
CodesCacheRefreshByCodeClResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const codesCacheRefreshByCodeCl = ({
|
||||
codeCl
|
||||
}: CodesCacheRefreshByCodeClParams) => {
|
||||
return resultify(
|
||||
axios.post<CodesCacheRefreshByCodeClResponse>(API_URL.codesCacheRefreshByCodelCl(codeCl)),
|
||||
);
|
||||
};
|
||||
|
||||
export const useCodesCacheRefreshByCodeClMutation = (options?: UseMutationOptions<CodesCacheRefreshByCodeClResponse, CBDCAxiosError, CodesCacheRefreshByCodeClParams>) => {
|
||||
const mutation = useMutation<CodesCacheRefreshByCodeClResponse, CBDCAxiosError, CodesCacheRefreshByCodeClParams>({
|
||||
...options,
|
||||
mutationFn: ({
|
||||
codeCl
|
||||
}: CodesCacheRefreshByCodeClParams) => codesCacheRefreshByCodeCl({
|
||||
codeCl
|
||||
}),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
26
src/entities/common/api/use-codes-cache-refresh-mutation.ts
Normal file
26
src/entities/common/api/use-codes-cache-refresh-mutation.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import { CodesCacheRefreshResponse } from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const codesCacheRefresh = () => {
|
||||
return resultify(
|
||||
axios.post<CodesCacheRefreshResponse>(API_URL.counselList()),
|
||||
);
|
||||
};
|
||||
|
||||
export const useCodesCacheRefreshMutation = (options?: UseMutationOptions<CodesCacheRefreshResponse, CBDCAxiosError>) => {
|
||||
const mutation = useMutation<CodesCacheRefreshResponse, CBDCAxiosError>({
|
||||
...options,
|
||||
mutationFn: () => codesCacheRefresh(),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
26
src/entities/common/api/use-codes-cache-status-mutaion.ts
Normal file
26
src/entities/common/api/use-codes-cache-status-mutaion.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import { CodesCacheStatusResponse } from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const codesCacheStatus = () => {
|
||||
return resultify(
|
||||
axios.get<CodesCacheStatusResponse>(API_URL.codesCacheStatus()),
|
||||
);
|
||||
};
|
||||
|
||||
export const useCodesGroupByCodeClMutation = (options?: UseMutationOptions<CodesCacheStatusResponse, CBDCAxiosError>) => {
|
||||
const mutation = useMutation<CodesCacheStatusResponse, CBDCAxiosError>({
|
||||
...options,
|
||||
mutationFn: () => codesCacheStatus(),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
33
src/entities/common/api/use-codes-group-by-codeCl-mutaion.ts
Normal file
33
src/entities/common/api/use-codes-group-by-codeCl-mutaion.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
CodesGroupByCodeClParams,
|
||||
CodesGroupByCodeClResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const codesGroupByCodeCl = ({ codeCl }: CodesGroupByCodeClParams) => {
|
||||
return resultify(
|
||||
axios.get<CodesGroupByCodeClResponse>(API_URL.codesGroupByCodeCl(codeCl)),
|
||||
);
|
||||
};
|
||||
|
||||
export const useCodesGroupByCodeClMutation = (options?: UseMutationOptions<CodesGroupByCodeClResponse, CBDCAxiosError, CodesGroupByCodeClParams>) => {
|
||||
const mutation = useMutation<CodesGroupByCodeClResponse, CBDCAxiosError, CodesGroupByCodeClParams>({
|
||||
...options,
|
||||
mutationFn: ({
|
||||
codeCl
|
||||
}: CodesGroupByCodeClParams) => codesGroupByCodeCl({
|
||||
codeCl
|
||||
}),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
33
src/entities/common/api/use-codes-list-by-codeCl-mutaion.ts
Normal file
33
src/entities/common/api/use-codes-list-by-codeCl-mutaion.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
CodesListByCodeClParams,
|
||||
CodesListByCodeClResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const codesListByCodeCl = ({ codeCl }: CodesListByCodeClParams) => {
|
||||
return resultify(
|
||||
axios.get<CodesListByCodeClResponse>(API_URL.codesListByCodeCl(codeCl)),
|
||||
);
|
||||
};
|
||||
|
||||
export const useCodesListByCodeClMutation = (options?: UseMutationOptions<CodesListByCodeClResponse, CBDCAxiosError, CodesListByCodeClParams>) => {
|
||||
const mutation = useMutation<CodesListByCodeClResponse, CBDCAxiosError, CodesListByCodeClParams>({
|
||||
...options,
|
||||
mutationFn: ({
|
||||
codeCl
|
||||
}: CodesListByCodeClParams) => codesListByCodeCl({
|
||||
codeCl
|
||||
}),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
64
src/entities/common/api/use-codes-select-mutation.ts
Normal file
64
src/entities/common/api/use-codes-select-mutation.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
CodesSelectParams,
|
||||
CodesSelectGetResponse,
|
||||
CodesSelectPostResponse,
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const codesSelect = ({
|
||||
codeCl,
|
||||
colNm,
|
||||
code1,
|
||||
code2,
|
||||
useCl,
|
||||
method
|
||||
}: CodesSelectParams) => {
|
||||
if(method === 'get'){
|
||||
return resultify(
|
||||
axios.get<CodesSelectGetResponse>(API_URL.codesSelect()),
|
||||
);
|
||||
}
|
||||
else{
|
||||
return resultify(
|
||||
axios.post<CodesSelectPostResponse>(API_URL.codesSelect(), {
|
||||
codeCl,
|
||||
colNm,
|
||||
code1,
|
||||
code2,
|
||||
useCl
|
||||
}),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const useCodesSelectMutation = (options?: UseMutationOptions<CodesSelectGetResponse | CodesSelectPostResponse, CBDCAxiosError, CodesSelectParams>) => {
|
||||
const mutation = useMutation<CodesSelectGetResponse | CodesSelectPostResponse, CBDCAxiosError, CodesSelectParams>({
|
||||
...options,
|
||||
mutationFn: ({
|
||||
codeCl,
|
||||
colNm,
|
||||
code1,
|
||||
code2,
|
||||
useCl,
|
||||
method
|
||||
}: CodesSelectParams) => codesSelect({
|
||||
codeCl,
|
||||
colNm,
|
||||
code1,
|
||||
code2,
|
||||
useCl,
|
||||
method
|
||||
}),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
EmptyTokenAddSendCodeParams,
|
||||
EmptyTokenAddSendCodeResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const emptyTokenAddSendCode = (params: EmptyTokenAddSendCodeParams) => {
|
||||
return resultify(
|
||||
axios.post<EmptyTokenAddSendCodeResponse>(API_URL.emptyTokenFindSendCode(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useEmptyTokenAddSendCodeMutation = (options?: UseMutationOptions<EmptyTokenAddSendCodeResponse, CBDCAxiosError, EmptyTokenAddSendCodeParams>) => {
|
||||
const mutation = useMutation<EmptyTokenAddSendCodeResponse, CBDCAxiosError, EmptyTokenAddSendCodeParams>({
|
||||
...options,
|
||||
mutationFn: (params: EmptyTokenAddSendCodeParams) => emptyTokenAddSendCode(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
29
src/entities/common/api/use-empty-token-change-mutation.ts
Normal file
29
src/entities/common/api/use-empty-token-change-mutation.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
EmptyTokenChangeParams,
|
||||
EmptyTokenChangeResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const emptyTokenChange = (params: EmptyTokenChangeParams) => {
|
||||
return resultify(
|
||||
axios.post<EmptyTokenChangeResponse>(API_URL.emptyTokenChange(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useEmptyTokenChangeMutation = (options?: UseMutationOptions<EmptyTokenChangeResponse, CBDCAxiosError, EmptyTokenChangeParams>) => {
|
||||
const mutation = useMutation<EmptyTokenChangeResponse, CBDCAxiosError, EmptyTokenChangeParams>({
|
||||
...options,
|
||||
mutationFn: (params: EmptyTokenChangeParams) => emptyTokenChange(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
EmptyTokenFindSendCodeParams,
|
||||
EmptyTokenFindSendCodeResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const emptyTokenFindSendCode = (params: EmptyTokenFindSendCodeParams) => {
|
||||
return resultify(
|
||||
axios.post<EmptyTokenFindSendCodeResponse>(API_URL.emptyTokenFindSendCode(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useEmptyTokenFindSendCodeMutation = (options?: UseMutationOptions<EmptyTokenFindSendCodeResponse, CBDCAxiosError, EmptyTokenFindSendCodeParams>) => {
|
||||
const mutation = useMutation<EmptyTokenFindSendCodeResponse, CBDCAxiosError, EmptyTokenFindSendCodeParams>({
|
||||
...options,
|
||||
mutationFn: (params: EmptyTokenFindSendCodeParams) => emptyTokenFindSendCode(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
EmptyTokenVerifyCodeParams,
|
||||
EmptyTokenVerifyCodeResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const emptyTokenVerifyCode = (params: EmptyTokenVerifyCodeParams) => {
|
||||
return resultify(
|
||||
axios.post<EmptyTokenVerifyCodeResponse>(API_URL.emptyTokenVerifyCode(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useEmptyTokenVerifyCodeMutation = (options?: UseMutationOptions<EmptyTokenVerifyCodeResponse, CBDCAxiosError, EmptyTokenVerifyCodeParams>) => {
|
||||
const mutation = useMutation<EmptyTokenVerifyCodeResponse, CBDCAxiosError, EmptyTokenVerifyCodeParams>({
|
||||
...options,
|
||||
mutationFn: (params: EmptyTokenVerifyCodeParams) => emptyTokenVerifyCode(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
8
src/entities/common/model/constants.ts
Normal file
8
src/entities/common/model/constants.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export const DEFAULT_PAGE_PARAM = {
|
||||
cursor: 'string',
|
||||
size: 0,
|
||||
sortBy: 'string',
|
||||
sortOrder: 'ASC',
|
||||
orderBy: 'string',
|
||||
limit: 0,
|
||||
};
|
||||
130
src/entities/common/model/types.ts
Normal file
130
src/entities/common/model/types.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
export interface DefaulResponsePagination {
|
||||
nextCursor: string | null;
|
||||
hasNext: boolean;
|
||||
};
|
||||
export enum HeaderType {
|
||||
NoHeader = 'NoHeader',
|
||||
Home = 'Home',
|
||||
Alim = 'Alim',
|
||||
LeftArrow = 'LeftArrow',
|
||||
RightClose = 'RightClose',
|
||||
};
|
||||
export interface HeaderNavigationProps {
|
||||
onBack?: (() => void) | undefined;
|
||||
headerTitle?: string;
|
||||
headerLeft?: React.ReactNode;
|
||||
headerRight?: React.ReactNode;
|
||||
menuOn: boolean;
|
||||
headerType: HeaderType;
|
||||
setMenuOn: (menuOn: boolean) => void;
|
||||
};
|
||||
|
||||
export interface FooterProps {
|
||||
setMenuOn: (menuOn: boolean) => void;
|
||||
footerCurrentPage?: string | null;
|
||||
};
|
||||
export enum FooterItemActiveKey {
|
||||
Home = 'Home',
|
||||
Transaction = 'Transaction',
|
||||
Settlement = 'Settlement',
|
||||
Account = 'Account',
|
||||
};
|
||||
export interface CodesSelectParams {
|
||||
codeCl?: string;
|
||||
colNm?: string;
|
||||
code1?: string;
|
||||
code2?: string;
|
||||
useCl?: string;
|
||||
method: 'get' | 'post';
|
||||
};
|
||||
export interface CodeListItem {
|
||||
codeCl: string;
|
||||
code1: string;
|
||||
code2: string;
|
||||
desc1: string;
|
||||
desc2: string;
|
||||
desc3: string;
|
||||
encDesc1: string;
|
||||
encDesc2: string;
|
||||
encDesc3: string;
|
||||
colNm: string;
|
||||
orderNo: number;
|
||||
};
|
||||
export interface CodeGroupItem {
|
||||
groupCode: string;
|
||||
groupType: string;
|
||||
groupName: string;
|
||||
codeList: Array<CodeListItem>;
|
||||
};
|
||||
export interface CodesSelectGetResponse {
|
||||
codeGroups: Array<CodeGroupItem>;
|
||||
};
|
||||
export interface CodesSelectPostResponse {
|
||||
codeList: Array<CodeListItem>;
|
||||
};
|
||||
export interface CodesListByCodeClParams {
|
||||
codeCl: string;
|
||||
};
|
||||
export interface CodesListByCodeClResponse {
|
||||
codeList: Array<CodeListItem>;
|
||||
};
|
||||
export interface CodesGroupByCodeClParams {
|
||||
codeCl: string;
|
||||
};
|
||||
export interface CodesGroupByCodeClResponse extends CodeGroupItem {
|
||||
|
||||
}
|
||||
export interface CodesCacheStatusResponse {
|
||||
additionalProp1: string;
|
||||
additionalProp2: string;
|
||||
additionalProp3: string;
|
||||
};
|
||||
export interface CodesCacheRefreshResponse {
|
||||
|
||||
};
|
||||
export interface CodesCacheRefreshByCodeClParams {
|
||||
codeCl: string;
|
||||
};
|
||||
export interface CodesCacheRefreshByCodeClResponse {
|
||||
|
||||
};
|
||||
export interface EmptyTokenVerifyCodeParams {
|
||||
usrid: string;
|
||||
authType: string;
|
||||
content: string;
|
||||
authCode: string;
|
||||
};
|
||||
export interface EmptyTokenVerifyCodeResponse {
|
||||
tfaId: string;
|
||||
valid: boolean;
|
||||
};
|
||||
export interface EmptyTokenFindSendCodeParams {
|
||||
usrid: string;
|
||||
password: string;
|
||||
authType: string;
|
||||
content: string;
|
||||
};
|
||||
export interface EmptyTokenFindSendCodeResponse {
|
||||
expiresIn: string;
|
||||
authCode: string;
|
||||
};
|
||||
export interface EmptyTokenChangeParams {
|
||||
usrid: string;
|
||||
password: string;
|
||||
tfaId: string;
|
||||
newPassword: string;
|
||||
newConfirmPassword: string;
|
||||
};
|
||||
export interface EmptyTokenChangeResponse {
|
||||
|
||||
};
|
||||
export interface EmptyTokenAddSendCodeParams {
|
||||
usrid: string;
|
||||
password: string;
|
||||
authType: string;
|
||||
content: string;
|
||||
};
|
||||
export interface EmptyTokenAddSendCodeResponse {
|
||||
expiresIn: string;
|
||||
authCode: string;
|
||||
};
|
||||
18
src/entities/home/model/types.ts
Normal file
18
src/entities/home/model/types.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
export interface FavoriteItemProps {
|
||||
img?: string,
|
||||
text?: string
|
||||
};
|
||||
export interface NoticeItemProps {
|
||||
title?: string,
|
||||
meta1?: string,
|
||||
meta2?: string,
|
||||
img?: string,
|
||||
};
|
||||
export interface HomeBottomBannerProps {
|
||||
setBottomBannerOn: (bottomBannerOn: boolean) => void;
|
||||
bottomBannerOn: boolean;
|
||||
};
|
||||
export interface AuthRegisterProps {
|
||||
setAuthRegisterOn: (authRegisterOn: boolean) => void;
|
||||
authRegisterOn: boolean;
|
||||
};
|
||||
74
src/entities/home/ui/auth-reguster.tsx
Normal file
74
src/entities/home/ui/auth-reguster.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { AuthRegisterProps } from '../model/types';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
export const AuthRegister = ({
|
||||
setAuthRegisterOn,
|
||||
authRegisterOn,
|
||||
}: AuthRegisterProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToClose = () => {
|
||||
setAuthRegisterOn(false);
|
||||
};
|
||||
const onClickToRegister = () => {
|
||||
// register
|
||||
};
|
||||
|
||||
const variants = {
|
||||
hidden: { y: '100%' },
|
||||
visible: { y: '0%' },
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{ (authRegisterOn) &&
|
||||
<div className="bg-dim"></div>
|
||||
}
|
||||
<motion.div
|
||||
className="bottomsheet"
|
||||
initial="hidden"
|
||||
animate={ (authRegisterOn)? 'visible': 'hidden' }
|
||||
variants={ variants }
|
||||
transition={{ duration: 0.5 }}
|
||||
>
|
||||
<div className="bottomsheet-header">
|
||||
<div className="bottomsheet-title">
|
||||
<h2>간편 인증 등록</h2>
|
||||
<button
|
||||
className="close-btn"
|
||||
type="button"
|
||||
>
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/ico_close.svg' }
|
||||
alt="닫기"
|
||||
onClick={ () => onClickToClose() }
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bottomsheet-content">
|
||||
<div className="text-section">
|
||||
<div>
|
||||
간편 인증 등록 한번으로,<br/>
|
||||
비밀번호 없이 편리하게 로그인하세요.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bottomsheet-footer">
|
||||
<button
|
||||
className="btn-50 btn-darkgray flex-1"
|
||||
type="button"
|
||||
onClick={ () => onClickToClose() }
|
||||
>다음에</button>
|
||||
<button
|
||||
className="btn-50 btn-blue flex-2"
|
||||
type="button"
|
||||
onClick={ () => onClickToRegister() }
|
||||
>지금 등록하기</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
44
src/entities/home/ui/day-status-box-container1.tsx
Normal file
44
src/entities/home/ui/day-status-box-container1.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
|
||||
export const BoxContainer1 = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="box-wrap">
|
||||
<h3>오늘 매출</h3>
|
||||
<div className="today-sales">
|
||||
<span className="won01">937,284,000원</span>
|
||||
<span className="per">↑ 43.6%</span>
|
||||
<a href="#" className="arrow">
|
||||
<img src={ IMAGE_ROOT + '/ico_arrow.svg' } alt="오늘 매출 바로가기" />
|
||||
</a>
|
||||
</div>
|
||||
<ul className="dales-detail">
|
||||
<li className="approve">승인 건수 <strong>8,277건</strong></li>
|
||||
<li className="cancel">취소 건수 <strong>320건</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="box-wrap">
|
||||
<h3>오늘 정산</h3>
|
||||
<div className="today-sales">
|
||||
<span className="won02">24,734,000원</span>
|
||||
<span className="per">입금완료</span>
|
||||
<a href="#" className="arrow">
|
||||
<img src={ IMAGE_ROOT + '/ico_arrow.svg' } alt="오늘 매출 바로가기" />
|
||||
</a>
|
||||
</div>
|
||||
<div className="progressbar">
|
||||
<div className="progress-header">
|
||||
<span className="progress-title">정산한도</span>
|
||||
<span className="progress-remaining">23% 남음</span>
|
||||
</div>
|
||||
<div className="progress-container">
|
||||
<div className="progress-bar">
|
||||
<div className="progress-fill" style={{width: '77%'}}></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="remain-limit">잔여정산한도 <strong>7,833,000원</strong></div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
114
src/entities/home/ui/day-status-box-container2.tsx
Normal file
114
src/entities/home/ui/day-status-box-container2.tsx
Normal file
@@ -0,0 +1,114 @@
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
|
||||
export const BoxContainer2 = () => {
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<div className="section-header">
|
||||
<h3>매출/정산 현황</h3>
|
||||
<p>(전월 전체 매출/정산 대비 기준 )</p>
|
||||
</div>
|
||||
<div className="box-wrap two-sales">
|
||||
<h4>총 매출액</h4>
|
||||
<div className="today-sales mt-sty">
|
||||
<span className="won01">937,284,000원</span>
|
||||
<span className="per">↑ 43.6%</span>
|
||||
<a className="arrow">
|
||||
<img src={ IMAGE_ROOT + '/ico_arrow.svg' } alt="오늘 매출 바로가기" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="box-wrap two-sales">
|
||||
<h4>총 정산액</h4>
|
||||
<div className="today-sales mt-sty">
|
||||
<span className="won02">24,734,000원</span>
|
||||
<span className="per">↑ 26.8%</span>
|
||||
<a className="arrow">
|
||||
<img src={ IMAGE_ROOT + '/ico_arrow.svg' } alt="오늘 매출 바로가기" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="section-header">
|
||||
<h3>거래 인사이트</h3>
|
||||
<p>(최근 일주일 기준)</p>
|
||||
</div>
|
||||
<div className="box-wrap two-sales img-customer">
|
||||
<h4>평균 객단가</h4>
|
||||
<div className="two-account">
|
||||
<span>937,284,000원</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="box-wrap two-sales img-states">
|
||||
<h4>하루 평균 매출 및 건수</h4>
|
||||
<div className="two-account">
|
||||
<span>73,000,000원(1,800건)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="box-wrap ranking">
|
||||
<h4>매출이 가장 높은 요일</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<span className="ranking-num-01">1</span>
|
||||
<span>월요일 (354,342,000원)</span>
|
||||
<span className="last-per-01">30%</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="ranking-num-ot">2</span>
|
||||
<span>화요일 (63,983,000원)</span>
|
||||
<span className="last-per-ot">20%</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="ranking-num-ot">3</span>
|
||||
<span>수요일 (5,938,000원)</span>
|
||||
<span className="last-per-ot">10%</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="box-wrap ranking">
|
||||
<h4>매출이 가장 높은 시간</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<span className="ranking-num-01">1</span>
|
||||
<span>18시 (5,342,000원)</span>
|
||||
<span className="last-per-01">30%</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="ranking-num-ot">2</span>
|
||||
<span>10시 (994,000원)</span>
|
||||
<span className="last-per-ot">20%</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="ranking-num-ot">3</span>
|
||||
<span>23시 (478,000원)</span>
|
||||
<span className="last-per-ot">10%</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="box-wrap ranking">
|
||||
<h4>가장 많이쓰인 결제 수단</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<span className="ranking-num-01">1</span>
|
||||
<span>신용카드 (354,342,000원)</span>
|
||||
<span className="last-per-01">30%</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="ranking-num-ot">2</span>
|
||||
<span>가상계좌 (64,094,000원)</span>
|
||||
<span className="last-per-ot">20%</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="ranking-num-ot">3</span>
|
||||
<span>휴대폰 (478,000원)</span>
|
||||
<span className="last-per-ot">10%</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
50
src/entities/home/ui/day-status-box.tsx
Normal file
50
src/entities/home/ui/day-status-box.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { HomeNoticeList } from './home-notice-list';
|
||||
import { BoxContainer1 } from './day-status-box-container1';
|
||||
import { BoxContainer2 } from './day-status-box-container2';
|
||||
export const DayStatusBox = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="day-status">
|
||||
<div className="day-tab">
|
||||
<div>2025.06.16</div>
|
||||
<div>
|
||||
<button className="day-tab-btn active" data-target="one">일</button>
|
||||
<button className="day-tab-btn" data-target="two">월</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="con-box one active">
|
||||
{ <BoxContainer1></BoxContainer1> }
|
||||
</div>
|
||||
<div className="con-box two">
|
||||
{ <BoxContainer2></BoxContainer2> }
|
||||
</div>
|
||||
<div className="swiper-banner">
|
||||
<div className="banner-wrapper">
|
||||
<div className="banner-slide active">
|
||||
<div className="banner-content">
|
||||
<img src={ IMAGE_ROOT + '/home-banner01.png' } alt="배너 이미지" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="banner-slide">
|
||||
<div className="banner-content">
|
||||
<img src={ IMAGE_ROOT + '/home-banner01.png' } alt="배너 이미지" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="banner-slide">
|
||||
<div className="banner-content">
|
||||
<img src={ IMAGE_ROOT + '/home-banner01.png' } alt="배너 이미지" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="banner-pagination">
|
||||
<span className="banner-dot active" data-slide="0"></span>
|
||||
<span className="banner-dot" data-slide="1"></span>
|
||||
<span className="banner-dot" data-slide="2"></span>
|
||||
</div>
|
||||
</div>
|
||||
{ <HomeNoticeList></HomeNoticeList> }
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
17
src/entities/home/ui/favorite-item.tsx
Normal file
17
src/entities/home/ui/favorite-item.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
60
src/entities/home/ui/favorite-wrapper.tsx
Normal file
60
src/entities/home/ui/favorite-wrapper.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import 'swiper/css';
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { FavoriteItem } from './favorite-item';
|
||||
import { FavoriteItemProps } from '../model/types'
|
||||
|
||||
|
||||
export const FavoriteWrapper = () => {
|
||||
const items: Array<FavoriteItemProps> = [
|
||||
{img: IMAGE_ROOT + '/ico_menu_01.svg', text: '지급대행'},
|
||||
{img: IMAGE_ROOT + '/ico_menu_02.svg', text: '거래내역조회'},
|
||||
{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 = {
|
||||
img: IMAGE_ROOT + '/ico_menu_plus.svg',
|
||||
text: '편집하기'
|
||||
};
|
||||
|
||||
const getItems = () => {
|
||||
let rs = [];
|
||||
for(let i=0;i<items.length;i++){
|
||||
let img = items[i]?.img;
|
||||
let text = items[i]?.text;
|
||||
let key = 'slide-key-'+i;
|
||||
rs.push(
|
||||
<SwiperSlide
|
||||
key={ key }
|
||||
>
|
||||
<FavoriteItem
|
||||
img={ img }
|
||||
text={ text }
|
||||
></FavoriteItem>
|
||||
</SwiperSlide>
|
||||
);
|
||||
}
|
||||
|
||||
return rs;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Swiper
|
||||
spaceBetween={9}
|
||||
slidesPerView={4}
|
||||
onSlideChange={() => console.log('slide change')}
|
||||
>
|
||||
{ getItems() }
|
||||
<SwiperSlide>
|
||||
<FavoriteItem
|
||||
img={ itemAdd.img }
|
||||
text={ itemAdd.text }
|
||||
></FavoriteItem>
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
61
src/entities/home/ui/home-bottom-banner.tsx
Normal file
61
src/entities/home/ui/home-bottom-banner.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import moment from 'moment';
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { StorageKeys } from '@/shared/constants/local-storage';
|
||||
import { setLocalStorage } from '@/shared/lib/web-view-bridge';
|
||||
import { HomeBottomBannerProps } from '../model/types';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
export const HomeBottomBanner = ({
|
||||
setBottomBannerOn,
|
||||
bottomBannerOn
|
||||
}: HomeBottomBannerProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToClose = () => {
|
||||
// close
|
||||
setBottomBannerOn(false);
|
||||
};
|
||||
const onClickToCloseDay = () => {
|
||||
// 오늘 날짜 기록
|
||||
const today = moment().format('YYYYMMDD');
|
||||
setLocalStorage(StorageKeys.BottomBannerClose, today);
|
||||
onClickToClose();
|
||||
};
|
||||
|
||||
const variants = {
|
||||
hidden: { y: '100%' },
|
||||
visible: { y: '0%' },
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{bottomBannerOn &&
|
||||
<div className="bg-dim"></div>
|
||||
}
|
||||
<motion.div
|
||||
className="bottomsheet banner"
|
||||
initial="hidden"
|
||||
animate={ (bottomBannerOn)? 'visible': 'hidden' }
|
||||
variants={ variants }
|
||||
transition={{ duration: 0.5 }}
|
||||
>
|
||||
<div className="bottomsheet-content">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/sample_banner.png' }
|
||||
alt="배너"
|
||||
/>
|
||||
<div className="banner-page">
|
||||
<span className="current">1</span>
|
||||
/
|
||||
<span className="total">3</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bottom-btn">
|
||||
<span onClick={ () => onClickToCloseDay() }>오늘 하루 보지 않기</span>
|
||||
<span onClick={ () => onClickToClose() }>닫기</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
33
src/entities/home/ui/home-notice-item.tsx
Normal file
33
src/entities/home/ui/home-notice-item.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { NoticeItemProps } from '../model/types';
|
||||
|
||||
export const HomeNoticeItem = ({
|
||||
title,
|
||||
meta1,
|
||||
meta2,
|
||||
img
|
||||
}: NoticeItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigate = (path: string) => {
|
||||
navigate(path + '14');
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="notice-item">
|
||||
<div className="notice-content">
|
||||
<div className="notice-title">{ title }</div>
|
||||
<div className="notice-meta">{ meta1}<span>{ meta2 }</span></div>
|
||||
</div>
|
||||
<div
|
||||
className="notice-arrow"
|
||||
onClick={ () => onClickToNavigate(PATHS.support.notice.detail) }
|
||||
>
|
||||
<img src={ img } alt="공지사항 바로가기" />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
66
src/entities/home/ui/home-notice-list.tsx
Normal file
66
src/entities/home/ui/home-notice-list.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
/* eslint-disable @cspell/spellchecker */
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { HomeNoticeItem } from './home-notice-item';
|
||||
|
||||
export const HomeNoticeList = () => {
|
||||
const items = [
|
||||
{
|
||||
title: '시스템 안정화를 위한 정기 점검이 예정되어 있습니다.',
|
||||
meta1: '공지사항',
|
||||
meta2: '25년 5월 23일',
|
||||
img: IMAGE_ROOT + '/Forward.svg'
|
||||
},
|
||||
{
|
||||
title: '가맹점 관리 메뉴에 거래내역 엑셀 다운로드 기능이 추가 되었습니다.',
|
||||
meta1: '공지사항',
|
||||
meta2: '25년 5월 23일',
|
||||
img: IMAGE_ROOT + '/Forward.svg'
|
||||
},
|
||||
{
|
||||
title: '신규 가맹점을 대상으로 거래수수료 인하 혜택을 12월까지 제공합니다.',
|
||||
meta1: '공지사항',
|
||||
meta2: '25년 5월 23일',
|
||||
img: IMAGE_ROOT + '/Forward.svg'
|
||||
},
|
||||
{
|
||||
title: '앱의 안정성과 사용성을 개선한 버전 2.3.1이 출시되었습니다.',
|
||||
meta1: '공지사항',
|
||||
meta2: '25년 5월 23일',
|
||||
img: IMAGE_ROOT + '/Forward.svg'
|
||||
},
|
||||
{
|
||||
title: '점검 시간 동안 일부 서비스 이용이 제한될 수 있으니 미리 확인해주세요.',
|
||||
meta1: '공지사항',
|
||||
meta2: '25년 5월 23일',
|
||||
img: IMAGE_ROOT + '/Forward.svg'
|
||||
},
|
||||
];
|
||||
|
||||
const getItems = () => {
|
||||
let rs = [];
|
||||
for(let i=0;i<items.length;i++){
|
||||
let key = 'notice-key-'+i;
|
||||
rs.push(
|
||||
<HomeNoticeItem
|
||||
key={ key }
|
||||
title={ items[i]?.title }
|
||||
meta1={ items[i]?.meta1 }
|
||||
meta2={ items[i]?.meta2 }
|
||||
img={ items[i]?.img }
|
||||
></HomeNoticeItem>
|
||||
);
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="notice-list">
|
||||
<h3>공지 & 최신정보</h3>
|
||||
<div className="notice-box">
|
||||
{ getItems() }
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
10
src/entities/menu/model/types.ts
Normal file
10
src/entities/menu/model/types.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export interface MenuCategoryItem {
|
||||
title: string;
|
||||
path: string;
|
||||
};
|
||||
export interface MenuCategoryProps {
|
||||
category: string;
|
||||
categoryIcon?: string;
|
||||
items: Array<MenuCategoryItem>;
|
||||
setMenuOn: (menuOn: boolean) => void;
|
||||
};
|
||||
50
src/entities/menu/ui/menu-category.tsx
Normal file
50
src/entities/menu/ui/menu-category.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { MenuCategoryProps } from '../model/types';
|
||||
|
||||
export const MenuCategory = ({
|
||||
category,
|
||||
categoryIcon,
|
||||
items,
|
||||
setMenuOn
|
||||
}: MenuCategoryProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigate = (path?: string) => {
|
||||
if(!!path){
|
||||
setMenuOn(false);
|
||||
navigate(path);
|
||||
}
|
||||
};
|
||||
|
||||
const getMenuItems = () => {
|
||||
let rs = [];
|
||||
for(let i=0;i<items.length;i++){
|
||||
let title = items[i]?.title;
|
||||
let path = items[i]?.path;
|
||||
let key = 'menu-item-key-'+i;
|
||||
rs.push(
|
||||
<li
|
||||
key={ key }
|
||||
onClick={ () => onClickToNavigate(path) }
|
||||
>{ title }</li>
|
||||
);
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="menu-category">
|
||||
<div className="category-header">
|
||||
<div className={ 'category-icon ' + categoryIcon }></div>
|
||||
<span>{ category }</span>
|
||||
</div>
|
||||
<ul className="category-items">
|
||||
{ getMenuItems() }
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
7
src/entities/payment/model/types.ts
Normal file
7
src/entities/payment/model/types.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export enum PaymentTabKeys {
|
||||
Info = 'Info',
|
||||
DataNotification = 'DataNotification',
|
||||
};
|
||||
export interface PaymentTabProps {
|
||||
activeTab: PaymentTabKeys;
|
||||
};
|
||||
108
src/entities/payment/ui/card-commission-bottom-sheet.tsx
Normal file
108
src/entities/payment/ui/card-commission-bottom-sheet.tsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
|
||||
export const CardCommissionCycleBottomSheet = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-dim"></div>
|
||||
<div className="bottomsheet">
|
||||
<div className="bottomsheet-header">
|
||||
<div className="bottomsheet-title">
|
||||
<h2>수수료 및 정산주기</h2>
|
||||
<button
|
||||
className="close-btn"
|
||||
type="button"
|
||||
>
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/images/ico_close.svg' }
|
||||
alt="닫기"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bottomsheet-content">
|
||||
<div className="card-fee">
|
||||
<div className="desc">정산주기 : 일일(+3일)</div>
|
||||
|
||||
<div className="notice-tabs">
|
||||
<button
|
||||
className="tab36 on"
|
||||
type="button"
|
||||
>일반</button>
|
||||
<button
|
||||
className="tab36"
|
||||
type="button"
|
||||
>무이자</button>
|
||||
<button
|
||||
className="tab36"
|
||||
type="button"
|
||||
>머니/포인트</button>
|
||||
</div>
|
||||
|
||||
<div className="card-fee-box">
|
||||
<span className="label">카드사</span>
|
||||
<div className="field wid-100">
|
||||
<select>
|
||||
<option>KB국민</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="card-fee-list">
|
||||
<div className="card-fee-list-header">
|
||||
<span className="th-left">할부개월</span>
|
||||
<span className="th-right">수수료</span>
|
||||
</div>
|
||||
<div className="card-fee-row">
|
||||
<span>02 개월</span>
|
||||
<span>2.000%</span>
|
||||
</div>
|
||||
<div className="card-fee-row">
|
||||
<span>03 개월</span>
|
||||
<span>3.100%</span>
|
||||
</div>
|
||||
<div className="card-fee-row">
|
||||
<span>04 개월</span>
|
||||
<span>4.400%</span>
|
||||
</div>
|
||||
<div className="card-fee-row">
|
||||
<span>05 개월</span>
|
||||
<span>5.200%</span>
|
||||
</div>
|
||||
<div className="card-fee-row">
|
||||
<span>06 개월</span>
|
||||
<span>6.000%</span>
|
||||
</div>
|
||||
<div className="card-fee-row">
|
||||
<span>07 개월</span>
|
||||
<span>6.600%</span>
|
||||
</div>
|
||||
<div className="card-fee-row">
|
||||
<span>08 개월</span>
|
||||
<span>7.500%</span>
|
||||
</div>
|
||||
<div className="card-fee-row">
|
||||
<span>09 개월</span>
|
||||
<span>8.000%</span>
|
||||
</div>
|
||||
<div className="card-fee-row">
|
||||
<span>10 개월</span>
|
||||
<span>9.000%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/*
|
||||
<div className="bottomsheet-footer">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
type="button"
|
||||
disabled
|
||||
>신청</button>
|
||||
</div>
|
||||
*/}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
65
src/entities/payment/ui/credit-card-list-bottom-sheet.tsx
Normal file
65
src/entities/payment/ui/credit-card-list-bottom-sheet.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
|
||||
export const CreditCardListBottomSheet = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-dim"></div>
|
||||
<div className="bottomsheet">
|
||||
<div className="bottomsheet-header">
|
||||
<div className="bottomsheet-title">
|
||||
<h2>카드사</h2>
|
||||
<button
|
||||
className="close-btn"
|
||||
type="button"
|
||||
>
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/ico_close.svg' }
|
||||
alt="닫기"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bottomsheet-content">
|
||||
<div className="card-list">
|
||||
<div className="card-option selected">
|
||||
<span className="name">KB국민</span>
|
||||
<i className="check"></i>
|
||||
</div>
|
||||
<div className="card-option">
|
||||
<span className="name">비씨</span>
|
||||
<i className="check"></i>
|
||||
</div>
|
||||
<div className="card-option">
|
||||
<span className="name">하나(외환)</span>
|
||||
<i className="check"></i>
|
||||
</div>
|
||||
<div className="card-option">
|
||||
<span className="name">삼성</span>
|
||||
<i className="check"></i>
|
||||
</div>
|
||||
<div className="card-option">
|
||||
<span className="name">신한</span>
|
||||
<i className="check"></i>
|
||||
</div>
|
||||
<div className="card-option">
|
||||
<span className="name">현대</span>
|
||||
<i className="check"></i>
|
||||
</div>
|
||||
<div className="card-option">
|
||||
<span className="name">롯데</span>
|
||||
<i className="check"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bottomsheet-footer">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
type="button"
|
||||
>확인</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
60
src/entities/payment/ui/data-notification-wrap.tsx
Normal file
60
src/entities/payment/ui/data-notification-wrap.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
export const DataNotificationWrap = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="ing-list">
|
||||
<div className="input-wrapper top-select mt-16">
|
||||
<select>
|
||||
<option value="1">nicetest00g</option>
|
||||
<option value="2">nicetest00g</option>
|
||||
<option value="3">nicetest00g</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="notify-container">
|
||||
<div className="notify-header">
|
||||
<h3 className="notify-title">결제데이터 통보 조회</h3>
|
||||
</div>
|
||||
<ul className="notify-list">
|
||||
<li>
|
||||
<div className="notify-row">
|
||||
<span className="notify-name">신용카드</span>
|
||||
<span className="ic20 arrow-down"></span>
|
||||
</div>
|
||||
</li>
|
||||
<li className="notify-divider"></li>
|
||||
<li>
|
||||
<div className="notify-row">
|
||||
<span className="notify-name">계좌이체</span>
|
||||
<span className="ic20 arrow-down"></span>
|
||||
</div>
|
||||
</li>
|
||||
<li className="notify-divider"></li>
|
||||
<li>
|
||||
<div className="notify-row">
|
||||
<span className="notify-name">가상계좌</span>
|
||||
<span className="ic20 arrow-down"></span>
|
||||
</div>
|
||||
</li>
|
||||
<li className="notify-divider"></li>
|
||||
<li>
|
||||
<div className="notify-row">
|
||||
<span className="notify-name">휴대폰</span>
|
||||
<span className="ic20 arrow-down"></span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div className="notify-row">
|
||||
<span className="notify-name">에스크로 결제</span>
|
||||
<span className="ic20 arrow-down"></span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="notify-bar">
|
||||
<span>결제데이터 통보 설정은 PC에서 가능합니다.</span>
|
||||
<span>전송 설정한 지불수단만 노출됩니다.</span>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
363
src/entities/payment/ui/info-wrap.tsx
Normal file
363
src/entities/payment/ui/info-wrap.tsx
Normal file
@@ -0,0 +1,363 @@
|
||||
import { IMAGE_ROOT } from "@/shared/constants/common";
|
||||
|
||||
export const InfoWrap = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="ing-list">
|
||||
<div className="ing-title">서비스 이용, 수수료 및 정산주기</div>
|
||||
<ul className="ing-card-list">
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_01.svg' }
|
||||
alt="신용카드"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">신용카드</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_02.svg' }
|
||||
alt="카카오페이"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">카카오페이</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_03.svg' }
|
||||
alt="네이버페이"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">네이버페이</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_04.svg' }
|
||||
alt="삼성페이"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">삼성페이</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_05.svg' }
|
||||
alt="계좌이체"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">계좌이체</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_06.svg' }
|
||||
alt="휴대폰결제"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">휴대폰결제</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_07.svg' }
|
||||
alt="문화상품권"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">문화상품권</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_08.svg' }
|
||||
alt="SSG머니"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">SSG머니</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_09.svg' }
|
||||
alt="TV페이"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">TV페이</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_10.svg' }
|
||||
alt="삼성페이(카드)"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">삼성페이(카드)</span>
|
||||
</div>
|
||||
<button
|
||||
className ="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_11.svg' }
|
||||
alt="애플페이"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">애플페이</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_12.svg' }
|
||||
alt="토스페이"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">토스페이</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_13.svg' }
|
||||
alt="PAYCO"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">PAYCO</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_14.svg' }
|
||||
alt="리브페이"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">리브페이</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_14.svg' }
|
||||
alt="대만결제"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">대만결제</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_15.svg' }
|
||||
alt="티머니페이"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">티머니페이</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_16.svg' }
|
||||
alt="L.PAY"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">L.PAY</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_17.svg' }
|
||||
alt="PAYU"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">PAYU</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_18.svg' }
|
||||
alt="TW라인페이"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">TW라인페이</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div className="ing-title">가맹점 분담 무이자 정보</div>
|
||||
<ul className="ing-card-list">
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_01.svg' }
|
||||
alt="신용카드"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">신용카드</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_20.svg' }
|
||||
alt="SK PAY"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">SK PAY</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_09.svg' }
|
||||
alt="TV페이"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">TV페이</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
<li className="ing-card">
|
||||
<div className="ing-card-head">
|
||||
<div className="ing-card-icon">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/pay_04.svg' }
|
||||
alt="삼성페이(카드)"
|
||||
/>
|
||||
</div>
|
||||
<span className="ing-card-name">삼성페이(카드)</span>
|
||||
</div>
|
||||
<button
|
||||
className="ing-card-link"
|
||||
type="button"
|
||||
>수수료 및 정산주기 ></button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
52
src/entities/payment/ui/no-interest-info-bottom-sheet.tsx
Normal file
52
src/entities/payment/ui/no-interest-info-bottom-sheet.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
|
||||
export const NoInterestInfoBottomSheet = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-dim"></div>
|
||||
<div className="bottomsheet">
|
||||
<div className="bottomsheet-header">
|
||||
<div className="bottomsheet-title">
|
||||
<h2>무이자 정보</h2>
|
||||
<button
|
||||
className="close-btn"
|
||||
type="button"
|
||||
>
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/ico_close.svg' }
|
||||
alt="닫기"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="fee-cycle">
|
||||
<div className="card-fee-box">
|
||||
<span className="label">카드사</span>
|
||||
<div className="field wid-100">
|
||||
<select>
|
||||
<option>KB국민</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="desc dot">할부개월 : 02, 03, 07</div>
|
||||
<div className="desc dot">적용기간 : 2025.06.01 ~ 9999.12.31</div>
|
||||
<div className="desc dot">적용금액 : 70,000</div>
|
||||
<div className="divider"></div>
|
||||
<div className="desc dot">할부개월 : 15, 20, 36, 60</div>
|
||||
<div className="desc dot">적용기간 : 2025.06.01 ~ 9999.12.31</div>
|
||||
<div className="desc dot">적용금액 : 50,000</div>
|
||||
</div>
|
||||
{/*
|
||||
<div className="bottomsheet-footer">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
type="button"
|
||||
>확인</button>
|
||||
</div>
|
||||
*/}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
};
|
||||
37
src/entities/payment/ui/payment-tab.tsx
Normal file
37
src/entities/payment/ui/payment-tab.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import {
|
||||
PaymentTabKeys,
|
||||
PaymentTabProps
|
||||
} from '../model/types';
|
||||
|
||||
export const PaymentTab = ({
|
||||
activeTab
|
||||
}: PaymentTabProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigation = (tab: PaymentTabKeys) => {
|
||||
if(activeTab !== tab){
|
||||
if(tab === PaymentTabKeys.Info){
|
||||
navigate(PATHS.payment.info);
|
||||
}
|
||||
else if(tab === PaymentTabKeys.DataNotification){
|
||||
navigate(PATHS.payment.dataNotification);
|
||||
}
|
||||
}
|
||||
};
|
||||
return(
|
||||
<>
|
||||
<div className="subTab">
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === PaymentTabKeys.Info)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(PaymentTabKeys.Info) }
|
||||
>결제 정보</button>
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === PaymentTabKeys.DataNotification)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(PaymentTabKeys.DataNotification) }
|
||||
>결제데이터 통보</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
52
src/entities/payment/ui/transfer-commission-bottom-sheet.tsx
Normal file
52
src/entities/payment/ui/transfer-commission-bottom-sheet.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
|
||||
export const TransferCommissionBottomSheet = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-dim"></div>
|
||||
<div className="bottomsheet">
|
||||
<div className="bottomsheet-header">
|
||||
<div className="bottomsheet-title">
|
||||
<h2>수수료 및 정산주기</h2>
|
||||
<button
|
||||
className="close-btn"
|
||||
type="button"
|
||||
>
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/ico_close.svg' }
|
||||
alt="닫기"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="fee-cycle">
|
||||
<div className="desc dot">정산주기 : 일일(+3일)</div>
|
||||
<div className="desc dot">수수료</div>
|
||||
<div className="divider"></div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row pl-10">
|
||||
<span className="k">결제수수료(최저수수료)</span>
|
||||
<span className="v">1원</span>
|
||||
</li>
|
||||
<li className="kv-row pl-10">
|
||||
<span className="k">결제수수료(1원~)</span>
|
||||
<span className="v">1원</span>
|
||||
</li>
|
||||
<li className="kv-row pl-10">
|
||||
<span className="k">취소수수료</span>
|
||||
<span className="v">1원</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="bottomsheet-footer">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
type="button"
|
||||
>확인</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
41
src/entities/redirect/model/store.ts
Normal file
41
src/entities/redirect/model/store.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/* eslint-disable @cspell/spellchecker */
|
||||
import { lens } from '@dhmk/zustand-lens';
|
||||
import { PathType } from '~/shared/constants/paths';
|
||||
|
||||
export interface UtilEvents {
|
||||
redirectPath?: PathType;
|
||||
notiBarMessage?: string;
|
||||
snackBarMessage?: string;
|
||||
}
|
||||
export interface UtilEventState extends UtilEvents {
|
||||
setRedirectPath: (redirectPath: PathType) => void;
|
||||
setNotiBarMessage: (notiBarMessage: string) => void;
|
||||
setSnackBarMessage: (snackBarMessage: string) => void;
|
||||
}
|
||||
export const createUtilEventSlice = lens<UtilEventState>((set, get) => ({
|
||||
setRedirectPath: (redirectPath) => {
|
||||
set((state: UtilEventState) => {
|
||||
return {
|
||||
...state,
|
||||
redirectPath,
|
||||
};
|
||||
});
|
||||
},
|
||||
setNotiBarMessage: (notiBarMessage) => {
|
||||
set((state: UtilEventState) => {
|
||||
return {
|
||||
...state,
|
||||
notiBarMessage,
|
||||
};
|
||||
});
|
||||
},
|
||||
setSnackBarMessage: (snackBarMessage) => {
|
||||
set((state: UtilEventState) => {
|
||||
return {
|
||||
...state,
|
||||
snackBarMessage,
|
||||
};
|
||||
});
|
||||
},
|
||||
}));
|
||||
29
src/entities/settlement/api/use-settlement-list-mutation.ts
Normal file
29
src/entities/settlement/api/use-settlement-list-mutation.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
SettlementListParams,
|
||||
SettlementListResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const settlementList = (params: SettlementListParams) => {
|
||||
return resultify(
|
||||
axios.post<SettlementListResponse>(API_URL.settlementList(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useSettlementListMutation = (options?: UseMutationOptions<SettlementListResponse, CBDCAxiosError, SettlementListParams>) => {
|
||||
const mutation = useMutation<SettlementListResponse, CBDCAxiosError, SettlementListParams>({
|
||||
...options,
|
||||
mutationFn: (params: SettlementListParams) => settlementList(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
110
src/entities/settlement/model/types.ts
Normal file
110
src/entities/settlement/model/types.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { DefaulResponsePagination } from '@/entities/common/model/types';
|
||||
|
||||
export enum AltMsgKeys {
|
||||
Fold = '접기',
|
||||
UnFold = '펼치기',
|
||||
};
|
||||
export enum SortByKeys {
|
||||
New = 'New',
|
||||
Amount = 'Amount',
|
||||
};
|
||||
export enum SettlementTabKeys {
|
||||
Calendar = 'calendar',
|
||||
List = 'list'
|
||||
};
|
||||
export enum DetailInfoKeys {
|
||||
Amount = 'Amount',
|
||||
Settlement = 'Settlement',
|
||||
};
|
||||
export interface SettlementTabProps {
|
||||
activeTab: SettlementTabKeys
|
||||
};
|
||||
export interface SettlementRequestParams {
|
||||
tid?: string;
|
||||
}
|
||||
|
||||
export interface SettlementDetailParams extends SettlementRequestParams {
|
||||
svcCd: string;
|
||||
};
|
||||
|
||||
|
||||
export interface DetailAmountInfoProps {
|
||||
mid: string;
|
||||
amount: number;
|
||||
cardAmount: number;
|
||||
pointAmount: number;
|
||||
couponAmount: number;
|
||||
kakaoMoney: number;
|
||||
kakaoPoint: number;
|
||||
kakaoInstantDiscount: number;
|
||||
naverPoint: number;
|
||||
tossMoney: number;
|
||||
tossDiscount: number;
|
||||
paycoPoint: number;
|
||||
paycoCoupon: number;
|
||||
escrowFee: number;
|
||||
};
|
||||
export interface DetailSettlementInfoProps {
|
||||
approvalSettleDate: string;
|
||||
approvalSettleAmount: number;
|
||||
cancelSettleDate: string;
|
||||
cancelSettleAmount: number;
|
||||
};
|
||||
export interface DetailResponse {
|
||||
amountInfo?: DetailAmountInfoProps;
|
||||
settlementInfo?: DetailSettlementInfoProps;
|
||||
};
|
||||
export interface DetailInfoProps extends DetailResponse{
|
||||
show?: boolean;
|
||||
tid?: string;
|
||||
onClickToShowInfo?: (info: DetailInfoKeys) => void;
|
||||
};
|
||||
export interface DetailArrowProps {
|
||||
show?: boolean;
|
||||
};
|
||||
export interface SortOptionsBoxProps {
|
||||
sortBy: SortByKeys;
|
||||
onCliCkToSort: (sortBy: SortByKeys) => void;
|
||||
};
|
||||
export interface ListItemProps extends ListItem{
|
||||
|
||||
};
|
||||
export interface ListDateGroupProps {
|
||||
date?: string;
|
||||
items?: Array<ListItemProps>;
|
||||
};
|
||||
export interface ListItem {
|
||||
tid?: string;
|
||||
mid?: string;
|
||||
stateDate?: string;
|
||||
stateCode?: string;
|
||||
stateName?: string;
|
||||
installmentMonth?: string;
|
||||
serviceCode?: string;
|
||||
serviceName?: string;
|
||||
serviceDetailName?: string;
|
||||
goodsAmount?: number;
|
||||
};
|
||||
|
||||
export interface SettlementRequestParams {
|
||||
tid?: string;
|
||||
}
|
||||
export interface SettlementListParams extends SettlementRequestParams {
|
||||
moid: string;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
stateCode: string;
|
||||
serviceCode: string;
|
||||
minAmount: number;
|
||||
maxAmount: number;
|
||||
dateCl: string;
|
||||
goodsName: string;
|
||||
cardCode: string;
|
||||
bankCode: string;
|
||||
searchCl: string;
|
||||
searchValue: string;
|
||||
};
|
||||
export interface SettlementListResponse extends DefaulResponsePagination {
|
||||
content: Array<ListItemProps>;
|
||||
};
|
||||
|
||||
188
src/entities/settlement/ui/calandar-wrap.tsx
Normal file
188
src/entities/settlement/ui/calandar-wrap.tsx
Normal file
@@ -0,0 +1,188 @@
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
|
||||
export const CalendarWrap = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="calendar-wrap">
|
||||
<div className="input-wrapper top-select">
|
||||
<select>
|
||||
<option value="1">nicetest00g</option>
|
||||
<option value="2">nicetest00g</option>
|
||||
<option value="3">nicetest00g</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="month-group">
|
||||
<button
|
||||
className="month-btn"
|
||||
aria-label="이전 달"
|
||||
>
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/ico_date_prev.svg' }
|
||||
alt="이전"
|
||||
/>
|
||||
</button>
|
||||
<div className="month-title">2024년 3월</div>
|
||||
<button
|
||||
className="month-btn"
|
||||
aria-label="다음 달"
|
||||
>
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/ico_date_next.svg' }
|
||||
alt="다음"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="amount-group">
|
||||
<div className="amount-row">
|
||||
<div className="amount-label">정산 <span className="complete">완료</span> 금액</div>
|
||||
<div className="amount-value">
|
||||
<NumericFormat
|
||||
value={ '734723983000' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
suffix={ '원' }
|
||||
></NumericFormat>
|
||||
</div>
|
||||
</div>
|
||||
<div className="amount-row">
|
||||
<div className="amount-label">정산 <span className="scheduled">예정</span> 금액</div>
|
||||
<div className="amount-value">
|
||||
<NumericFormat
|
||||
value={ '465323000' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
suffix={ '원' }
|
||||
></NumericFormat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="legend-group">
|
||||
<div className="legend-item">
|
||||
<div className="legend-dot complete"></div>
|
||||
<div className="legend-text">정산 완료</div>
|
||||
</div>
|
||||
<div className="legend-item">
|
||||
<div className="legend-dot scheduled"></div>
|
||||
<div className="legend-text">입금 예정</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="calendar-grid">
|
||||
<div className="weekdays">
|
||||
<div className="weekday sun">일</div>
|
||||
<div className="weekday">월</div>
|
||||
<div className="weekday">화</div>
|
||||
<div className="weekday">수</div>
|
||||
<div className="weekday">목</div>
|
||||
<div className="weekday">금</div>
|
||||
<div className="weekday sat">토</div>
|
||||
</div>
|
||||
<div className="days">
|
||||
<div className="day other">29</div>
|
||||
<div className="day other">30</div>
|
||||
<div className="day complete">1</div>
|
||||
<div className="day">2</div>
|
||||
<div className="day">3</div>
|
||||
<div className="day">4</div>
|
||||
<div className="day">5</div>
|
||||
<div className="day">6</div>
|
||||
<div className="day complete">7</div>
|
||||
<div className="day">8</div>
|
||||
<div className="day">9</div>
|
||||
<div className="day complete">10</div>
|
||||
<div className="day">11</div>
|
||||
<div className="day">12</div>
|
||||
<div className="day">13</div>
|
||||
<div className="day">14</div>
|
||||
<div className="day">15</div>
|
||||
<div className="day">16</div>
|
||||
<div className="day complete">17</div>
|
||||
<div className="day complete">18</div>
|
||||
<div className="day">19</div>
|
||||
<div className="day">20</div>
|
||||
<div className="day">21</div>
|
||||
<div className="day">22</div>
|
||||
<div className="day complete">23</div>
|
||||
<div className="day">24</div>
|
||||
<div className="day">25</div>
|
||||
<div className="day">26</div>
|
||||
<div className="day">27</div>
|
||||
<div className="day scheduled">28</div>
|
||||
<div className="day scheduled">29</div>
|
||||
<div className="day">30</div>
|
||||
<div className="day">31</div>
|
||||
<div className="day other">1</div>
|
||||
<div className="day other">2</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="settlement-list">
|
||||
<div className="settlement-item">
|
||||
<div className="settlement-tag scheduled">예정</div>
|
||||
<div className="settlement-date">03.29 (금)</div>
|
||||
<div className="settlement-amount">
|
||||
<NumericFormat
|
||||
value={ '34837000' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
suffix={ ' 원' }
|
||||
></NumericFormat>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settlement-item">
|
||||
<div className="settlement-tag scheduled">예정</div>
|
||||
<div className="settlement-date">03.28 (목)</div>
|
||||
<div className="settlement-amount">
|
||||
<NumericFormat
|
||||
value={ '834374000' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
suffix={ ' 원' }
|
||||
></NumericFormat>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settlement-item">
|
||||
<div className="settlement-tag complete">확정</div>
|
||||
<div className="settlement-date">03.27 (수)</div>
|
||||
<div className="settlement-amount">
|
||||
<NumericFormat
|
||||
value={ '23345000' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
suffix={ ' 원' }
|
||||
></NumericFormat>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settlement-item">
|
||||
<div className="settlement-tag complete">확정</div>
|
||||
<div className="settlement-date">03.25 (월)</div>
|
||||
<div className="settlement-amount">
|
||||
<NumericFormat
|
||||
value={ '84847000' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
suffix={ ' 원' }
|
||||
></NumericFormat>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settlement-item">
|
||||
<div className="settlement-tag complete">확정</div>
|
||||
<div className="settlement-date">03.19 (화)</div>
|
||||
<div className="settlement-amount">
|
||||
<NumericFormat
|
||||
value={ '57235000' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
suffix={ ' 원' }
|
||||
></NumericFormat>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
79
src/entities/settlement/ui/detail-amount-info.tsx
Normal file
79
src/entities/settlement/ui/detail-amount-info.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { DetailInfoKeys, DetailInfoProps } from '@/entities/settlement/model/types';
|
||||
|
||||
export const DetailAmountInfo = ({
|
||||
amountInfo,
|
||||
show,
|
||||
tid,
|
||||
onClickToShowInfo
|
||||
}: DetailInfoProps) => {
|
||||
|
||||
const onClickToSetShowInfo = () => {
|
||||
if(!!onClickToShowInfo){
|
||||
onClickToShowInfo(DetailInfoKeys.Amount);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="txn-section">
|
||||
<div className="section-title">금액 정보</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">거래금액 합계</span>
|
||||
<span className="v">6,017,600 (269건)</span>
|
||||
<ul className="txn-amount-detail">
|
||||
<li>
|
||||
<span>· 신용카드</span>
|
||||
<span>6,017,000 (260건)</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>· 계좌이체</span>
|
||||
<span>600 (9건)</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">PG 수수료 합계</span>
|
||||
<span className="v">205,255</span>
|
||||
<ul className="txn-amount-detail">
|
||||
<li>
|
||||
<span>· 결제수수료</span>
|
||||
<span>165,384</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>· 에스크로 수수료</span>
|
||||
<span>0</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>· 인증 수수료</span>
|
||||
<span>21,300</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>· VAT</span>
|
||||
<span>18,571</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">보류</span>
|
||||
<span className="v">0</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">해제</span>
|
||||
<span className="v">0</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">상계</span>
|
||||
<span className="v">- 80,603</span>
|
||||
</li>
|
||||
<li className="kv-row bolder">
|
||||
<span className="k">정산금액</span>
|
||||
<span className="v">5,731,742</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
23
src/entities/settlement/ui/detail-arrow.tsx
Normal file
23
src/entities/settlement/ui/detail-arrow.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { AltMsgKeys, DetailArrowProps } from '../model/types';
|
||||
|
||||
export const DetailArrow = ({ show }: DetailArrowProps) => {
|
||||
const [altMsg, setAltMsg] = useState<AltMsgKeys>(AltMsgKeys.Fold);
|
||||
const [className, setClassName] = useState<string>('ic20 rot-180');
|
||||
|
||||
useEffect(() => {
|
||||
setAltMsg((show)? AltMsgKeys.Fold: AltMsgKeys.UnFold);
|
||||
setClassName(`ic20 ${(show)? 'rot-180': ''}`);
|
||||
}, [show]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<img
|
||||
className={ className }
|
||||
src={ IMAGE_ROOT + '/select_arrow.svg' }
|
||||
alt={ altMsg }
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
74
src/entities/settlement/ui/detail-settlement-info.tsx
Normal file
74
src/entities/settlement/ui/detail-settlement-info.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
import moment from 'moment';
|
||||
import { motion } from 'framer-motion';
|
||||
import { DetailInfoKeys, DetailInfoProps } from '@/entities/settlement/model/types';
|
||||
import { DetailArrow } from './detail-arrow';
|
||||
|
||||
export const DetailSettlementInfo = ({
|
||||
settlementInfo,
|
||||
show,
|
||||
onClickToShowInfo
|
||||
}: DetailInfoProps) => {
|
||||
const variants = {
|
||||
hidden: { height: 0, padding: 0, display: 'none' },
|
||||
visible: { height: 'auto', paddingTop: '12px', display: 'block' },
|
||||
};
|
||||
|
||||
const onClickToSetShowInfo = () => {
|
||||
if(!!onClickToShowInfo){
|
||||
onClickToShowInfo(DetailInfoKeys.Settlement);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="txn-section">
|
||||
<div
|
||||
className="section-title with-toggle"
|
||||
onClick={ () => onClickToSetShowInfo() }
|
||||
>
|
||||
정산 정보 <DetailArrow show={ show }></DetailArrow>
|
||||
</div>
|
||||
<motion.ul
|
||||
className="kv-list"
|
||||
initial="hidden"
|
||||
animate={ (show)? 'visible': 'hidden' }
|
||||
variants={ variants }
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<li className="kv-row">
|
||||
<span className="k">MID</span>
|
||||
<span className="v">cruquis01m</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">이체상태</span>
|
||||
<span className="v">정상처리</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">이체ID</span>
|
||||
<span className="v">APG000600m</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">이체시간</span>
|
||||
<span className="v">12:00:00</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">계좌번호</span>
|
||||
<span className="v">123231231****</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">입금인자</span>
|
||||
<span className="v">나이스페이먼츠</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">정상입금액</span>
|
||||
<span className="v">5,731,742</span>
|
||||
</li>
|
||||
<li className="kv-row nopadding">
|
||||
<span className="k">오류사유</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
</motion.ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
50
src/entities/settlement/ui/list-date-group.tsx
Normal file
50
src/entities/settlement/ui/list-date-group.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import moment from 'moment';
|
||||
import 'moment/dist/locale/ko';
|
||||
import { ListDateGroupProps } from '../model/types';
|
||||
import { ListItem } from './list-item';
|
||||
|
||||
export const ListDateGroup = ({
|
||||
date,
|
||||
items
|
||||
}: ListDateGroupProps) => {
|
||||
moment.locale('ko');
|
||||
const getStateDate = () => {
|
||||
let stateDate = moment(date).format('YY.MM.DD(ddd)');
|
||||
return stateDate;
|
||||
};
|
||||
|
||||
const getListItem = () => {
|
||||
let rs = [];
|
||||
if(!!items && items.length>0){
|
||||
for(let i=0;i<items.length;i++){
|
||||
let key = 'ListItem-'+i;
|
||||
rs.push(
|
||||
<ListItem
|
||||
key={ key }
|
||||
tid={ items[i]?.tid }
|
||||
mid={ items[i]?.mid }
|
||||
stateDate={ items[i]?.stateDate }
|
||||
stateCode={ items[i]?.stateCode }
|
||||
stateName={ items[i]?.stateName }
|
||||
installmentMonth={ items[i]?.installmentMonth }
|
||||
serviceCode={ items[i]?.serviceCode }
|
||||
serviceName={ items[i]?.serviceName }
|
||||
serviceDetailName={ items[i]?.serviceDetailName }
|
||||
goodsAmount={ items[i]?.goodsAmount }
|
||||
></ListItem>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return rs;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="date-group">
|
||||
<div className="date-header">{ getStateDate() }</div>
|
||||
{ getListItem() }
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
99
src/entities/settlement/ui/list-item.tsx
Normal file
99
src/entities/settlement/ui/list-item.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { ListItemProps } from '../model/types';
|
||||
|
||||
export const ListItem = ({
|
||||
tid,
|
||||
mid,
|
||||
stateDate,
|
||||
stateCode,
|
||||
stateName,
|
||||
installmentMonth,
|
||||
serviceCode,
|
||||
serviceName,
|
||||
serviceDetailName,
|
||||
goodsAmount
|
||||
}: ListItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
const getItemClass = () => {
|
||||
let rs = '';
|
||||
if(stateCode === '0'){
|
||||
rs = '';
|
||||
}
|
||||
else if(stateCode === '1'){
|
||||
rs = 'approved';
|
||||
}
|
||||
else if(stateCode === '2'){
|
||||
rs = 'refund';
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
|
||||
const getDotClass = (str?: string) => {
|
||||
let rs = '';
|
||||
if(stateCode === '0'){
|
||||
rs = '';
|
||||
}
|
||||
else if(stateCode === '1'){
|
||||
rs = 'blue';
|
||||
}
|
||||
else if(stateCode === '2'){
|
||||
rs = 'gray';
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.settlement.detail + tid, {
|
||||
state: {
|
||||
tid: tid
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const getTime = () => {
|
||||
let time = stateDate?.substring(8, 12);
|
||||
let timeStr = time?.substring(0, 2) + ':' + time?.substring(2, 4);
|
||||
return timeStr;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={ `transaction-item ${getItemClass()}` }
|
||||
onClick={ () => onClickToNavigate() }
|
||||
>
|
||||
<div className="transaction-status">
|
||||
<div className={ `status-dot ${getDotClass()}`}></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">{ `${serviceName}(${serviceDetailName})` }</div>
|
||||
<div className="transaction-details">
|
||||
<span>{ stateName }</span>
|
||||
<span className="separator">|</span>
|
||||
<span>{ getTime() }</span>
|
||||
<span className="separator">|</span>
|
||||
<span>{ mid }</span>
|
||||
{ (!!installmentMonth && parseInt(installmentMonth) > 1) &&
|
||||
<>
|
||||
<span className="separator">|</span>
|
||||
<span>{ installmentMonth }개월 할부</span>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">
|
||||
{
|
||||
<NumericFormat
|
||||
value={ goodsAmount }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
suffix={ '원' }
|
||||
></NumericFormat>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
211
src/entities/settlement/ui/list-wrap.tsx
Normal file
211
src/entities/settlement/ui/list-wrap.tsx
Normal file
@@ -0,0 +1,211 @@
|
||||
import moment from 'moment';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { ListDateGroup } from './list-date-group';
|
||||
import { ListItem, ListDateGroupProps, SortByKeys } from '@/entities/settlement/model/types';
|
||||
import { useSettlementListMutation } from '@/entities/settlement/api/use-settlement-list-mutation';
|
||||
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constants';
|
||||
import { SortOptionsBox } from '@/entities/transaction/ui/sort-options-box';
|
||||
|
||||
export const ListWrap = () => {
|
||||
const [selectedServiceCode, setSelectedServiceCode] = useState<string>('st');
|
||||
const [sortBy, setSortBy] = useState<SortByKeys>(SortByKeys.New);
|
||||
const [listItems, setListItems] = useState<ListDateGroupProps>({});
|
||||
const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM);
|
||||
const [fromDate, setFromDate] = useState(moment().subtract(1, 'month').format('YYYYMMDD'));
|
||||
const [toDate, setToDate] = useState(moment().format('YYYYMMDD'));
|
||||
|
||||
const { mutateAsync: settlementList } = useSettlementListMutation();
|
||||
|
||||
const callList = (option?: {
|
||||
sortBy?: string,
|
||||
val?: string
|
||||
}) => {
|
||||
let listSummaryParams = {
|
||||
moid: 'string',
|
||||
tid: 'string',
|
||||
fromDate: fromDate,
|
||||
toDate: toDate,
|
||||
stateCode: '0',
|
||||
serviceCode: (option?.val)? option.val: selectedServiceCode,
|
||||
minAmount: 0,
|
||||
maxAmount: 0,
|
||||
dateCl: 'TRANS',
|
||||
goodsName: 'string',
|
||||
cardCode: 'st',
|
||||
bankCode: 'str',
|
||||
searchCl: 'CARD_NO',
|
||||
searchValue: 'string',
|
||||
};
|
||||
pageParam.sortBy = (option?.sortBy)? option.sortBy: sortBy;
|
||||
setPageParam(pageParam);
|
||||
|
||||
let listParams = {
|
||||
...listSummaryParams,
|
||||
...{page: pageParam}
|
||||
};
|
||||
settlementList(listParams).then((rs) => {
|
||||
setListItems(assembleData(rs.content));
|
||||
});
|
||||
};
|
||||
|
||||
const assembleData = (content: Array<ListItem>) => {
|
||||
let data: any = {};
|
||||
if(content && content.length > 0){
|
||||
for(let i=0;i<content?.length;i++){
|
||||
let stateDate = content[i]?.stateDate;
|
||||
let groupDate = stateDate?.substring(0, 8);
|
||||
if(!!groupDate && !data.hasOwnProperty(groupDate)){
|
||||
data[groupDate] = [];
|
||||
}
|
||||
if(!!groupDate && data.hasOwnProperty(groupDate)){
|
||||
data[groupDate].push(content[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
};
|
||||
const onCliCkToSort = (sort: SortByKeys) => {
|
||||
setSortBy(sort);
|
||||
callList({sortBy: sort});
|
||||
};
|
||||
useEffect(() => {
|
||||
callList();
|
||||
}, []);
|
||||
|
||||
const getListDateGroup = () => {
|
||||
let rs = [];
|
||||
if(Object.keys(listItems).length > 0){
|
||||
for (const [key, value] of Object.entries(listItems)) {
|
||||
rs.push(
|
||||
<ListDateGroup
|
||||
key={ key }
|
||||
date={ key }
|
||||
items={ value }
|
||||
></ListDateGroup>
|
||||
);
|
||||
}
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="summary-section">
|
||||
<div className="credit-controls">
|
||||
<div>
|
||||
<input
|
||||
className="credit-period"
|
||||
type="text"
|
||||
value="2025.06.01 ~ 2025.06.31"
|
||||
readOnly={ true }
|
||||
/>
|
||||
<button className="filter-btn">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/ico_setting.svg' }
|
||||
alt="검색옵션"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<button className="download-btn">
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/ico_download.svg' }
|
||||
alt="다운로드"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div className="summary-label label">정산금액</div>
|
||||
<div className="summary-amount divTop">
|
||||
<span className="amount-text">
|
||||
<NumericFormat
|
||||
value={ '83745200' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
suffix={ '원' }
|
||||
></NumericFormat>
|
||||
</span>
|
||||
<button>
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/ico_divTop_arrow.svg' }
|
||||
alt="화살표"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div className="summary-extend">
|
||||
<ul className="summary-amount-list">
|
||||
<li className="summary-amount-item">
|
||||
<span className="label">거래금액</span>
|
||||
<span className="value">
|
||||
<NumericFormat
|
||||
value={ '67860120' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
></NumericFormat> <span className="unit">원</span>
|
||||
</span>
|
||||
</li>
|
||||
<li className="summary-amount-item">
|
||||
<span className="label">PG수수료</span>
|
||||
<span className="value minus">
|
||||
<NumericFormat
|
||||
value={ '-2409428' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
></NumericFormat> <span className="unit">원</span>
|
||||
</span>
|
||||
</li>
|
||||
<li className="summary-amount-item">
|
||||
<span className="label">보류</span>
|
||||
<span className="value">
|
||||
<NumericFormat
|
||||
value={ '0' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
></NumericFormat> <span className="unit">원</span>
|
||||
</span>
|
||||
</li>
|
||||
<li className="summary-amount-item">
|
||||
<span className="label">해제</span>
|
||||
<span className="value link">
|
||||
<NumericFormat
|
||||
value={ '5000' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
></NumericFormat> <span className="unit">원</span>
|
||||
</span>
|
||||
</li>
|
||||
<li className="summary-amount-item">
|
||||
<span className="label">상계</span>
|
||||
<span className="value minus">
|
||||
<NumericFormat
|
||||
value={ '-388393' }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
></NumericFormat> <span className="unit">원</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="filter-section">
|
||||
<SortOptionsBox
|
||||
sortBy={ sortBy }
|
||||
onCliCkToSort={ onCliCkToSort }
|
||||
></SortOptionsBox>
|
||||
<div>
|
||||
<div className="full-menu-keywords no-padding">
|
||||
<span className="keyword-tag active">거래건별 보기</span>
|
||||
<span className="keyword-tag">정산내역</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-list">
|
||||
{
|
||||
(!!listItems && Object.keys(listItems).length > 0) &&
|
||||
getListDateGroup()
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
37
src/entities/settlement/ui/settlement-tab.tsx
Normal file
37
src/entities/settlement/ui/settlement-tab.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import {
|
||||
SettlementTabKeys,
|
||||
SettlementTabProps
|
||||
} from '../model/types';
|
||||
|
||||
export const SettlementTab = ({
|
||||
activeTab
|
||||
}: SettlementTabProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigation = (tab: SettlementTabKeys) => {
|
||||
if(activeTab !== tab){
|
||||
if(tab === SettlementTabKeys.Calendar){
|
||||
navigate(PATHS.settlement.calendar);
|
||||
}
|
||||
else if(tab === SettlementTabKeys.List){
|
||||
navigate(PATHS.settlement.list);
|
||||
}
|
||||
}
|
||||
};
|
||||
return(
|
||||
<>
|
||||
<div className="subTab">
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === SettlementTabKeys.Calendar)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(SettlementTabKeys.Calendar) }
|
||||
>정산달력</button>
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === SettlementTabKeys.List)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(SettlementTabKeys.List) }
|
||||
>정산내역</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
22
src/entities/settlement/ui/sort-options-box.tsx
Normal file
22
src/entities/settlement/ui/sort-options-box.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { SortByKeys, SortOptionsBoxProps } from '../model/types';
|
||||
export const SortOptionsBox = ({
|
||||
sortBy,
|
||||
onCliCkToSort
|
||||
}: SortOptionsBoxProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="sort-options">
|
||||
<button
|
||||
className={ `sort-btn ${(sortBy === SortByKeys.New)? 'active': ''}` }
|
||||
onClick={ () => onCliCkToSort(SortByKeys.New) }
|
||||
>최신순</button>
|
||||
<span className="sort-divider">|</span>
|
||||
<button
|
||||
className={ `sort-btn ${(sortBy === SortByKeys.Amount)? 'active': ''}` }
|
||||
onClick={ () => onCliCkToSort(SortByKeys.Amount) }
|
||||
>고액순</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
29
src/entities/support/api/use-counsel-list-mutation.ts
Normal file
29
src/entities/support/api/use-counsel-list-mutation.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
CounselListParams,
|
||||
CounselListResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const counselList = (params: CounselListParams) => {
|
||||
return resultify(
|
||||
axios.post<CounselListResponse>(API_URL.counselList(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useCounselListMutation = (options?: UseMutationOptions<CounselListResponse, CBDCAxiosError, CounselListParams>) => {
|
||||
const mutation = useMutation<CounselListResponse, CBDCAxiosError, CounselListParams>({
|
||||
...options,
|
||||
mutationFn: (params: CounselListParams) => counselList(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
29
src/entities/support/api/use-counsel-save-mutation.ts
Normal file
29
src/entities/support/api/use-counsel-save-mutation.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
CounselSaveParams,
|
||||
CounselSaveResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const counselSave = (params: CounselSaveParams) => {
|
||||
return resultify(
|
||||
axios.post<CounselSaveResponse>(API_URL.counselSave(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useCounselSaveMutation = (options?: UseMutationOptions<CounselSaveResponse, CBDCAxiosError, CounselSaveParams>) => {
|
||||
const mutation = useMutation<CounselSaveResponse, CBDCAxiosError, CounselSaveParams>({
|
||||
...options,
|
||||
mutationFn: (params: CounselSaveParams) => counselSave(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
29
src/entities/support/api/use-faq-list-mutation.ts
Normal file
29
src/entities/support/api/use-faq-list-mutation.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
FaqListParams,
|
||||
FaqListResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const faqList = (params: FaqListParams) => {
|
||||
return resultify(
|
||||
axios.post<FaqListResponse>(API_URL.faqList(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useFaqListMutation = (options?: UseMutationOptions<FaqListResponse, CBDCAxiosError, FaqListParams>) => {
|
||||
const mutation = useMutation<FaqListResponse, CBDCAxiosError, FaqListParams>({
|
||||
...options,
|
||||
mutationFn: (params: FaqListParams) => faqList(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
48
src/entities/support/model/types.ts
Normal file
48
src/entities/support/model/types.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { DefaulResponsePagination } from '@/entities/common/model/types';
|
||||
|
||||
export interface SupportParams {
|
||||
mid?: string;
|
||||
};
|
||||
export interface FaqListParams {
|
||||
category: string;
|
||||
searchValue: string;
|
||||
};
|
||||
export interface FaqListItemProps {
|
||||
sortNo: string;
|
||||
seq: string;
|
||||
category: string;
|
||||
categoryName: string;
|
||||
title: string;
|
||||
contents: string;
|
||||
};
|
||||
export interface FaqListResponse extends DefaulResponsePagination {
|
||||
content: Array<FaqListItemProps>;
|
||||
};
|
||||
export interface CounselListParams extends SupportParams {
|
||||
|
||||
};
|
||||
export interface CounselListItemProps {
|
||||
sortNo: string;
|
||||
seq: string;
|
||||
statusCode: string;
|
||||
statusName: string;
|
||||
requestDate: string;
|
||||
requestName: string;
|
||||
title: string;
|
||||
contents: string;
|
||||
answer: string;
|
||||
};
|
||||
export interface CounselListResponse extends DefaulResponsePagination {
|
||||
content: Array<CounselListItemProps>
|
||||
};
|
||||
export interface CounselSaveParams extends SupportParams {
|
||||
counselType: string;
|
||||
requestName: string;
|
||||
requestTel: string;
|
||||
requestEmail: string;
|
||||
title: string;
|
||||
contents: string;
|
||||
};
|
||||
export interface CounselSaveResponse {
|
||||
|
||||
};
|
||||
29
src/entities/tax/api/use-invoice-detail-mutation.ts
Normal file
29
src/entities/tax/api/use-invoice-detail-mutation.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/shared/api/urls';
|
||||
import { resultify } from '@/shared/lib/resultify';
|
||||
import { CBDCAxiosError } from '@/shared/@types/error';
|
||||
import {
|
||||
InvoiceDetailParams,
|
||||
InvoiceDetailResponse
|
||||
} from '../model/types';
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
export const invoiceDetail = (params: InvoiceDetailParams) => {
|
||||
return resultify(
|
||||
axios.post<InvoiceDetailResponse>(API_URL.allTransactionList(), params),
|
||||
);
|
||||
};
|
||||
|
||||
export const useInvoiceDetailMutation = (options?: UseMutationOptions<InvoiceDetailResponse, CBDCAxiosError, InvoiceDetailParams>) => {
|
||||
const mutation = useMutation<InvoiceDetailResponse, CBDCAxiosError, InvoiceDetailParams>({
|
||||
...options,
|
||||
mutationFn: (params: InvoiceDetailParams) => invoiceDetail(params),
|
||||
});
|
||||
|
||||
return {
|
||||
...mutation,
|
||||
};
|
||||
};
|
||||
87
src/entities/tax/model/types.ts
Normal file
87
src/entities/tax/model/types.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
export enum TaxTabKeys {
|
||||
InvoiceList = 'InvoiceList',
|
||||
VatReference = 'VatReference',
|
||||
};
|
||||
export interface TaxTabProps {
|
||||
activeTab: TaxTabKeys;
|
||||
};
|
||||
export interface InvoiceFilterProps {
|
||||
filterOn: boolean;
|
||||
setFilterOn: (filterOn: boolean) => void;
|
||||
};
|
||||
export enum SortByKeys {
|
||||
New = 'New',
|
||||
Amount = 'Amount',
|
||||
};
|
||||
export interface SortOptionsBoxProps {
|
||||
sortBy: SortByKeys;
|
||||
onCliCkToSort: (sortBy: SortByKeys) => void;
|
||||
};
|
||||
export enum AltMsgKeys {
|
||||
Fold = '접기',
|
||||
UnFold = '펼치기',
|
||||
};
|
||||
export enum DetailInfoSectionKeys {
|
||||
Amount = 'Amount',
|
||||
Publish = 'Publish',
|
||||
Receiver = 'Receiver',
|
||||
Supplier = 'Supplier',
|
||||
};
|
||||
export interface InvoiceArrowProps {
|
||||
show?: boolean;
|
||||
};
|
||||
export interface InvoiceListParams {
|
||||
|
||||
};
|
||||
export interface invoiceListResponse {
|
||||
|
||||
};
|
||||
export interface ListItem {
|
||||
tid?: string;
|
||||
pname?: string;
|
||||
userid?: string;
|
||||
idate?: string;
|
||||
kind?: string;
|
||||
amount?: number;
|
||||
};
|
||||
export interface ListItemProps extends ListItem{
|
||||
|
||||
};
|
||||
export interface ListDateGroupProps {
|
||||
date: string;
|
||||
items: Array<ListItemProps>
|
||||
}
|
||||
export interface InvoiceListProps {
|
||||
listItems: Record<string, Array<ListItemProps>>
|
||||
};
|
||||
export interface InvoiceDetailParams {
|
||||
svcCd?: string;
|
||||
tid: string;
|
||||
};
|
||||
export interface InvoiceDetailResponse {
|
||||
|
||||
};
|
||||
export interface DetailAmountInfoProps {
|
||||
|
||||
};
|
||||
export interface DetailPublishInfoProps {
|
||||
|
||||
};
|
||||
export interface DetailReceiverInfoProps {
|
||||
|
||||
};
|
||||
export interface DetailSupplierInfoProps {
|
||||
|
||||
};
|
||||
export interface DetailResponse {
|
||||
amountInfo?: DetailAmountInfoProps;
|
||||
publishInfo?: DetailPublishInfoProps;
|
||||
receiverInfo?: DetailReceiverInfoProps;
|
||||
supplierInfo?: DetailSupplierInfoProps;
|
||||
};
|
||||
|
||||
export interface DetailInfoSectionProps extends DetailResponse {
|
||||
show?: boolean;
|
||||
tid?: string;
|
||||
onClickToShowInfo?: (info: DetailInfoSectionKeys) => void;
|
||||
};
|
||||
47
src/entities/tax/ui/detail-amount-info-section.tsx
Normal file
47
src/entities/tax/ui/detail-amount-info-section.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import { DetailInfoSectionProps } from '../model/types';
|
||||
import { InvoiceArrow } from './invoice-arrow';
|
||||
|
||||
export const DetailAmountInfoSection = ({
|
||||
amountInfo,
|
||||
show,
|
||||
onClickToShowInfo
|
||||
}: DetailInfoSectionProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="txn-num-group">
|
||||
<div className="txn-amount">
|
||||
<div className="value">48,125,100<span className="unit">원</span></div>
|
||||
<button
|
||||
className="chip-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>금액상세</span> <InvoiceArrow show={ show }></InvoiceArrow>
|
||||
</button>
|
||||
</div>
|
||||
<div className="amount-expand">
|
||||
<ul className="amount-list">
|
||||
<li className="amount-item">
|
||||
<span className="label">· 공급가액</span>
|
||||
<span className="value">43,750,000 원</span>
|
||||
</li>
|
||||
<li className="amount-item">
|
||||
<span className="label">· VAT</span>
|
||||
<span className="value">4,375,100 원</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="txn-mid">
|
||||
<span className="value">croquis01m</span>
|
||||
</div>
|
||||
<div className="txn-mid">
|
||||
<span className="value">2025.08.19</span>
|
||||
</div>
|
||||
<div className="txn-doc">
|
||||
<button className="doc-btn" type="button">세금계산서</button>
|
||||
<button className="doc-btn" type="button">상세자료</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
46
src/entities/tax/ui/detail-publish-info-section.tsx
Normal file
46
src/entities/tax/ui/detail-publish-info-section.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { DetailInfoSectionProps } from '../model/types';
|
||||
|
||||
export const DetailPublishInfoSection = ({
|
||||
publishInfo,
|
||||
show,
|
||||
onClickToShowInfo
|
||||
}: DetailInfoSectionProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="txn-section">
|
||||
<div className="section-title">발행 정보</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">MID</span>
|
||||
<span className="v">nictest01m</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">발행대상일자</span>
|
||||
<span className="v">2025.06.01 ~ 2025.06.30</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">발행일자</span>
|
||||
<span className="v">2025.06.30</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">적요</span>
|
||||
<span className="v">PG 수수료</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">발행대상</span>
|
||||
<span className="v">일반</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">영수구분</span>
|
||||
<span className="v">영수</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">Email</span>
|
||||
<span className="v">test@nicepay.co.kr</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user