Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement i18n basic example #613

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"Pomodoro",
"Svgr",
"tailwindcss",
"Ttranslate",
"UMAMI",
"zustand"
]
Expand Down
18 changes: 18 additions & 0 deletions messages/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"Index":{
"save":"save",
"share":"share",
"clear":"clear",
"Save_current_combo":"Save current combo",
"Share_current_combo":"Share current combo",
"Clear_all_active_sounds":"Clear all active sounds"
},
"Header":{
"Reset_Pomodoro_timer":"Reset Pomodoro timer",
"Toggle_Pomodoro_timer":"Toggle Pomodoro timer",
"Global_volume_in":"Global volume in",
"Enable/disable_sound":"Enable/disable sound",
"Toggle_theme_menu":"Toggle theme menu",
"Toggle_combo_list":"Toggle combo list"
}
}
19 changes: 19 additions & 0 deletions messages/pt-br.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"Index":{
"save":"salvar",
"share":"compartilhar",
"clear":"limpar",
"Save_current_combo":"Salvar combinação atual",
"Share_current_combo":"Compartilhar combinação atual",
"Clear_all_active_sounds":"Limpar todos os sons ativos",
"Toggle_combo_list":"Alternar lista de combinações"
},
"Header":{
"Reset_Pomodoro_timer":"Redefinir temporizador Pomodoro",
"Toggle_Pomodoro_timer":"Alternar temporizador Pomodoro",
"Global_volume_in":"Volume global em",
"Enable/disable_sound":"Ativar/desativar som",
"Toggle_theme_menu":"Alternar menu de tema",
"Toggle_combo_list":"Alternar lista de combinações"
}
}
3 changes: 2 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const withNextIntl = require('next-intl/plugin')()
const withSvgr = require('@newhighsco/next-plugin-svgr')
const withPWA = require('@ducanh2912/next-pwa').default({
dest: 'public'
Expand All @@ -15,4 +16,4 @@ const configWithSvgr = withSvgr({
}
})

module.exports = withPWA(configWithSvgr)
module.exports = withNextIntl(withPWA(configWithSvgr))
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@headlessui/react": "1.7.17",
"@newhighsco/next-plugin-svgr": "^3.0.104",
"next": "14.0.3",
"next-intl": "^3.1.4",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "4.12.0",
Expand Down
93 changes: 93 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import '@testing-library/jest-dom'
import { render, screen } from '@testing-library/react'
import Home from '~/app/page'
import Home from '~/app/[locale]/page'

describe('Home', () => {
it('Renders the page heading', () => {
Expand Down
File renamed without changes.
File renamed without changes
23 changes: 21 additions & 2 deletions src/app/layout.tsx → src/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { Metadata } from 'next'
import Script from 'next/script'
import { Nunito } from 'next/font/google'

import { NextIntlClientProvider, useMessages } from 'next-intl'
import { notFound } from 'next/navigation'

// Can be imported from a shared config
const locales = ['en', 'pt-br']

import './global.css'

const APP_NAME = 'Noisekun'
Expand Down Expand Up @@ -72,7 +78,16 @@ const nunito = Nunito({
variable: '--font-nunito'
})

export default function RootLayout({ children }: { children: ReactNode }) {
export default function RootLayout({
children,
params: { locale }
}: {
children: ReactNode
params: any
}) {
if (!locales.includes(locale as any)) notFound()
const messages = useMessages()

return (
<html lang="en">
<head>
Expand All @@ -82,7 +97,11 @@ export default function RootLayout({ children }: { children: ReactNode }) {
data-website-id={process.env.UMAMI_WEBSITE_ID}
/>
</head>
<body className={nunito.variable}>{children}</body>
<body className={nunito.variable}>
<NextIntlClientProvider locale={locale} messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
)
}
17 changes: 14 additions & 3 deletions src/app/page.tsx → src/app/[locale]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Footer } from '~/components/footer'
import { useThemeStore } from '~/stores/theme-store'
import { SaveComboButton } from '~/components/save-combo-button'
import { InteractionModal } from '~/components/interaction-modal'
import { useTranslations } from 'next-intl'

import { sounds } from '~/sounds'

Expand All @@ -24,6 +25,7 @@ export default function Home() {
)

const [querySounds] = useQueryState('sounds')
const t = useTranslations('Index')

useEffect(() => {
if (!querySounds.length) setUserHasInteracted(true)
Expand All @@ -35,9 +37,18 @@ export default function Home() {
<div className="styled-scrollbar h-[90vh] space-y-24 overflow-y-scroll pt-16 md:h-[87vh]">
<div className="m-auto flex w-fit flex-col items-center gap-3">
<div className="hidden w-full items-center justify-end gap-2 px-4 xs:flex">
<SaveComboButton />
<ShareButton />
<ClearButton />
<SaveComboButton
titleTranslate={t('Save_current_combo')}
textTranslate={t('save')}
/>
<ShareButton
titleTranslate={t('Share_current_combo')}
textTranslate={t('share')}
/>
<ClearButton
titleTranslate={t('Clear_all_active_sounds')}
textTranslate={t('clear')}
/>
</div>
<div className="grid h-fit w-fit grid-cols-1 gap-12 xs:grid-cols-2 2xs:grid-cols-3 sm:grid-cols-4 lg:grid-cols-5 2xl:grid-cols-6">
{sounds.map(sound => (
Expand Down
File renamed without changes.
7 changes: 4 additions & 3 deletions src/components/clear-button/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useSoundsStateStore } from '~/stores/sounds-state-store'
import { useThemeStore } from '~/stores/theme-store'
import { actionButton } from '~/shared/styles/action-button'
import { TTranslate } from '~/types/Ttranslate'

export function ClearButton() {
export function ClearButton({ titleTranslate, textTranslate }: TTranslate) {
const bulkSoundUpdate = useSoundsStateStore(state => state.bulkUpdate)
const soundStates = useSoundsStateStore(state => state.sounds)

Expand All @@ -26,10 +27,10 @@ export function ClearButton() {
disabled={isDisabled()}
onClick={clear}
className={actionButton({ theme })}
title="Clear all active sounds"
title={titleTranslate}
data-umami-event="Clear Button"
>
clear
{textTranslate}
</button>
)
}
5 changes: 3 additions & 2 deletions src/components/header/combo-list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import {
toggleEditContainer,
triggerButton
} from './styles'
import { TTitleTranslate } from '~/types/Ttranslate'

export function ComboList() {
export function ComboList({ titleTranslate }: TTitleTranslate) {
const theme = useThemeStore(set => set.theme)
const setTheme = useThemeStore(set => set.setTheme)
const sounds = useSoundsStateStore(state => state.sounds)
Expand Down Expand Up @@ -61,7 +62,7 @@ export function ComboList() {
<div className="z-40">
<Menu>
<Menu.Button
title="Toggle combo list"
title={titleTranslate}
data-umami-event="Open combo list"
disabled={isEmpty}
className={triggerButton({ theme })}
Expand Down
14 changes: 10 additions & 4 deletions src/components/header/global-volume-controller/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import { useGlobalVolumeStore } from '~/stores/global-volume-store'
import { useThemeStore } from '~/stores/theme-store'
import { volumeControllerInput } from '~/shared/styles/volume-controller-input'
import { soundButton } from './styles'
import { TGlobalVolumeControllerTranslate } from '~/types/Ttranslate'

export function GlobalVolumeController() {
export function GlobalVolumeController({
titleGlobalVolumeTranslate,
titleEnableTranslate
}: TGlobalVolumeControllerTranslate) {
const MAX_VALUE = 1000

const [rangeValue, setRangeValue] = useState(MAX_VALUE)
Expand Down Expand Up @@ -47,13 +51,15 @@ export function GlobalVolumeController() {
className="group relative hidden h-max w-28 items-center data-[is-showing='true']:flex"
>
<span className="sr-only">
Global volume in {Number(globalVolume * 100).toFixed(1)}%
{titleGlobalVolumeTranslate} {Number(globalVolume * 100).toFixed(1)}%
</span>
<input
className={volumeControllerInput({ theme })}
type="range"
name="global-volume-controller"
title={`Global volume in ${Number(globalVolume * 100).toFixed(1)}%`}
title={`${titleGlobalVolumeTranslate} ${Number(
globalVolume * 100
).toFixed(1)}%`}
min="0"
max={MAX_VALUE}
value={rangeValue}
Expand All @@ -64,7 +70,7 @@ export function GlobalVolumeController() {
/>
</div>
<button
title="Enable/disable sound"
title={titleEnableTranslate}
className={soundButton({ theme })}
onClick={toggleMuted}
data-umami-event="Mute/Unmute global volume"
Expand Down
Loading