Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions i18n/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,27 @@ import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

import enCommon from '../locales/en/common.json';
import enMainPage from '../locales/en/mainPage.json';
import koCommon from '../locales/ko/common.json';
import koMainPage from '../locales/ko/mainPage.json';

const resources = {
en: { common: enCommon },
ko: { common: koCommon },
en: {
common: enCommon,
mainPage: enMainPage,
},
ko: {
common: koCommon,
mainPage: koMainPage,
},
};

i18n.use(initReactI18next).init({
resources,
lng: 'ko',
fallbackLng: 'en',
ns: ['common', 'mainPage'],
defaultNS: 'common',
interpolation: {
escapeValue: false,
},
Expand Down
6 changes: 1 addition & 5 deletions locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,5 @@
"recruitmentInfo": "recruitment",
"companiesInfo": "Companies",
"nearBy": "Surrounding",
"community": "Community",
"mainBannerTitle1": "For foreigners",
"mainBannerTitle2": "recruitment platform",
"mainBannerSubtitle": "It provides customized employment information and services for foreigners looking for a job in Korea",
"viewRecruitment": "View Recruitment"
"community": "Community"
}
8 changes: 8 additions & 0 deletions locales/en/mainPage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mainBannerTitle1": "For foreigners",
"mainBannerTitle2": "recruitment platform",
"mainBannerSubtitle": "It provides customized employment information and services for foreigners looking for a job in Korea",
"viewRecruitment": "View Recruitment",
"searchTitle": "Find the job you want",
"searchSubTitle": "You can search for customized recruitment information by keyword, region, occupation, etc."
}
6 changes: 1 addition & 5 deletions locales/ko/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,5 @@
"recruitmentInfo": "채용정보",
"companiesInfo": "기업정보",
"nearBy": "주변기업찾기",
"community": "커뮤니티",
"mainBannerTitle1": "외국인을 위한",
"mainBannerTitle2": "채용 플랫폼",
"mainBannerSubtitle": "한국에서 일자리를 찾고 있는 외국인을 위한 맞춤형 취업 정보와 서비스를 제공합니다",
"viewRecruitment": "채용정보 보기"
"community": "커뮤니티"
}
8 changes: 8 additions & 0 deletions locales/ko/mainPage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mainBannerTitle1": "외국인을 위한",
"mainBannerTitle2": "채용 플랫폼",
"mainBannerSubtitle": "한국에서 일자리를 찾고 있는 외국인을 위한 맞춤형 취업 정보와 서비스를 제공합니다",
"viewRecruitment": "채용정보 보기",
"searchTitle": "원하는 일자리를 찾아보세요",
"searchSubTitle": "키워드, 지역, 직종 등으로 맞춤형 채용정보를 검색할 수 있습니다."
}
72 changes: 41 additions & 31 deletions scripts/generateTranslations.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,51 @@ import csv from 'csv-parser';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// 번역 csv 파일 배열
const csvs = [
{ locales: 'common.json', translations: 'commonTranslations.csv' },
{ locales: 'mainPage.json', translations: 'mainPageTranslations.csv' },
];

// CSV 파일 경로 및 출력 디렉터리 설정
const csvFilePath = join(__dirname, '..', 'translations', 'translations.csv');
const csvFilePaths = csvs.map(csv => ({
locales: csv.locales,
translations: join(__dirname, '..', 'translations', csv.translations),
}));
const localesPath = join(__dirname, '..', 'locales');

// 언어별 번역 데이터를 담을 객체
const translations = {};

