summaryrefslogtreecommitdiff
path: root/i18n
diff options
context:
space:
mode:
Diffstat (limited to 'i18n')
-rw-r--r--i18n/client.ts67
-rw-r--r--i18n/index.ts34
-rw-r--r--i18n/locales/en/login.json43
-rw-r--r--i18n/locales/en/translation.json75
-rw-r--r--i18n/locales/ko/login.json41
-rw-r--r--i18n/locales/ko/translation.json74
-rw-r--r--i18n/settings.ts18
7 files changed, 352 insertions, 0 deletions
diff --git a/i18n/client.ts b/i18n/client.ts
new file mode 100644
index 00000000..0cb38f22
--- /dev/null
+++ b/i18n/client.ts
@@ -0,0 +1,67 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+import i18next, { FlatNamespace, KeyPrefix } from 'i18next';
+import {
+ initReactI18next,
+ useTranslation as useTranslationOrg,
+ UseTranslationOptions,
+ UseTranslationResponse,
+ FallbackNs,
+} from 'react-i18next';
+import { useCookies } from 'react-cookie';
+import resourcesToBackend from 'i18next-resources-to-backend';
+import LanguageDetector from 'i18next-browser-languagedetector';
+import { getOptions, languages, cookieName } from '@/i18n/settings';
+
+const runsOnServerSide = typeof window === 'undefined';
+
+i18next
+ .use(initReactI18next)
+ .use(LanguageDetector)
+ .use(
+ resourcesToBackend(
+ (language: string, namespace: string) =>
+ import(`./locales/${language}/${namespace}.json`)
+ )
+ )
+ .init({
+ ...getOptions(),
+ lng: 'ko',
+ detection: {
+ order: ['path', 'htmlTag', 'cookie', 'navigator'],
+ },
+ preload: runsOnServerSide ? languages : [],
+ });
+
+export function useTranslation<
+ Ns extends FlatNamespace,
+ KPrefix extends KeyPrefix<FallbackNs<Ns>> = undefined,
+>(
+ lng: string,
+ ns?: Ns,
+ options?: UseTranslationOptions<KPrefix>
+): UseTranslationResponse<FallbackNs<Ns>, KPrefix> {
+ 1;
+ const [cookies, setCookie] = useCookies([cookieName]);
+ const ret = useTranslationOrg(ns, options);
+ const { i18n } = ret;
+ if (runsOnServerSide && lng && i18n.resolvedLanguage !== lng) {
+ i18n.changeLanguage(lng);
+ } else {
+ const [activeLng, setActiveLng] = useState(i18n.resolvedLanguage);
+ useEffect(() => {
+ if (activeLng === i18n.resolvedLanguage) return;
+ setActiveLng(i18n.resolvedLanguage);
+ }, [activeLng, i18n.resolvedLanguage]);
+ useEffect(() => {
+ if (!lng || i18n.resolvedLanguage === lng) return;
+ i18n.changeLanguage(lng);
+ }, [lng, i18n]);
+ useEffect(() => {
+ if (cookies.i18next === lng) return;
+ setCookie(cookieName, lng, { path: '/home' });
+ }, [lng, cookies.i18next]);
+ }
+ return ret;
+}
diff --git a/i18n/index.ts b/i18n/index.ts
new file mode 100644
index 00000000..c78ecd1e
--- /dev/null
+++ b/i18n/index.ts
@@ -0,0 +1,34 @@
+import { createInstance, Namespace, FlatNamespace, KeyPrefix } from 'i18next';
+import resourcesToBackend from 'i18next-resources-to-backend';
+import { initReactI18next } from 'react-i18next/initReactI18next';
+import { FallbackNs } from 'react-i18next';
+
+import { getOptions } from '@/i18n/settings';
+
+const initI18next = async (lng: string, ns: string | string[]) => {
+ const i18nInstance = createInstance();
+ await i18nInstance
+ .use(initReactI18next)
+ .use(
+ resourcesToBackend(
+ (language: string, namespace: string) =>
+ import(`./locales/${language}/${namespace}.json`)
+ )
+ )
+ .init(getOptions(lng, ns));
+ return i18nInstance;
+};
+
+export async function useTranslation<
+ Ns extends FlatNamespace,
+ KPrefix extends KeyPrefix<FallbackNs<Ns>> = undefined,
+>(lng: string, ns?: Ns, options: { keyPrefix?: KPrefix } = {}) {
+ const i18nextInstance = await initI18next(
+ lng,
+ Array.isArray(ns) ? (ns as string[]) : (ns as string)
+ );
+ return {
+ t: i18nextInstance.getFixedT(lng, ns, options.keyPrefix),
+ i18n: i18nextInstance,
+ };
+} \ No newline at end of file
diff --git a/i18n/locales/en/login.json b/i18n/locales/en/login.json
new file mode 100644
index 00000000..f84e3ae3
--- /dev/null
+++ b/i18n/locales/en/login.json
@@ -0,0 +1,43 @@
+{
+ "welcome": "Welcome back",
+ "loginMessage": "Login to SHI eVCP",
+ "email": "Email",
+ "password": "Password",
+ "forgotPassword": "Forgot your password?",
+ "resetPassword": "Reset Password",
+ "resetDescription": "Enter your account's email address and we'll send you a password reset link.",
+ "login": "Login",
+ "orContinueWith": "Or continue with",
+ "loginWithKnox": "Login with Knox",
+ "noAccount": "Don't have an account?",
+ "signUp": "Sign up",
+ "and":"and",
+ "ContinueWithEmail":"Continue with Email",
+ "defaultErrorMessage":"There is an error",
+ "errorTitle":"Error",
+ "otpSentTitle":"Sent OTP",
+ "otpSentMessage":"Please check your mailbox.",
+ "invalidToken": "You have clicked on an invalid link. The link is valid for 10 minutes.",
+ "verifyOtp": "Verify OTP",
+ "verifying": "Verifying OTP",
+ "loginSuccess": "Login successful",
+ "youAreLoggedIn": "You have been logged in.",
+ "languages": {
+ "english": "English",
+ "korean": "한국어"
+ },
+ "termsMessage": "By clicking continue, you agree to our",
+ "termsOfService": "Terms of Service",
+ "privacyPolicy": "Privacy Policy",
+
+ "title": "Partner Portal",
+ "description": "Authentication forms built using the components.",
+ "loginLink": "Login",
+ "blockquote": "삼성중공업의 협업 플랫폼입니다. 입찰, 견적, 계약 등의 행위를 할 수 있으며 엔지니어링 데이터를 편리하게 입력하고 입력된 데이터를 사용자가 원하는 형식으로 쉽게 프린트할 수 있습니다. 엔지니어링 문서를 쉽게 제출할 수 있으며 이 모든 과정 동안 쉽고 투명하게 커뮤니케이션을 할 수 있습니다.",
+ "footer": "DTSolution",
+ "heading": "Request Company Repository",
+ "subheading": "Enter your business number(tax ID) below to request",
+ "agreement": "By clicking, you agree to our",
+ "joinButton": "Join with Tax ID"
+
+ } \ No newline at end of file
diff --git a/i18n/locales/en/translation.json b/i18n/locales/en/translation.json
new file mode 100644
index 00000000..99ac1acc
--- /dev/null
+++ b/i18n/locales/en/translation.json
@@ -0,0 +1,75 @@
+{
+ "verifyYourEmailTitle": "Verify your email to sign in",
+ "greeting": "Hello",
+ "receivedSignInAttempt": "We have received a sign-in attempt from {{location}}.",
+ "enterCodeInstruction": "To complete the sign-in process; enter the 6-digit code in the original window, or enter it in a new one by going to the link below:",
+ "securityWarning": "If you didn't attempt to sign in but received this email, or if the location doesn't match, please ignore this email. Don't share or forward the 6-digit code with anyone. Our customer service will never ask for it. Do not read this code out loud. Be cautious of phishing attempts and always verify the sender and domain (shi.com) before acting. If you are concerned about your account's safety, please visit our Help page to get in touch with us.",
+ "Filters":"Filters",
+ "nofilters":"No filters applied",
+ "addfilters":"Add filters to refine your results.",
+ "Where":"Where",
+ "noFields":"No fields found.",
+ "searchFileds":"Search fields...",
+ "resetFilters":"Reset filters",
+ "addFilter":"Add filter",
+ "filterInputPlaceholder":"Enter a value...",
+ "Contains":"Contains",
+ "Does not contain":"Does not contain",
+ "Is":"Is",
+ "Is not":"Is not",
+ "Is empty":"Is empty",
+ "Is not empty":"Is not empty",
+ "Is less than":"Is less than",
+ "Is less than or equal to":"Is less than or equal to",
+ "Is greater than":"Is greater than",
+ "Is greater than or equal to":"Is greater than or equal to",
+ "Is before":"Is before",
+ "Is after": "Is after",
+ "Is on or before":"Is on or before",
+ "Is on or after": "Is on or after",
+ "Is between":"Is between",
+ "Is relative to today":"Is relative to today",
+ "And":"And",
+ "Or":"Or",
+ "Asc":"Asc",
+ "Desc":"Desc",
+ "Select options":" Select options...",
+
+ "adminCreated": {
+ "title": "eVCP Admin Account Created",
+ "greeting": "Hello",
+ "body1": "Your Admin account has been created successfully. You can now access eVCP via the link below.",
+ "loginCTA": "Go to Login",
+ "supportMsg": "If you have any questions, please contact support or your administrator at any time.",
+ "footerDisclaimer": "This email was sent automatically from the eVCP system. If you received it by mistake, please contact customer support."
+ },
+
+ "adminEmailChanged": {
+ "title": "Your Admin Email Has Been Updated",
+ "greeting": "Hello",
+ "body": {
+ "intro": "We noticed that your admin email address has recently changed.",
+ "oldEmail": "Old Email",
+ "newEmail": "New Email"
+ },
+ "loginCTA": "Go to Login",
+ "supportMsg": "If you have any questions, please contact support or your administrator.",
+ "footerDisclaimer": "This is an automated email from eVCP. If you received this email by mistake, please contact support."
+ },
+ "rfqInvite": {
+ "title": "RFQ Invitation",
+ "heading": "Invitation to RFQ",
+ "greeting": "Hello",
+ "bodyIntro": "We are pleased to invite you to the following project:",
+ "projectName": "Project Name",
+ "projectCode": "Project Code",
+ "dueDate": "Due Date",
+ "description": "Description",
+ "itemListTitle": "Below is the list of requested items:",
+ "moreDetail": "For more details, please log in to our portal.",
+ "viewButton": "View RFQ",
+ "supportMsg": "If you have any questions, please contact us at your earliest convenience.",
+ "footerDisclaimer": "This email was sent automatically. Please do not reply."
+ }
+
+ } \ No newline at end of file
diff --git a/i18n/locales/ko/login.json b/i18n/locales/ko/login.json
new file mode 100644
index 00000000..f209afe4
--- /dev/null
+++ b/i18n/locales/ko/login.json
@@ -0,0 +1,41 @@
+{
+ "welcome": "다시 오신 것을 환영합니다",
+ "loginMessage": "SHI eVCP 로그인",
+ "email": "이메일",
+ "password": "비밀번호",
+ "forgotPassword": "비밀번호를 잊으셨나요?",
+ "resetPassword": "비밀번호 재설정",
+ "resetDescription": "계정의 이메일 주소를 입력하시면 비밀번호 재설정 링크를 보내드립니다.",
+ "login": "로그인",
+ "orContinueWith": "또는 다음을 이용하여 계속",
+ "loginWithKnox": "Knox로 로그인",
+ "noAccount": "계정이 없으신가요?",
+ "signUp": "회원가입",
+ "and":"와",
+ "ContinueWithEmail":"Continue with Email",
+ "defaultErrorMessage":"에러가 발생했습니다.",
+ "otpSentTitle":"OTP 발송",
+ "otpSentMessage":"메일로 전송된 OTP를 확인하세요.",
+ "errorTitle":"에러",
+ "invalidToken":"유효하지 않은 링크를 클릭하셨습니다. 링크는 10분 간 유효합니다.",
+ "verifyOtp":"OPT 인증",
+ "verifying":"OPT 인증 중",
+ "loginSuccess":"로그인 성공",
+ "youAreLoggedIn":"로그인이 되었습니다.",
+ "languages": {
+ "english": "English",
+ "korean": "한국어"
+ },
+ "termsMessage": "로그인을 진행하면 다음을 동의하는 것으로 간주합니다.",
+ "title": "파트너 포털",
+ "description": "컴포넌트를 사용하여 구축된 인증 양식.",
+ "loginLink": "로그인",
+ "blockquote": "삼성중공업의 협업 플랫폼입니다. 입찰, 견적, 계약 등의 행위를 할 수 있으며 엔지니어링 데이터를 편리하게 입력하고 입력된 데이터를 사용자가 원하는 형식으로 쉽게 프린트할 수 있습니다. 엔지니어링 문서를 쉽게 제출할 수 있으며 이 모든 과정 동안 쉽고 투명하게 커뮤니케이션을 할 수 있습니다.",
+ "footer": "DTSolution",
+ "heading": "회사 리포지토리 요청",
+ "subheading": "요청하려면 아래에 사업자 번호(세금 ID)를 입력하세요",
+ "agreement": "버튼을 클릭하면 다음에 동의하게 됩니다:",
+ "termsOfService": "서비스 약관",
+ "privacyPolicy": "개인정보 보호정책",
+ "joinButton": "사업자 번호로 신청하기"
+} \ No newline at end of file
diff --git a/i18n/locales/ko/translation.json b/i18n/locales/ko/translation.json
new file mode 100644
index 00000000..1603d538
--- /dev/null
+++ b/i18n/locales/ko/translation.json
@@ -0,0 +1,74 @@
+{
+ "verifyYourEmailTitle": "로그인을 위해 이메일 인증하기",
+ "greeting": "안녕하세요",
+ "receivedSignInAttempt": "{{location}}에서 로그인 시도가 있었습니다.",
+ "enterCodeInstruction": "로그인을 완료하려면 원래 창에 6자리 코드를 입력하시거나, 아래 링크를 통해 새 창을 열어 6자리 코드를 입력하세요:",
+ "securityWarning": "로그인을 시도하지 않았는데 이 이메일을 받으셨거나, 위치 정보가 일치하지 않는다면 이 이메일을 무시하시기 바랍니다. 이 6자리 코드를 절대 다른 사람과 공유하거나 전달하지 마십시오. 고객 서비스 팀은 이 코드를 요청하지 않습니다. 이 코드를 소리 내어 읽지 마세요. 피싱 시도를 주의하시고, 조치를 취하기 전 발신자와 도메인(shi.com)을 반드시 확인하세요. 계정 보안에 대한 우려가 있다면, 도움말 페이지를 방문해 문의해주시기 바랍니다.",
+ "Filters":"필터",
+ "nofilters":"적용된 필터가 없습니다.",
+ "addfilters":"필터를 추가하면 원하는 결과를 찾을 수 있습니다.",
+ "Where":"필드",
+ "noFields":"필드가 없습니다.",
+ "searchFileds":"필드명을 검색...",
+ "resetFilters":"필터 초기화",
+ "addFilter":"필터 추가",
+ "filterInputPlaceholder":"값을 넣으세요...",
+ "Contains":"포함",
+ "Does not contain":"포함하지 않는",
+ "Is":"다음 값과 같음",
+ "Is not":"다음 값과 같지 않음",
+ "Is empty":"비어 있음",
+ "Is not empty":"비어 있지 않음",
+ "Is less than":"다음 값보다 작음",
+ "Is less than or equal to":"다음 값보다 작거나 같음",
+ "Is greater than":"다음 값보다 큼",
+ "Is greater than or equal to":"다음 값보다 크거나 같음",
+ "Is before":"다음 날짜 이전",
+ "Is after": "다음 날짜 이후",
+ "Is on or before":"다음 날짜이거나 이전",
+ "Is on or after":"다음 날짜이거나 이후",
+ "Is between":"다음 범위 사이",
+ "Is relative to today":"오늘 기준으로 계산",
+ "And":"그리고",
+ "Or":"또는",
+ "Asc":"오름차순",
+ "Desc":"내림차순",
+ "Select options":" 옵션을 선택하세요...",
+ "adminCreated": {
+ "title": "eVCP 어드민 계정이 생성되었습니다",
+ "greeting": "안녕하세요",
+ "body1": "어드민(Admin) 계정이 성공적으로 생성되었습니다. 아래 링크를 통해 EVCP에 접속하실 수 있습니다.",
+ "loginCTA": "로그인하러 가기",
+ "supportMsg": "시스템 이용 중 문의 사항이나 문제가 있으시면 언제든지 담당자나 고객지원으로 연락 부탁드립니다.",
+ "footerDisclaimer": "본 메일은 eVCP 시스템에서 발송되는 자동 안내메일입니다. 잘못 수신하셨다면 고객센터로 문의 부탁드립니다."
+ },
+ "adminEmailChanged": {
+ "title": "어드민 이메일이 변경되었습니다",
+ "greeting": "안녕하세요",
+ "body": {
+ "intro": "어드민 이메일 주소가 최근 변경된 것을 확인했습니다.",
+ "oldEmail": "이전 이메일",
+ "newEmail": "새 이메일"
+ },
+ "loginCTA": "로그인하러 가기",
+ "supportMsg": "궁금한 점이 있으면 담당자 또는 고객지원으로 문의 부탁드립니다.",
+ "footerDisclaimer": "이 메일은 eVCP 시스템에서 자동으로 발송된 안내 메일입니다. 잘못 수신하셨다면 고객센터로 연락 부탁드립니다."
+ },
+ "rfqInvite": {
+ "title": "RFQ 초대장",
+ "heading": "RFQ 초대",
+ "greeting": "안녕하세요",
+ "bodyIntro": "다음 프로젝트에 귀하를 초대합니다:",
+ "projectName": "프로젝트명",
+ "projectCode": "프로젝트 코드",
+ "dueDate": "마감일",
+ "description": "상세 내용",
+ "itemListTitle": "요청된 아이템 목록은 다음과 같습니다:",
+ "moreDetail": "자세한 내용은 포털에 로그인하여 확인하시기 바랍니다.",
+ "viewButton": "RFQ 보기",
+ "supportMsg": "궁금하신 점이 있으면 언제든지 문의해 주세요.",
+ "footerDisclaimer": "이 이메일은 자동 발송되었습니다. 회신하지 말아 주세요."
+ }
+
+
+ } \ No newline at end of file
diff --git a/i18n/settings.ts b/i18n/settings.ts
new file mode 100644
index 00000000..6db8718c
--- /dev/null
+++ b/i18n/settings.ts
@@ -0,0 +1,18 @@
+export const fallbackLng = 'ko';
+export const languages = [fallbackLng, 'en'];
+export const defaultNS = 'translation';
+export const cookieName = 'i18next';
+
+export function getOptions(
+ lng = fallbackLng,
+ ns: string | string[] = defaultNS
+) {
+ return {
+ supportedLngs: languages,
+ fallbackLng,
+ lng,
+ fallbackNS: defaultNS,
+ defaultNS,
+ ns,
+ };
+} \ No newline at end of file