Add localization for header menus/some modals

This commit is contained in:
Justin Edmund 2022-03-04 18:42:06 -08:00
parent 5ea57f0e07
commit b91d84028f
7 changed files with 170 additions and 26 deletions

View file

@ -1,21 +1,24 @@
import React from 'react'
import { useTranslation } from 'next-i18next'
import * as Dialog from '@radix-ui/react-dialog'
import CrossIcon from '~public/icons/Cross.svg'
import './index.scss'
const AboutModal = () => {
const { t } = useTranslation('common')
return (
<Dialog.Root>
<Dialog.Trigger asChild>
<li className="MenuItem">
<span>About</span>
<span>{t('modals.about.title')}</span>
</li>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Content className="About Dialog" onOpenAutoFocus={ (event) => event.preventDefault() }>
<div className="DialogHeader">
<Dialog.Title className="DialogTitle">About</Dialog.Title>
<Dialog.Title className="DialogTitle">{t('menu.about')}</Dialog.Title>
<Dialog.Close className="DialogClose" asChild>
<span>
<CrossIcon />

View file

@ -98,6 +98,10 @@
font-size: $font-small;
line-height: 1.1;
max-width: 300px;
&.jp {
max-width: 270px;
}
}
}

View file

@ -1,6 +1,8 @@
import React, { useEffect, useState } from 'react'
import { useCookies } from 'react-cookie'
import { useRouter } from 'next/router'
import { useSnapshot } from 'valtio'
import { useTranslation } from 'next-i18next'
import * as Dialog from '@radix-ui/react-dialog'
import * as Switch from '@radix-ui/react-switch'
@ -15,8 +17,13 @@ import CrossIcon from '~public/icons/Cross.svg'
import './index.scss'
const AccountModal = () => {
const { t } = useTranslation('common')
const { account } = useSnapshot(accountState)
const router = useRouter()
const locale = (router.locale && ['en', 'ja'].includes(router.locale)) ? router.locale : 'en'
// Cookies
const [accountCookies] = useCookies(['account'])
const [userCookies, setUserCookies] = useCookies(['user'])
@ -46,7 +53,7 @@ const AccountModal = () => {
const pictureOptions = (
pictureData.sort((a, b) => (a.name.en > b.name.en) ? 1 : -1).map((item, i) => {
return (
<option key={`picture-${i}`} value={item.filename}>{item.name.en}</option>
<option key={`picture-${i}`} value={item.filename}>{item.name[locale]}</option>
)
})
)
@ -109,14 +116,14 @@ const AccountModal = () => {
<Dialog.Root open={open} onOpenChange={openChange}>
<Dialog.Trigger asChild>
<li className="MenuItem">
<span>Settings</span>
<span>{t('menu.settings')}</span>
</li>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Content className="Account Dialog" onOpenAutoFocus={ (event) => event.preventDefault() }>
<div className="DialogHeader">
<div className="DialogTop">
<Dialog.Title className="SubTitle">Account Settings</Dialog.Title>
<Dialog.Title className="SubTitle">{t('modals.settings.title')}</Dialog.Title>
<Dialog.Title className="DialogTitle">@{account.user?.username}</Dialog.Title>
</div>
<Dialog.Close className="DialogClose" asChild>
@ -129,7 +136,7 @@ const AccountModal = () => {
<form onSubmit={update}>
<div className="field">
<div className="left">
<label>Picture</label>
<label>{t('modals.settings.labels.picture')}</label>
</div>
<div className={`preview ${pictureData.find(i => i.filename === picture)?.element}`}>
@ -147,18 +154,18 @@ const AccountModal = () => {
</div>
<div className="field">
<div className="left">
<label>Language</label>
<label>{t('modals.settings.labels.language')}</label>
</div>
<select name="language" onChange={handleLanguageChange} value={language} ref={languageSelect}>
<option key="en" value="en">English</option>
<option key="jp" value="jp">Japanese</option>
<option key="en" value="en">{t('modals.settings.language.english')}</option>
<option key="jp" value="jp">{t('modals.settings.language.japanese')}</option>
</select>
</div>
<div className="field">
<div className="left">
<label>Private</label>
<p>Hide your profile and prevent your grids from showing up in collections</p>
<label>{t('modals.settings.labels.private')}</label>
<p className={locale}>{t('modals.settings.descriptions.private')}</p>
</div>
<Switch.Root className="Switch" onCheckedChange={handlePrivateChange} checked={privateProfile}>
@ -166,7 +173,7 @@ const AccountModal = () => {
</Switch.Root>
</div>
<Button>Save settings</Button>
<Button>{t('modals.settings.buttons.confirm')}</Button>
</form>
</Dialog.Content>
<Dialog.Overlay className="Overlay" />

View file

@ -90,14 +90,14 @@ const BottomHeader = () => {
<AlertDialog.Overlay className="Overlay" />
<AlertDialog.Content className="Dialog">
<AlertDialog.Title className="DialogTitle">
{t('delete_team.title')}
{t('modals.delete_team.title')}
</AlertDialog.Title>
<AlertDialog.Description className="DialogDescription">
{t('delete_team.description')}
{t('modals.delete_team.description')}
</AlertDialog.Description>
<div className="actions">
<AlertDialog.Cancel className="Button modal">{t('delete_team.buttons.cancel')}</AlertDialog.Cancel>
<AlertDialog.Action className="Button modal destructive" onClick={(e) => deleteTeam(e)}>{t('delete_team.buttons.confirm')}</AlertDialog.Action>
<AlertDialog.Cancel className="Button modal">{t('modals.delete_team.buttons.cancel')}</AlertDialog.Cancel>
<AlertDialog.Action className="Button modal destructive" onClick={(e) => deleteTeam(e)}>{t('modals.delete_team.buttons.confirm')}</AlertDialog.Action>
</div>
</AlertDialog.Content>
</AlertDialog.Portal>

View file

@ -1,6 +1,7 @@
import React from 'react'
import Link from 'next/link'
import { useCookies } from 'react-cookie'
import { useTranslation } from 'next-i18next'
import AboutModal from '~components/AboutModal'
import AccountModal from '~components/AccountModal'
@ -16,6 +17,8 @@ interface Props {
}
const HeaderMenu = (props: Props) => {
const { t } = useTranslation('common')
const [accountCookies] = useCookies(['account'])
const [userCookies] = useCookies(['user'])
@ -35,22 +38,22 @@ const HeaderMenu = (props: Props) => {
/profile/${userCookies.user.picture}@2x.png 2x`}
src={`/profile/${userCookies.user.picture}.png`}
/>
</div
></Link>
</div>
</Link>
</li>
<li className="MenuItem">
<Link href={`/saved` || ''}>Saved</Link>
<Link href={`/saved` || ''}>{t('menu.saved')}</Link>
</li>
</div>
<div className="MenuGroup">
<li className="MenuItem">
<Link href='/teams'>Teams</Link>
<Link href='/teams'>{t('menu.teams')}</Link>
</li>
<li className="MenuItem disabled">
<div>
<span>Guides</span>
<i className="tag">Coming Soon</i>
<span>{t('menu.guides')}</span>
<i className="tag">{t('coming_soon')}</i>
</div>
</li>
</div>
@ -58,7 +61,7 @@ const HeaderMenu = (props: Props) => {
<AboutModal />
<AccountModal />
<li className="MenuItem" onClick={props.logout}>
<span>Logout</span>
<span>{t('menu.logout')}</span>
</li>
</div>
</ul>
@ -74,13 +77,13 @@ const HeaderMenu = (props: Props) => {
</div>
<div className="MenuGroup">
<li className="MenuItem">
<Link href='/teams'>Teams</Link>
<Link href='/teams'>{t('menu.teams')}</Link>
</li>
<li className="MenuItem disabled">
<div>
<span>Guides</span>
<i className="tag">Coming Soon</i>
<span>{t('menu.guides')}</span>
<i className="tag">{t('menu.logout')}</i>
</div>
</li>
</div>

View file

@ -0,0 +1,63 @@
{
"buttons": {
"copy": "Copy link",
"delete": "Delete team",
"edit_info": "Edit info",
"hide_info": "Hide info",
"menu": "Menu",
"new": "New"
},
"modals": {
"about": {
"title": "About"
},
"delete_team": {
"title": "Delete team",
"description": "Are you sure you want to permanently delete this team?",
"buttons": {
"confirm": "Yes, delete",
"cancel": "Nevermind"
}
},
"settings": {
"title": "Account Settings",
"labels": {
"picture": "Picture",
"language": "Language",
"private": "Private"
},
"descriptions": {
"private": "Hide your profile and prevent your grids from showing up in collections"
},
"language": {
"english": "English",
"japanese": "Japanese"
},
"buttons": {
"confirm": "Save settings"
}
}
},
"menu": {
"about": "About",
"guides": "Guides",
"saved": "Saved",
"settings": "Settings",
"teams": "Teams",
"logout": "Logout"
},
"party": {
"segmented_control": {
"class": "Class",
"characters": "Characters",
"weapons": "Weapons",
"summons": "Summons"
}
},
"teams": {
"title": "Discover Teams",
"loading": "Loading teams...",
"not_found": "No teams found"
},
"coming_soon": "Coming Soon"
}

View file

@ -0,0 +1,64 @@
{
"buttons": {
"copy": "リンクをコピー",
"delete": "編成を削除",
"show_info": "詳細を編集",
"hide_info": "詳細を非表示",
"menu": "メニュー",
"new": "作成"
},
"modals": {
"about": {
"title": "このサイトについて"
},
"delete_team": {
"title": "編成を削除しますか",
"description": "編成を削除する操作は取り消せません。",
"buttons": {
"confirm": "削除",
"cancel": "キャンセル"
}
},
"settings": {
"title": "アカウント設定",
"labels": {
"picture": "プロフィール画像",
"language": "言語",
"private": "プライベート"
},
"descriptions": {
"private": "プロフィールを隠し、編成をコレクションに表示されないようにします"
},
"language": {
"english": "英語",
"japanese": "日本語"
},
"buttons": {
"confirm": "設定を保存する"
}
}
},
"menu": {
"about": "このサイトについて",
"guides": "攻略",
"saved": "保存した編成",
"settings": "アカウント設定",
"teams": "編成一覧",
"logout": "ログアウト"
},
"party": {
"segmented_control": {
"class": "ジョブ",
"characters": "キャラ",
"weapons": "武器",
"summons": "召喚石"
}
},
"teams": {
"title": "編成一覧",
"loading": "ロード中...",
"not_found": "編成は見つかりませんでした"
},
"coming_soon": "開発中"
}