diff --git a/libs/gi/localization/assets/locales/en/artifact.json b/libs/gi/localization/assets/locales/en/artifact.json index df98210d51..299cfcd8ed 100644 --- a/libs/gi/localization/assets/locales/en/artifact.json +++ b/libs/gi/localization/assets/locales/en/artifact.json @@ -121,5 +121,11 @@ "rvSliderBtn": { "maximum": "MRV", "current": "RV" + }, + "optExcludeModal": { + "excludeMsg": "Are you sure you want to exclude {{count}} artifacts from build optimization?", + "includeMsg": "Are you sure you want to include {{count}} artifacts to build optimization?", + "excludeBtn": "Exclude Artifacts", + "includeBtn": "Include Artifacts" } } diff --git a/libs/gi/localization/assets/locales/en/build.json b/libs/gi/localization/assets/locales/en/build.json new file mode 100644 index 0000000000..dd882dc9a2 --- /dev/null +++ b/libs/gi/localization/assets/locales/en/build.json @@ -0,0 +1,60 @@ +{ + "buildDropdown": { + "tcBadge": "TC", + "equipped": "Equipped Build" + }, + "buildCardTip": { + "edit": "Edit Build Settings", + "copyTc": "Copy to TC Builds", + "duplicate": "Duplicate Build", + "equip": "Equip Build", + "delete": "Delete Build" + }, + "buildEqCard": { + "name": "Equipped Build", + "copy": { + "nameReal": "Duplicate of Equipped", + "nameTc": "Equipped Build - Copied", + "desc": "Copied from Equipped Build" + } + }, + "buildRealCard": { + "copy": { + "nameReal": "Duplicate of {{name}}", + "nameTc": "{{name}} - Copied", + "equipped": "Equipped" + }, + "edit": { + "title": "Build Settings", + "label": "Build Name", + "placeholder": "Build Name", + "desc": "Build Description" + } + }, + "buildTcCard": { + "copy": { + "nameTc": "Duplicate of {{name}}" + }, + "edit": { + "title": "Build Settings", + "label": "Build Name", + "placeholder": "Build Name", + "desc": "Build Description" + } + }, + "equipBuildModal": { + "title": "Confirm Equipment Changes for <2>{{currentName}}", + "desc": "Do you want to make the changes shown below?", + "overwrite": "Copy the current equipment in <2>{{currentName}} to a new build. Otherwise, they will be overwritten.", + "label": "Build Name", + "newName": "Duplicate of {{currentName}}", + "cancel": "Cancel", + "equip": "Equip" + }, + "compareBtn": { + "compare": "Compare", + "equipped": "Equipped ", + "crrBadge": "Current", + "tcBadge": "TC" + } +} diff --git a/libs/gi/localization/assets/locales/en/loadout.json b/libs/gi/localization/assets/locales/en/loadout.json new file mode 100644 index 0000000000..9e7548e90e --- /dev/null +++ b/libs/gi/localization/assets/locales/en/loadout.json @@ -0,0 +1,79 @@ +{ + "loadoutSettings": { + "alert": "Loadouts provides character context data, including bonus stats, conditionals, multi-targets, optimization config, and stores builds. A single Loadout can be used for many teams.", + "title": "Build Management", + "builds": "Builds", + "newBuildBtn": "New Build", + "tcBuilds": "TC Builds", + "newTcBuildBtn": "New TC Build" + }, + "mTargetEditor": { + "title": "Target Editor", + "rankMobile": "#", + "rank": "Rank #", + "desc": "Target Description", + "noReaction": "No Reactions" + }, + "mTargetImport": { + "invalid": "Invalid Multi-Optimization Config", + "failed": "Data Import failed.", + "button": "Import Multi-Opt", + "title": "Import Multi-Opt", + "desc": "Import a Multi-opt in JSON form below.", + "label": "JSON Data", + "placeholder": "Paste your Team JSON here", + "import": "Import" + }, + "showFormulas": { + "button": "Show Formulas & Calcs", + "title": "Formulas & Calculations" + }, + "loDropdown": { + "createModal": { + "title": "Create a new Loadout For <2/>", + "label": "New Loadout Name", + "placeholder": "New Loadout Name", + "desc": "New Loadout Description", + "cancel": "Cancel", + "confirm": "Confirm" + }, + "label": "Loadout: ", + "create": "Create a new Loadout", + "builds": "{{count}} Builds", + "tcs": "{{count}} TC Builds", + "multi": "{{count}} Multi-Opt" + }, + "loadoutHeader": { + "builds": "Builds: ", + "tcBuilds": "TC Builds: ", + "mltTargets": "Custom multi-targets: ", + "optTarget": "Optimization Target:" + }, + "loadoutEditor": { + "label": "Loadout Name", + "placeholder": "Loadout Name", + "desc": "Loadout Description", + "dupBtn": "Duplicate Loadout", + "delBtn": "Delete Loadout", + "optTarget": "Optimization Target", + "conditionals": "Conditionals: ", + "builds": "Builds", + "teams": "Teams", + "addNewTeam": "Add new Team", + "bonusStats": "Bonus Stats", + "mltTargets": "Custom multi-targets" + }, + "loadoutDelModal": { + "title": "Delete Loadout: <1>{{name}}?", + "desc": "Deleting the Loadout will also delete the following data:", + "builds": "All saved builds: ", + "tcBuilds": "All saved TC builds: ", + "mTargets": "All Custom Multi-targets: ", + "bonus": "Bonus stats: ", + "condi": "Conditionals: ", + "optConfig": "Optimization Configuration", + "affected": "Any teams with this loadout will have this loadout removed from the team. Teams will not be deleted. Teams affected: ", + "cancel": "Cancel", + "delete": "Delete" + } +} diff --git a/libs/gi/localization/assets/locales/en/page_character.json b/libs/gi/localization/assets/locales/en/page_character.json index d6092392d7..501b94e489 100644 --- a/libs/gi/localization/assets/locales/en/page_character.json +++ b/libs/gi/localization/assets/locales/en/page_character.json @@ -41,15 +41,25 @@ "duplicate": "Duplicate", "target_one": "<0>{{count}} Target", "target_other": "<0>{{count}} Targets", - "jsonDescWarning": "It seems like you're trying to import a multi-opt config. This isn't the right place for that! Please go back one modal and press Import Multi-Opt." + "jsonDescWarning": "It seems like you're trying to import a multi-opt config. This isn't the right place for that! Please go back one modal and press Import Multi-Opt.", + "label": "Custom Multi-target Name", + "desc": "Custom Multi-target Description", + "export": "Export", + "confirm": "Are you sure you want to delete this target?", + "copyMsg": "Copied configuration to clipboard." }, "addStats": { "title": "Bonus Stats", "info": "You can use these fields to add buffs/debuffs not directly supported in GO, such as food buffs, Abyss cards, or Superconduct. Please refer to the <1>Genshin Impact Wiki for specific values.", - "label": "New Bonus Stat" + "label": "New Bonus Stat", + "main": "Main Stats", + "other": "Other Stats", + "misc": "Misc Stats", + "special": "<0>Special: " }, "tabTheorycraft": { "distribute": "Distribute", + "distInput": "Substats", "compareToggle": { "equipped": "Compare vs. equipped", "tc": "Show TC stats" @@ -107,5 +117,10 @@ "teammateUsing": { "weapon": "Teammate <1> is using this weapon.", "artifact": "Teammate <1> is using this <3>" + }, + "charContentModal": { + "loadoutsWith": "Team Loadouts with <2/>", + "addLoAndTeam": "Add new Loadout+Team", + "addTeam": "Add new Team" } } diff --git a/libs/gi/localization/assets/locales/en/page_character_optimize.json b/libs/gi/localization/assets/locales/en/page_character_optimize.json index 84ee3df799..09d883bfdf 100644 --- a/libs/gi/localization/assets/locales/en/page_character_optimize.json +++ b/libs/gi/localization/assets/locales/en/page_character_optimize.json @@ -1,4 +1,5 @@ { + "specialized": "Specialized:", "mainStat": { "levelAssTooltip": { "title": "Main Stat Level Assumption", @@ -28,6 +29,22 @@ "upOptNoResults": "It looks like there aren't any artifacts available for upgrading that could enhance your setup. Your artifact filters might be too restrictive. Alternatively, try the main artifact optimizer to find a better build.", "upOptInfo": "The Artifact Upgrader identifies artifacts with high potential to boost the Optimization Target's value, guiding you to artifacts worth leveling up.
As it only swaps one artifact at a time, for the best overall build across all artifacts, use the main artifact optimizer.", "upOptEmptyBuild": "You're using a partially empty build. Since the Artifact Upgrader only swaps artifacts individually, completing a set is unlikely. It's recommended to begin with a base build, preferably generated from the main Optimizer.", + "upOptShowingNum": "Showing {{count}} out of {{value}} Artifacts", + "upOptChart": { + "est": " (est.)", + "prob": "Prob. upgrade{{est}}: ", + "average": "Average increase{{est}}: ", + "equipped": "Equipped", + "current": "Current on Build", + "incLabel": "Relative Increase to Target", + "probLabel": "Probability", + "const": " Constrained", + "exactDist": "Exact{{const}} Distribution", + "estimatedDist": "Estimated Distribution", + "currentTarget": "Current Target", + "currentLine": "Current Target Value", + "averageLine": "Average Increase" + }, "excludeArt": { "title_exclude": "Excluded Artifacts", "title_tooltip": "Add artifacts to this character's exclusion list. Artifacts in the exclusion list will not be considered for build generation.", @@ -59,6 +76,8 @@ }, "usingState": "Using" }, + "useTeamArts": "Use artifacts in teammates' active builds", + "tcBadge": "TC build", "allowPartial": "Allow Partial Builds (<5 artifacts)", "constraintFilter": { "title": "Minimum Build Constraints", @@ -115,9 +134,39 @@ "cancel": "Cancel", "generateBuilds": "Generate Builds" }, + "buildShowingNum": "Showing <2>{{count}} build generated for <6/>.", + "generatedOn": "Build generated on: ", + "selectChar": "Select a character to generate builds.", + "clearBuildsBtn": "Clear Builds", + "createBuildTc": { + "button": "New TC Build", + "title": "New Theorycraft Build", + "desc": "Copy over this build to a new TC Build", + "label": "TC Build Name", + "cancel": "Cancel", + "create": "Create" + }, + "createBuildReal": { + "button": "New Build", + "title": "New Build", + "desc": "Copy over this build to a new build", + "label": "Build Name", + "cancel": "Cancel", + "create": "Create" + }, + "buildDisplay": { + "equippedBadge": "(Equipped)", + "currentBadge": "(current build)", + "equipped": "Equipped", + "equipToCrr": "Equip to Current Build", + "oldWeapon": "Old Weapon", + "tcWeapon": "TC Weapon", + "newWeapon": "New Weapon" + }, "removeBuildButton": "Remove Build", "theorycraftButton": "Theorycraft", "currentlyEquippedBuild": "Currently Equipped", + "activeBuild": "Active Build", "addBuildToList": "Add build to list", "graphBuildLabel": "Graph #<1>{{count}}", "buildCompleted": "Build Completed", diff --git a/libs/gi/localization/assets/locales/en/page_team.json b/libs/gi/localization/assets/locales/en/page_team.json index ffd44f99ad..0862bd5dc7 100644 --- a/libs/gi/localization/assets/locales/en/page_team.json +++ b/libs/gi/localization/assets/locales/en/page_team.json @@ -1,10 +1,79 @@ { + "searchLabel": { + "char": "Characters", + "team": "Team Name" + }, + "addTeamBtn": "Add Team", + "importTeamBtn": "Import Team", + "importForm": { + "title": "Import Team", + "desc": "Import a team in JSON form below.", + "label": "JSON Data", + "placeholder": "Paste your Team JSON here", + "importBtn": "Import", + "error": { + "verifi": "Data verification failed.", + "import": "Data Import failed." + } + }, + "teamDelModal": { + "teamName": "Delete Team:", + "alert": "Removing the team will remove: resonance buffs, and enemy configs stored in the team. Loadouts that are only in this team are also selected by default for deletion.", + "delBtn": "Delete", + "onlyCrrTeam": "Only in current team", + "usingMltTeams": "In {{count}} teams" + }, + "teamSettings": { + "tab": { + "team": "Team Settings", + "char": "Character {{count}}" + }, + "alert": { + "desc": "Teams are a container for 4 character loadouts. It provides a way for characters to apply team buffs, and configuration of enemy stats. Loadouts can be shared between teams.", + "first": "The first character in the team receives any \"active on-field character\" buffs, and cannot be empty." + }, + "exportBtn": "Export Team", + "dupBtn": "Duplicate Team", + "deleteBtn": "Delete Team", + "addCharBtn": "Add Character", + "toFieldBtn": "To Field", + "onFieldBtn": "On-field Character" + }, + "exportModal": { + "msg": "Copied team data to clipboard.", + "title": "Team Export", + "alert": "Export the team data to be imported by another user. All the team and loadout data (bonus stats, enemy config, optimize config) are exported. All exported non-TC builds are converted to TC builds.", + "selAll": "Select All", + "unselAll": "Unselect All", + "export": "Export", + "target": "Optimization Target:", + "mTargets": "Mtargets to Export", + "builds": "Builds to Export", + "equipped": "Equipped Build", + "tcBadge": "TC Build" + }, + "enemyEditor": { + "enemyLevel": "Enemy ", + "defIgn": "DEF Ignore {{value}}%", + "defRed": "DEF Red. {{value}}%", + "announceBtn": "To get the specific resistance values of enemies, please visit the wiki.", + "note": "Note: Genshin Impact halves resistance shred values below 0%. For the sake of calculations enter the RAW value and GO will do the rest. (e.g. 10% - 20% = -10%)", + "immunity": "Immunity" + }, + "teamComponents": { + "teamBuffs": "Received Team Buffs", + "tcBadge": "TC Build" + }, "buildInfo": { "equipped": "This is the build currently equipped to your character, this represents in-game equipement and is persistent outside of the Loadout.", "build": "A Build is comprised of a weapon and 5 artifacts.", "tcbuild": "A Theorycraft Build allows defining a build by raw stats." }, + "charProfile": { + "button": "EDIT" + }, "buildTcCharOverride": { + "tip": "Set a specific level, constellation, ascension, or talent level for this TC build, that is different from the base character", "btn": "Override Character Data for This TC build" }, "team": { diff --git a/libs/gi/localization/assets/locales/en/page_weapon.json b/libs/gi/localization/assets/locales/en/page_weapon.json index ca6801b544..b89762830a 100644 --- a/libs/gi/localization/assets/locales/en/page_weapon.json +++ b/libs/gi/localization/assets/locales/en/page_weapon.json @@ -1,4 +1,5 @@ { + "weaponFilterTitle": "Weapon Filter", "showingNum_one": "Showing <1>{{count}} out of {{value}} Weapon", "showingNum_other": "Showing <1>{{count}} out of {{value}} Weapons", "edit": "Edit Weapon", @@ -18,5 +19,14 @@ "subheadings": { "general": "General", "inventory": "Inventory" - } + }, + "refinement": "Refinement <1>{{rank}}", + "weaponType": { + "sword": "Sword", + "claymore": "Claymore", + "polearm": "Polearm", + "bow": "Bow", + "catalyst": "Catalyst" + }, + "tcBuild": "TC Build" } diff --git a/libs/gi/page-team/src/BuildDropdown.tsx b/libs/gi/page-team/src/BuildDropdown.tsx index 5abe7b2046..de390f9d6f 100644 --- a/libs/gi/page-team/src/BuildDropdown.tsx +++ b/libs/gi/page-team/src/BuildDropdown.tsx @@ -4,7 +4,8 @@ import type { LoadoutDatum } from '@genshin-optimizer/gi/db' import { useDatabase } from '@genshin-optimizer/gi/db-ui' import CheckroomIcon from '@mui/icons-material/Checkroom' import { Box, MenuItem } from '@mui/material' -// TODO: Translation +import { useTranslation } from 'react-i18next' + export default function BuildDropdown({ teamId, loadoutDatum, @@ -14,6 +15,7 @@ export default function BuildDropdown({ loadoutDatum: LoadoutDatum dropdownBtnProps?: Omit }) { + const { t } = useTranslation('build') const database = useDatabase() const { teamCharId, buildType, buildId, buildTcId } = loadoutDatum const teamChar = database.teamChars.get(teamCharId)! @@ -27,7 +29,9 @@ export default function BuildDropdown({ title={ {database.teams.getActiveBuildName(loadoutDatum)} - {buildType === 'tc' && TC} + {buildType === 'tc' && ( + {t`buildDropdown.tcBadge`} + )} } {...dropdownBtnProps} @@ -37,7 +41,7 @@ export default function BuildDropdown({ onClick={() => onChangeLoadoutDatum({ buildType: 'equipped' })} sx={{ display: 'flex', gap: 1 }} > - Equipped Build + {t`buildDropdown.equipped`} {buildIds.map((bId) => { const { name } = database.builds.get(bId)! @@ -67,7 +71,7 @@ export default function BuildDropdown({ sx={{ display: 'flex', gap: 1 }} > {name} - TC + {t`buildDropdown.tcBadge`} ) })} diff --git a/libs/gi/page-team/src/CharProfileCard.tsx b/libs/gi/page-team/src/CharProfileCard.tsx index 3c3c953af6..3066ec56b1 100644 --- a/libs/gi/page-team/src/CharProfileCard.tsx +++ b/libs/gi/page-team/src/CharProfileCard.tsx @@ -14,10 +14,12 @@ import { input } from '@genshin-optimizer/gi/wr' import DriveFileRenameOutlineIcon from '@mui/icons-material/DriveFileRenameOutline' import { Box, Button, Grid, Typography } from '@mui/material' import { useContext } from 'react' +import { useTranslation } from 'react-i18next' import { CharProfileCharEditor } from './CharProfileCharEditor' /* Image card with star and name and level */ export default function CharacterProfileCard() { + const { t } = useTranslation('page_team') const { character: { key: characterKey }, } = useContext(CharacterContext) @@ -36,8 +38,7 @@ export default function CharacterProfileCard() { onClick={onShowEditor} startIcon={} > - {/* TODO: translation */} - EDIT + {t`charProfile.button`} diff --git a/libs/gi/page-team/src/CharProfileCharEditor.tsx b/libs/gi/page-team/src/CharProfileCharEditor.tsx index b2bca665bf..3cdacf2365 100644 --- a/libs/gi/page-team/src/CharProfileCharEditor.tsx +++ b/libs/gi/page-team/src/CharProfileCharEditor.tsx @@ -30,7 +30,7 @@ import { Typography, } from '@mui/material' import { Suspense, useContext } from 'react' -import { useTranslation } from 'react-i18next' +import { Trans, useTranslation } from 'react-i18next' import { BuildTcContext } from './BuildTcContext' export function CharProfileCharEditor({ @@ -84,8 +84,11 @@ function Content({ onClose }: { onClose?: () => void }) { - Set a specific level, constellation, ascension, or talent level - for this TC build, that is different from the base character + + Set a specific level, constellation, ascension, or talent + level for this TC build, that is different from the base + character + } > diff --git a/libs/gi/page-team/src/CharacterDisplay/Build/BuildEquipped.tsx b/libs/gi/page-team/src/CharacterDisplay/Build/BuildEquipped.tsx index 40605a6cb4..f3a537eefd 100644 --- a/libs/gi/page-team/src/CharacterDisplay/Build/BuildEquipped.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/Build/BuildEquipped.tsx @@ -13,7 +13,9 @@ import { } from '@genshin-optimizer/gi/ui' import { Grid } from '@mui/material' import { useContext } from 'react' +import { useTranslation } from 'react-i18next' export function BuildEquipped({ active = false }: { active?: boolean }) { + const { t } = useTranslation('build') const { teamId, teamCharId } = useContext(TeamCharacterContext) const { character: { key: characterKey, equippedArtifacts, equippedWeapon }, @@ -25,7 +27,7 @@ export function BuildEquipped({ active = false }: { active?: boolean }) { }) const onDupe = () => database.teamChars.newBuild(teamCharId, { - name: 'Duplicate of Equipped', + name: t`buildEqCard.copy.nameReal`, artifactIds: equippedArtifacts, weaponId: equippedWeapon, }) @@ -40,14 +42,14 @@ export function BuildEquipped({ active = false }: { active?: boolean }) { if (!newBuildTcId) return // copy over name database.buildTcs.set(newBuildTcId, { - name: `Equipped Build - Copied`, - description: 'Copied from Equipped Build', + name: t`buildEqCard.copy.nameTc`, + description: t`buildEqCard.copy.desc`, }) } return ( database.teamChars.newBuild(teamCharId, { - name: `Duplicate of ${name}`, + name: t('buildRealCard.copy.nameReal', { name }), artifactIds: artifactIds, weaponId: weaponId, }) @@ -112,7 +113,7 @@ export default function BuildReal({ void }) { + const { t } = useTranslation('build') const { character: { key: characterKey }, } = useContext(CharacterContext) @@ -233,7 +235,7 @@ function BuildEditor({ return ( @@ -244,14 +246,14 @@ function BuildEditor({ setName(e.target.value)} /> setDesc(e.target.value)} multiline diff --git a/libs/gi/page-team/src/CharacterDisplay/Build/BuildTc.tsx b/libs/gi/page-team/src/CharacterDisplay/Build/BuildTc.tsx index d79d8603b3..f051c49da8 100644 --- a/libs/gi/page-team/src/CharacterDisplay/Build/BuildTc.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/Build/BuildTc.tsx @@ -35,6 +35,7 @@ import { Typography, } from '@mui/material' import { useContext, useDeferredValue, useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' export default function BuildTc({ buildTcId, @@ -43,6 +44,7 @@ export default function BuildTc({ buildTcId: string active?: boolean }) { + const { t } = useTranslation('build') const [open, onOpen, onClose] = useBoolState() const { teamId, teamCharId } = useContext(TeamCharacterContext) const database = useDatabase() @@ -60,7 +62,7 @@ export default function BuildTc({ const onDupe = () => database.teamChars.newBuildTc(teamCharId, { ...structuredClone(buildTc), - name: `Duplicate of ${name}`, + name: t('buildTcCard.copy.nameTc', { name }), }) return ( <> @@ -233,6 +235,7 @@ function BuildTcEditor({ buildTcId: string onClose: () => void }) { + const { t } = useTranslation('build') const database = useDatabase() const build = useBuildTc(buildTcId)! @@ -268,7 +271,7 @@ function BuildTcEditor({ return ( @@ -279,14 +282,14 @@ function BuildTcEditor({ setName(e.target.value)} /> setDesc(e.target.value)} multiline diff --git a/libs/gi/page-team/src/CharacterDisplay/CompareBtn.tsx b/libs/gi/page-team/src/CharacterDisplay/CompareBtn.tsx index 99debffc31..340d019d90 100644 --- a/libs/gi/page-team/src/CharacterDisplay/CompareBtn.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/CompareBtn.tsx @@ -5,18 +5,19 @@ import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank' import type { ButtonGroupProps } from '@mui/material' import { Button, ButtonGroup, MenuItem } from '@mui/material' import { useContext } from 'react' +import { useTranslation } from 'react-i18next' /** * The UI component that modifies the compare data in a TeamChar. * This is used in conjuction with useCompareData hook to supply a compareData to the compare UI. */ -// TODO: Translation export default function CompareBtn({ buttonGroupProps = {}, }: { buttonGroupProps?: ButtonGroupProps }) { + const { t } = useTranslation('build') const database = useDatabase() const { teamId, @@ -40,11 +41,11 @@ export default function CompareBtn({ {database.buildTcs.get(compareBuildTcId)?.name ?? ''}{' '} - TC + {t`compareBtn.tcBadge`} ) : ( - 'Equipped' + t`compareBtn.equipped` ) const current = (compareType === 'equipped' && buildType === 'equipped') || @@ -65,7 +66,7 @@ export default function CompareBtn({ }) } > - Compare + {t`compareBtn.compare`} - Current + {t`compareBtn.crrBadge`} )} @@ -87,10 +88,10 @@ export default function CompareBtn({ }) } > - Equipped{' '} + {t`compareBtn.equipped`} {buildType === 'equipped' && ( - Current + {t`compareBtn.crrBadge`} )} @@ -108,7 +109,7 @@ export default function CompareBtn({ {database.builds.get(bId)!.name}{' '} {buildType === 'real' && bId === buildId && ( - Current + {t`compareBtn.crrBadge`} )} @@ -125,11 +126,11 @@ export default function CompareBtn({ > {database.buildTcs.get(bTcId)?.name ?? ''}{' '} - TC + {t`compareBtn.tcBadge`} {buildType === 'tc' && bTcId === buildTcId && ( - Current + {t`compareBtn.crrBadge`} )} diff --git a/libs/gi/page-team/src/CharacterDisplay/CustomMultiTarget/CustomMultiTargetCard.tsx b/libs/gi/page-team/src/CharacterDisplay/CustomMultiTarget/CustomMultiTargetCard.tsx index 1e3dfcb106..9b8116ab6d 100644 --- a/libs/gi/page-team/src/CharacterDisplay/CustomMultiTarget/CustomMultiTargetCard.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/CustomMultiTarget/CustomMultiTargetCard.tsx @@ -88,14 +88,14 @@ export default function CustomMultiTargetCard({ (index: number) => () => { if ( Object.values(target.targets[index].bonusStats).length && - !window.confirm(`Are you sure you want to delete this target?`) + !window.confirm(t`multiTarget.confirm`) ) return const targets = [...target.targets] targets.splice(index, 1) setTarget({ ...target, targets }) }, - [target, setTarget] + [target, setTarget, t] ) const [selectedTarget, setSelectedTarget] = useState(-1) @@ -124,7 +124,7 @@ export default function CustomMultiTargetCard({ const copyToClipboard = () => navigator.clipboard .writeText(JSON.stringify(target)) - .then(() => alert('Copied configuration to clipboard.')) + .then(() => alert(t`multiTarget.copyMsg`)) .catch(console.error) const customTargetDisplays = useMemo( @@ -192,7 +192,7 @@ export default function CustomMultiTargetCard({ > setTarget((target) => ({ @@ -204,7 +204,7 @@ export default function CustomMultiTargetCard({ {description && descIsJson && } { setDescIsJson( @@ -243,7 +243,7 @@ export default function CustomMultiTargetCard({ startIcon={} sx={{ flexGrow: 1 }} > - Export + {t`multiTarget.export`} - + - Import a Multi-opt in JSON form below. + {t`mTargetImport.desc`} setData(e.target.value)} multiline @@ -65,7 +67,7 @@ export default function CustomMultiTargetImportBtn({ disabled={!data} onClick={importData} > - Import + {t`mTargetImport.import`} diff --git a/libs/gi/page-team/src/CharacterDisplay/CustomMultiTarget/MTargetEditor.tsx b/libs/gi/page-team/src/CharacterDisplay/CustomMultiTarget/MTargetEditor.tsx index e941395b2b..ed626cf15c 100644 --- a/libs/gi/page-team/src/CharacterDisplay/CustomMultiTarget/MTargetEditor.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/CustomMultiTarget/MTargetEditor.tsx @@ -72,7 +72,7 @@ export default function MTargetEditor({ setTargetIndex: (ind?: number) => void onDup: () => void }) { - const { t } = useTranslation('page_character') + const { t } = useTranslation(['page_character', 'loadout']) const { character: { key: characterKey }, } = useContext(CharacterContext) @@ -146,14 +146,16 @@ export default function MTargetEditor({ }} onClick={() => setcollapse((c) => !c)} > - Target Editor + {t`loadout:mTargetEditor.title`} {collapse ? : } - {isMobile ? '#' : 'Rank #'} + {isMobile + ? t`loadout:mTargetEditor.rankMobile` + : t`loadout:mTargetEditor.rank`} ), }} @@ -286,7 +288,7 @@ export default function MTargetEditor({ setCustomTarget({ ...customTarget, description }) @@ -315,7 +317,7 @@ function ReactionDropdown({ infusionAura?: InfusionAuraElementKey }) { const ele = node.info.variant ?? 'physical' - const { t } = useTranslation('page_character') + const { t } = useTranslation(['page_character', 'loadout']) if ( !['pyro', 'hydro', 'cryo', 'electro', 'dendro'].some( @@ -343,7 +345,7 @@ function ReactionDropdown({ return ( setReactionMode()}> - No Reactions + {t`loadout:mTargetEditor.noReaction`} {reactions.map((rm) => ( diff --git a/libs/gi/page-team/src/CharacterDisplay/LoadoutSettingElement.tsx b/libs/gi/page-team/src/CharacterDisplay/LoadoutSettingElement.tsx index ebf67b67c6..f9bf8383a1 100644 --- a/libs/gi/page-team/src/CharacterDisplay/LoadoutSettingElement.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/LoadoutSettingElement.tsx @@ -33,7 +33,6 @@ import BuildTc from './Build/BuildTc' import { CustomMultiTargetButton } from './CustomMultiTarget' import StatModal from './StatModal' -// TODO: Translation const columns = { xs: 1, sm: 1, md: 2, lg: 2 } export default function LoadoutSettingElement() { const database = useDatabase() @@ -98,6 +97,7 @@ export default function LoadoutSettingElement() { } function BuildManagementContent() { + const { t } = useTranslation('loadout') const database = useDatabase() const { teamCharId, @@ -112,7 +112,7 @@ function BuildManagementContent() { title={ - Build Management + {t`loadoutSettings.title`} } /> @@ -128,14 +128,14 @@ function BuildManagementContent() { - Builds + {t`loadoutSettings.builds`} @@ -156,7 +156,7 @@ function BuildManagementContent() { - TC Builds + {t`loadoutSettings.tcBuilds`} @@ -215,6 +215,7 @@ function DetailStatButton({ buttonProps = {} }: { buttonProps?: ButtonProps }) { ) } function FormulasButton({ buttonProps = {} }: { buttonProps?: ButtonProps }) { + const { t } = useTranslation('loadout') const { onModalOpen } = useContext(FormulaDataContext) return ( ) } diff --git a/libs/gi/page-team/src/CharacterDisplay/StatModal.tsx b/libs/gi/page-team/src/CharacterDisplay/StatModal.tsx index adeada1c3a..0daf6e41b6 100644 --- a/libs/gi/page-team/src/CharacterDisplay/StatModal.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/StatModal.tsx @@ -176,6 +176,7 @@ function StatDisplayContent({ } function MainStatsCards() { + const { t } = useTranslation('page_character') const { character: { key: characterKey }, } = useContext(CharacterContext) @@ -208,7 +209,7 @@ function MainStatsCards() { - + - Special:{' '} + + Special:{' '} + - + {!!miscStatReadNodes.length && ( - + diff --git a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/ChartCard/CustomTooltip.tsx b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/ChartCard/CustomTooltip.tsx index 477e6c5dbd..9cd4440ff7 100644 --- a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/ChartCard/CustomTooltip.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/ChartCard/CustomTooltip.tsx @@ -133,8 +133,7 @@ export default function CustomTooltip({ )} {activeBuild && ( - {/* TODO: Translation */} - Active Build + {t`activeBuild`} )} {generLabel && {generLabel}} diff --git a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/ExcludeArt.tsx b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/ExcludeArt.tsx index ad61073e97..80d578dd7b 100644 --- a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/ExcludeArt.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/ExcludeArt.tsx @@ -226,7 +226,7 @@ function ExcludeArtRedButtons({ onExclude: (ids: string[]) => void onInclude: (ids: string[]) => void }) { - const { t } = useTranslation(['artifact', 'ui']) + const { t } = useTranslation('artifact') const { numExclude, numInclude } = useMemo(() => { const excludedFiltered = artExclusion.filter((i) => artifactIds.includes(i)) @@ -237,13 +237,11 @@ function ExcludeArtRedButtons({ }, [artifactIds, artExclusion]) const excludeArtifacts = () => - window.confirm( - `Are you sure you want to exclude ${numExclude} artifacts from build optimization?` - ) && onExclude(artifactIds) + window.confirm(t('optExcludeModal.excludeMsg', { count: numExclude })) && + onExclude(artifactIds) const includeArtifacts = () => - window.confirm( - `Are you sure you want to include ${numInclude} artifacts to build optimization?` - ) && onInclude(artifactIds) + window.confirm(t('optExcludeModal.includeMsg', { count: numInclude })) && + onInclude(artifactIds) return ( @@ -255,9 +253,7 @@ function ExcludeArtRedButtons({ onClick={excludeArtifacts} startIcon={} > - - Exclude Artifacts - + {t`optExcludeModal.excludeBtn`} {numExclude} @@ -271,9 +267,7 @@ function ExcludeArtRedButtons({ onClick={includeArtifacts} startIcon={} > - - Include Artifacts - + {t`optExcludeModal.includeBtn`} {numInclude} diff --git a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/UseTeammateArt.tsx b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/UseTeammateArt.tsx index 3112b73658..588429003b 100644 --- a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/UseTeammateArt.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/Components/UseTeammateArt.tsx @@ -16,6 +16,7 @@ import { } from '@mui/material' import type { ReactNode } from 'react' import { Suspense, memo, useContext } from 'react' +import { useTranslation } from 'react-i18next' export const UseTeammateArt = memo(function UseTeammateArt({ totalTally, useTeammateBuild, @@ -25,6 +26,7 @@ export const UseTeammateArt = memo(function UseTeammateArt({ useTeammateBuild: boolean disabled?: boolean }) { + const { t } = useTranslation('page_character_optimize') const database = useDatabase() const { teamCharId, @@ -92,7 +94,7 @@ export const UseTeammateArt = memo(function UseTeammateArt({ ) : ( - TC build + {t`tcBadge`} )} @@ -120,8 +122,7 @@ export const UseTeammateArt = memo(function UseTeammateArt({ disabled={disabled} > - {/* TODO: Translation */} - Use artifacts in teammates' active builds + {t`useTeamArts`} diff --git a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/index.tsx b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/index.tsx index 97cccbdd57..82f30ee8e8 100644 --- a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/index.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/index.tsx @@ -547,6 +547,9 @@ export default function TabBuild() { ) const getNormBuildLabel = useCallback((index: number) => `#${index + 1}`, []) + const buildShowingCount = + builds.length + (graphBuilds ? graphBuilds.length : 0) + return ( {noArtifact && } @@ -787,20 +790,29 @@ export default function TabBuild() { {builds ? ( - Showing{' '} - - {builds.length + (graphBuilds ? graphBuilds.length : 0)} - {' '} - build generated for {characterName}.{' '} + + Showing{' '} + {{ count: buildShowingCount } as any}{' '} + build generated for{' '} + + . + {' '} {!!buildDate && ( - Build generated on:{' '} + {t`generatedOn`} {new Date(buildDate).toLocaleString()} )} ) : ( - Select a character to generate builds. + {t`selectChar`} )} @@ -998,6 +1010,7 @@ const BuildItemWrapper = memo(function BuildItemWrapper({ ) }) function CopyTcButton({ build }: { build: GeneratedBuild }) { + const { t } = useTranslation('page_character_optimize') const [name, setName] = useState('') const [showTcPrompt, onShowTcPrompt, OnHideTcPrompt] = useBoolState() @@ -1033,14 +1046,13 @@ function CopyTcButton({ build }: { build: GeneratedBuild }) { startIcon={} onClick={onShowTcPrompt} > - New TC Build + {t`createBuildTc.button`} {/* TODO: Dialog Wanted to use a Dialog here, but was having some weird issues with closing out of it */} - {/* TODO: Translation */} @@ -1051,19 +1063,21 @@ function CopyTcButton({ build }: { build: GeneratedBuild }) { - Copy over this build to a new TC Build + {t`createBuildTc.desc`} setName(e.target.value)} autoFocus margin="dense" - label="TC Build Name" + label={t`createBuildTc.label`} fullWidth /> - + @@ -1077,6 +1091,7 @@ function CopyBuildButton({ }: { build: GeneratedBuild }) { + const { t } = useTranslation('page_character_optimize') const [name, setName] = useState('') const [showPrompt, onShowPrompt, OnHidePrompt] = useBoolState() @@ -1102,10 +1117,9 @@ function CopyBuildButton({ startIcon={} onClick={onShowPrompt} > - New Build + {t`createBuildReal.button`} {/* TODO: Dialog Wanted to use a Dialog here, but was having some weird issues with closing out of it */} - {/* TODO: Translation */} @@ -1124,20 +1138,22 @@ function CopyBuildButton({ - Copy over this build to a new build + {t`createBuildReal.desc`}
setName(e.target.value)} autoFocus margin="dense" - label="Build Name" + label={t`createBuildReal.label`} fullWidth /> - + diff --git a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabTheorycraft/index.tsx b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabTheorycraft/index.tsx index 529ce567a7..38f1ed0df8 100644 --- a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabTheorycraft/index.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabTheorycraft/index.tsx @@ -336,7 +336,7 @@ export default function TabTheorycraft() { value={distributedSubstats} disabled={!optimizationTarget || solving} onChange={(v) => v !== undefined && setDistributedSubstats(v)} - endAdornment={'Substats'} + endAdornment={t`tabTheorycraft.distInput`} sx={{ borderRadius: 1, px: 1, @@ -390,19 +390,19 @@ export default function TabTheorycraft() { The selected Optimization target and constraints scales with:{' '} - {[...scalesWith] - .map((k) => ( - - - - - )) - .flatMap((value, index, array) => { - if (index === array.length - 2) - return [value, , and ] - if (index === array.length - 1) return value - return [value, , ] - })} + {new Intl.ListFormat() + .format(Array(scalesWith.size).fill('\u200B')) + .split(/([^\u200B]+)/) + .map((str, i) => + str === '\u200B' + ? ((k) => ( + + + + + ))([...scalesWith][i / 2]) + : str + )} . The solver will only distribute stats to these substats. {' '} diff --git a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabUpgradeOpt/LevelFilter.tsx b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabUpgradeOpt/LevelFilter.tsx index 817c79acc4..e09fae832c 100644 --- a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabUpgradeOpt/LevelFilter.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabUpgradeOpt/LevelFilter.tsx @@ -6,7 +6,6 @@ import { CardContent, Divider, Tooltip, Typography } from '@mui/material' import { memo } from 'react' import { useTranslation } from 'react-i18next' -// TODO: Translation export const LevelFilter = memo(function LevelFilter({ levelTotal, upOptLevelLow, diff --git a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabUpgradeOpt/UpgradeOptChartCard.tsx b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabUpgradeOpt/UpgradeOptChartCard.tsx index 16ad56ae51..f1087a0252 100644 --- a/libs/gi/page-team/src/CharacterDisplay/Tabs/TabUpgradeOpt/UpgradeOptChartCard.tsx +++ b/libs/gi/page-team/src/CharacterDisplay/Tabs/TabUpgradeOpt/UpgradeOptChartCard.tsx @@ -19,6 +19,7 @@ import { uiInput as input } from '@genshin-optimizer/gi/wr' import CheckroomIcon from '@mui/icons-material/Checkroom' import { Box, Button, Divider, Grid, Tooltip, Typography } from '@mui/material' import { useCallback, useContext, useEffect, useMemo } from 'react' +import { useTranslation } from 'react-i18next' import { Area, ComposedChart, @@ -146,6 +147,7 @@ function UpgradeOptChartCardGraph({ upOptCalc, ix, }: Props) { + const { t } = useTranslation('page_character_optimize') const upArt = upOptCalc.artifacts[ix] const database = useDatabase() const [, forceUpdate] = useForceUpdate() @@ -224,13 +226,13 @@ function UpgradeOptChartCardGraph({ const probUpgradeText = ( - Prob. upgrade{isExact ? '' : ' (est.)'}:{' '} + {t('upOptChart.prob', { est: isExact ? '' : t`upOptChart.est` })} {(100 * reportP).toFixed(1)}% ) const avgIncText = ( - Average increase{isExact ? '' : ' (est.)'}:{' '} + {t('upOptChart.average', { est: isExact ? '' : t`upOptChart.est` })} {reportD <= 0 ? '' : '+'} {((100 * reportD) / thr0).toFixed(1)}% @@ -262,9 +264,9 @@ function UpgradeOptChartCardGraph({ > {isCurrentlyEquipped ? ( - Equipped + {t`upOptChart.equipped`} ) : ( - {'Current on Build'} + {t`upOptChart.current`} )} @@ -291,7 +293,7 @@ function UpgradeOptChartCardGraph({ tickFormatter={(v) => `${v <= 0 ? '' : '+'}${v}%`} >
@@ -112,7 +113,8 @@ export function LoadoutDropdown({ > {label ? ( - Loadout: {name} + {t`loDropdown.label`} + {name} ) : ( {name} @@ -121,7 +123,7 @@ export function LoadoutDropdown({ } {...dropdownBtnProps} > - onShow()}>Create a new Loadout + onShow()}>{t`loDropdown.create`} {teamCharIds.map((tcId) => { const { name, buildIds, buildTcIds, customMultiTargets } = database.teamChars.get(tcId)! @@ -137,15 +139,15 @@ export function LoadoutDropdown({ color={buildIds.length ? 'primary' : 'secondary'} sx={{ marginLeft: 'auto' }} > - {buildIds.length} Builds + {t(`loDropdown.builds`, { count: buildIds.length })} - {buildTcIds.length} TC Builds + {t(`loDropdown.tcs`, { count: buildTcIds.length })} - {customMultiTargets.length} Multi-Opt + {t(`loDropdown.multi`, { count: customMultiTargets.length })} ) diff --git a/libs/gi/page-team/src/TeamCharacterSelector.tsx b/libs/gi/page-team/src/TeamCharacterSelector.tsx index 9f476985eb..77dc3e52da 100644 --- a/libs/gi/page-team/src/TeamCharacterSelector.tsx +++ b/libs/gi/page-team/src/TeamCharacterSelector.tsx @@ -203,7 +203,7 @@ export default function TeamCharacterSelector({ icon={} iconPosition="start" value={'team'} - label={'Team Settings'} + label={t`teamSettings.tab.team`} onClick={() => navigate(`/teams/${teamId}/`)} /> {loadoutData.map((loadoutDatum, ind) => { @@ -227,7 +227,7 @@ export default function TeamCharacterSelector({ teamCharKey ? ( ) : ( - `Character ${ind + 1}` // TODO: Translation + t('teamSettings.tab.char', { count: ind + 1 }) ) } onClick={() => diff --git a/libs/gi/page-team/src/TeamSetting/TeamComponents.tsx b/libs/gi/page-team/src/TeamSetting/TeamComponents.tsx index affefead4e..5027d92d38 100644 --- a/libs/gi/page-team/src/TeamSetting/TeamComponents.tsx +++ b/libs/gi/page-team/src/TeamSetting/TeamComponents.tsx @@ -41,9 +41,11 @@ import { Typography, } from '@mui/material' import { Suspense, useContext, useMemo } from 'react' +import { useTranslation } from 'react-i18next' import { Link } from 'react-router-dom' export function TeamBuffDisplay() { + const { t } = useTranslation('page_team') const { data } = useContext(DataContext) const nodes = useMemo(() => { const teamBuffs = data.getTeamBuff() @@ -70,7 +72,7 @@ export function TeamBuffDisplay() { > }> - Received Team Buffs + {t`teamComponents.teamBuffs`} {nodes.length} @@ -192,6 +194,7 @@ function TcEquipmentRow({ }: { loadoutDatum: LoadoutDatum }) { + const { t } = useTranslation('page_team') const { artifact: { sets }, } = useBuildTc(buildTcId)! @@ -205,8 +208,7 @@ function TcEquipmentRow({ gap: 1, }} > - {/* TODO: Translation */} - TC Build + {t`teamComponents.tcBadge`} {Object.entries(sets).map(([setKey, number]) => ( void teamId: string }) { + const { t } = useTranslation('page_team') const database = useDatabase() const team = useTeam(teamId)! const { loadoutData } = team @@ -93,7 +94,7 @@ export default function TeamExportModal({ const dataStr = JSON.stringify(data) navigator.clipboard .writeText(dataStr) - .then(() => alert('Copied team data to clipboard.')) + .then(() => alert(t`exportModal.msg`)) .catch(console.error) } const [selAll, setSelAll] = useState(true) @@ -134,7 +135,7 @@ export default function TeamExportModal({ @@ -151,12 +152,19 @@ export default function TeamExportModal({ }} > - Export the team data to be imported by another user. All the team - and loadout data (bonus stats, enemy config, optimize config) are - exported. All exported non-TC builds are converted to TC builds. + + Export the team data to be imported by another user. All the + team and loadout data (bonus stats, enemy config, optimize + config) are exported. All exported non-TC builds are converted + to TC builds. + - @@ -189,7 +197,7 @@ export default function TeamExportModal({ sx={{ display: 'flex', gap: 2, justifyContent: 'flex-end' }} >
@@ -205,6 +213,7 @@ function LoadoutSetting({ setting: LoadoutExportSetting setSetting: (loadoutExportSetting: Partial) => void }) { + const { t } = useTranslation('page_team') const database = useDatabase() const teamChar = useTeamChar(loadout.teamCharId)! const { @@ -258,7 +267,7 @@ function LoadoutSetting({ sx={{ display: 'flex', gap: 1, alignItems: 'center' }} > - Optimization Target: + {t`exportModal.target`} - Mtargets to Export + {t`exportModal.mTargets`} @@ -326,7 +335,7 @@ function LoadoutSetting({ - Builds to Export + {t`exportModal.builds`} @@ -342,7 +351,7 @@ function LoadoutSetting({ tabIndex={-1} disableRipple /> - + {buildIds.map((buildId) => { @@ -395,7 +404,7 @@ function LoadoutSetting({ - {buildTc.name} TC Build + {buildTc.name} {t`exportModal.tcBadge`} } /> diff --git a/libs/gi/page-team/src/TeamSetting/index.tsx b/libs/gi/page-team/src/TeamSetting/index.tsx index 4e5db5ec75..cbefefe96e 100644 --- a/libs/gi/page-team/src/TeamSetting/index.tsx +++ b/libs/gi/page-team/src/TeamSetting/index.tsx @@ -20,6 +20,7 @@ import DeleteForeverIcon from '@mui/icons-material/DeleteForever' import type { ButtonProps } from '@mui/material' import { Alert, Box, Button, CardContent, Grid } from '@mui/material' import { Suspense, useMemo, useState } from 'react' +import { Trans, useTranslation } from 'react-i18next' import { useNavigate } from 'react-router-dom' import BuildDropdown from '../BuildDropdown' import { LoadoutDropdown } from '../LoadoutDropdown' @@ -27,7 +28,6 @@ import { ResonanceDisplay } from './ResonanceDisplay' import { TeammateDisplay } from './TeamComponents' import TeamExportModal from './TeamExportModal' -// TODO: Translation export default function TeamSetting({ teamId, teamData, @@ -36,6 +36,7 @@ export default function TeamSetting({ teamData?: TeamData buttonProps?: ButtonProps }) { + const { t } = useTranslation('page_team') const navigate = useNavigate() const database = useDatabase() const [show, onShow, onHide] = useBoolState() @@ -64,7 +65,7 @@ export default function TeamSetting({ disabled={noChars} onClick={onShow} > - Export Team + {t`teamSettings.exportBtn`} } > - Delete Team + {t`teamSettings.deleteBtn`} @@ -102,6 +103,7 @@ function TeamEditor({ teamId: string teamData?: TeamData }) { + const { t } = useTranslation('page_team') const database = useDatabase() const team = database.teams.get(teamId)! const { loadoutData } = team @@ -184,8 +186,10 @@ function TeamEditor({ - The first character in the team receives any "active on-field character" - buffs, and cannot be empty. + + The first character in the team receives any "active on-field + character" buffs, and cannot be empty. + {loadoutData.map((loadoutDatum, ind) => ( @@ -207,7 +211,7 @@ function TeamEditor({ disabled={!!ind && !loadoutData.some((id) => id)} startIcon={} > - Add Character + {t`teamSettings.addCharBtn`} )} @@ -229,6 +233,7 @@ function CharSelButton({ teamData?: TeamData onClickChar: () => void }) { + const { t } = useTranslation('page_team') const database = useDatabase() const { teamCharId } = loadoutDatum const { key: characterKey } = database.teamChars.get(teamCharId)! @@ -291,11 +296,11 @@ function CharSelButton({ /> {index ? ( ) : ( )} {dataContextValue && ( diff --git a/libs/gi/page-team/src/index.tsx b/libs/gi/page-team/src/index.tsx index e488e7c11f..d50c5f6ae3 100644 --- a/libs/gi/page-team/src/index.tsx +++ b/libs/gi/page-team/src/index.tsx @@ -126,6 +126,7 @@ function Page({ teamId }: { teamId: string }) { 'sillyWisher_charNames', 'charNames_gen', 'page_character', + 'page_team', ]) useTitle( @@ -136,11 +137,11 @@ function Page({ teamId }: { teamId: string }) { silly ? 'sillyWisher_charNames' : 'charNames_gen' }:${charKeyToLocGenderedCharKey(characterKey, gender)}` ) - : t('Team Settings') + : t`page_team:teamSettings.tab.team` const tabName = tab ? t(`page_character:tabs.${tab}`) : characterKey - ? t('Loadout/Build') + ? t`page_character:tabs.setting` : tab return tabName ? `${team.name} - ${charName} - ${tabName}` diff --git a/libs/gi/page-teams/src/index.tsx b/libs/gi/page-teams/src/index.tsx index 338c7c7106..05300f3a6e 100644 --- a/libs/gi/page-teams/src/index.tsx +++ b/libs/gi/page-teams/src/index.tsx @@ -37,10 +37,9 @@ import { teamFilterConfigs, teamSortConfigs, teamSortMap } from './TeamSort' const columns = { xs: 1, sm: 2, md: 2, lg: 3, xl: 3 } const numToShowMap = { xs: 6, sm: 12, md: 18, lg: 24, xl: 24 } -// TODO: Translation - export default function PageTeams() { const { t } = useTranslation([ + 'page_team', 'page_teams', // Always load these 2 so character names are loaded for searching/sorting 'sillyWisher_charNames', @@ -70,10 +69,11 @@ export default function PageTeams() { try { const dataObj = JSON.parse(data) if (!database.teams.import(dataObj)) - window.alert(`Data verification failed.`) + window.alert(t`importForm.error.verifi`) onHideImport() } catch (e) { - window.alert(`Data Import failed. ${e}`) + window.alert(t`importForm.error.import` + `\n${e}`) + return } } @@ -154,7 +154,7 @@ export default function PageTeams() { onChange={(e: ChangeEvent) => setSearchTerm(e.target.value) } - label="Team Name" + label={t`searchLabel.team`} // size="small" sx={{ height: '100%', flexGrow: 1 }} InputProps={{ @@ -178,20 +178,20 @@ export default function PageTeams() { - + - Import a team in JSON form below. + {t`importForm.desc`} setData(e.target.value)} multiline @@ -202,7 +202,7 @@ export default function PageTeams() { disabled={!data} onClick={importData} > - Import + {t`importForm.importBtn`} @@ -213,7 +213,7 @@ export default function PageTeams() { color="info" startIcon={} > - Import Team + {t`importTeamBtn`} - - - Weapon Filter - - + {t`weaponFilterTitle`} { })) export default ExpandButton - -// TODO: Translation export function EnemyExpandCard({ teamId }: { teamId: string }) { + const { t } = useTranslation('page_team') const [expanded, setexpanded] = useState(false) const toggle = useCallback( () => setexpanded(!expanded), @@ -69,7 +69,8 @@ export function EnemyExpandCard({ teamId }: { teamId: string }) { color="success" label={ - Enemy {enemyLevel} + {t`enemyEditor.enemyLevel`} + {enemyLevel} } /> @@ -78,8 +79,12 @@ export function EnemyExpandCard({ teamId }: { teamId: string }) { ))} - DEF Red. {enemyDefRed_} - DEF Ignore {enemyDefIgn_} + + {t('enemyEditor.defIgn', { value: enemyDefIgn_ })} + + + {t('enemyEditor.defRed', { value: enemyDefRed_ })} + - To get the specific resistance values of enemies, please visit the - wiki. + {t`enemyEditor.announceBtn`} @@ -220,7 +225,7 @@ export function EnemyEditor({ ) } > - Immunity + {t`enemyEditor.immunity`} @@ -257,11 +262,7 @@ export function EnemyEditor({ /> - - Note: Genshin Impact halves resistance shred values below 0%. For the - sake of calculations enter the RAW value and GO will do the rest. - (e.g. 10% - 20% = -10%) - + {t`enemyEditor.note`} ) diff --git a/libs/gi/ui/src/components/build/BuildCard.tsx b/libs/gi/ui/src/components/build/BuildCard.tsx index d6e33ab106..7a17e57a3f 100644 --- a/libs/gi/ui/src/components/build/BuildCard.tsx +++ b/libs/gi/ui/src/components/build/BuildCard.tsx @@ -15,8 +15,8 @@ import { Typography, } from '@mui/material' import type { ReactNode } from 'react' +import { useTranslation } from 'react-i18next' -// TODO: Translation export function BuildCard({ name, description, @@ -42,6 +42,7 @@ export function BuildCard({ onRemove?: () => void hideFooter?: boolean }) { + const { t } = useTranslation('build') const clickableAreaContent = ( <> Edit Build Settings} + title={{t`buildCardTip.edit`}} placement="top" arrow > @@ -99,7 +100,7 @@ export function BuildCard({ Copy to TC Builds} + title={{t`buildCardTip.copyTc`}} placement="top" arrow > @@ -113,7 +114,7 @@ export function BuildCard({ Duplicate Build} + title={{t`buildCardTip.duplicate`}} placement="top" arrow > @@ -127,7 +128,7 @@ export function BuildCard({ Equip Build} + title={{t`buildCardTip.equip`}} placement="top" arrow > @@ -141,7 +142,7 @@ export function BuildCard({ Delete Build} + title={{t`buildCardTip.delete`}} placement="top" arrow > diff --git a/libs/gi/ui/src/components/build/BuildDisplayItem.tsx b/libs/gi/ui/src/components/build/BuildDisplayItem.tsx index a0589617f1..f6b6c148a5 100644 --- a/libs/gi/ui/src/components/build/BuildDisplayItem.tsx +++ b/libs/gi/ui/src/components/build/BuildDisplayItem.tsx @@ -81,7 +81,6 @@ type BuildDisplayItemProps = { mainStatAssumptionLevel: number } -// TODO: Translation for build UI //for displaying each artifact build export const BuildDisplayItem = memo(function BuildDisplayItem({ label, @@ -90,6 +89,7 @@ export const BuildDisplayItem = memo(function BuildDisplayItem({ disabled, mainStatAssumptionLevel, }: BuildDisplayItemProps) { + const { t } = useTranslation('page_character_optimize') const { loadoutDatum: { buildType, buildId }, teamChar: { buildIds = [] }, @@ -345,8 +345,9 @@ export const BuildDisplayItem = memo(function BuildDisplayItem({ {label} - {/* TODO: Translation */} - {currentlyEquipped && (Equipped)} + {currentlyEquipped && ( + {t`buildDisplay.equippedBadge`} + )} )} @@ -361,8 +362,7 @@ export const BuildDisplayItem = memo(function BuildDisplayItem({ )?.name } - {/* TODO: Translation */} - {isActiveBuild && (current build)} + {isActiveBuild && {t`buildDisplay.currentBadge`}} {sameAsBuildIds.length > 1 && ( } > - Equip to Current Build + {t`buildDisplay.equipToCrr`} {extraButtonsRight} @@ -452,6 +452,7 @@ function CompareWeaponModal({ showWeapon: boolean onClose: () => void }) { + const { t } = useTranslation('page_character_optimize') const database = useDatabase() const diffCurrentWeap = oldId !== newId @@ -479,12 +480,12 @@ function CompareWeaponModal({ - Old Weapon + {t`buildDisplay.oldWeapon`} {oldId === 'tc' ? ( - TC Weapon + {t`buildDisplay.tcWeapon`} ) : ( @@ -501,7 +502,7 @@ function CompareWeaponModal({ - New Weapon + {t`buildDisplay.newWeapon`} diff --git a/libs/gi/ui/src/components/build/EquipBuildModal.tsx b/libs/gi/ui/src/components/build/EquipBuildModal.tsx index 31c6a49c84..8fbbfc6d1b 100644 --- a/libs/gi/ui/src/components/build/EquipBuildModal.tsx +++ b/libs/gi/ui/src/components/build/EquipBuildModal.tsx @@ -27,6 +27,7 @@ import { } from '@mui/material' import type { ReactNode } from 'react' import { useContext, useMemo, useState } from 'react' +import { Trans, useTranslation } from 'react-i18next' import type { dataContextObj } from '../../context' import { DataContext } from '../../context' import { useCharData, useTeamData } from '../../hooks' @@ -56,8 +57,8 @@ export function EquipBuildModal(props: Props & { show: boolean }) { ) } -/* TODO: Translation */ function Content(props: Props) { + const { t } = useTranslation('build') const { currentName, currentWeaponId, @@ -81,7 +82,8 @@ function Content(props: Props) { const toEquip = () => { if (copyCurrent) { database.teamChars.newBuild(teamCharId, { - name: name !== '' ? name : `Duplicate of ${currentName}`, + name: + name !== '' ? name : t('equipBuildModal.newName', { currentName }), artifactIds: currentArtifactIds, weaponId: currentWeaponId, }) @@ -99,7 +101,10 @@ function Content(props: Props) { - Confirm Equipment Changes for {currentName} + + Confirm Equipment Changes for{' '} + {{ currentName } as any} + } @@ -118,16 +123,15 @@ function Content(props: Props) { }} > {/* Confirmation Message */} - - Do you want to make the changes shown below? - + {t`equipBuildModal.desc`} {teamCharId && ( - Copy the current equipment in {currentName} to - a new build. Otherwise, they will be overwritten. - + + Copy the current equipment in{' '} + {{ currentName } as any} to a new build. + Otherwise, they will be overwritten. + } control={ setName(e.target.value)} size="small" @@ -157,10 +161,10 @@ function Content(props: Props) { }} > {/* Active Build */} diff --git a/libs/gi/ui/src/components/character/CharacterMultiAutocomplete.tsx b/libs/gi/ui/src/components/character/CharacterMultiAutocomplete.tsx index 4bc727f1f8..f6fd9a8f7a 100644 --- a/libs/gi/ui/src/components/character/CharacterMultiAutocomplete.tsx +++ b/libs/gi/ui/src/components/character/CharacterMultiAutocomplete.tsx @@ -27,7 +27,12 @@ export function CharacterMultiAutocomplete({ setCharKey: (v: CharacterKey[]) => void acProps?: Partial> }) { - const { t } = useTranslation(['sillyWisher_charNames', 'charNames_gen']) + const { t } = useTranslation([ + 'page_team', + 'sillyWisher_charNames', + 'charNames_gen', + ]) + const { silly } = useContext(SillyContext) const database = useDatabase() const { gender } = useDBMeta() @@ -129,7 +134,7 @@ export function CharacterMultiAutocomplete({ return ( }> void }) { + const { t } = useTranslation('page_weapon') const [show, onOpen, onClose] = useBoolState() return ( {' '} - {/* TODO translation */} - {weaponTypeKey} + {t(`weaponType.${weaponTypeKey}`)} diff --git a/libs/gi/ui/src/components/character/card/CharacterCardEquipmentRow.tsx b/libs/gi/ui/src/components/character/card/CharacterCardEquipmentRow.tsx index 6f31599959..fe1dbeaa97 100644 --- a/libs/gi/ui/src/components/character/card/CharacterCardEquipmentRow.tsx +++ b/libs/gi/ui/src/components/character/card/CharacterCardEquipmentRow.tsx @@ -5,6 +5,7 @@ import { useDatabase } from '@genshin-optimizer/gi/db-ui' import { input } from '@genshin-optimizer/gi/wr' import { Box, Card, Grid, Typography } from '@mui/material' import { useContext } from 'react' +import { useTranslation } from 'react-i18next' import { DataContext } from '../../../context' import { ArtifactCardPico } from '../../artifact' import { WeaponCardPico, WeaponCardPicoObj } from '../../weapon' @@ -56,6 +57,7 @@ export function CharacterCardEquipmentRowTC({ }: { weapon: ICachedWeapon }) { + const { t } = useTranslation('page_weapon') return ( @@ -74,9 +76,8 @@ export function CharacterCardEquipmentRowTC({ alignItems: 'center', }} > - {/* TODO: Translation */} - TC Build + {t`tcBuild`} diff --git a/libs/gi/ui/src/components/character/card/CharacterCardStats.tsx b/libs/gi/ui/src/components/character/card/CharacterCardStats.tsx index 2e1ce3ab2c..232f0e63c4 100644 --- a/libs/gi/ui/src/components/character/card/CharacterCardStats.tsx +++ b/libs/gi/ui/src/components/character/card/CharacterCardStats.tsx @@ -2,11 +2,13 @@ import type { CardBackgroundColor } from '@genshin-optimizer/common/ui' import { input } from '@genshin-optimizer/gi/wr' import { ListItem, Typography } from '@mui/material' import { useContext } from 'react' +import { useTranslation } from 'react-i18next' import { DataContext } from '../../../context' import { resolveInfo } from '../../../util' import { FieldDisplayList, NodeFieldDisplay } from '../../FieldDisplay' export function CharacterCardStats({ bgt }: { bgt?: CardBackgroundColor }) { + const { t } = useTranslation('page_character_optimize') const { data } = useContext(DataContext) const specialNode = data.get(input.special) const { name, icon } = resolveInfo(specialNode.info) @@ -18,7 +20,7 @@ export function CharacterCardStats({ bgt }: { bgt?: CardBackgroundColor }) { {name && ( - Specialized: + {t`specialized`} {icon} {name} diff --git a/libs/gi/ui/src/components/character/editor/BuildRealSimplified.tsx b/libs/gi/ui/src/components/character/editor/BuildRealSimplified.tsx index 90fe2e2de2..50a48bc048 100644 --- a/libs/gi/ui/src/components/character/editor/BuildRealSimplified.tsx +++ b/libs/gi/ui/src/components/character/editor/BuildRealSimplified.tsx @@ -7,7 +7,6 @@ import { ArtifactCardNano } from '../../artifact' import { BuildCard } from '../../build' import { WeaponCardNano } from '../../weapon' -// TODO: Translation export function BuildRealSimplified({ buildId, characterKey, diff --git a/libs/gi/ui/src/components/character/editor/Content.tsx b/libs/gi/ui/src/components/character/editor/Content.tsx index d78a9f4203..b9927ec3f1 100644 --- a/libs/gi/ui/src/components/character/editor/Content.tsx +++ b/libs/gi/ui/src/components/character/editor/Content.tsx @@ -20,7 +20,7 @@ import CloseIcon from '@mui/icons-material/Close' import DeleteForeverIcon from '@mui/icons-material/DeleteForever' import { Box, Button, Grid, IconButton, Typography } from '@mui/material' import { useCallback, useContext, useEffect, useMemo } from 'react' -import { useTranslation } from 'react-i18next' +import { Trans, useTranslation } from 'react-i18next' import { useNavigate } from 'react-router-dom' import { DataContext, SillyContext } from '../../../context' import { AddTeamInfo } from '../../AddTeamInfo' @@ -202,6 +202,7 @@ function EquipmentSection() { ) } function InTeam() { + const { t } = useTranslation('page_character') const navigate = useNavigate() const { @@ -243,12 +244,13 @@ function InTeam() { }) navigate(`/teams/${teamId}`) } - // TODO: Translation return ( - Team Loadouts with{' '} - + + Team Loadouts with{' '} + + {!Object.values(loadoutTeamMap).length && } @@ -267,7 +269,7 @@ function InTeam() { variant="outlined" sx={{ backgroundColor: 'contentLight.main' }} > - Add new Loadout+Team + {t`charContentModal.addLoAndTeam`} diff --git a/libs/gi/ui/src/components/character/editor/LoadoutCard.tsx b/libs/gi/ui/src/components/character/editor/LoadoutCard.tsx index 140b58403d..5677221ad8 100644 --- a/libs/gi/ui/src/components/character/editor/LoadoutCard.tsx +++ b/libs/gi/ui/src/components/character/editor/LoadoutCard.tsx @@ -10,6 +10,7 @@ import { Divider, Grid, } from '@mui/material' +import { useTranslation } from 'react-i18next' import { useNavigate } from 'react-router-dom' import { TeamCard } from '../../team' import { LoadoutEditor } from './LoadoutEditor' @@ -19,7 +20,6 @@ const columns = { md: 2, } as const -// TODO: Translation export function LoadoutCard({ teamCharId, teamIds, @@ -27,6 +27,7 @@ export function LoadoutCard({ teamCharId: string teamIds: string[] }) { + const { t } = useTranslation('page_character') const navigate = useNavigate() const database = useDatabase() const onAddTeam = (teamCharId: string) => { @@ -71,7 +72,7 @@ export function LoadoutCard({ color="info" startIcon={} > - Add new Team + {t`charContentModal.addTeam`} diff --git a/libs/gi/ui/src/components/character/editor/LoadoutEditor.tsx b/libs/gi/ui/src/components/character/editor/LoadoutEditor.tsx index 7861034aa9..c784cc7130 100644 --- a/libs/gi/ui/src/components/character/editor/LoadoutEditor.tsx +++ b/libs/gi/ui/src/components/character/editor/LoadoutEditor.tsx @@ -34,6 +34,7 @@ import { Typography, } from '@mui/material' import { useMemo } from 'react' +import { useTranslation } from 'react-i18next' import { useNavigate } from 'react-router-dom' import { OptimizationIcon } from '../../../consts' import { DocumentDisplay } from '../../DocumentDisplay' @@ -56,6 +57,7 @@ export function LoadoutEditor({ teamCharId: string teamIds: string[] }) { + const { t } = useTranslation('loadout') const [showRemoval, onShowRemoval, onHideRemoval] = useBoolState() const navigate = useNavigate() const database = useDatabase() @@ -122,14 +124,14 @@ export function LoadoutEditor({ database.teamChars.set(teamCharId, { name })} /> database.teamChars.set(teamCharId, { description }) @@ -146,7 +148,7 @@ export function LoadoutEditor({ fullWidth startIcon={} > - Duplicate Loadout + {t`loadoutEditor.dupBtn`} @@ -164,7 +166,7 @@ export function LoadoutEditor({ color="error" onClick={onShowRemoval} > - Delete Loadout + {t`loadoutEditor.delBtn`} @@ -190,7 +192,7 @@ export function LoadoutEditor({ }} > - Optimization Target + {t`loadoutEditor.optTarget`} } /> @@ -218,7 +220,8 @@ export function LoadoutEditor({ - Conditionals: {conditionalCount} + {t`loadoutEditor.conditionals`} + {conditionalCount} @@ -231,7 +234,7 @@ export function LoadoutEditor({ title={ - Builds + {t`loadoutEditor.builds`} } /> @@ -267,7 +270,7 @@ export function LoadoutEditor({ title={ - Teams + {t`loadoutEditor.teams`} } /> @@ -295,7 +298,7 @@ export function LoadoutEditor({ color="info" startIcon={} > - Add new Team + {t`loadoutEditor.addNewTeam`} @@ -310,6 +313,7 @@ function BonusStatsCard({ }: { bonusStats: TeamCharacter['bonusStats'] }) { + const { t } = useTranslation('loadout') return ( - Bonus Stats + {t`loadoutEditor.bonusStats`} } titleTypographyProps={{ variant: 'h6' }} @@ -348,6 +352,7 @@ function MultiTargetCard({ }: { customMultiTargets: TeamCharacter['customMultiTargets'] }) { + const { t } = useTranslation('loadout') return ( - Custom multi-targets + {t`loadoutEditor.mltTargets`} } titleTypographyProps={{ variant: 'h6' }} diff --git a/libs/gi/ui/src/components/character/editor/LoadoutHeaderContent.tsx b/libs/gi/ui/src/components/character/editor/LoadoutHeaderContent.tsx index 4038d9dc33..dc4b39bbd2 100644 --- a/libs/gi/ui/src/components/character/editor/LoadoutHeaderContent.tsx +++ b/libs/gi/ui/src/components/character/editor/LoadoutHeaderContent.tsx @@ -7,6 +7,7 @@ import PersonIcon from '@mui/icons-material/Person' import SettingsIcon from '@mui/icons-material/Settings' import { Box, CardContent, Typography } from '@mui/material' import type { ReactNode } from 'react' +import { useTranslation } from 'react-i18next' import { OptimizationIcon } from '../../../consts' import { OptimizationTargetDisplay } from './OptimizationTargetDisplay' export function LoadoutHeaderContent({ @@ -18,6 +19,7 @@ export function LoadoutHeaderContent({ showSetting?: boolean children?: ReactNode }) { + const { t } = useTranslation('loadout') const database = useDatabase() const { name, @@ -46,26 +48,29 @@ export function LoadoutHeaderContent({ - Builds: {buildIds.length} + {t`loadoutHeader.builds`} + {buildIds.length} - TC Builds: {buildTcIds.length} + {t`loadoutHeader.tcBuilds`} + {buildTcIds.length} - Custom multi-targets: {customMultiTargets.length} + {t`loadoutHeader.mltTargets`} + {customMultiTargets.length} {optimizationTarget && ( - Optimization Target: + {t`loadoutHeader.optTarget`} void conditionalCount: number }) { + const { t } = useTranslation('loadout') const database = useDatabase() const { name, @@ -60,7 +62,9 @@ export function RemoveLoadout({ - Delete Loadout: {name}? + + Delete Loadout: {{ name } as any}? + } action={ @@ -76,14 +80,13 @@ export function RemoveLoadout({ {description} )} - - Deleting the Loadout will also delete the following data: - + {t`loadoutDelModal.desc`} {!!buildIds.length && ( - All saved builds: {buildIds.length}{' '} + {t`loadoutDelModal.builds`} + {buildIds.length}{' '} @@ -112,7 +115,8 @@ export function RemoveLoadout({ {!!buildTcIds.length && ( - All saved TC builds: {buildTcIds.length}{' '} + {t`loadoutDelModal.tcBuilds`} + {buildTcIds.length}{' '} @@ -141,7 +145,8 @@ export function RemoveLoadout({ {!!customMultiTargets.length && ( - All Custom Multi-targets: {customMultiTargets.length}{' '} + {t`loadoutDelModal.mTargets`} + {customMultiTargets.length}{' '} @@ -169,24 +174,25 @@ export function RemoveLoadout({ {!!Object.keys(bonusStats).length && ( - Bonus stats: {Object.keys(bonusStats).length} + {t`loadoutDelModal.bonus`} + {Object.keys(bonusStats).length} )} {!!conditionalCount && ( - Conditionals: {conditionalCount} + {t`loadoutDelModal.condi`} + {conditionalCount} )} - Optimization Configuration + {t`loadoutDelModal.optConfig`} {!!teamIds.length && ( - Any teams with this loadout will have this loadout removed - from the team. Teams will not be deleted. Teams affected:{' '} + {t`loadoutDelModal.affected`} {teamIds.length} @@ -218,14 +224,14 @@ export function RemoveLoadout({ diff --git a/libs/gi/ui/src/components/loadout/LoadoutInfoAlert.tsx b/libs/gi/ui/src/components/loadout/LoadoutInfoAlert.tsx index 84d14f706b..2812dc0a1e 100644 --- a/libs/gi/ui/src/components/loadout/LoadoutInfoAlert.tsx +++ b/libs/gi/ui/src/components/loadout/LoadoutInfoAlert.tsx @@ -1,12 +1,16 @@ import { Alert } from '@mui/material' +import { Trans, useTranslation } from 'react-i18next' -// TODO: Translation export function LoadoutInfoAlert() { + const { t } = useTranslation('loadout') return ( - Loadouts provides character context data, including bonus - stats, conditionals, multi-targets, optimization config, and stores - builds. A single Loadout can be used for many teams. + + Loadouts provides character context data, including + bonus stats, conditionals, multi-targets, optimization config, and + stores builds. A single Loadout can be used for many + teams. + ) } diff --git a/libs/gi/ui/src/components/team/TeamCard.tsx b/libs/gi/ui/src/components/team/TeamCard.tsx index 4648010775..987c57ef22 100644 --- a/libs/gi/ui/src/components/team/TeamCard.tsx +++ b/libs/gi/ui/src/components/team/TeamCard.tsx @@ -55,8 +55,6 @@ import { getBuildTcArtifactData, iconAsset } from '../../util' import { ArtifactSlotName } from '../artifact' import { TeamDelModal } from './TeamDelModal' -// TODO: Translation - export function TeamCard({ teamId, onClick, diff --git a/libs/gi/ui/src/components/team/TeamDelModal.tsx b/libs/gi/ui/src/components/team/TeamDelModal.tsx index 5bf1c973ee..00dce246a9 100644 --- a/libs/gi/ui/src/components/team/TeamDelModal.tsx +++ b/libs/gi/ui/src/components/team/TeamDelModal.tsx @@ -23,6 +23,7 @@ import { Typography, } from '@mui/material' import { useMemo, useState } from 'react' +import { Trans, useTranslation } from 'react-i18next' import type { dataContextObj } from '../../context/DataContext' import { DataContext } from '../../context/DataContext' import { useCharData } from '../../hooks/useCharData' @@ -38,6 +39,7 @@ export function TeamDelModal({ onHide: () => void onDel: () => void }) { + const { t } = useTranslation('page_team') const database = useDatabase() const team = useTeam(teamId)! const { name, description, loadoutData } = team @@ -78,7 +80,7 @@ export function TeamDelModal({ alignItems: 'center', }} > - Delete Team: + {t`teamDelModal.teamName`} {name} {description && ( @@ -96,9 +98,11 @@ export function TeamDelModal({ - Removing the team will remove: resonance buffs, and enemy configs - stored in the team. Loadouts that are only in this team are also - selected by default for deletion. + + Removing the team will remove: resonance buffs, and enemy configs + stored in the team. Loadouts that are only in this team are also + selected by default for deletion. + {loadoutData.map((loadoutDatum, i) => loadoutDatum ? ( @@ -119,7 +123,7 @@ export function TeamDelModal({ startIcon={} onClick={onDelete} > - Delete + {t`teamDelModal.delBtn`} @@ -137,6 +141,7 @@ function LoadoutDisplay({ onClick: () => void inTeams: Team[] }) { + const { t } = useTranslation('page_team') const teamChar = useTeamChar(teamCharId)! const { key: characterKey } = teamChar const teamData = useCharData(characterKey) @@ -162,8 +167,8 @@ function LoadoutDisplay({ {inTeams.length === 1 - ? 'Only in current team' - : `In ${inTeams.length} teams`} + ? t`teamDelModal.onlyCrrTeam` + : t('teamDelModal.usingMltTeams', { count: inTeams.length })} diff --git a/libs/gi/ui/src/components/team/TeamInfoAlert.tsx b/libs/gi/ui/src/components/team/TeamInfoAlert.tsx index 021d2a8707..9ce789cd7b 100644 --- a/libs/gi/ui/src/components/team/TeamInfoAlert.tsx +++ b/libs/gi/ui/src/components/team/TeamInfoAlert.tsx @@ -1,12 +1,15 @@ import { Alert } from '@mui/material' +import { Trans, useTranslation } from 'react-i18next' -// TODO: Translation export function TeamInfoAlert() { + const { t } = useTranslation('page_team') return ( - Teams are a container for 4 character loadouts. It - provides a way for characters to apply team buffs, and configuration of - enemy stats. Loadouts can be shared between teams. + + Teams are a container for 4 character loadouts. It + provides a way for characters to apply team buffs, and configuration of + enemy stats. Loadouts can be shared between teams. + ) } diff --git a/libs/gi/ui/src/components/weapon/WeaponCard.tsx b/libs/gi/ui/src/components/weapon/WeaponCard.tsx index 7a1a92064e..49f985b7b1 100644 --- a/libs/gi/ui/src/components/weapon/WeaponCard.tsx +++ b/libs/gi/ui/src/components/weapon/WeaponCard.tsx @@ -32,7 +32,7 @@ import { } from '@mui/material' import type { ReactNode } from 'react' import { Suspense, useCallback, useMemo } from 'react' -import { useTranslation } from 'react-i18next' +import { Trans, useTranslation } from 'react-i18next' import { getCalcDisplay, resolveInfo } from '../../util' import { LocationAutocomplete, LocationName } from '../character' import { WeaponName } from './WeaponTrans' @@ -167,7 +167,9 @@ export function WeaponCardObj({ /{ascensionMaxLevel[ascension]} - Refinement {refinement} + + Refinement {{ rank: refinement } as any} +