메뉴 및 슬라이드 메뉴 다국어화

- MenuItems에 영문 메뉴명(menuNameEng) 추가
- MenuCategory 컴포넌트에 i18n 적용하여 언어별 메뉴 표시
- SlideMenu 컴포넌트 다국어 지원 추가
- ko.json, en.json에 slideMenu 번역 키 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jay Sheen
2025-10-29 15:22:55 +09:00
parent 7c0da1cd8e
commit 0c40d2150c
5 changed files with 114 additions and 54 deletions

View File

@@ -1,4 +1,5 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
interface SlideMenuProps { interface SlideMenuProps {
isOpen: boolean; isOpen: boolean;
@@ -6,6 +7,8 @@ interface SlideMenuProps {
} }
const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => { const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => {
const { t } = useTranslation();
// ESC 키로 메뉴 닫기 // ESC 키로 메뉴 닫기
useEffect(() => { useEffect(() => {
const handleEscape = (event: KeyboardEvent) => { const handleEscape = (event: KeyboardEvent) => {
@@ -50,7 +53,7 @@ const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => {
paddingTop: `calc(1rem + env(safe-area-inset-top, 0px))` paddingTop: `calc(1rem + env(safe-area-inset-top, 0px))`
}} }}
> >
<h2 className="text-xl font-bold text-gray-900"></h2> <h2 className="text-xl font-bold text-gray-900">{t('slideMenu.title')}</h2>
<button <button
onClick={onClose} onClick={onClose}
className="p-2 rounded-md hover:bg-gray-100 transition-colors" className="p-2 rounded-md hover:bg-gray-100 transition-colors"
@@ -65,14 +68,14 @@ const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => {
<div className="p-4 flex-1 overflow-y-scroll pb-16 scrollbar-hide"> <div className="p-4 flex-1 overflow-y-scroll pb-16 scrollbar-hide">
<div className="space-y-6"> <div className="space-y-6">
<div className="border border-gray-200 rounded-lg p-6"> <div className="border border-gray-200 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4"> </h3> <h3 className="text-lg font-semibold text-gray-800 mb-4">{t('slideMenu.accountManagement')}</h3>
<ul className="space-y-3"> <ul className="space-y-3">
<li> <li>
<a href="#" className="flex items-center text-gray-700 hover:text-blue-600 transition-colors"> <a href="#" className="flex items-center text-gray-700 hover:text-blue-600 transition-colors">
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg> </svg>
{t('slideMenu.profileSettings')}
</a> </a>
</li> </li>
<li> <li>
@@ -80,7 +83,7 @@ const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => {
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
</svg> </svg>
{t('slideMenu.changePassword')}
</a> </a>
</li> </li>
<li> <li>
@@ -88,21 +91,21 @@ const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => {
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 17h5l-5 5v-5zM8 17H3l5 5v-5zM12 3v3m6.364-.636l-2.121 2.121M21 12h-3M18.364 18.364l-2.121-2.121M12 21v-3m-6.364.636l2.121-2.121M3 12h3M5.636 5.636l2.121 2.121" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 17h5l-5 5v-5zM8 17H3l5 5v-5zM12 3v3m6.364-.636l-2.121 2.121M21 12h-3M18.364 18.364l-2.121-2.121M12 21v-3m-6.364.636l2.121-2.121M3 12h3M5.636 5.636l2.121 2.121" />
</svg> </svg>
{t('slideMenu.notificationSettings')}
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
<div className="border border-gray-200 rounded-lg p-6"> <div className="border border-gray-200 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4"> </h3> <h3 className="text-lg font-semibold text-gray-800 mb-4">{t('slideMenu.paymentService')}</h3>
<ul className="space-y-3"> <ul className="space-y-3">
<li> <li>
<a href="#" className="flex items-center text-gray-700 hover:text-blue-600 transition-colors"> <a href="#" className="flex items-center text-gray-700 hover:text-blue-600 transition-colors">
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg> </svg>
{t('slideMenu.paymentHistory')}
</a> </a>
</li> </li>
<li> <li>
@@ -110,7 +113,7 @@ const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => {
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />
</svg> </svg>
{t('slideMenu.refundRequest')}
</a> </a>
</li> </li>
<li> <li>
@@ -118,21 +121,21 @@ const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => {
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />
</svg> </svg>
{t('slideMenu.paymentMethodManagement')}
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
<div className="border border-gray-200 rounded-lg p-6"> <div className="border border-gray-200 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4"> </h3> <h3 className="text-lg font-semibold text-gray-800 mb-4">{t('slideMenu.customerSupport')}</h3>
<ul className="space-y-3"> <ul className="space-y-3">
<li> <li>
<a href="#" className="flex items-center text-gray-700 hover:text-blue-600 transition-colors"> <a href="#" className="flex items-center text-gray-700 hover:text-blue-600 transition-colors">
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg> </svg>
FAQ {t('slideMenu.faq')}
</a> </a>
</li> </li>
<li> <li>
@@ -140,7 +143,7 @@ const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => {
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg> </svg>
1:1 {t('slideMenu.inquiry')}
</a> </a>
</li> </li>
<li> <li>
@@ -148,21 +151,21 @@ const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => {
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg> </svg>
{t('slideMenu.termsOfService')}
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
<div className="border border-gray-200 rounded-lg p-6"> <div className="border border-gray-200 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-800 mb-4"></h3> <h3 className="text-lg font-semibold text-gray-800 mb-4">{t('slideMenu.other')}</h3>
<ul className="space-y-3"> <ul className="space-y-3">
<li> <li>
<a href="#" className="flex items-center text-gray-700 hover:text-blue-600 transition-colors"> <a href="#" className="flex items-center text-gray-700 hover:text-blue-600 transition-colors">
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg> </svg>
{t('slideMenu.appInfo')}
</a> </a>
</li> </li>
<li> <li>
@@ -170,7 +173,7 @@ const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => {
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
</svg> </svg>
{t('slideMenu.developerInfo')}
</a> </a>
</li> </li>
<li> <li>
@@ -178,7 +181,7 @@ const SlideMenu: React.FC<SlideMenuProps> = ({ isOpen, onClose }) => {
<svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
</svg> </svg>
{t('slideMenu.logout')}
</a> </a>
</li> </li>
</ul> </ul>

View File

@@ -49,92 +49,100 @@ export const MenuItems = [
menuId: 30, menuId: 30,
parent: 30, parent: 30,
menuName: '거래조회', menuName: '거래조회',
menuNameEng: 'Transactions',
iconFilePath: 'transaction-icon', iconFilePath: 'transaction-icon',
subMenu: [ subMenu: [
{menuId: 31, parent: 30, menuName: '거래내역조회', menuNameEng: '',iconFilePath: '/images/menu_icon_31.svg', programPath: PATHS.transaction.allTransaction.list}, {menuId: 31, parent: 30, menuName: '거래내역조회', menuNameEng: 'Transaction History',iconFilePath: '/images/menu_icon_31.svg', programPath: PATHS.transaction.allTransaction.list},
{menuId: 32, parent: 30, menuName: '현금영수증발행', menuNameEng: '',iconFilePath: '/images/menu_icon_32.svg', programPath: PATHS.transaction.cashReceipt.list}, {menuId: 32, parent: 30, menuName: '현금영수증발행', menuNameEng: 'Cash Receipt',iconFilePath: '/images/menu_icon_32.svg', programPath: PATHS.transaction.cashReceipt.list},
{menuId: 33, parent: 30, menuName: '에스크로', menuNameEng: '',iconFilePath: '/images/menu_icon_33.svg', programPath: PATHS.transaction.escrow.list}, {menuId: 33, parent: 30, menuName: '에스크로', menuNameEng: 'Escrow',iconFilePath: '/images/menu_icon_33.svg', programPath: PATHS.transaction.escrow.list},
{menuId: 34, parent: 30, menuName: '빌링', menuNameEng: '',iconFilePath: '/images/menu_icon_34.svg', programPath: PATHS.transaction.billing.list} {menuId: 34, parent: 30, menuName: '빌링', menuNameEng: 'Billing',iconFilePath: '/images/menu_icon_34.svg', programPath: PATHS.transaction.billing.list}
] ]
}, },
{ {
menuId: 35, menuId: 35,
parent: 35, parent: 35,
menuName: '정산조회', menuName: '정산조회',
menuNameEng: 'Settlement',
iconFilePath: 'settlement-icon', iconFilePath: 'settlement-icon',
subMenu: [ subMenu: [
{menuId: 36, parent: 35, menuName: '정산달력', menuNameEng: '',iconFilePath: '/images/menu_icon_36.svg', programPath: PATHS.settlement.calendar}, {menuId: 36, parent: 35, menuName: '정산달력', menuNameEng: 'Settlement Calendar',iconFilePath: '/images/menu_icon_36.svg', programPath: PATHS.settlement.calendar},
{menuId: 37, parent: 35, menuName: '정산내역', menuNameEng: '',iconFilePath: '/images/menu_icon_37.svg', programPath: PATHS.settlement.list} {menuId: 37, parent: 35, menuName: '정산내역', menuNameEng: 'Settlement History',iconFilePath: '/images/menu_icon_37.svg', programPath: PATHS.settlement.list}
] ]
}, },
{ {
menuId: 38, menuId: 38,
parent: 38, parent: 38,
menuName: '가맹점관리', menuName: '가맹점관리',
menuNameEng: 'Merchant',
iconFilePath: 'merchant-icon', iconFilePath: 'merchant-icon',
subMenu: [ subMenu: [
{menuId: 39, parent: 38, menuName: '가맹점정보', menuNameEng: '',iconFilePath: '/images/menu_icon_39.svg', programPath: PATHS.merchant.info}, {menuId: 39, parent: 38, menuName: '가맹점정보', menuNameEng: 'Merchant Info',iconFilePath: '/images/menu_icon_39.svg', programPath: PATHS.merchant.info},
{menuId: 40, parent: 38, menuName: '등록현황', menuNameEng: '',iconFilePath: '/images/menu_icon_40.svg', programPath: PATHS.merchant.registrationStatus} {menuId: 40, parent: 38, menuName: '등록현황', menuNameEng: 'Registration Status',iconFilePath: '/images/menu_icon_40.svg', programPath: PATHS.merchant.registrationStatus}
] ]
}, },
{ {
menuId: 41, menuId: 41,
parent: 41, parent: 41,
menuName: '결제관리', menuName: '결제관리',
menuNameEng: 'Payment',
iconFilePath: 'payment-icon', iconFilePath: 'payment-icon',
subMenu: [ subMenu: [
{menuId: 42, parent: 41, menuName: '결제정보', menuNameEng: '',iconFilePath: '/images/menu_icon_42.svg', programPath: PATHS.payment.info}, {menuId: 42, parent: 41, menuName: '결제정보', menuNameEng: 'Payment Info',iconFilePath: '/images/menu_icon_42.svg', programPath: PATHS.payment.info},
{menuId: 43, parent: 41, menuName: '결제데이터통보', menuNameEng: '',iconFilePath: '/images/menu_icon_43.svg', programPath: PATHS.payment.notificationData}, {menuId: 43, parent: 41, menuName: '결제데이터통보', menuNameEng: 'Payment Notification',iconFilePath: '/images/menu_icon_43.svg', programPath: PATHS.payment.notificationData},
] ]
}, },
{ {
menuId: 44, menuId: 44,
parent: 44, parent: 44,
menuName: '계정관리', menuName: '계정관리',
menuNameEng: 'Account',
iconFilePath: 'account-icon', iconFilePath: 'account-icon',
subMenu: [ subMenu: [
{menuId: 45, parent: 44, menuName: '사용자관리', menuNameEng: '',iconFilePath: '/images/menu_icon_45.svg', programPath: PATHS.account.user.manage}, {menuId: 45, parent: 44, menuName: '사용자관리', menuNameEng: 'User Management',iconFilePath: '/images/menu_icon_45.svg', programPath: PATHS.account.user.manage},
{menuId: 46, parent: 44, menuName: '비밀번호관리', menuNameEng: '',iconFilePath: '/images/menu_icon_46.svg', programPath: PATHS.account.password.manage}, {menuId: 46, parent: 44, menuName: '비밀번호관리', menuNameEng: 'Password Management',iconFilePath: '/images/menu_icon_46.svg', programPath: PATHS.account.password.manage},
] ]
}, },
{ {
menuId: 47, menuId: 47,
parent: 47, parent: 47,
menuName: '부가세신고자료', menuName: '부가세신고자료',
menuNameEng: 'VAT',
iconFilePath: 'vat-icon', iconFilePath: 'vat-icon',
subMenu: [ subMenu: [
{menuId: 48, parent: 47, menuName: '세금계산서', menuNameEng: '',iconFilePath: '/images/menu_icon_48.svg', programPath: PATHS.vatReturn.list}, {menuId: 48, parent: 47, menuName: '세금계산서', menuNameEng: 'Tax Invoice',iconFilePath: '/images/menu_icon_48.svg', programPath: PATHS.vatReturn.list},
{menuId: 49, parent: 47, menuName: '부가세참고', menuNameEng: '',iconFilePath: '/images/menu_icon_49.svg', programPath: PATHS.vatReturn.reference}, {menuId: 49, parent: 47, menuName: '부가세참고', menuNameEng: 'VAT Reference',iconFilePath: '/images/menu_icon_49.svg', programPath: PATHS.vatReturn.reference},
] ]
}, },
{ {
menuId: 50, menuId: 50,
parent: 50, parent: 50,
menuName: '부가서비스', menuName: '부가서비스',
menuNameEng: 'Services',
iconFilePath: 'service-icon', iconFilePath: 'service-icon',
subMenu: [ subMenu: [
{menuId: 51, parent: 50, menuName: '부가서비스소개', menuNameEng: '',iconFilePath: '/images/menu_icon_51.svg', programPath: PATHS.additionalService.list}, {menuId: 51, parent: 50, menuName: '부가서비스소개', menuNameEng: 'Service Overview',iconFilePath: '/images/menu_icon_51.svg', programPath: PATHS.additionalService.list},
{menuId: 52, parent: 50, menuName: '신용카드ARS카드결제', menuNameEng: '',iconFilePath: '/images/menu_icon_52.svg', programPath: PATHS.additionalService.ars.list}, {menuId: 52, parent: 50, menuName: '신용카드ARS카드결제', menuNameEng: 'ARS Card Payment',iconFilePath: '/images/menu_icon_52.svg', programPath: PATHS.additionalService.ars.list},
{menuId: 53, parent: 50, menuName: '지급대행', menuNameEng: '',iconFilePath: '/images/menu_icon_53.svg', programPath: PATHS.additionalService.payout.list}, {menuId: 53, parent: 50, menuName: '지급대행', menuNameEng: 'Payment Agency',iconFilePath: '/images/menu_icon_53.svg', programPath: PATHS.additionalService.payout.list},
{menuId: 54, parent: 50, menuName: '링크결제', menuNameEng: '',iconFilePath: '/images/menu_icon_54.svg', programPath: PATHS.additionalService.linkPayment.shippingHistory}, {menuId: 54, parent: 50, menuName: '링크결제', menuNameEng: 'Link Payment',iconFilePath: '/images/menu_icon_54.svg', programPath: PATHS.additionalService.linkPayment.shippingHistory},
{menuId: 55, parent: 50, menuName: '자금이체', menuNameEng: '',iconFilePath: '/images/menu_icon_55.svg', programPath: PATHS.additionalService.fundAccount.transferList}, {menuId: 55, parent: 50, menuName: '자금이체', menuNameEng: 'Fund Transfer',iconFilePath: '/images/menu_icon_55.svg', programPath: PATHS.additionalService.fundAccount.transferList},
{menuId: 56, parent: 50, menuName: 'KEY-IN결제', menuNameEng: '',iconFilePath: '/images/menu_icon_56.svg', programPath: PATHS.additionalService.keyInPayment.list}, {menuId: 56, parent: 50, menuName: 'KEY-IN결제', menuNameEng: 'KEY-IN Payment',iconFilePath: '/images/menu_icon_56.svg', programPath: PATHS.additionalService.keyInPayment.list},
{menuId: 57, parent: 50, menuName: 'SMS결제통보', menuNameEng: '',iconFilePath: '/images/menu_icon_57.svg', programPath: PATHS.additionalService.smsPaymentNotification}, {menuId: 57, parent: 50, menuName: 'SMS결제통보', menuNameEng: 'SMS Notification',iconFilePath: '/images/menu_icon_57.svg', programPath: PATHS.additionalService.smsPaymentNotification},
{menuId: 58, parent: 50, menuName: '알림톡결제통보', menuNameEng: '',iconFilePath: '/images/menu_icon_58.svg', programPath: PATHS.additionalService.alimtalk.list}, {menuId: 58, parent: 50, menuName: '알림톡결제통보', menuNameEng: 'Alimtalk Notification',iconFilePath: '/images/menu_icon_58.svg', programPath: PATHS.additionalService.alimtalk.list},
{menuId: 59, parent: 50, menuName: '계좌점유인증', menuNameEng: '',iconFilePath: '/images/menu_icon_59.svg', programPath: PATHS.additionalService.accountHolderAuth.list}, {menuId: 59, parent: 50, menuName: '계좌점유인증', menuNameEng: 'Account Holder Auth',iconFilePath: '/images/menu_icon_59.svg', programPath: PATHS.additionalService.accountHolderAuth.list},
{menuId: 60, parent: 50, menuName: '계좌성명조회', menuNameEng: '',iconFilePath: '/images/menu_icon_60.svg', programPath: PATHS.additionalService.accountHolderSearch.list}, {menuId: 60, parent: 50, menuName: '계좌성명조회', menuNameEng: 'Account Holder Search',iconFilePath: '/images/menu_icon_60.svg', programPath: PATHS.additionalService.accountHolderSearch.list},
{menuId: 65, parent: 50, menuName: '안면인증', menuNameEng: '',iconFilePath: '/images/menu_icon_65.svg', programPath: PATHS.additionalService.faceAuth.list}, {menuId: 65, parent: 50, menuName: '안면인증', menuNameEng: 'Face Auth',iconFilePath: '/images/menu_icon_65.svg', programPath: PATHS.additionalService.faceAuth.list},
] ]
}, },
{ {
menuId: 61, menuId: 61,
parent: 61, parent: 61,
menuName: '고객지원', menuName: '고객지원',
menuNameEng: 'Support',
iconFilePath: 'support-icon', iconFilePath: 'support-icon',
subMenu: [ subMenu: [
{menuId: 62, parent: 61, menuName: '공지사항', menuNameEng: '',iconFilePath: '/images/menu_icon_62.svg', programPath: PATHS.support.notice.list}, {menuId: 62, parent: 61, menuName: '공지사항', menuNameEng: 'Notice',iconFilePath: '/images/menu_icon_62.svg', programPath: PATHS.support.notice.list},
{menuId: 63, parent: 61, menuName: '자주묻는질문', menuNameEng: '',iconFilePath: '/images/menu_icon_63.svg', programPath: PATHS.support.faq.list}, {menuId: 63, parent: 61, menuName: '자주묻는질문', menuNameEng: 'FAQ',iconFilePath: '/images/menu_icon_63.svg', programPath: PATHS.support.faq.list},
{menuId: 64, parent: 61, menuName: '1:1문의', menuNameEng: '',iconFilePath: '/images/menu_icon_64.svg', programPath: PATHS.support.qna.list}, {menuId: 64, parent: 61, menuName: '1:1문의', menuNameEng: 'Q&A',iconFilePath: '/images/menu_icon_64.svg', programPath: PATHS.support.qna.list},
] ]
}, },
]; ];

View File

@@ -5,6 +5,8 @@ import { UserFavorite } from '@/entities/user/model/types';
import { RefObject, useEffect, useState } from 'react'; import { RefObject, useEffect, useState } from 'react';
import { useLocation } from 'react-router'; import { useLocation } from 'react-router';
import { MenuItem } from '../model/types'; import { MenuItem } from '../model/types';
import { useTranslation } from 'react-i18next';
import { MenuItems } from '@/entities/common/model/constant';
export interface MenuCategoryProps { export interface MenuCategoryProps {
menuId?: number; menuId?: number;
@@ -32,6 +34,7 @@ export const MenuCategory = ({
itemIndex itemIndex
}: MenuCategoryProps) => { }: MenuCategoryProps) => {
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const { i18n } = useTranslation();
// const location = useLocation(); // const location = useLocation();
const [favoriteItems, setFavoriteItems] = useState<Array<UserFavorite>>([]); const [favoriteItems, setFavoriteItems] = useState<Array<UserFavorite>>([]);
@@ -115,29 +118,33 @@ export const MenuCategory = ({
let rs = []; let rs = [];
if(subMenu){ if(subMenu){
for(let i=0;i<subMenu.length;i++){ for(let i=0;i<subMenu.length;i++){
const displayName = i18n.language === 'en' && subMenu[i]?.menuNameEng
? subMenu[i]?.menuNameEng
: subMenu[i]?.menuName;
if(!!editMode && subMenu[i] && subMenu[i]?.menuId){ if(!!editMode && subMenu[i] && subMenu[i]?.menuId){
rs.push( rs.push(
<li <li
key={ `menu-item-key-${menuId}-${i}` } key={ `menu-item-key-${menuId}-${i}` }
onClick={ () => onClickToNavigate(subMenu[i]?.programPath) } onClick={ () => onClickToNavigate(subMenu[i]?.programPath) }
> >
<span>{ subMenu[i]?.menuName }</span> <span>{ displayName }</span>
<div className="check_box_scrap"> <div className="check_box_scrap">
<input <input
id={ `menu-item-checkbox-${subMenu[i]?.menuId}-${i}` } id={ `menu-item-checkbox-${subMenu[i]?.menuId}-${i}` }
className="checkbox" className="checkbox"
type="checkbox" type="checkbox"
checked={ menuIds.includes(subMenu[i]?.menuId)? true: false } checked={ menuIds.includes(subMenu[i]?.menuId)? true: false }
onChange={ (e) => favoriteSetting( onChange={ (e) => favoriteSetting(
e.target.checked, e.target.checked,
subMenu[i]?.menuId, subMenu[i]?.menuId,
subMenu[i]?.menuName, subMenu[i]?.menuName,
subMenu[i]?.menuNameEng, subMenu[i]?.menuNameEng,
subMenu[i]?.iconFilePath, subMenu[i]?.iconFilePath,
subMenu[i]?.programPath, subMenu[i]?.programPath,
)} )}
/> />
<label <label
className="gtr" className="gtr"
htmlFor={ `menu-item-checkbox-${subMenu[i]?.menuId}-${i}` } htmlFor={ `menu-item-checkbox-${subMenu[i]?.menuId}-${i}` }
></label> ></label>
@@ -150,16 +157,20 @@ export const MenuCategory = ({
<li <li
key={ `menu-item-key-${i}` } key={ `menu-item-key-${i}` }
onClick={ () => onClickToNavigate(subMenu[i]?.programPath) } onClick={ () => onClickToNavigate(subMenu[i]?.programPath) }
>{ subMenu[i]?.menuName }</li> >{ displayName }</li>
); );
} }
} }
} }
return rs; return rs;
}; };
const displayCategoryName = i18n.language === 'en'
? MenuItems.find(item => item.menuId === menuId)?.menuNameEng || menuName
: menuName;
return ( return (
<> <>
<div <div
@@ -172,7 +183,7 @@ export const MenuCategory = ({
> >
<div className="category-header"> <div className="category-header">
<div className={ 'category-icon ' + iconFilePath }></div> <div className={ 'category-icon ' + iconFilePath }></div>
<span>{ menuName }</span> <span>{ displayCategoryName }</span>
</div> </div>
<ul className="category-items"> <ul className="category-items">
{ getMenuItems() } { getMenuItems() }

View File

@@ -166,5 +166,24 @@
"contents": "Contents is Required." "contents": "Contents is Required."
} }
} }
},
"slideMenu": {
"title": "Menu",
"accountManagement": "Account Management",
"profileSettings": "Profile Settings",
"changePassword": "Change Password",
"notificationSettings": "Notification Settings",
"paymentService": "Payment Service",
"paymentHistory": "Payment History",
"refundRequest": "Refund Request",
"paymentMethodManagement": "Payment Method Management",
"customerSupport": "Support",
"faq": "FAQ",
"inquiry": "Q&A",
"termsOfService": "Terms of Service",
"other": "Other",
"appInfo": "App Info",
"developerInfo": "Developer Info",
"logout": "Logout"
} }
} }

View File

@@ -171,5 +171,24 @@
"contents": "문의내용은 필수 항목 입니다." "contents": "문의내용은 필수 항목 입니다."
} }
} }
},
"slideMenu": {
"title": "메뉴",
"accountManagement": "계정 관리",
"profileSettings": "프로필 설정",
"changePassword": "비밀번호 변경",
"notificationSettings": "알림 설정",
"paymentService": "결제 서비스",
"paymentHistory": "결제 내역",
"refundRequest": "환불 요청",
"paymentMethodManagement": "결제 방법 관리",
"customerSupport": "고객 지원",
"faq": "FAQ",
"inquiry": "1:1 문의",
"termsOfService": "이용약관",
"other": "기타",
"appInfo": "앱 정보",
"developerInfo": "개발자 정보",
"logout": "로그아웃"
} }
} }