diff --git a/package.json b/package.json index d045e93..7d1e31e 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,12 @@ "antd": "^4.20.1", "axios": "^0.27.2", "eslint-plugin-react-hooks": "^4.5.0-next-bd4784c8f-20220425", + "i18next": "^21.8.8", "lodash": "^4.17.21", "moment": "^2.29.3", "react": "^18.0.0", "react-dom": "^18.0.0", + "react-i18next": "^11.17.0", "react-json-formatter": "^0.2.1", "react-redux": "^8.0.1", "react-router-dom": "6", diff --git a/src/i18n/index.js b/src/i18n/index.js new file mode 100644 index 0000000..4dd8804 --- /dev/null +++ b/src/i18n/index.js @@ -0,0 +1,29 @@ +import i18n from 'i18next' +import { initReactI18next } from 'react-i18next' +import { button, form, validate, message } from './ko' + +// the translations +// (tip move them in a JSON file and import them, +// or even better, manage them separated from your code: https://react.i18next.com/guides/multiple-translation-files) +const resources = { + ko: { + translation: { + button, + form, + validate, + message + } + } +} + +i18n + .use(initReactI18next) // passes i18n down to react-i18next + .init({ + resources, + lng: 'ko', + interpolation: { + escapeValue: false // react already safes from xss + } + }) + +export default i18n diff --git a/src/i18n/ko/button.json b/src/i18n/ko/button.json new file mode 100644 index 0000000..a5ef887 --- /dev/null +++ b/src/i18n/ko/button.json @@ -0,0 +1,5 @@ +{ + "login": { + "submit": "로그인" + } +} diff --git a/src/i18n/ko/form.json b/src/i18n/ko/form.json new file mode 100644 index 0000000..336b090 --- /dev/null +++ b/src/i18n/ko/form.json @@ -0,0 +1,11 @@ +{ + "label": { + "login": { + "save_id": "아이디 저장", + "find_id": "아이디 찾기", + "find_pw": "비밀번호 찾기", + "id": "아이디", + "pw": "비밀번호" + } + } +} diff --git a/src/i18n/ko/index.js b/src/i18n/ko/index.js new file mode 100644 index 0000000..6ae57a2 --- /dev/null +++ b/src/i18n/ko/index.js @@ -0,0 +1,6 @@ +import button from './button.json' +import form from './form.json' +import validate from './validate.json' +import message from './message.json' + +export { button, form, validate, message } diff --git a/src/i18n/ko/message.json b/src/i18n/ko/message.json new file mode 100644 index 0000000..85e3ed1 --- /dev/null +++ b/src/i18n/ko/message.json @@ -0,0 +1,5 @@ +{ + "login": { + "success": "정상적으로 로그인 되었습니다." + } +} diff --git a/src/i18n/ko/validate.json b/src/i18n/ko/validate.json new file mode 100644 index 0000000..7f4a37f --- /dev/null +++ b/src/i18n/ko/validate.json @@ -0,0 +1,6 @@ +{ + "login": { + "validate_login_id": "아이디를 입력해주세요.", + "validate_login_pw": "비밀번호를 입력해주세요." + } +} diff --git a/src/index.js b/src/index.js index 2a24034..0edb24a 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom/client' import { BrowserRouter } from 'react-router-dom' import 'antd/dist/antd.min.css' import './styles/index.scss' +import './i18n' import App from './views/App' import { Provider } from 'react-redux' diff --git a/src/styles/scss/_login.scss b/src/styles/scss/_login.scss index c4074b7..1f56f57 100644 --- a/src/styles/scss/_login.scss +++ b/src/styles/scss/_login.scss @@ -3,7 +3,7 @@ } .login-wrapper { - margin-top: 200px; + margin-top: 190px; max-height: 560px; .ant-input-prefix { diff --git a/src/views/login/Login.js b/src/views/login/Login.js index 14cbd65..51c0e9e 100644 --- a/src/views/login/Login.js +++ b/src/views/login/Login.js @@ -17,6 +17,7 @@ import { authUser, userAccount } from '../../store/actions/user_action' import { SET_LOADING } from '../../store/modules/app' import { useNavigate } from 'react-router-dom' import { notificationSuccess } from '../../components/notification/Notification' +import { useTranslation } from 'react-i18next' import _ from 'lodash' import banner1 from '../../assets/images/login/user_banner_01.png' @@ -24,6 +25,7 @@ import banner2 from '../../assets/images/login/user_banner_02.png' import banner3 from '../../assets/images/login/user_banner_03.png' const Login = () => { + const { t } = useTranslation() const dispatch = useDispatch() const navigate = useNavigate() const { isAuthentication } = useSelector((state) => ({ @@ -42,13 +44,13 @@ const Login = () => { username: [ { required: true, - message: '아이디를 입력해주세요.' + message: t('validate.login.validate_login_id') } ], password: [ { required: true, - message: '비밀번호를 입력해주세요.' + message: t('validate.login.validate_login_pw') } ] } @@ -72,7 +74,7 @@ const Login = () => { navigate('/dashboard', { replace: true }) dispatch(SET_LOADING(false)) notificationSuccess({ - description: '정상적으로 로그인 되었습니다.' + description: t('message.login.success') }) }, 600) } @@ -126,7 +128,7 @@ const Login = () => { }} onFinish={onFinish} > -