Skip to content

Commit

Permalink
Add internationalization and replace all hardcoded labels with i18n e…
Browse files Browse the repository at this point in the history
…ntries (#215)

* adding i18next

* fixing name spaces

* fixing pnpm lock file

* fixing bun
  • Loading branch information
ManyRios authored Nov 7, 2024
1 parent 8be9df3 commit 86c9df9
Show file tree
Hide file tree
Showing 47 changed files with 981 additions and 491 deletions.
Binary file modified bun.lockb
Binary file not shown.
4 changes: 4 additions & 0 deletions packages/features/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
"cmdk": "1.0.0",
"dayjs": "1.11.12",
"easy-mesh-gradient": "0.0.5",
"i18next": "^23.16.0",
"i18next-browser-languagedetector": "^8.0.0",
"immer": "10.1.1",
"js-beautify": "1.15.1",
"lucide-react": "0.417.0",
Expand All @@ -62,6 +64,8 @@
"react-dom": "18.3.1",
"react-error-boundary": "4.0.13",
"react-hook-form": "7.52.1",
"react-i18next": "^15.0.3",
"react-mixpanel-browser": "4.1.0",
"react-qr-code": "2.0.15",
"react-router": "6.25.1",
"react-router-dom": "6.25.1",
Expand Down
9 changes: 9 additions & 0 deletions packages/features/src/@types/i18next.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import "i18next"
import resources from "./resources"
const { ns1, ns2 } = resources

declare module "i18next" {
interface CustomTypeOptions {
defaultNS: "ns1"
}
}
9 changes: 9 additions & 0 deletions packages/features/src/@types/resources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import ns1 from "../i18n/locales/en/en.json"
import ns2 from "../i18n/locales/tr/tr.json"

const resources = {
ns1,
ns2,
} as const

export default resources
7 changes: 5 additions & 2 deletions packages/features/src/address-book/views/address-book.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import type { MouseEvent } from "react"
import { Link } from "react-router-dom"
import { toast } from "sonner"

import { useTranslation } from "react-i18next"

type AddressBookViewProps = {
contacts: Contact[]
removeContact: ({ index }: { index: number }) => void
Expand All @@ -25,11 +27,12 @@ export const AddressBookView = ({
navigator.clipboard.writeText(address)
toast.success("Address copied")
}
const { t } = useTranslation()
return (
<AppLayout>
<div className="pb-12 bg-secondary rounded-b-2xl">
<MenuBar variant="dashboard" />
<h2 className="ml-8 mt-1 text-3xl">Address book</h2>
<h2 className="ml-8 mt-1 text-3xl">{t("addressBook.addressBook")}</h2>
</div>
<div className="py-6 px-8 space-y-2">
<Link
Expand All @@ -38,7 +41,7 @@ export const AddressBookView = ({
data-testid="addressBook/addAddressButton"
>
<Plus width={16} height={16} className="text-[#F6C177]" />
<p>Add new contact</p>
<p>{t("addressBook.addNewContact")}</p>
</Link>
<div className="space-y-2">
{contacts.map((contact, index) => {
Expand Down
7 changes: 5 additions & 2 deletions packages/features/src/address-book/views/new-address.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { useForm } from "react-hook-form"
import { useLocation } from "react-router-dom"
import { NewAddressFormSchema } from "../components/new-address-form.schema"

import { useTranslation } from "react-i18next"

type NewAddressViewProps = {
onGoBack: () => void
onSubmit: (contact: { name: string; address: string }) => void
Expand All @@ -30,11 +32,12 @@ export const NewAddressView = ({ onGoBack, onSubmit }: NewAddressViewProps) => {
useEffect(() => {
setValue("address", location.state?.address || "")
}, [])
const { t } = useTranslation()
return (
<AppLayout>
<div className="pb-12 bg-secondary rounded-b-2xl">
<MenuBar variant="back" onBackClicked={onGoBack} />
<h2 className="ml-8 mt-1 text-3xl">New contact</h2>
<h2 className="ml-8 mt-1 text-3xl">{t("addressBook.newContact")}</h2>
</div>
<div className="pt-6 pb-8 px-8 flex flex-col flex-1">
<form
Expand Down Expand Up @@ -79,7 +82,7 @@ export const NewAddressView = ({ onGoBack, onSubmit }: NewAddressViewProps) => {
disabled={disableSubmit}
data-testid="submitForm"
>
Add contact
{t("addressBook.addContact")}
</button>
</form>
</div>
Expand Down
9 changes: 6 additions & 3 deletions packages/features/src/components/address-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { CopyIcon, ExternalLinkIcon, UserPlusIcon } from "lucide-react"
import { Link } from "react-router-dom"
import { toast } from "sonner"

import { useTranslation } from "react-i18next"

type AddressDropdownProps = {
publicKey: string
className?: string
Expand Down Expand Up @@ -34,6 +36,7 @@ export const AddressDropdown = ({
)
window.open(url, "_blank")?.focus()
}
const { t } = useTranslation()
return (
<div className={clsx("dropdown", dropdownEnd && "dropdown-end")}>
<div
Expand All @@ -55,13 +58,13 @@ export const AddressDropdown = ({
<li onClick={handleClick}>
<button type="button" onClick={copyAddress} className="flex gap-2">
<CopyIcon />
<span>Copy Address</span>
<span>{t("components.copyAddress")}</span>
</button>
</li>
<li onClick={handleClick}>
<button type="button" onClick={openInExplorer} className="flex gap-2">
<ExternalLinkIcon />
<span>Open in Minascan</span>
<span>{t("components.openInMinascan")}</span>
</button>
</li>
<li onClick={handleClick}>
Expand All @@ -71,7 +74,7 @@ export const AddressDropdown = ({
className="flex gap-2"
>
<UserPlusIcon />
<span>Create Contact</span>
<span>{t("addressBook.createContact")}</span>
</Link>
</li>
</ul>
Expand Down
12 changes: 7 additions & 5 deletions packages/features/src/components/fee-picker.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TransactionFee } from "@/common/lib/const"
import { clsx } from "clsx"

import { useTranslation } from "react-i18next"
type TransactionFeeShortProps = {
feeValue: keyof typeof TransactionFee
onClick: () => void
Expand All @@ -10,13 +10,14 @@ export const TransactionFeeShort = ({
feeValue,
onClick,
}: TransactionFeeShortProps) => {
const { t } = useTranslation()
return (
<button
type="button"
className="btn btn-link text-base-content no-underline hover:no-underline"
onClick={onClick}
>
<span className="underline">Transaction fee:</span>
<span className="underline">{t("components.transactionFee")}</span>
<span>{TransactionFee[feeValue]} MINA</span>
</button>
)
Expand All @@ -28,6 +29,7 @@ type FeePickerProps = {
}

export const FeePicker = ({ feeValue, setValue }: FeePickerProps) => {
const { t } = useTranslation()
return (
<div className="join w-full">
<button
Expand All @@ -38,7 +40,7 @@ export const FeePicker = ({ feeValue, setValue }: FeePickerProps) => {
)}
onClick={() => setValue("fee", "slow")}
>
<div>Slow</div>
<div>{t("onboarding.slow")}</div>
<div className="text-nowrap">{TransactionFee.slow} MINA</div>
</button>
<button
Expand All @@ -49,7 +51,7 @@ export const FeePicker = ({ feeValue, setValue }: FeePickerProps) => {
)}
onClick={() => setValue("fee", "default")}
>
<div>Normal</div>
<div>{t("onboarding.normal")}</div>
<div className="text-nowrap">{TransactionFee.default} MINA</div>
</button>
<button
Expand All @@ -60,7 +62,7 @@ export const FeePicker = ({ feeValue, setValue }: FeePickerProps) => {
)}
onClick={() => setValue("fee", "fast")}
>
<div>Fast</div>
<div>{t("onboarding.fast")}</div>
<div className="text-nowrap">{TransactionFee.fast} MINA</div>
</button>
</div>
Expand Down
7 changes: 4 additions & 3 deletions packages/features/src/components/from-to.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ArrowRightIcon } from "lucide-react"
import { useTranslation } from "react-i18next"
import { AddressDropdown } from "./address-dropdown"

type FromToProps = {
tx: {
from: string
Expand All @@ -9,17 +9,18 @@ type FromToProps = {
}

export const FromTo = ({ tx }: FromToProps) => {
const { t } = useTranslation()
return (
<div className="card bg-secondary py-3 px-4 flex flex-row justify-between mt-1">
<div className="flex flex-col">
<div className="text-[#7D7A9C]">From</div>
<div className="text-[#7D7A9C]">{t("components.from")}</div>
<AddressDropdown publicKey={tx.from} className="before:ml-20" />
</div>
<div className="btn btn-circle btn-neutral text-mint">
<ArrowRightIcon size={24} />
</div>
<div className="flex flex-col">
<div className="text-[#7D7A9C]">To</div>
<div className="text-[#7D7A9C]">{t("components.to")}</div>
<AddressDropdown
publicKey={tx.to}
className="before:-ml-20"
Expand Down
7 changes: 5 additions & 2 deletions packages/features/src/components/hash-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import clsx from "clsx"
import { CopyIcon, ExternalLinkIcon } from "lucide-react"
import { toast } from "sonner"

import { useTranslation } from "react-i18next"

type HashDropdownProps = {
hash: string
className?: string
Expand All @@ -27,6 +29,7 @@ export const HashDropdown = ({ hash, className }: HashDropdownProps) => {
)
window.open(url, "_blank")?.focus()
}
const { t } = useTranslation()
return (
<div className={clsx("dropdown dropdown-top dropdown-end")}>
<div
Expand All @@ -40,13 +43,13 @@ export const HashDropdown = ({ hash, className }: HashDropdownProps) => {
<li onClick={handleClick}>
<button type="button" onClick={copyHash} className="flex gap-2">
<CopyIcon />
<span>Copy Hash</span>
<span>{t("components.copyHash")}</span>
</button>
</li>
<li onClick={handleClick}>
<button type="button" onClick={openInExplorer} className="flex gap-2">
<ExternalLinkIcon />
<span>Open in Minascan</span>
<span>{t("components.openInMinascan")}</span>
</button>
</li>
</ul>
Expand Down
14 changes: 9 additions & 5 deletions packages/features/src/components/menu-drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import { useVault } from "@palladxyz/vault"
import { ChevronDownIcon, XIcon } from "lucide-react"
import { Link, useNavigate } from "react-router-dom"

import { useTranslation } from "react-i18next"

export const MenuDrawer = () => {
const navigate = useNavigate()
const networkId = useVault((state) => state.currentNetworkId)
const { t } = useTranslation()

return (
<div className="drawer drawer-end">
<input id="menu-drawer" type="checkbox" className="drawer-toggle" />
Expand Down Expand Up @@ -64,39 +68,39 @@ export const MenuDrawer = () => {
onClick={() => navigate("/")}
data-testid="menu/activity"
>
Dashboard
{t("components.dashboard")}
</button>
<button
type="button"
className="text-3xl text-left"
onClick={() => navigate("/transactions")}
data-testid="menu/activity"
>
Activity
{t("components.activity")}
</button>
<button
type="button"
className="text-3xl text-left"
onClick={() => navigate("/staking")}
data-testid="menu/staking"
>
Staking
{t("components.staking")}
</button>
<button
type="button"
className="text-3xl text-left"
onClick={() => navigate("/contacts")}
data-testid="menu/addressBook"
>
Address Book
{t("components.adressBook")}
</button>
<button
type="button"
className="text-3xl text-left"
onClick={() => navigate("/settings")}
data-testid="menu/settings"
>
Settings
{t("components.settings")}
</button>
</div>
</div>
Expand Down
11 changes: 7 additions & 4 deletions packages/features/src/error-renderer/views/error.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type { FallbackProps } from "react-error-boundary"
import { useTranslation } from "react-i18next"
//import { useMixpanel } from "react-mixpanel-browser"

export const ErrorView = ({ error, resetErrorBoundary }: FallbackProps) => {
const stringifiedError = JSON.stringify(
Expand All @@ -8,19 +10,20 @@ export const ErrorView = ({ error, resetErrorBoundary }: FallbackProps) => {
const report = async () => {
resetErrorBoundary()
}
const { t } = useTranslation()
return (
<div className="flex flex-1 flex-col justify-center items-center min-h-screen w-full p-8">
<div className="card flex flex-col flex-1 bg-secondary w-full">
<div className="card-body flex-1 flex flex-col gap-4 p-4">
<h1 className="text-xl">Woops</h1>
<p className="flex-[0] text-gray-400">An error happened.</p>
<p className="flex-[0] text-gray-400">{t("error.errorHappend")}</p>
<a
href="https://get.pallad.co/status"
target="_blank"
rel="noopener noreferrer"
className="underline"
>
Check services status.
{t("error.checkServiceStatus")}
</a>
<textarea
className="textarea textarea-bordered rounded-xl resize-none flex-1"
Expand All @@ -33,14 +36,14 @@ export const ErrorView = ({ error, resetErrorBoundary }: FallbackProps) => {
className="btn bg-neutral flex-1"
onClick={resetErrorBoundary}
>
Try Again
{t("error.tryAgain")}
</button>
<button
type="button"
className="btn btn-primary flex-1"
onClick={report}
>
Send Report
{t("error.sendReport")}
</button>
</div>
</div>
Expand Down
26 changes: 26 additions & 0 deletions packages/features/src/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import i18next from "i18next"
import LanguageDetector from "i18next-browser-languagedetector"
import { initReactI18next } from "react-i18next"
import ns1 from "./locales/en/en.json"
import ns2 from "./locales/tr/tr.json"

const defaultNS = "ns1"

const resources = {
en: {
ns1,
},
tr: {
ns2,
},
}

i18next
.use(LanguageDetector)
.use(initReactI18next)
.init({
debug: false,
fallbackLng: ["en", "tr"],
resources: resources,
defaultNS,
})
Loading

0 comments on commit 86c9df9

Please sign in to comment.