// CSV 파일을 스트림으로 읽고, 각 행(row)을 처리
fs.createReadStream(csvFilePath)
.pipe(csv())
.on('data', row => {
const translationKey = row.key;
for (const lang in row) {
if (lang === 'key') continue;
if (!translations[lang]) {
translations[lang] = {};
csvFilePaths.forEach(csvFilePath => {
// 언어별 번역 데이터를 담을 객체
const translations = {};
fs.createReadStream(csvFilePath.translations)
.pipe(csv())
.on('data', row => {
const translationKey = row.key;
for (const lang in row) {
if (lang === 'key') continue;
if (!translations[lang]) {
translations[lang] = {};
}
translations[lang][translationKey] = row[lang];
}
translations[lang][translationKey] = row[lang];
}
})
.on('end', () => {
console.log('CSV 파일 읽기 완료!');
})
.on('end', () => {
console.log('CSV 파일 읽기 완료!');

// 언어별로 common.json 파일 생성
for (const lang of Object.keys(translations)) {
const langDir = join(localesPath, lang);
if (!fs.existsSync(langDir)) {
fs.mkdirSync(langDir, { recursive: true });
// 언어별로 json 파일 생성
for (const lang of Object.keys(translations)) {
const langDir = join(localesPath, lang);
if (!fs.existsSync(langDir)) {
fs.mkdirSync(langDir, { recursive: true });
}
const jsonFilePath = join(langDir, csvFilePath.locales);
fs.writeFileSync(
jsonFilePath,
JSON.stringify(translations[lang], null, 2),
'utf8',
);
console.log(`${lang} -> ${jsonFilePath} 생성 완료`);
}
const jsonFilePath = join(langDir, 'common.json');
fs.writeFileSync(
jsonFilePath,
JSON.stringify(translations[lang], null, 2),
'utf8',
);
console.log(`${lang} -> ${jsonFilePath} 생성 완료`);
}
});
});
});
2 changes: 1 addition & 1 deletion src/components/main/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ChevronRight } from 'lucide-react';
import { useTranslation } from 'react-i18next';

export default function Banner() {
const { t } = useTranslation('common');
const { t } = useTranslation('mainPage');

return (
<section className={styles.heroSection}>
Expand Down
9 changes: 5 additions & 4 deletions src/components/main/SearchSection.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { useTranslation } from 'react-i18next';
import styles from './searchSection.module.scss';
import SearchSectionForm from './SearchSectionForm';

export default function SearchSection() {
const { t } = useTranslation('mainPage');

return (
<section className={styles.searchSection}>
<div className={styles.container}>
<div className={styles.searchWrapper}>
<div className={styles.searchHeader}>
<h2 className={styles.sectionTitle}>원하는 일자리를 찾아보세요</h2>
<p className={styles.sectionSubtitle}>
키워드, 지역, 직종 등으로 맞춤형 채용정보를 검색할 수 있습니다.
</p>
<h2 className={styles.sectionTitle}>{t('searchTitle')}</h2>
<p className={styles.sectionSubtitle}>{t('searchSubTitle')}</p>
<SearchSectionForm />
</div>
</div>
Expand Down
8 changes: 8 additions & 0 deletions translations/commonTranslations.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
key,ko,en
signUp,회원가입,Sign up
login,로그인,Login
searchRecruitment,채용 공고 검색하기,Search for job postings
recruitmentInfo,채용정보,recruitment
companiesInfo,기업정보,Companies
nearBy,주변기업찾기,Surrounding
community,커뮤니티,Community
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
key,ko,en
signUp,회원가입,Sign up
login,로그인,Login
searchRecruitment,채용 공고 검색하기,Search for job postings
recruitmentInfo,채용정보,recruitment
companiesInfo,기업정보,Companies
nearBy,주변기업찾기,Surrounding
community,커뮤니티,Community
mainBannerTitle1,외국인을 위한,For foreigners
mainBannerTitle2,채용 플랫폼,recruitment platform
mainBannerSubtitle,한국에서 일자리를 찾고 있는 외국인을 위한 맞춤형 취업 정보와 서비스를 제공합니다,It provides customized employment information and services for foreigners looking for a job in Korea
viewRecruitment,채용정보 보기,View Recruitment
viewRecruitment,채용정보 보기,View Recruitment
searchTitle,원하는 일자리를 찾아보세요,Find the job you want
searchSubTitle,"키워드, 지역, 직종 등으로 맞춤형 채용정보를 검색할 수 있습니다.","You can search for customized recruitment information by keyword, region, occupation, etc."