Localize filter bar and dropdowns
This commit is contained in:
parent
d0323861db
commit
110cc0c769
7 changed files with 131 additions and 42 deletions
|
|
@ -17,6 +17,11 @@
|
||||||
font-size: $font-regular;
|
font-size: $font-regular;
|
||||||
padding: ($unit) $unit * 2;
|
padding: ($unit) $unit * 2;
|
||||||
|
|
||||||
|
&.ja {
|
||||||
|
padding-top: 6px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { useTranslation } from 'next-i18next'
|
||||||
|
|
||||||
import * as ToggleGroup from '@radix-ui/react-toggle-group'
|
import * as ToggleGroup from '@radix-ui/react-toggle-group'
|
||||||
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
@ -9,28 +12,32 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ElementToggle = (props: Props) => {
|
const ElementToggle = (props: Props) => {
|
||||||
|
const router = useRouter()
|
||||||
|
const { t } = useTranslation('common')
|
||||||
|
const locale = (router.locale && ['en', 'ja'].includes(router.locale)) ? router.locale : 'en'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToggleGroup.Root className="ToggleGroup" type="single" defaultValue={`${props.currentElement}`} aria-label="Element" onValueChange={props.sendValue}>
|
<ToggleGroup.Root className="ToggleGroup" type="single" defaultValue={`${props.currentElement}`} aria-label="Element" onValueChange={props.sendValue}>
|
||||||
<ToggleGroup.Item className="ToggleItem" value="0" aria-label="null">
|
<ToggleGroup.Item className={`ToggleItem ${locale}`} value="0" aria-label="null">
|
||||||
Null
|
{t('elements.null')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item className="ToggleItem wind" value="1" aria-label="wind">
|
<ToggleGroup.Item className={`ToggleItem wind ${locale}`} value="1" aria-label="wind">
|
||||||
Wind
|
{t('elements.wind')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item className="ToggleItem fire" value="2" aria-label="fire">
|
<ToggleGroup.Item className={`ToggleItem fire ${locale}`} value="2" aria-label="fire">
|
||||||
Fire
|
{t('elements.fire')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item className="ToggleItem water" value="3" aria-label="water">
|
<ToggleGroup.Item className={`ToggleItem water ${locale}`} value="3" aria-label="water">
|
||||||
Water
|
{t('elements.water')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item className="ToggleItem earth" value="4" aria-label="earth">
|
<ToggleGroup.Item className={`ToggleItem earth ${locale}`} value="4" aria-label="earth">
|
||||||
Earth
|
{t('elements.earth')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item className="ToggleItem dark" value="5" aria-label="dark">
|
<ToggleGroup.Item className={`ToggleItem dark ${locale}`} value="5" aria-label="dark">
|
||||||
Dark
|
{t('elements.dark')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
<ToggleGroup.Item className="ToggleItem light" value="6" aria-label="light">
|
<ToggleGroup.Item className={`ToggleItem light ${locale}`} value="6" aria-label="light">
|
||||||
Light
|
{t('elements.light')}
|
||||||
</ToggleGroup.Item>
|
</ToggleGroup.Item>
|
||||||
</ToggleGroup.Root>
|
</ToggleGroup.Root>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'next-i18next'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
|
||||||
import RaidDropdown from '~components/RaidDropdown'
|
import RaidDropdown from '~components/RaidDropdown'
|
||||||
|
|
@ -12,6 +13,8 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilterBar = (props: Props) => {
|
const FilterBar = (props: Props) => {
|
||||||
|
const { t } = useTranslation('common')
|
||||||
|
|
||||||
const elementSelect = React.createRef<HTMLSelectElement>()
|
const elementSelect = React.createRef<HTMLSelectElement>()
|
||||||
const raidSelect = React.createRef<HTMLSelectElement>()
|
const raidSelect = React.createRef<HTMLSelectElement>()
|
||||||
const recencySelect = React.createRef<HTMLSelectElement>()
|
const recencySelect = React.createRef<HTMLSelectElement>()
|
||||||
|
|
@ -33,14 +36,14 @@ const FilterBar = (props: Props) => {
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
{props.children}
|
{props.children}
|
||||||
<select onChange={selectChanged} ref={elementSelect}>
|
<select onChange={selectChanged} ref={elementSelect}>
|
||||||
<option key={-1} value={-1}>All elements</option>
|
<option key={-1} value={-1}>{t('elements.full.all')}</option>
|
||||||
<option key={-0} value={0}>Null</option>
|
<option key={-0} value={0}>{t('elements.full.null')}</option>
|
||||||
<option key={1}value={1}>Wind</option>
|
<option key={1}value={1}>{t('elements.full.wind')}</option>
|
||||||
<option key={2}value={2}>Fire</option>
|
<option key={2}value={2}>{t('elements.full.fire')}</option>
|
||||||
<option key={3}value={3}>Water</option>
|
<option key={3}value={3}>{t('elements.full.water')}</option>
|
||||||
<option key={4}value={4}>Earth</option>
|
<option key={4}value={4}>{t('elements.full.earth')}</option>
|
||||||
<option key={5}value={5}>Dark</option>
|
<option key={5}value={5}>{t('elements.full.dark')}</option>
|
||||||
<option key={6}value={6}>Light</option>
|
<option key={6}value={6}>{t('elements.full.light')}</option>
|
||||||
</select>
|
</select>
|
||||||
<RaidDropdown
|
<RaidDropdown
|
||||||
allOption={true}
|
allOption={true}
|
||||||
|
|
@ -48,13 +51,13 @@ const FilterBar = (props: Props) => {
|
||||||
ref={raidSelect}
|
ref={raidSelect}
|
||||||
/>
|
/>
|
||||||
<select onChange={selectChanged} ref={recencySelect}>
|
<select onChange={selectChanged} ref={recencySelect}>
|
||||||
<option key={-1} value={-1}>All time</option>
|
<option key={-1} value={-1}>{t('recency.all_time')}</option>
|
||||||
<option key={86400} value={86400}>Last day</option>
|
<option key={86400} value={86400}>{t('recency.last_day')}</option>
|
||||||
<option key={604800} value={604800}>Last week </option>
|
<option key={604800} value={604800}>{t('recency.last_week')}</option>
|
||||||
<option key={2629746} value={2629746}>Last month</option>
|
<option key={2629746} value={2629746}>{t('recency.last_month')}</option>
|
||||||
<option key={7889238} value={7889238}>Last 3 months</option>
|
<option key={7889238} value={7889238}>{t('recency.last_3_months')}</option>
|
||||||
<option key={15778476} value={15778476}>Last 6 months</option>
|
<option key={15778476} value={15778476}>{t('recency.last_6_months')}</option>
|
||||||
<option key={31556952} value={31556952}>Last year</option>
|
<option key={31556952} value={31556952}>{t('recency.last_year')}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
import { useSnapshot } from 'valtio'
|
import { useSnapshot } from 'valtio'
|
||||||
|
import { useTranslation } from 'next-i18next'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
|
||||||
import { accountState } from '~utils/accountState'
|
import { accountState } from '~utils/accountState'
|
||||||
|
|
@ -30,6 +32,10 @@ const GridRep = (props: Props) => {
|
||||||
|
|
||||||
const { account } = useSnapshot(accountState)
|
const { account } = useSnapshot(accountState)
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const { t } = useTranslation('common')
|
||||||
|
const locale = (router.locale && ['en', 'ja'].includes(router.locale)) ? router.locale : 'en'
|
||||||
|
|
||||||
const [mainhand, setMainhand] = useState<Weapon>()
|
const [mainhand, setMainhand] = useState<Weapon>()
|
||||||
const [weapons, setWeapons] = useState<GridArray<Weapon>>({})
|
const [weapons, setWeapons] = useState<GridArray<Weapon>>({})
|
||||||
|
|
||||||
|
|
@ -66,12 +72,12 @@ const GridRep = (props: Props) => {
|
||||||
|
|
||||||
function generateMainhandImage() {
|
function generateMainhandImage() {
|
||||||
return (mainhand) ?
|
return (mainhand) ?
|
||||||
<img alt={mainhand?.name.en} src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${mainhand?.granblue_id}.jpg`} /> : ''
|
<img alt={mainhand?.name[locale]} src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${mainhand?.granblue_id}.jpg`} /> : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateGridImage(position: number) {
|
function generateGridImage(position: number) {
|
||||||
return (weapons[position]) ?
|
return (weapons[position]) ?
|
||||||
<img alt={weapons[position]?.name.en} src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapons[position]?.granblue_id}.jpg`} /> : ''
|
<img alt={weapons[position]?.name[locale]} src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapons[position]?.granblue_id}.jpg`} /> : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendSaveData() {
|
function sendSaveData() {
|
||||||
|
|
@ -96,10 +102,10 @@ const GridRep = (props: Props) => {
|
||||||
|
|
||||||
const details = (
|
const details = (
|
||||||
<div className="Details">
|
<div className="Details">
|
||||||
<h2 className={titleClass} onClick={navigate}>{ (props.name) ? props.name : 'Untitled' }</h2>
|
<h2 className={titleClass} onClick={navigate}>{ (props.name) ? props.name : t('no_title') }</h2>
|
||||||
<div className="bottom">
|
<div className="bottom">
|
||||||
<div className={raidClass}>{ (props.raid) ? props.raid.name.en : 'No raid set' }</div>
|
<div className={raidClass}>{ (props.raid) ? props.raid.name[locale] : t('no_raid') }</div>
|
||||||
<time className="last-updated" dateTime={props.createdAt.toISOString()}>{formatTimeAgo(props.createdAt, 'en-us')}</time>
|
<time className="last-updated" dateTime={props.createdAt.toISOString()}>{formatTimeAgo(props.createdAt, locale)}</time>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
@ -108,8 +114,8 @@ const GridRep = (props: Props) => {
|
||||||
<div className="Details">
|
<div className="Details">
|
||||||
<div className="top">
|
<div className="top">
|
||||||
<div className="info">
|
<div className="info">
|
||||||
<h2 className={titleClass} onClick={navigate}>{ (props.name) ? props.name : 'Untitled' }</h2>
|
<h2 className={titleClass} onClick={navigate}>{ (props.name) ? props.name : t('no_title') }</h2>
|
||||||
<div className={raidClass}>{ (props.raid) ? props.raid.name.en : 'No raid set' }</div>
|
<div className={raidClass}>{ (props.raid) ? props.raid.name[locale] : t('no_raid') }</div>
|
||||||
</div>
|
</div>
|
||||||
{ (!props.user || (account.user && account.user.id !== props.user.id)) ?
|
{ (!props.user || (account.user && account.user.id !== props.user.id)) ?
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -122,9 +128,9 @@ const GridRep = (props: Props) => {
|
||||||
<div className="bottom">
|
<div className="bottom">
|
||||||
<div className={userClass}>
|
<div className={userClass}>
|
||||||
{ userImage() }
|
{ userImage() }
|
||||||
{ (props.user) ? props.user.username : 'Anonymous' }
|
{ (props.user) ? props.user.username : t('no_user') }
|
||||||
</div>
|
</div>
|
||||||
<time className="last-updated" dateTime={props.createdAt.toISOString()}>{formatTimeAgo(props.createdAt, 'en-us')}</time>
|
<time className="last-updated" dateTime={props.createdAt.toISOString()}>{formatTimeAgo(props.createdAt, locale)}</time>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useState } from 'react'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { useTranslation } from 'next-i18next'
|
||||||
|
|
||||||
import { appState } from '~utils/appState'
|
import { appState } from '~utils/appState'
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
|
|
@ -14,6 +16,10 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const RaidDropdown = React.forwardRef<HTMLSelectElement, Props>(function useFieldSet(props, ref) {
|
const RaidDropdown = React.forwardRef<HTMLSelectElement, Props>(function useFieldSet(props, ref) {
|
||||||
|
const router = useRouter()
|
||||||
|
const { t } = useTranslation('common')
|
||||||
|
const locale = (router.locale && ['en', 'ja'].includes(router.locale)) ? router.locale : 'en'
|
||||||
|
|
||||||
const [raids, setRaids] = useState<Raid[][]>()
|
const [raids, setRaids] = useState<Raid[][]>()
|
||||||
|
|
||||||
const raidGroups = [
|
const raidGroups = [
|
||||||
|
|
@ -37,7 +43,7 @@ const RaidDropdown = React.forwardRef<HTMLSelectElement, Props>(function useFiel
|
||||||
id: '0',
|
id: '0',
|
||||||
name: {
|
name: {
|
||||||
en: 'All raids',
|
en: 'All raids',
|
||||||
jp: '全て'
|
ja: '全てのマルチ'
|
||||||
},
|
},
|
||||||
level: 0,
|
level: 0,
|
||||||
group: 0,
|
group: 0,
|
||||||
|
|
@ -65,7 +71,7 @@ const RaidDropdown = React.forwardRef<HTMLSelectElement, Props>(function useFiel
|
||||||
const options = raids && raids.length > 0 && raids[index].length > 0 &&
|
const options = raids && raids.length > 0 && raids[index].length > 0 &&
|
||||||
raids[index].sort((a, b) => a.element - b.element).map((item, i) => {
|
raids[index].sort((a, b) => a.element - b.element).map((item, i) => {
|
||||||
return (
|
return (
|
||||||
<option key={i} value={item.id}>{item.name.en}</option>
|
<option key={i} value={item.id}>{item.name[locale]}</option>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,34 @@
|
||||||
"new": "New",
|
"new": "New",
|
||||||
"wiki": "View more on gbf.wiki"
|
"wiki": "View more on gbf.wiki"
|
||||||
},
|
},
|
||||||
|
"elements": {
|
||||||
|
"null": "Null",
|
||||||
|
"wind": "Wind",
|
||||||
|
"fire": "Fire",
|
||||||
|
"water": "Water",
|
||||||
|
"earth": "Earth",
|
||||||
|
"dark": "Dark",
|
||||||
|
"light": "Light",
|
||||||
|
"full": {
|
||||||
|
"all": "All elements",
|
||||||
|
"null": "Null",
|
||||||
|
"wind": "Wind",
|
||||||
|
"fire": "Fire",
|
||||||
|
"water": "Water",
|
||||||
|
"earth": "Earth",
|
||||||
|
"dark": "Dark",
|
||||||
|
"light": "Light"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"recency": {
|
||||||
|
"all_time": "All time",
|
||||||
|
"last_day": "Last day",
|
||||||
|
"last_week": "Last week",
|
||||||
|
"last_month": "Last month",
|
||||||
|
"last_3_months": "Last 3 months",
|
||||||
|
"last_6_months": "Last 6 months",
|
||||||
|
"last_year": "Last year"
|
||||||
|
},
|
||||||
"summons": {
|
"summons": {
|
||||||
"main": "Main Summon",
|
"main": "Main Summon",
|
||||||
"friend": "Friend Summon",
|
"friend": "Friend Summon",
|
||||||
|
|
@ -66,5 +94,8 @@
|
||||||
"loading": "Loading teams...",
|
"loading": "Loading teams...",
|
||||||
"not_found": "No teams found"
|
"not_found": "No teams found"
|
||||||
},
|
},
|
||||||
"coming_soon": "Coming Soon"
|
"coming_soon": "Coming Soon",
|
||||||
|
"no_title": "Untitled",
|
||||||
|
"no_raid": "No raid",
|
||||||
|
"no_user": "Anonymous"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,34 @@
|
||||||
"new": "作成",
|
"new": "作成",
|
||||||
"wiki": "gbf.wikiで詳しく見る"
|
"wiki": "gbf.wikiで詳しく見る"
|
||||||
},
|
},
|
||||||
|
"elements": {
|
||||||
|
"null": "無",
|
||||||
|
"wind": "風",
|
||||||
|
"fire": "火",
|
||||||
|
"water": "水",
|
||||||
|
"earth": "土",
|
||||||
|
"dark": "闇",
|
||||||
|
"light": "光",
|
||||||
|
"full": {
|
||||||
|
"all": "全属性",
|
||||||
|
"null": "無属性",
|
||||||
|
"wind": "風属性",
|
||||||
|
"fire": "火属性",
|
||||||
|
"water": "水属性",
|
||||||
|
"earth": "土属性",
|
||||||
|
"dark": "闇属性",
|
||||||
|
"light": "光属性"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"recency": {
|
||||||
|
"all_time": "全ての期間",
|
||||||
|
"last_day": "1日",
|
||||||
|
"last_week": "7日",
|
||||||
|
"last_month": "1ヶ月",
|
||||||
|
"last_3_months": "3ヶ月",
|
||||||
|
"last_6_months": "6ヶ月",
|
||||||
|
"last_year": "1年"
|
||||||
|
},
|
||||||
"summons": {
|
"summons": {
|
||||||
"main": "メイン",
|
"main": "メイン",
|
||||||
"friend": "フレンド",
|
"friend": "フレンド",
|
||||||
|
|
@ -66,6 +94,9 @@
|
||||||
"loading": "ロード中...",
|
"loading": "ロード中...",
|
||||||
"not_found": "編成は見つかりませんでした"
|
"not_found": "編成は見つかりませんでした"
|
||||||
},
|
},
|
||||||
"coming_soon": "開発中"
|
"coming_soon": "開発中",
|
||||||
|
"no_title": "無題",
|
||||||
|
"no_raid": "マルチなし",
|
||||||
|
"no_user": "無名"
|
||||||
}
|
}
|
||||||
|
|
||||||
Loading…
Reference in a new issue