diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 8f389160..cc2d37a3 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -4,5 +4,55 @@ "title": "Welcome, streamer", "description": "Unlock the Ultimate Dota 2 Streaming Experience with Dotabod! Boost your stream's engagement, showcase real-time stats, and delight your audience with our all-in-one streaming toolkit. Elevate your game and become the streamer you were meant to be!" }, - "live": "Live" + "live": "Live", + "button": { + "getStarted": "Get started", + "goToDashboard": "Go to dashboard", + "joinDiscord": "Join Discord" + }, + "languageCard": { + "title": "Language", + "subtitle": "The @dotabod Twitch chat bot will speak in this language.", + "usedBy": "Used by", + "dotabods": "dotabods", + "percentTranslated": "% translated", + "onlyOneUsing": "You're the only one using this language", + "helpComplete": "Help complete on Crowdin", + "fixLocaleIssues": "Fix locale issues on Crowdin" + }, + "dashboard": { + "setup": { + "title": "Setup", + "subtitle": "Let's get Dotabod working for you right away", + "twitch": "Twitch", + "dota2": "Dota 2", + "obs": "OBS", + "allDone": "All done!", + "streamOfflineWarning": "Your stream is offline, and Dotabod will only work once you start streaming and go online.", + "thatsIt": "That's it! You're all set up.", + "hopIntoMatch": "You can either hop into a match right away, or you can test Dotabod first.", + "howToTest": "How to test Dotabod", + "demoHeroStep": "Demo any hero to get Dotabod to recognize your Steam account.", + "livePreviewStep": "While demoing, visit the Live Preview page to confirm the overlay is showing.", + "troubleshootingStep": "Having trouble? Visit the Troubleshooting page to get help." + }, + "features": { + "main": { + "title": "Main features", + "subtitle": "Customize the options your stream receives." + }, + "advanced": { + "title": "Advanced features", + "subtitle": "Looking for even more? They'll be here" + }, + "chat": { + "title": "Chat features", + "subtitle": "The bot reacts with chat messages to your game events as you play your match." + }, + "overlay": { + "title": "Overlay features", + "subtitle": "Enhance your stream with these overlay features" + } + } + } } diff --git a/src/components/Button.jsx b/src/components/Button.jsx index 054a7367..2db78d91 100644 --- a/src/components/Button.jsx +++ b/src/components/Button.jsx @@ -1,6 +1,7 @@ import clsx from 'clsx' import Link from 'next/link' import { forwardRef } from 'react' +import { useTranslation } from 'next-i18next' const baseStyles = { solid: @@ -25,6 +26,7 @@ export const Button = forwardRef(function Button( { variant = 'solid', color = 'gray', className, href, ...props }, ref ) { + const { t } = useTranslation('common') className = clsx( baseStyles[variant], variantStyles[variant][color], @@ -32,8 +34,12 @@ export const Button = forwardRef(function Button( ) return href ? ( - + + {t(props.children)} + ) : ( - ) }) diff --git a/src/components/Card.tsx b/src/components/Card.tsx index 8f1dfa79..86b0ab57 100644 --- a/src/components/Card.tsx +++ b/src/components/Card.tsx @@ -1,6 +1,9 @@ import clsx from 'clsx' +import { useTranslation } from 'next-i18next' export const Card = ({ children = null, className = '', ...props }) => { + const { t } = useTranslation('common') + return (
{ )} {...props} > - {children} + {t(children)}
) } diff --git a/src/components/Dashboard/CommandDetail.tsx b/src/components/Dashboard/CommandDetail.tsx index ba4ea2b1..14fc58cd 100644 --- a/src/components/Dashboard/CommandDetail.tsx +++ b/src/components/Dashboard/CommandDetail.tsx @@ -2,727 +2,699 @@ import { chatterInfo } from '@/components/Dashboard/Features/ChatterCard' import TwitchChat from '@/components/TwitchChat' import { Settings } from '@/lib/defaultSettings' import Image from 'next/image' +import { useTranslation } from 'next-i18next' -const CommandDetail = { - [Settings.commandDisable]: { - title: 'Disable Dotabod', - description: - 'Toggle to stop or start responding to game events and commands.', - cmd: '!toggle', - alias: ['enable', 'disable'], - allowed: 'mods', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandOnline]: { - title: 'Online or offline status', - description: - 'Updates the status of your stream that Dotabod sees to online or offline.', - cmd: '!online', - alias: ['offline', 'forceonline', 'forceoffline'], - allowed: 'mods', - response: (props: Record = {}) => ( - - ), - }, - [Settings.chatter]: { - title: 'Mute Dotabod', - description: - 'Will prevent Dotabod from auto sending chatters, but will still respond to commands.', - cmd: '!mute', - alias: ['unmute'], - allowed: 'mods', - response: (props: Record = {}) => ( - - ), - }, - fixparty: { - title: 'Fix party match', - description: - "Dotabod can't detect party games right now (sadge). So if it does 25 mmr for a completed match, use !fixparty to adjust it to 20. You must type this after every party match.", - cmd: '!fixparty', - alias: ['fixsolo'], - allowed: 'mods', - response: (props: Record = {}) => ( - - ), - }, - refresh: { - title: 'Refresh', - description: - 'Refreshes your OBS overlay without having to do it from OBS. Used in case the overlay is messed up.', - cmd: '!refresh', - alias: [], - allowed: 'mods', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandSteam]: { - key: Settings.commandSteam, - title: 'Steam ID', - description: - "Retrieve the steam ID of the account you're currently playing on.", - cmd: '!steam', - alias: ['steamid', 'account'], - allowed: 'mods', - response: (props: Record = {}) => ( - - ), - }, - setmmr: { - title: 'Set MMR', - description: 'Manually set your MMR.', - cmd: '!setmmr', - alias: ['mmr=', 'mmrset'], - allowed: 'mods', - response: (props: Record = {}) => ( - - ), - }, - beta: { - title: 'Dotabod Beta', - description: - 'Want to join the beta? You will get the latest features and updates before anyone else.', - cmd: '!beta', - alias: ['joinbeta', 'leavebeta', 'betaoff', 'betaon'], - allowed: 'mods', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandPleb]: { - key: Settings.commandPleb, - title: 'Pleb', - description: - 'When you have sub only mode turned on, use !pleb to let one non-sub send a message. Then all your subs can point and laugh 😂.', - cmd: '!pleb', - alias: [], - allowed: 'mods', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandModsonly]: { - key: Settings.commandModsonly, - title: 'Mods only', - description: - 'Only allow mods to send messages in chat. Turns sub only mode on and deletes messages from subs.', - cmd: '!modsonly', - alias: [], - allowed: 'mods', - response: (props: Record = {}) => ( - - Mods only mode is now on - based - clap - . Only mods can type. - - } - /> - ), - }, - [Settings.commandCommands]: { - key: Settings.commandCommands, - title: 'Command list', - description: - 'All available commands with Dotabod. This list is filtered to only the commands you enabled. If a mod uses !commands, it will show mod only commands as well.', - cmd: '!commands', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandRanked]: { - key: Settings.commandRanked, - title: 'Ranked or not?', - description: 'Chatters can find out if this match is ranked or not.', - cmd: '!ranked', - alias: ['isranked'], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandAvg]: { - key: Settings.commandAvg, - title: 'Average MMR', - description: - 'For the current game, show the average MMR of all players. Only works if not immortal.', - cmd: '!avg', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandOpendota]: { - key: Settings.commandOpendota, - title: 'Opendota', - description: - 'Shows the Opendota link for your currently logged in steam account.', - cmd: '!opendota', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - - [Settings.commandDotabuff]: { - key: Settings.commandDotabuff, - title: 'Dotabuff', - description: - 'Shows the Dotabuff link for your currently logged in steam account.', - cmd: '!dotabuff', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandXPM]: { - key: Settings.commandXPM, - title: 'XPM', - description: 'Live experience per minute for your chatters on demand.', - cmd: '!xpm', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandWL]: { - key: Settings.commandWL, - title: 'Win / Loss', - description: - 'Says the total wins and losses for current stream duration. Disabling this command will hide these statistics in the stream overlay.', - cmd: '!wl', - alias: ['score', 'winrate', 'wr'], - allowed: 'all', - response: (props: Record = {}, all = true) => ( - <> - - {all && ( - - )} - - ), - }, - [Settings.commandMmr]: { - key: Settings.commandMmr, - title: 'MMR', - description: - 'Using chat command !mmr, viewers can get an accurate mmr update in chat. Auto updates immediately with every match!', - cmd: '!mmr', - alias: ['rank', 'medal'], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandGPM]: { - key: Settings.commandGPM, - title: 'GPM', - description: - 'At any time, chatters can request your live gold per minute with !gpm. Playing alch or anti-mage? Show off your gpm!', - cmd: '!gpm', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandAPM]: { - key: Settings.commandAPM, - title: 'APM', - description: - 'Actions per minute. A good indicator of speed and efficiency.', - cmd: '!apm', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, +const CommandDetail = () => { + const { t } = useTranslation('common') - [Settings.commandNP]: { - key: Settings.commandNP, - title: 'Notable players', - description: 'Find out if your match has any pros.', - cmd: '!np', - alias: ['who', 'players'], - allowed: 'all', - response: (props: Record = {}, all = true) => ( -
- = {}) => ( + + ), + }, + [Settings.commandOnline]: { + title: t('commandOnline.title'), + description: t('commandOnline.description'), + cmd: '!online', + alias: ['offline', 'forceonline', 'forceoffline'], + allowed: 'mods', + response: (props: Record = {}) => ( + + ), + }, + [Settings.chatter]: { + title: t('chatter.title'), + description: t('chatter.description'), + cmd: '!mute', + alias: ['unmute'], + allowed: 'mods', + response: (props: Record = {}) => ( + + ), + }, + fixparty: { + title: t('fixparty.title'), + description: t('fixparty.description'), + cmd: '!fixparty', + alias: ['fixsolo'], + allowed: 'mods', + response: (props: Record = {}) => ( + + ), + }, + refresh: { + title: t('refresh.title'), + description: t('refresh.description'), + cmd: '!refresh', + alias: [], + allowed: 'mods', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandSteam]: { + key: Settings.commandSteam, + title: t('commandSteam.title'), + description: t('commandSteam.description'), + cmd: '!steam', + alias: ['steamid', 'account'], + allowed: 'mods', + response: (props: Record = {}) => ( + + ), + }, + setmmr: { + title: t('setmmr.title'), + description: t('setmmr.description'), + cmd: '!setmmr', + alias: ['mmr=', 'mmrset'], + allowed: 'mods', + response: (props: Record = {}) => ( + + ), + }, + beta: { + title: t('beta.title'), + description: t('beta.description'), + cmd: '!beta', + alias: ['joinbeta', 'leavebeta', 'betaoff', 'betaon'], + allowed: 'mods', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandPleb]: { + key: Settings.commandPleb, + title: t('commandPleb.title'), + description: t('commandPleb.description'), + cmd: '!pleb', + alias: [], + allowed: 'mods', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandModsonly]: { + key: Settings.commandModsonly, + title: t('commandModsonly.title'), + description: t('commandModsonly.description'), + cmd: '!modsonly', + alias: [], + allowed: 'mods', + response: (props: Record = {}) => ( + - All Pick: + {t('commandModsonly.response')} south korea - DuBu (Shadow Shaman) · russia - Collapse (Magnus) · - estonia - Puppy (Chen) · - usa - PPD (Tusk) · - usa - Rajjix (Timbersaw) } /> - {all && ( - <> - + ), + }, + [Settings.commandCommands]: { + key: Settings.commandCommands, + title: t('commandCommands.title'), + description: t('commandCommands.description'), + cmd: '!commands', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandRanked]: { + key: Settings.commandRanked, + title: t('commandRanked.title'), + description: t('commandRanked.description'), + cmd: '!ranked', + alias: ['isranked'], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandAvg]: { + key: Settings.commandAvg, + title: t('commandAvg.title'), + description: t('commandAvg.description'), + cmd: '!avg', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandOpendota]: { + key: Settings.commandOpendota, + title: t('commandOpendota.title'), + description: t('commandOpendota.description'), + cmd: '!opendota', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandDotabuff]: { + key: Settings.commandDotabuff, + title: t('commandDotabuff.title'), + description: t('commandDotabuff.description'), + cmd: '!dotabuff', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandXPM]: { + key: Settings.commandXPM, + title: t('commandXPM.title'), + description: t('commandXPM.description'), + cmd: '!xpm', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandWL]: { + key: Settings.commandWL, + title: t('commandWL.title'), + description: t('commandWL.description'), + cmd: '!wl', + alias: ['score', 'winrate', 'wr'], + allowed: 'all', + response: (props: Record = {}, all = true) => ( + <> + + {all && ( - - )} -
- ), - }, - [Settings.commandSmurfs]: { - key: Settings.commandSmurfs, - title: 'Smurfs', - description: 'Shows total games played for each player in the match.', - cmd: '!smurfs', - alias: ['lifetimes', 'totals', 'games', 'smurf'], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandGM]: { - key: Settings.commandGM, - title: 'Game medals', - description: 'Return the rankings for each players in the game.', - cmd: '!gm', - alias: ['medals', 'ranks'], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandLG]: { - key: Settings.commandLG, - title: 'Last game', - description: "Find out if you're playing with anyone from your last match.", - cmd: '!lg', - alias: ['lastgame'], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - ping: { - title: 'Ping', - description: - 'If Dotabod responds with Pong, that means the servers are operating normally.', - cmd: '!ping', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - dotabod: { - title: 'About', - description: "Tell everyone about the new bot you're using!", - cmd: '!dotabod', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandLGS]: { - key: Settings.commandLGS, - title: 'Last game score', - description: - 'Quickly see whether or not you won last game, duration, how long ago', - cmd: '!lgs', - alias: ['lastgamescore', 'lgscore', 'lgwl'], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandProfile]: { - key: Settings.commandProfile, - title: 'Profile', - description: - 'Shows the profile link for the hero color you specify during a live match.', - cmd: '!profile', - alias: ['stats', 'check'], - allowed: 'all', - response: (props: Record = {}) => ( - <> - - - - ), - }, - [Settings.commandHero]: { - key: Settings.commandHero, - title: 'Hero', - description: - "Shows currently playing hero's score in the last 30 days. Uses OpenDota API, so your profile must be public for this to work.", - cmd: '!hero', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - <> - - - - ), - }, - [Settings.commandBuilds]: { - key: Settings.commandBuilds, - title: 'Dota 2 Pro Tracker', - description: - 'Get a quick link to pro builds and guides for your currently playing hero.', - cmd: '!builds', - alias: ['dota2pt', 'build', 'd2pt', 'getbuild'], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandDelay]: { - key: Settings.commandDelay, - title: 'Stream delay', - description: - 'Tells chat the Dotabod bot delay you configured from the features page.', - cmd: '!delay', - alias: ['streamdelay'], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandRosh]: { - key: Settings.commandRosh, - title: 'Roshan and aegis', - description: 'Tells chat the current roshan and aegis status.', - cmd: '!rosh', - alias: ['aegis'], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandItems]: { - key: Settings.commandItems, - title: 'Get items', - description: - 'Want to know what a hero, enemy or ally, has in their inventory?', - cmd: '!items', - alias: ['item'], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandVersion]: { - title: 'Version', - description: 'Tells chat the current running version of Dotabod.', - cmd: '!version', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandResetwl]: { - title: 'Reset win loss', - description: 'Resets your win losses to 0-0.', - cmd: '!resetwl', - allowed: 'mods', - alias: [], - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandLocale]: { - title: 'Locale', - description: 'Tells chat the current locale of Dotabod.', - cmd: '!locale', - alias: ['translation', 'translatedby'], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandFacet]: { - key: Settings.commandFacet, - title: 'Facet Information', - description: 'Provides information about the selected facet of a hero.', - cmd: '!facet jug 2', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandWinProbability]: { - key: Settings.commandWinProbability, - title: 'Win Probability', - description: 'Shows the current win probability for the game.', - cmd: '!wp', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandSpectators]: { - key: Settings.commandSpectators, - title: 'Spectator Count', - description: - 'Displays the number of spectators currently watching the match live.', - cmd: '!spectators', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, - [Settings.commandInnate]: { - key: Settings.commandInnate, - title: 'Innate Ability', - description: "Provides information about a hero's innate ability.", - cmd: '!innate 4', - alias: [], - allowed: 'all', - response: (props: Record = {}) => ( - - ), - }, + )} + + ), + }, + [Settings.commandMmr]: { + key: Settings.commandMmr, + title: t('commandMmr.title'), + description: t('commandMmr.description'), + cmd: '!mmr', + alias: ['rank', 'medal'], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandGPM]: { + key: Settings.commandGPM, + title: t('commandGPM.title'), + description: t('commandGPM.description'), + cmd: '!gpm', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandAPM]: { + key: Settings.commandAPM, + title: t('commandAPM.title'), + description: t('commandAPM.description'), + cmd: '!apm', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandNP]: { + key: Settings.commandNP, + title: t('commandNP.title'), + description: t('commandNP.description'), + cmd: '!np', + alias: ['who', 'players'], + allowed: 'all', + response: (props: Record = {}, all = true) => ( +
+ + {t('commandNP.response1')} + south korea + {t('commandNP.response2')} + russia + {t('commandNP.response3')} + estonia + {t('commandNP.response4')} + usa + {t('commandNP.response5')} + usa + {t('commandNP.response6')} + + } + /> + {all && ( + <> + + + + )} +
+ ), + }, + [Settings.commandSmurfs]: { + key: Settings.commandSmurfs, + title: t('commandSmurfs.title'), + description: t('commandSmurfs.description'), + cmd: '!smurfs', + alias: ['lifetimes', 'totals', 'games', 'smurf'], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandGM]: { + key: Settings.commandGM, + title: t('commandGM.title'), + description: t('commandGM.description'), + cmd: '!gm', + alias: ['medals', 'ranks'], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandLG]: { + key: Settings.commandLG, + title: t('commandLG.title'), + description: t('commandLG.description'), + cmd: '!lg', + alias: ['lastgame'], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + ping: { + title: t('ping.title'), + description: t('ping.description'), + cmd: '!ping', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + dotabod: { + title: t('dotabod.title'), + description: t('dotabod.description'), + cmd: '!dotabod', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandLGS]: { + key: Settings.commandLGS, + title: t('commandLGS.title'), + description: t('commandLGS.description'), + cmd: '!lgs', + alias: ['lastgamescore', 'lgscore', 'lgwl'], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandProfile]: { + key: Settings.commandProfile, + title: t('commandProfile.title'), + description: t('commandProfile.description'), + cmd: '!profile', + alias: ['stats', 'check'], + allowed: 'all', + response: (props: Record = {}) => ( + <> + + + + ), + }, + [Settings.commandHero]: { + key: Settings.commandHero, + title: t('commandHero.title'), + description: t('commandHero.description'), + cmd: '!hero', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + <> + + + + ), + }, + [Settings.commandBuilds]: { + key: Settings.commandBuilds, + title: t('commandBuilds.title'), + description: t('commandBuilds.description'), + cmd: '!builds', + alias: ['dota2pt', 'build', 'd2pt', 'getbuild'], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandDelay]: { + key: Settings.commandDelay, + title: t('commandDelay.title'), + description: t('commandDelay.description'), + cmd: '!delay', + alias: ['streamdelay'], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandRosh]: { + key: Settings.commandRosh, + title: t('commandRosh.title'), + description: t('commandRosh.description'), + cmd: '!rosh', + alias: ['aegis'], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandItems]: { + key: Settings.commandItems, + title: t('commandItems.title'), + description: t('commandItems.description'), + cmd: '!items', + alias: ['item'], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandVersion]: { + title: t('commandVersion.title'), + description: t('commandVersion.description'), + cmd: '!version', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandResetwl]: { + title: t('commandResetwl.title'), + description: t('commandResetwl.description'), + cmd: '!resetwl', + allowed: 'mods', + alias: [], + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandLocale]: { + title: t('commandLocale.title'), + description: t('commandLocale.description'), + cmd: '!locale', + alias: ['translation', 'translatedby'], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandFacet]: { + key: Settings.commandFacet, + title: t('commandFacet.title'), + description: t('commandFacet.description'), + cmd: '!facet jug 2', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandWinProbability]: { + key: Settings.commandWinProbability, + title: t('commandWinProbability.title'), + description: t('commandWinProbability.description'), + cmd: '!wp', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandSpectators]: { + key: Settings.commandSpectators, + title: t('commandSpectators.title'), + description: t('commandSpectators.description'), + cmd: '!spectators', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + [Settings.commandInnate]: { + key: Settings.commandInnate, + title: t('commandInnate.title'), + description: t('commandInnate.description'), + cmd: '!innate 4', + alias: [], + allowed: 'all', + response: (props: Record = {}) => ( + + ), + }, + } } export default CommandDetail diff --git a/src/components/Homepage/Hero.tsx b/src/components/Homepage/Hero.tsx index 4e842cea..b6b469c5 100644 --- a/src/components/Homepage/Hero.tsx +++ b/src/components/Homepage/Hero.tsx @@ -14,6 +14,7 @@ import TwitchSvg from 'src/images/logos/twitch.svg' import useSWR from 'swr' import Particles from '../magicui/particles' import { LiveIcon } from './LiveIcon' +import { useTranslation } from 'next-i18next' const featuredUsers = [ { @@ -144,6 +145,7 @@ export function Hero() { topLive: { name: string; image: string }[] }>('/api/featured-users', fetcher) const track = useTrack() + const { t } = useTranslation('common') return (
@@ -159,7 +161,7 @@ export function Hero() {

- Welcome, {name} + {t('hero.title', { name })}

- Unlock the Ultimate Dota 2 Streaming Experience with Dotabod! - Boost your stream's engagement, showcase real-time stats, and - delight your audience with our all-in-one streaming toolkit. - Elevate your game and become the streamer you were meant to be! + {t('hero.description')}

@@ -180,9 +179,9 @@ export function Hero() {
{session?.status === 'authenticated' ? ( - Go to dashboard + {t('button.goToDashboard')} ) : ( - Get started + {t('button.getStarted')} )}
@@ -194,7 +193,7 @@ export function Hero() { >
discord - Join Discord + {t('button.joinDiscord')}
@@ -228,8 +227,7 @@ export function Hero() { alt="twitch logo" /> - Featured in over {new Intl.NumberFormat().format(20000)}{' '} - Twitch streamers + {t('hero.featuredIn', { count: new Intl.NumberFormat().format(20000) })}
@@ -263,7 +261,7 @@ export function Hero() {
- Top streamers using Dotabod: + {t('hero.topStreamers')}
    @@ -289,7 +287,7 @@ export function Hero() {
    - Random Dotabod streamers: + {t('hero.randomStreamers')}
      diff --git a/src/pages/dashboard/commands.tsx b/src/pages/dashboard/commands.tsx index 189f7ccd..3ddc6916 100644 --- a/src/pages/dashboard/commands.tsx +++ b/src/pages/dashboard/commands.tsx @@ -7,8 +7,10 @@ import { Empty, Input, Segmented } from 'antd' import Head from 'next/head' import { type ReactElement, useState } from 'react' import CommandDetail from '../../components/Dashboard/CommandDetail' +import { useTranslation } from 'next-i18next' const CommandsPage = () => { + const { t } = useTranslation('common') const [permission, setPermission] = useState('All') const [enabled, setEnabled] = useState('All') const { data } = useUpdate({ path: '/api/settings' }) @@ -63,26 +65,26 @@ const CommandsPage = () => { return ( <> - Dotabod | Commands + Dotabod | {t('commands.title')}
      setEnabled(v as string)} - options={['All', 'Enabled', 'Disabled']} + options={[t('commands.all'), t('commands.enabled'), t('commands.disabled')]} /> setPermission(v as string)} - options={['All', 'Mods', 'Plebs']} + options={[t('commands.all'), t('commands.mods'), t('commands.plebs')]} /> {
      {filteredCommands.length < 1 && ( )} diff --git a/src/pages/dashboard/features/index.tsx b/src/pages/dashboard/features/index.tsx index cab40461..0f0a7270 100644 --- a/src/pages/dashboard/features/index.tsx +++ b/src/pages/dashboard/features/index.tsx @@ -8,27 +8,32 @@ import Header from '@/components/Dashboard/Header' import type { NextPageWithLayout } from '@/pages/_app' import Head from 'next/head' import type { ReactElement } from 'react' +import { useTranslation } from 'next-i18next' -const FeaturesPage: NextPageWithLayout = () => ( - <> - - Dotabod | Main features - +const FeaturesPage: NextPageWithLayout = () => { + const { t } = useTranslation('common') -
      + return ( + <> + + Dotabod | {t('dashboard.features.main.title')} + -
      - - - - - -
      - -) +
      + +
      + + + + + +
      + + ) +} FeaturesPage.getLayout = function getLayout(page: ReactElement) { return {page} diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx index 936cb20e..9f7c8d0f 100644 --- a/src/pages/dashboard/index.tsx +++ b/src/pages/dashboard/index.tsx @@ -14,8 +14,10 @@ import Link from 'next/link' import { useRouter } from 'next/router' import { type ReactElement, useEffect, useState } from 'react' import useSWR from 'swr' +import { useTranslation } from 'next-i18next' const SetupPage = () => { + const { t } = useTranslation('common') const track = useTrack() const { data } = useSWR('/api/settings', fetcher) const isLive = data?.stream_online @@ -97,25 +99,25 @@ const SetupPage = () => { const steps = [ { - title: 'Twitch', + title: t('dashboard.setup.twitch'), content: , }, { - title: 'Dota 2', + title: t('dashboard.setup.dota2'), content: , }, { - title: 'OBS', + title: t('dashboard.setup.obs'), content: , }, { - title: 'All done!', + title: t('dashboard.setup.allDone'), content: ( {!isLive && (
      { )}
      - That's it! You're all set up. + {t('dashboard.setup.thatsIt')} { />
      -

      - You can either hop into a match right away, or you can test - Dotabod first. -

      +

      {t('dashboard.setup.hopIntoMatch')}

      { track('setup/collapse_test_dotabod') @@ -147,25 +146,18 @@ const SetupPage = () => { accordion items={[ { - label: 'How to test Dotabod', + label: t('dashboard.setup.howToTest'), children: ( <>
        +
      1. {t('dashboard.setup.demoHeroStep')}
      2. - Demo any hero to get Dotabod to recognize your Steam - account. + {t('dashboard.setup.livePreviewStep')}{' '} + {t('dashboard.setup.livePreviewPage')}
      3. - While demoing, visit the{' '} - Live Preview page to - confirm the overlay is showing. -
      4. -
      5. - Having trouble? Visit the{' '} - - Troubleshooting page - {' '} - to get help. + {t('dashboard.setup.troubleshootingStep')}{' '} + {t('dashboard.setup.troubleshootingPage')}
      @@ -191,13 +183,13 @@ const SetupPage = () => { return ( <> - Dotabod | Setup + Dotabod | {t('dashboard.setup.title')}
      - Let's get Dotabod working for you right away{' '} + {t('dashboard.setup.subtitle')}{' '} {
      } - title="Setup" + title={t('dashboard.setup.title')} /> {
      {active > 0 && ( )} {active === steps.length - 1 && ( )} {active < steps.length - 1 && ( )}