부가세 신고 페이지 및 컴포넌트 다국어화 완료

- 부가세 신고 페이지 다국어화 (3개 페이지)
  * 조회 페이지: 헤더 타이틀, 탭, 검색/다운로드
  * 상세 페이지: 세금계산서 상세 정보
  * 참조번호 발급 페이지: 신청 완료/실패 메시지
- 부가세 엔티티 컴포넌트 다국어화 (11개 컴포넌트)
  * vat-return-tab: 세금계산서/부가세참고 탭
  * list-wrap: 조회 페이지 래퍼
  * list-item: 거래 항목 (통화 표기 포함)
  * reference-wrap: 참조 자료 신청
  * reference-request-success/fail: 신청 결과
  * list-detail-bottom-sheet: 상세 내역 (10개 통화 인스턴스)
- 섹션 컴포넌트 다국어화 (4개)
  * amount-section: 금액 상세 (공급가액, VAT, 합계금액)
  * issue-section: 발행 정보 (발행대상일자, 적요 등)
  * supplier-section: 공급자 정보
  * receiver-section: 공급받는 자 정보
- 통화 표기 통일 (10개 인스턴스)
  * 한국어: 1,000원 (suffix)
  * 영어: ₩1,000 (prefix)
- 번역 키 추가: vatReturn 네임스페이스 29개 키
- 기존 번역 키 재사용 (merchant, transaction, common, home)

🤖 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-30 09:25:50 +09:00
parent 04fc07cfe5
commit bc1540ca04
16 changed files with 234 additions and 129 deletions

View File

