diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..8352350 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,18 @@ +# Contributing + +If you are reading this it means that you are interested to make unknown-art a better club. So, first of all, thank you. + +## New Pull Request + +It can be based on an open issue, but also on a spontaneous submission. If the issue is missing from the [issues page](https://github.com/silversonicaxel/unknown-art/issues), please create a new one, in order to allow me to better understand the scope of the new code. + +## New Language + +- create inside folder `locales` a new language folder, named after two digits _Language Code_, based on the BCP 47 format. +- replicate the same files and data structure, getting inspired by the default English `en` language code, or any other language you could prefer, and translate all locales into the new language. +- update the file `src/helpers/config/i18n.ts` in the following configuration: + - `locales` needs to include the new BCP 47 format language code. + - `locales_regional_codes` needs to include a new key-value pair to associate the language code with its corresponding regional code. +- update the files `locales/**/common.json` at the fieldset `language`. +- update e2e tests. +- create a new PR and wait for feedback. diff --git a/locales/en/home.json b/locales/en/home.json index d7ea14a..1953893 100644 --- a/locales/en/home.json +++ b/locales/en/home.json @@ -1,6 +1,6 @@ { "intro": "welcome dear reader!", - "content": "unknown art is where you can, hopefully, get in contact with persons, lovers, thinkers, minds or artists, all over the beautiful world.", + "content": "unknown art is where you can, hopefully, connect with individuals, lovers, thinkers, minds or artists, all over the beautiful world.", "logo": { "title": "hero image unknown art", "label": "hero image" diff --git a/locales/zh/bookshops.json b/locales/zh/bookshops.json new file mode 100644 index 0000000..ef99b92 --- /dev/null +++ b/locales/zh/bookshops.json @@ -0,0 +1,12 @@ +{ + "results": { + "notfound": "未找到结果。请尝试使用不同的搜索过滤条件。", + "wrongpagination": "没有可用的结果。看起来分页可能已在URL中被修改。请再次尝试搜索。" + }, + "form": { + "address": "地址", + "website": "网站", + "description": "描述", + "image": "图片" + } +} diff --git a/locales/zh/common.json b/locales/zh/common.json new file mode 100644 index 0000000..ff79130 --- /dev/null +++ b/locales/zh/common.json @@ -0,0 +1,77 @@ +{ + "title": "unknown art", + "description": "unknown art 是一个会让你了解全球艺术和独立书店的俱乐部。", + "menu" : { + "home": "首页", + "bookshops": "书店", + "bookshop": "书店" + }, + "language" : { + "it": "意大利语", + "en": "英语" + }, + "logo": { + "title": "unknown art 的标志", + "label": "主标志" + }, + "loading": "加载中", + "pagination": { + "current_page": "当前页面", + "page": "页面" + }, + "search": { + "title": "搜索书店", + "description": "筛选书店列表", + "field": { + "total": { + "label": "总计" + }, + "name": { + "label": "名称" + }, + "country": { + "label": "国家" + }, + "city": { + "label": "城市" + }, + "website": { + "label": "网站", + "option": { + "all": "全部", + "with": "有网站", + "without": "无网站" + } + } + }, + "action": { + "dialog": { + "title": "搜索", + "label": "打开书店搜索对话框" + }, + "close": { + "label": "关闭书店搜索对话框" + }, + "submit": { + "title": "搜索", + "label": "提交书店搜索" + }, + "reset": { + "title": "重置", + "label": "重置书店搜索" + } + } + }, + "error": { + "description": "{{page}} 页面有问题,您可以稍后访问我们,或尝试重新加载页面。", + "action": { + "reload": { + "title": "重新加载", + "label": "重新加载{{page}}页面" + } + } + }, + "notfound": { + "description": "未找到页面,请访问首页以解决问题。" + } +} diff --git a/locales/zh/home.json b/locales/zh/home.json new file mode 100644 index 0000000..be54a4e --- /dev/null +++ b/locales/zh/home.json @@ -0,0 +1,8 @@ +{ + "intro": "欢迎,亲爱的读者!", + "content": "unknown art 是一个你或许可以与来自我们美丽世界的各类人、爱好者、思想者、头脑或艺术家建立联系的世界。", + "logo": { + "title": "unknown art 的主图", + "label": "主图" + } +} diff --git a/src/app/[locale]/__e2e__/fixtures/page/HomePage.ts b/src/app/[locale]/__e2e__/fixtures/page/HomePage.ts index 916fab8..b58eb43 100644 --- a/src/app/[locale]/__e2e__/fixtures/page/HomePage.ts +++ b/src/app/[locale]/__e2e__/fixtures/page/HomePage.ts @@ -1,8 +1,15 @@ +import type { Locator } from '@playwright/test' +import { defaultLocale } from 'src/helpers/config/i18n' +import type { I18nLocale } from 'src/types/i18n' import { BasePage } from 'tests/fixtures' export class HomePage extends BasePage { - async goto(): Promise { - await this.page.goto('/') + async goto(locale: I18nLocale = defaultLocale): Promise { + await this.page.goto(`/${locale}`) + } + + getElement(): Locator { + return this.page.locator('main') } } diff --git a/src/app/[locale]/bookshops/[bookshopId]/page.tsx b/src/app/[locale]/bookshops/[bookshopId]/page.tsx index da9e674..11b272e 100644 --- a/src/app/[locale]/bookshops/[bookshopId]/page.tsx +++ b/src/app/[locale]/bookshops/[bookshopId]/page.tsx @@ -1,6 +1,6 @@ import fetchedMeta from 'fetch-meta-tags' import type { fetchedMeta as FetchedMetadata } from 'fetch-meta-tags' -import { locales_codes } from 'helpers/config/i18n' +import { locales_regional_codes } from 'helpers/config/i18n' import { meta, META_SITE_BASE_URL } from 'helpers/config/meta' import { getTranslationServer } from 'helpers/utils/getTranslationServer' import { isImageSecure } from 'helpers/utils/isImageSecure' @@ -37,7 +37,7 @@ export async function generateMetadata( description: t('description'), url: `${META_SITE_BASE_URL}${locale}/bookshops/${bookshop.id}`, siteName: meta.siteName, - locale: locales_codes[locale as I18nLocale], + locale: locales_regional_codes[locale as I18nLocale], type: 'website', } } diff --git a/src/app/[locale]/bookshops/layout.tsx b/src/app/[locale]/bookshops/layout.tsx index eff342a..30634cc 100644 --- a/src/app/[locale]/bookshops/layout.tsx +++ b/src/app/[locale]/bookshops/layout.tsx @@ -1,5 +1,5 @@ -import { locales_codes } from 'helpers/config/i18n' +import { locales_regional_codes } from 'helpers/config/i18n' import { meta, META_SITE_BASE_URL } from 'helpers/config/meta' import { getTranslationServer } from 'helpers/utils/getTranslationServer' import type { Metadata } from 'next' @@ -25,7 +25,7 @@ export async function generateMetadata( description: t('description'), url: `${META_SITE_BASE_URL}${locale}/bookshops`, siteName: meta.siteName, - locale: locales_codes[locale as I18nLocale], + locale: locales_regional_codes[locale as I18nLocale], type: 'website', } } diff --git a/src/app/[locale]/home.e2e.ts b/src/app/[locale]/home.e2e.ts index a7f056f..3875ed3 100644 --- a/src/app/[locale]/home.e2e.ts +++ b/src/app/[locale]/home.e2e.ts @@ -27,5 +27,37 @@ test.describe('src / app / [locale] > home', () => { expect(homePage.locales.getLanguage('en')).toBeDefined() expect(homePage.locales.getLanguage('it')).toBeDefined() + expect(homePage.locales.getLanguage('zh')).toBeDefined() }) + + /* eslint-disable max-len */ + test('all locale pages content', async ({ homePage }) => { + await homePage.goto('it') + await expect(homePage.getElement().getByRole('heading', { level: 1 })).toHaveText('unknown art') + await expect(homePage.getElement().getByRole('paragraph').nth(0)) + .toHaveText('benvenuto caro lettore!') + await expect(homePage.getElement().getByRole('paragraph').nth(1)) + .toHaveText('unknown art è il club che ti farà conoscere librerie artistiche ed indipendenti, in tutto il mondo.') + await expect(homePage.getElement().getByRole('paragraph').nth(2)) + .toHaveText('unknown art è il mondo dove puoi, forse, entrare in contatto con persone, amanti, pensatori, menti o artisti, di tutto il nostro bellissimo mondo.') + + await homePage.goto('zh') + await expect(homePage.getElement().getByRole('heading', { level: 1 })).toHaveText('unknown art') + await expect(homePage.getElement().getByRole('paragraph').nth(0)) + .toHaveText('欢迎,亲爱的读者!') + await expect(homePage.getElement().getByRole('paragraph').nth(1)) + .toHaveText('unknown art 是一个会让你了解全球艺术和独立书店的俱乐部。') + await expect(homePage.getElement().getByRole('paragraph').nth(2)) + .toHaveText('unknown art 是一个你或许可以与来自我们美丽世界的各类人、爱好者、思想者、头脑或艺术家建立联系的世界。') + + await homePage.goto('en') + await expect(homePage.getElement().getByRole('heading', { level: 1 })).toHaveText('unknown art') + await expect(homePage.getElement().getByRole('paragraph').nth(0)) + .toHaveText('welcome dear reader!') + await expect(homePage.getElement().getByRole('paragraph').nth(1)) + .toHaveText('unknown art is the club that will introduce you to arty and independent bookshops, all over the world.') + await expect(homePage.getElement().getByRole('paragraph').nth(2)) + .toHaveText('unknown art is where you can, hopefully, connect with individuals, lovers, thinkers, minds or artists, all over the beautiful world.') + }) + /* eslint-enable max-len */ }) diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 15624fe..8c834a8 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -1,7 +1,7 @@ import 'src/styles/globals.css' import 'src/styles/reset.css' import { font } from 'helpers/config/font' -import { locales, locales_codes } from 'helpers/config/i18n' +import { locales, locales_regional_codes } from 'helpers/config/i18n' import { meta, META_SITE_BASE_URL } from 'helpers/config/meta' import { DialogProvider } from 'helpers/providers/dialog' import { getTranslationServer } from 'helpers/utils/getTranslationServer' @@ -32,7 +32,7 @@ export async function generateMetadata({ params: { locale } }: HomeLayoutProps): description: t('description'), url: META_SITE_BASE_URL, siteName: meta.siteName, - locale: locales_codes[locale as I18nLocale], + locale: locales_regional_codes[locale as I18nLocale], type: 'website', } } diff --git a/src/components/menu/menu.test.tsx b/src/components/menu/menu.test.tsx index 7489577..d9df269 100644 --- a/src/components/menu/menu.test.tsx +++ b/src/components/menu/menu.test.tsx @@ -39,5 +39,6 @@ describe('Components > Menu', () => { expect(screen.getByText('en')).toBeDefined() expect(screen.getByText('it')).toBeDefined() + expect(screen.getByText('zh')).toBeDefined() }) }) diff --git a/src/helpers/config/i18n.ts b/src/helpers/config/i18n.ts index 143591e..392596c 100644 --- a/src/helpers/config/i18n.ts +++ b/src/helpers/config/i18n.ts @@ -3,11 +3,12 @@ import type { I18nLocale } from 'types/i18n' export const defaultLocale = 'en' -export const locales = [defaultLocale, 'it'] as const +export const locales = [defaultLocale, 'it', 'zh'] as const -export const locales_codes: Record = { +export const locales_regional_codes: Record = { en: 'en_GB', - it: 'it_IT' + it: 'it_IT', + zh: 'zh_CN' } export const I18N_COOKIE_NAME = 'NEXT_I18N_CURRENT_LOCALE' diff --git a/src/helpers/hooks/useLocalesCurrentUrl.ts b/src/helpers/hooks/useLocalesCurrentUrl.ts index 8f8e4e2..1e53621 100644 --- a/src/helpers/hooks/useLocalesCurrentUrl.ts +++ b/src/helpers/hooks/useLocalesCurrentUrl.ts @@ -5,7 +5,6 @@ import type { I18nLocale } from 'types/i18n' import { locales } from '../config/i18n' - export type UseLocalesCurrentUrlParams = { currentLocale: I18nLocale }