@@ -5,6 +5,7 @@ import { NumericFormat } from "react-number-format";
import { SlideDown } from 'react-slidedown'; import { SlideDown } from 'react-slidedown';
import 'react-slidedown/lib/slidedown.css'; import 'react-slidedown/lib/slidedown.css';
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useTranslation } from 'react-i18next';
export interface VatReturnListDetailBottomSheetProps { export interface VatReturnListDetailBottomSheetProps {
bottomSheetOn: boolean; bottomSheetOn: boolean;
@@ -25,7 +26,7 @@ export const VatReturnListDetailBottomSheet = ({
vatAmount, vatAmount,
totalAmount totalAmount
}: VatReturnListDetailBottomSheetProps) => { }: VatReturnListDetailBottomSheetProps) => {
const { t, i18n } = useTranslation();
const [isOpenDetail, setIsOpenDetail] = useState<Array<boolean>>([]); const [isOpenDetail, setIsOpenDetail] = useState<Array<boolean>>([]);
const onClickToClose = () => { const onClickToClose = () => {
@@ -48,14 +49,14 @@ export const VatReturnListDetailBottomSheet = ({
<div className="bottomsheet"> <div className="bottomsheet">
<div className="bottomsheet-header"> <div className="bottomsheet-header">
<div className="bottomsheet-title"> <div className="bottomsheet-title">
<h2> </h2> <h2>{t('vatReturn.viewDetails')}</h2>
<button <button
className="close-btn" className="close-btn"
type="button" type="button"
> >
<img <img
src={ IMAGE_ROOT +'/ico_close.svg' } src={ IMAGE_ROOT +'/ico_close.svg' }
alt="닫기" alt={t('common.close')}
onClick={ onClickToClose } onClick={ onClickToClose }
/> />
</button> </button>
@@ -66,46 +67,50 @@ export const VatReturnListDetailBottomSheet = ({
<div className="tax-detail-accordion"> <div className="tax-detail-accordion">
<div className="summary"> <div className="summary">
<div className="row"> <div className="row">
<div className="label desc dot"> :</div> <div className="label desc dot">{t('vatReturn.transactionAmount')} :</div>
<div className="value"> <div className="value">
<NumericFormat <NumericFormat
value={ transactionAmount } value={ transactionAmount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
suffix='원' prefix={i18n.language === 'en' ? t('home.currencySymbol') : ''}
suffix={i18n.language === 'en' ? '' : t('home.currencyWon')}
></NumericFormat> ></NumericFormat>
</div> </div>
</div> </div>
<div className="row"> <div className="row">
<div className="label desc dot"> :</div> <div className="label desc dot">{t('vatReturn.supplyAmount')} :</div>
<div className="value"> <div className="value">
<NumericFormat <NumericFormat
value={ supplyAmount } value={ supplyAmount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
suffix='원' prefix={i18n.language === 'en' ? t('home.currencySymbol') : ''}
suffix={i18n.language === 'en' ? '' : t('home.currencyWon')}
></NumericFormat> ></NumericFormat>
</div> </div>
</div> </div>
<div className="row"> <div className="row">
<div className="label desc dot">VAT :</div> <div className="label desc dot">{t('vatReturn.vat')} :</div>
<div className="value"> <div className="value">
<NumericFormat <NumericFormat
value={ vatAmount } value={ vatAmount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
suffix='원' prefix={i18n.language === 'en' ? t('home.currencySymbol') : ''}
suffix={i18n.language === 'en' ? '' : t('home.currencyWon')}
></NumericFormat> ></NumericFormat>
</div> </div>
</div> </div>
<div className="row"> <div className="row">
<div className="label desc dot"> :</div> <div className="label desc dot">{t('vatReturn.totalAmount')} :</div>
<div className="value"> <div className="value">
<NumericFormat <NumericFormat
value={ totalAmount } value={ totalAmount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
suffix='원' prefix={i18n.language === 'en' ? t('home.currencySymbol') : ''}
suffix={i18n.language === 'en' ? '' : t('home.currencyWon')}
></NumericFormat> ></NumericFormat>
</div> </div>
</div> </div>
@@ -113,8 +118,8 @@ export const VatReturnListDetailBottomSheet = ({
{ breakdown && breakdown.length > 0 && { breakdown && breakdown.length > 0 &&
<div className="list"> <div className="list">
<div className="list-header"> <div className="list-header">
<div className="head-date"></div> <div className="head-date">{t('vatReturn.transactionDate')}</div>
<div className="head-amount"></div> <div className="head-amount">{t('vatReturn.totalAmount')}</div>
</div> </div>
{ {
breakdown.map((value, index) => ( breakdown.map((value, index) => (
@@ -128,7 +133,8 @@ export const VatReturnListDetailBottomSheet = ({
value={ value.totalAmount } value={ value.totalAmount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
suffix='원' prefix={i18n.language === 'en' ? t('home.currencySymbol') : ''}
suffix={i18n.language === 'en' ? '' : t('home.currencyWon')}
></NumericFormat> ></NumericFormat>
</span> </span>
<img <img
@@ -142,9 +148,9 @@ export const VatReturnListDetailBottomSheet = ({
{ isOpenDetail[index] && { isOpenDetail[index] &&
<div className="item item-detail"> <div className="item item-detail">
<div className="labels"> <div className="labels">
<span></span> <span>{t('vatReturn.transactionAmount')}</span>
<span></span> <span>{t('vatReturn.supplyAmount')}</span>
<span>VAT</span> <span>{t('vatReturn.vat')}</span>
</div> </div>
<div className="values"> <div className="values">
<span> <span>
@@ -152,7 +158,8 @@ export const VatReturnListDetailBottomSheet = ({
value={ value.transactionAmount } value={ value.transactionAmount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
suffix='원' prefix={i18n.language === 'en' ? t('home.currencySymbol') : ''}
suffix={i18n.language === 'en' ? '' : t('home.currencyWon')}
></NumericFormat> ></NumericFormat>
</span> </span>
<span> <span>
@@ -160,7 +167,8 @@ export const VatReturnListDetailBottomSheet = ({
value={ value.supplyAmount } value={ value.supplyAmount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
suffix='원' prefix={i18n.language === 'en' ? t('home.currencySymbol') : ''}
suffix={i18n.language === 'en' ? '' : t('home.currencyWon')}
></NumericFormat> ></NumericFormat>
</span> </span>
<span> <span>
@@ -168,7 +176,8 @@ export const VatReturnListDetailBottomSheet = ({
value={ value.vatAmount } value={ value.vatAmount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
suffix='원' prefix={i18n.language === 'en' ? t('home.currencySymbol') : ''}
suffix={i18n.language === 'en' ? '' : t('home.currencyWon')}
></NumericFormat> ></NumericFormat>
</span> </span>
</div> </div>

View File

@@ -1,4 +1,5 @@
import { NumericFormat } from 'react-number-format'; import { NumericFormat } from 'react-number-format';
import { useTranslation } from 'react-i18next';
import { PATHS } from '@/shared/constants/paths'; import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { ListItemProps } from '../model/types'; import { ListItemProps } from '../model/types';
@@ -12,6 +13,7 @@ export const ListItem = ({
paymentMethod, paymentMethod,
amount amount
}: ListItemProps) => { }: ListItemProps) => {
const { t, i18n } = useTranslation();
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const onClickToNavigate = () => { const onClickToNavigate = () => {
@@ -44,7 +46,8 @@ export const ListItem = ({
value={ amount } value={ amount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
suffix='원' prefix={i18n.language === 'en' ? t('home.currencySymbol') : ''}
suffix={i18n.language === 'en' ? '' : t('home.currencyWon')}
></NumericFormat> ></NumericFormat>
</div> </div>
</div> </div>

View File

@@ -1,5 +1,6 @@
import moment from 'moment'; import moment from 'moment';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { IMAGE_ROOT } from '@/shared/constants/common'; import { IMAGE_ROOT } from '@/shared/constants/common';
import { ListFilter } from './filter/list-filter'; import { ListFilter } from './filter/list-filter';
import { SortTypeBox } from '@/entities/common/ui/sort-type-box'; import { SortTypeBox } from '@/entities/common/ui/sort-type-box';
@@ -19,6 +20,7 @@ import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
import useIntersectionObserver from '@/widgets/intersection-observer'; import useIntersectionObserver from '@/widgets/intersection-observer';
export const ListWrap = () => { export const ListWrap = () => {
const { t } = useTranslation();
const userMid = useStore.getState().UserStore.mid; const userMid = useStore.getState().UserStore.mid;
const [onActionIntersect, setOnActionIntersect] = useState<boolean>(false); const [onActionIntersect, setOnActionIntersect] = useState<boolean>(false);
@@ -181,14 +183,14 @@ export const ListWrap = () => {
> >
<img <img
src={ IMAGE_ROOT + '/ico_setting.svg' } src={ IMAGE_ROOT + '/ico_setting.svg' }
alt="검색옵션" alt={t('transaction.searchOptions')}
/> />
</button> </button>
</div> </div>
<button className="download-btn"> <button className="download-btn">
<img <img
src={ IMAGE_ROOT + '/ico_download.svg' } src={ IMAGE_ROOT + '/ico_download.svg' }
alt="다운로드" alt={t('transaction.download')}
onClick={ onClickToDownloadExcel } onClick={ onClickToDownloadExcel }
/> />
</button> </button>

View File

@@ -1,4 +1,5 @@
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { useTranslation } from 'react-i18next';
import { import {
FilterMotionDuration, FilterMotionDuration,
FilterMotionStyle, FilterMotionStyle,
@@ -16,6 +17,7 @@ export const ReferenceRequestFail = ({
setPageOn, setPageOn,
errorMsg errorMsg
}: ReferenceRequestFailProps) => { }: ReferenceRequestFailProps) => {
const { t } = useTranslation();
const onClickToClose = () => { const onClickToClose = () => {
setPageOn(false); setPageOn(false);
}; };
@@ -40,13 +42,13 @@ export const ReferenceRequestFail = ({
aria-hidden="true" aria-hidden="true"
></div> ></div>
<h1 className="success-title"> <h1 className="success-title">
<span> </span> <span>{t('vatReturn.vatReferenceData')}</span>
<br/> <br/>
<span> </span> <span>{t('vatReturn.requestFailed')}</span>
</h1> </h1>
<div className="success-result"> <div className="success-result">
<p className="result-text align-left position_label"> <p className="result-text align-left position_label">
<span> :</span> <span>{t('vatReturn.result')} :</span>
<span>{ errorMsg }</span> <span>{ errorMsg }</span>
</p> </p>
</div> </div>
@@ -55,7 +57,7 @@ export const ReferenceRequestFail = ({
<button <button
className="btn-50 btn-blue flex-1" className="btn-50 btn-blue flex-1"
onClick={ onClickToClose } onClick={ onClickToClose }
></button> >{t('common.confirm')}</button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,4 +1,5 @@
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { useTranslation } from 'react-i18next';
import { import {
FilterMotionDuration, FilterMotionDuration,
FilterMotionStyle, FilterMotionStyle,
@@ -19,6 +20,7 @@ export const ReferenceRequestSuccess = ({
email, email,
startDate startDate
}: ReferenceRequestSuccessProps) => { }: ReferenceRequestSuccessProps) => {
const { t } = useTranslation();
const onClickToClose = () => { const onClickToClose = () => {
setPageOn(false); setPageOn(false);
}; };
@@ -39,25 +41,25 @@ export const ReferenceRequestSuccess = ({
> >
<div className="success-icon" aria-hidden="true"></div> <div className="success-icon" aria-hidden="true"></div>
<h1 className="success-title"> <h1 className="success-title">
<span> </span> <span>{t('vatReturn.vatReferenceData')}</span>
<br/> <br/>
<span> .</span> <span>{t('vatReturn.requestCompleted')}</span>
</h1> </h1>
<p className="success-subtitle"> .</p> <p className="success-subtitle">{t('vatReturn.fileProvidedBySelectedMethod')}</p>
<div className="success-result"> <div className="success-result">
<p className="result-text"> <p className="result-text">
<span> :</span> <span>{ moment(startDate).format('YYYY.MM.DD') }</span> <span>{t('vatReturn.applicationDate')} :</span> <span>{ moment(startDate).format('YYYY.MM.DD') }</span>
<br/> <br/>
<span> :</span> <span>{ email }</span> <span>{t('vatReturn.emailAddress')} :</span> <span>{ email }</span>
</p> </p>
</div> </div>
<p className="success-note dot"> <br/> .</p> <p className="success-note dot">{t('vatReturn.referenceDataNote')}</p>
</div> </div>
<div className="apply-row"> <div className="apply-row">
<button <button
className="btn-50 btn-blue flex-1" className="btn-50 btn-blue flex-1"
onClick={ onClickToClose } onClick={ onClickToClose }
></button> >{t('common.confirm')}</button>
</div> </div>
</div> </div>
</motion.div> </motion.div>

View File

@@ -1,5 +1,6 @@
import moment from 'moment'; import moment from 'moment';
import { useState } from 'react'; import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { FilterCalendar } from '@/shared/ui/filter/calendar'; import { FilterCalendar } from '@/shared/ui/filter/calendar';
import { FilterSelect } from '@/shared/ui/filter/select'; import { FilterSelect } from '@/shared/ui/filter/select';
import { ReferenceRequestSuccess } from './reference-request-success'; import { ReferenceRequestSuccess } from './reference-request-success';
@@ -11,6 +12,7 @@ import { useStore } from '@/shared/model/store';
import { useVatReturnReferenceRequestMutation } from '../api/use-vat-return-reference-request-mutation'; import { useVatReturnReferenceRequestMutation } from '../api/use-vat-return-reference-request-mutation';
export const ReferenceWrap = () => { export const ReferenceWrap = () => {
const { t } = useTranslation();
const midOptions = useStore.getState().UserStore.selectOptionsMids; const midOptions = useStore.getState().UserStore.selectOptionsMids;
const emailOptions = useStore.getState().UserStore.selectOptionsEmails; const emailOptions = useStore.getState().UserStore.selectOptionsEmails;
const userMid = useStore.getState().UserStore.mid; const userMid = useStore.getState().UserStore.mid;
@@ -48,13 +50,13 @@ export const ReferenceWrap = () => {
<> <>
<div className="option-list no-padding pt-30"> <div className="option-list no-padding pt-30">
<FilterSelect <FilterSelect
title='가맹점' title={t('merchant.title')}
selectValue={ mid } selectValue={ mid }
selectSetter={ setMid } selectSetter={ setMid }
selectOptions={ midOptions } selectOptions={ midOptions }
></FilterSelect> ></FilterSelect>
<FilterButtonGroups <FilterButtonGroups
title='거래 과세/면세 구분' title={t('vatReturn.taxExemptionType')}
activeValue={ payTax } activeValue={ payTax }
btnGroups={ VatReturnTaxBtnGroups } btnGroups={ VatReturnTaxBtnGroups }
setter={ setPayTax } setter={ setPayTax }
@@ -62,14 +64,14 @@ export const ReferenceWrap = () => {
maxBtn={ 2 } maxBtn={ 2 }
></FilterButtonGroups> ></FilterButtonGroups>
<FilterCalendar <FilterCalendar
title='거래기간' title={t('vatReturn.transactionPeriod')}
startDate={ startDate } startDate={ startDate }
endDate={ endDate } endDate={ endDate }
setStartDate={ setStartDate } setStartDate={ setStartDate }
setEndDate={ setEndDate } setEndDate={ setEndDate }
></FilterCalendar> ></FilterCalendar>
<FilterSelect <FilterSelect
title='수령메일주소' title={t('vatReturn.receivingEmail')}
selectValue={ email } selectValue={ email }
selectSetter={ setEmail } selectSetter={ setEmail }
selectOptions={ emailOptions } selectOptions={ emailOptions }
@@ -79,7 +81,7 @@ export const ReferenceWrap = () => {
<button <button
className="btn-50 btn-blue flex-1" className="btn-50 btn-blue flex-1"
onClick={ onClickToResquest } onClick={ onClickToResquest }
></button> >{t('vatReturn.requestData')}</button>
</div> </div>
<ReferenceRequestSuccess <ReferenceRequestSuccess
pageOn={ successPageOn } pageOn={ successPageOn }

View File

@@ -1,4 +1,5 @@
import moment from 'moment'; import moment from 'moment';
import { useTranslation } from 'react-i18next';
import { VatReturnDetailResponse } from '../../model/types'; import { VatReturnDetailResponse } from '../../model/types';
import { SectionTitleArrow } from '@/entities/common/ui/section-title-arrow'; import { SectionTitleArrow } from '@/entities/common/ui/section-title-arrow';
import { NumericFormat } from 'react-number-format'; import { NumericFormat } from 'react-number-format';
@@ -14,6 +15,7 @@ export interface AmountSectionProps {
export const AmountSection = ({ export const AmountSection = ({
detail detail
}: AmountSectionProps) => { }: AmountSectionProps) => {
const { t, i18n } = useTranslation();
const [isOpen, setIsOpen] = useState<boolean>(false); const [isOpen, setIsOpen] = useState<boolean>(false);
const [downloadBottomSheetOn, setDownloadBottomSheetOn] = useState<boolean>(false); const [downloadBottomSheetOn, setDownloadBottomSheetOn] = useState<boolean>(false);
@@ -35,19 +37,20 @@ export const AmountSection = ({
<div className="txn-num-group"> <div className="txn-num-group">
<div className="txn-amount"> <div className="txn-amount">
<div className="value"> <div className="value">
{i18n.language === 'en' && <span>{t('home.currencySymbol')}</span>}
<NumericFormat <NumericFormat
value={ detail.totalAmount } value={ detail.totalAmount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
></NumericFormat> ></NumericFormat>
<span className="unit"></span> <span className="unit">{i18n.language === 'en' ? '' : t('home.currencyWon')}</span>
</div> </div>
<button <button
className="chip-btn" className="chip-btn"
type="button" type="button"
onClick={ () => openSection() } onClick={ () => openSection() }
> >
<span></span> <SectionTitleArrow isOpen={ isOpen }></SectionTitleArrow> <span>{t('vatReturn.amountDetail')}</span> <SectionTitleArrow isOpen={ isOpen }></SectionTitleArrow>
</button> </button>
</div> </div>
<SlideDown className={'my-dropdown-slidedown'}> <SlideDown className={'my-dropdown-slidedown'}>
@@ -55,24 +58,26 @@ export const AmountSection = ({
<div className="amount-expand"> <div className="amount-expand">
<ul className="amount-list"> <ul className="amount-list">
<li className="amount-item"> <li className="amount-item">
<span className="label">·&nbsp;&nbsp;</span> <span className="label">·&nbsp;&nbsp;{t('vatReturn.supplyAmount')}</span>
<span className="value"> <span className="value">
<NumericFormat <NumericFormat
value={ detail.supplyAmount } value={ detail.supplyAmount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
suffix='원' prefix={i18n.language === 'en' ? t('home.currencySymbol') : ''}
suffix={i18n.language === 'en' ? '' : t('home.currencyWon')}
></NumericFormat> ></NumericFormat>
</span> </span>
</li> </li>
<li className="amount-item"> <li className="amount-item">
<span className="label">·&nbsp;&nbsp;VAT</span> <span className="label">·&nbsp;&nbsp;{t('vatReturn.vat')}</span>
<span className="value"> <span className="value">
<NumericFormat <NumericFormat
value={ detail.vatAmount } value={ detail.vatAmount }
thousandSeparator thousandSeparator
displayType="text" displayType="text"
suffix='원' prefix={i18n.language === 'en' ? t('home.currencySymbol') : ''}
suffix={i18n.language === 'en' ? '' : t('home.currencyWon')}
></NumericFormat> ></NumericFormat>
</span> </span>
</li> </li>
@@ -95,7 +100,7 @@ export const AmountSection = ({
className="doc-btn" className="doc-btn"
type="button" type="button"
onClick={ onClickToOpenDownloadBottomSheet } onClick={ onClickToOpenDownloadBottomSheet }
></button> >{t('vatReturn.taxInvoice')}</button>
</div> </div>
</div> </div>
{ !!downloadBottomSheetOn && { !!downloadBottomSheetOn &&

View File

@@ -1,4 +1,5 @@
import moment from 'moment'; import moment from 'moment';
import { useTranslation } from 'react-i18next';
import { VatReturnDetailResponse } from '../../model/types'; import { VatReturnDetailResponse } from '../../model/types';
export interface IssueSectionProps { export interface IssueSectionProps {
@@ -8,18 +9,19 @@ export interface IssueSectionProps {
export const IssueSection = ({ export const IssueSection = ({
detail detail
}: IssueSectionProps) => { }: IssueSectionProps) => {
const { t } = useTranslation();
return ( return (
<> <>
<div className="txn-section"> <div className="txn-section">
<div className="section-title"> </div> <div className="section-title">{t('vatReturn.issueInfo')}</div>
<ul className="kv-list"> <ul className="kv-list">
<li className="kv-row"> <li className="kv-row">
<span className="k">MID</span> <span className="k">MID</span>
<span className="v">{ detail.mid }</span> <span className="v">{ detail.mid }</span>
</li> </li>
<li className="kv-row"> <li className="kv-row">
<span className="k"></span> <span className="k">{t('vatReturn.issueTargetDate')}</span>
<span className="v"> <span className="v">
{ !!detail.targetBusinessStartDate && !!detail.targetBusinessEndDate && { !!detail.targetBusinessStartDate && !!detail.targetBusinessEndDate &&
moment(detail.targetBusinessStartDate).format('YYYY.MM.DD') moment(detail.targetBusinessStartDate).format('YYYY.MM.DD')
@@ -31,7 +33,7 @@ export const IssueSection = ({
</span> </span>
</li> </li>
<li className="kv-row"> <li className="kv-row">
<span className="k"></span> <span className="k">{t('vatReturn.issueDate')}</span>
<span className="v"> <span className="v">
{ !!detail.issueDate && { !!detail.issueDate &&
moment(detail.issueDate).format('YYYY.MM.DD') moment(detail.issueDate).format('YYYY.MM.DD')
@@ -39,15 +41,15 @@ export const IssueSection = ({
</span> </span>
</li> </li>
<li className="kv-row"> <li className="kv-row">
<span className="k"></span> <span className="k">{t('vatReturn.subject')}</span>
<span className="v">{ detail.subject }</span> <span className="v">{ detail.subject }</span>
</li> </li>
<li className="kv-row"> <li className="kv-row">
<span className="k"></span> <span className="k">{t('vatReturn.issueTarget')}</span>
<span className="v">{ detail.targetType }</span> <span className="v">{ detail.targetType }</span>
</li> </li>
<li className="kv-row"> <li className="kv-row">
<span className="k"></span> <span className="k">{t('vatReturn.receiptType')}</span>
<span className="v">{ detail.receiptType }</span> <span className="v">{ detail.receiptType }</span>
</li> </li>
<li className="kv-row"> <li className="kv-row">

View File

@@ -1,3 +1,4 @@
import { useTranslation } from 'react-i18next';
import { VatReturnDetailResponse } from '../../model/types'; import { VatReturnDetailResponse } from '../../model/types';
export interface ReceiverSectionProps { export interface ReceiverSectionProps {
@@ -7,23 +8,24 @@ export interface ReceiverSectionProps {
export const ReceiverSection = ({ export const ReceiverSection = ({
detail detail
}: ReceiverSectionProps) => { }: ReceiverSectionProps) => {
const { t } = useTranslation();
return ( return (
<> <>
<div className="txn-section"> <div className="txn-section">
<div className="section-title"> </div> <div className="section-title">{t('vatReturn.receiverInfo')}</div>
</div> </div>
<ul className="kv-list"> <ul className="kv-list">
<li className="kv-row"> <li className="kv-row">
<span className="k"></span> <span className="k">{t('merchant.businessRegistrationNumber')}</span>
<span className="v">{ detail.receiverBusinessRegistrationNumber }</span> <span className="v">{ detail.receiverBusinessRegistrationNumber }</span>
</li> </li>
<li className="kv-row"> <li className="kv-row">
<span className="k"></span> <span className="k">{t('merchant.companyName')}</span>
<span className="v">{ detail.receiverCompanyName }</span> <span className="v">{ detail.receiverCompanyName }</span>
</li> </li>
<li className="kv-row"> <li className="kv-row">
<span className="k"></span> <span className="k">{t('merchant.representativeName')}</span>
<span className="v">{ detail.receiverCeoName }</span> <span className="v">{ detail.receiverCeoName }</span>
</li> </li>
</ul> </ul>

View File

@@ -1,3 +1,4 @@
import { useTranslation } from 'react-i18next';
import { VatReturnDetailResponse } from '../../model/types'; import { VatReturnDetailResponse } from '../../model/types';
export interface SupplierSectionProps { export interface SupplierSectionProps {
@@ -7,23 +8,24 @@ export interface SupplierSectionProps {
export const SupplierSection = ({ export const SupplierSection = ({
detail detail
}: SupplierSectionProps) => { }: SupplierSectionProps) => {
const { t } = useTranslation();
return ( return (
<> <>
<div className="txn-section"> <div className="txn-section">
<div className="section-title"> </div> <div className="section-title">{t('vatReturn.supplierInfo')}</div>
</div> </div>
<ul className="kv-list"> <ul className="kv-list">
<li className="kv-row"> <li className="kv-row">
<span className="k"></span> <span className="k">{t('merchant.businessRegistrationNumber')}</span>
<span className="v">{ detail.supplierBusinessRegistrationNumber }</span> <span className="v">{ detail.supplierBusinessRegistrationNumber }</span>
</li> </li>
<li className="kv-row"> <li className="kv-row">
<span className="k"></span> <span className="k">{t('merchant.companyName')}</span>
<span className="v">{ detail.supplierCompanyName }</span> <span className="v">{ detail.supplierCompanyName }</span>
</li> </li>
<li className="kv-row"> <li className="kv-row">
<span className="k"></span> <span className="k">{t('merchant.representativeName')}</span>
<span className="v">{ detail.supplierCeoName }</span> <span className="v">{ detail.supplierCeoName }</span>
</li> </li>
</ul> </ul>

View File

@@ -1,3 +1,4 @@
import { useTranslation } from 'react-i18next';
import { PATHS } from '@/shared/constants/paths'; import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { import {
@@ -8,6 +9,7 @@ import {
export const VatReturnTab = ({ export const VatReturnTab = ({
activeTab activeTab
}: VatReturnTabProps) => { }: VatReturnTabProps) => {
const { t } = useTranslation();
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const onClickToNavigation = (tab: VatReturnTabKeys) => { const onClickToNavigation = (tab: VatReturnTabKeys) => {
@@ -26,11 +28,11 @@ export const VatReturnTab = ({
<button <button
className={`subtab-btn ${(activeTab === VatReturnTabKeys.List)? 'active': ''}` } className={`subtab-btn ${(activeTab === VatReturnTabKeys.List)? 'active': ''}` }
onClick={ () => onClickToNavigation(VatReturnTabKeys.List) } onClick={ () => onClickToNavigation(VatReturnTabKeys.List) }
> </button> >{t('vatReturn.taxInvoice')}</button>
<button <button
className={`subtab-btn ${(activeTab === VatReturnTabKeys.VatReference)? 'active': ''}` } className={`subtab-btn ${(activeTab === VatReturnTabKeys.VatReference)? 'active': ''}` }
onClick={ () => onClickToNavigation(VatReturnTabKeys.VatReference) } onClick={ () => onClickToNavigation(VatReturnTabKeys.VatReference) }
> </button> >{t('vatReturn.vatReference')}</button>
</div> </div>
</> </>
); );

View File

@@ -190,8 +190,8 @@
}, },
"account": { "account": {
"title": "Account Management", "title": "Account Management",
"userManagement": "User Management", "userManagement": "Users",
"passwordManagement": "Password Management", "passwordManagement": "Passwords",
"userSettings": "User Settings", "userSettings": "User Settings",
"addUser": "Add User", "addUser": "Add User",
"addAccount": "Add Account", "addAccount": "Add Account",
@@ -491,6 +491,39 @@
"faceAuth": { "faceAuth": {
"title": "Face Authentication" "title": "Face Authentication"
}, },
"vatReturn": {
"title": "VAT Return Data",
"taxInvoice": "Tax Invoice",
"vatReference": "VAT Reference",
"taxInvoiceDetail": "Tax Invoice Details",
"viewDetails": "View Details",
"transactionAmount": "Transaction Amount",
"supplyAmount": "Supply Amount",
"vat": "VAT",
"totalAmount": "Total Amount",
"transactionDate": "Transaction Date",
"amountDetail": "Amount Details",
"issueInfo": "Issue Information",
"issueTargetDate": "Issue Target Date",
"issueDate": "Issue Date",
"subject": "Subject",
"issueTarget": "Issue Target",
"receiptType": "Receipt Type",
"supplierInfo": "Supplier Information",
"receiverInfo": "Receiver Information",
"taxExemptionType": "Tax/Exemption Type",
"transactionPeriod": "Transaction Period",
"receivingEmail": "Receiving Email",
"requestData": "Request Data",
"vatReferenceData": "VAT Reference Data",
"requestCompleted": "Request completed.",
"requestFailed": "Request failed",
"fileProvidedBySelectedMethod": "The file will be provided by the selected method.",
"applicationDate": "Application Date",
"emailAddress": "Email Address",
"referenceDataNote": "Please compare with internal accounting data\nbefore using this reference material.",
"result": "Result"
},
"common": { "common": {
"latest": "Latest", "latest": "Latest",
"oldest": "Oldest" "oldest": "Oldest"

View File

@@ -495,6 +495,39 @@
"faceAuth": { "faceAuth": {
"title": "안면인증" "title": "안면인증"
}, },
"vatReturn": {
"title": "부가세 신고 자료",
"taxInvoice": "세금 계산서",
"vatReference": "부가세 참고",
"taxInvoiceDetail": "세금계산서 상세",
"viewDetails": "세부내역 조회",
"transactionAmount": "거래금액",
"supplyAmount": "공급가액",
"vat": "VAT",
"totalAmount": "합계금액",
"transactionDate": "거래일",
"amountDetail": "금액상세",
"issueInfo": "발행 정보",
"issueTargetDate": "발행대상일자",
"issueDate": "발행일자",
"subject": "적요",
"issueTarget": "발행대상",
"receiptType": "영수구분",
"supplierInfo": "공급자 정보",
"receiverInfo": "공급받는 자 정보",
"taxExemptionType": "거래 과세/면세 구분",
"transactionPeriod": "거래기간",
"receivingEmail": "수령메일주소",
"requestData": "자료신청",
"vatReferenceData": "부가세 참고 자료",
"requestCompleted": "신청이 완료되었습니다.",
"requestFailed": "신청 실패하였습니다",
"fileProvidedBySelectedMethod": "파일은 선택한 수령 방법으로 제공됩니다.",
"applicationDate": "신청일",
"emailAddress": "메일주소",
"referenceDataNote": "참고용 자료이므로 반드시 내부 회계자료 등과\n비교 후 사용해 주세요.",
"result": "결과"
},
"common": { "common": {
"latest": "최신순", "latest": "최신순",
"oldest": "오래된순" "oldest": "오래된순"

View File

@@ -1,4 +1,5 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { PATHS } from '@/shared/constants/paths'; import { PATHS } from '@/shared/constants/paths';
import { useLocation } from 'react-router'; import { useLocation } from 'react-router';
import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { useNavigate } from '@/shared/lib/hooks/use-navigate';
@@ -26,6 +27,7 @@ import { VatReturnListDetailBottomSheet } from '@/entities/vat-return/ui/list-de
import { useVatReturnBreakdownMutation } from '@/entities/vat-return/api/use-vat-return-breakdown-mutation'; import { useVatReturnBreakdownMutation } from '@/entities/vat-return/api/use-vat-return-breakdown-mutation';
export const DetailPage = () => { export const DetailPage = () => {
const { t } = useTranslation();
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const location = useLocation(); const location = useLocation();
@@ -37,7 +39,7 @@ export const DetailPage = () => {
const [detail, setDetail] = useState<VatReturnDetailResponse>({}); const [detail, setDetail] = useState<VatReturnDetailResponse>({});
const [breakdown, setBreakdown] = useState<Array<Breakdown>>([]); const [breakdown, setBreakdown] = useState<Array<Breakdown>>([]);
useSetHeaderTitle('세금계산서 상세'); useSetHeaderTitle(t('vatReturn.taxInvoiceDetail'));
useSetHeaderType(HeaderType.RightClose); useSetHeaderType(HeaderType.RightClose);
useSetOnBack(() => { useSetOnBack(() => {
navigate(PATHS.vatReturn.list); navigate(PATHS.vatReturn.list);
@@ -103,7 +105,7 @@ export const DetailPage = () => {
<button <button
className="btn-50 btn-blue flex-1" className="btn-50 btn-blue flex-1"
onClick={ onClickToOpenBottomSheet } onClick={ onClickToOpenBottomSheet }
> </button> >{t('vatReturn.viewDetails')}</button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,4 +1,5 @@
import { useState } from 'react'; import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { PATHS } from '@/shared/constants/paths'; import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { VatReturnTab } from '@/entities/vat-return/ui/vat-return-tab'; import { VatReturnTab } from '@/entities/vat-return/ui/vat-return-tab';
@@ -13,11 +14,12 @@ import {
} from '@/widgets/sub-layout/use-sub-layout'; } from '@/widgets/sub-layout/use-sub-layout';
export const ListPage = () => { export const ListPage = () => {
const { t } = useTranslation();
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const [activeTab, setActiveTab] = useState<VatReturnTabKeys>(VatReturnTabKeys.List); const [activeTab, setActiveTab] = useState<VatReturnTabKeys>(VatReturnTabKeys.List);
useSetHeaderTitle('부가세 신고 자료'); useSetHeaderTitle(t('vatReturn.title'));
useSetHeaderType(HeaderType.LeftArrow); useSetHeaderType(HeaderType.LeftArrow);
useSetFooterMode(false); useSetFooterMode(false);
useSetOnBack(() => { useSetOnBack(() => {

View File

@@ -1,4 +1,5 @@
import { useState } from 'react'; import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { PATHS } from '@/shared/constants/paths'; import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { VatReturnTab } from '@/entities/vat-return/ui/vat-return-tab'; import { VatReturnTab } from '@/entities/vat-return/ui/vat-return-tab';
@@ -13,11 +14,12 @@ import {
} from '@/widgets/sub-layout/use-sub-layout'; } from '@/widgets/sub-layout/use-sub-layout';
export const ReferencePage = () => { export const ReferencePage = () => {
const { t } = useTranslation();
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const [activeTab, setActiveTab] = useState<VatReturnTabKeys>(VatReturnTabKeys.VatReference); const [activeTab, setActiveTab] = useState<VatReturnTabKeys>(VatReturnTabKeys.VatReference);
useSetHeaderTitle('부가세 신고 자료'); useSetHeaderTitle(t('vatReturn.title'));
useSetHeaderType(HeaderType.LeftArrow); useSetHeaderType(HeaderType.LeftArrow);
useSetFooterMode(false); useSetFooterMode(false);
useSetOnBack(() => { useSetOnBack(() => {