Skip to content

Commit

Permalink
feat: add language toggle and hook up some translations
Browse files Browse the repository at this point in the history
  • Loading branch information
secondl1ght committed Jul 5, 2024
1 parent 89fffea commit b4c4ba9
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 11 deletions.
10 changes: 9 additions & 1 deletion messages/en.json
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
{}
{
"Index": {
"accounts": "Accounts",
"contacts": "Contacts",
"settings": "Settings",
"transactions": "Transactions",
"wallet": "Wallet"
}
}
10 changes: 9 additions & 1 deletion messages/es.json
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
{}
{
"Index": {
"accounts": "Cuentas",
"contacts": "Contactos",
"settings": "Configuración",
"transactions": "Transacciones",
"wallet": "Billetera"
}
}
6 changes: 5 additions & 1 deletion src/app/app/wallet/[walletId]/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { useTranslations } from 'next-intl';

import { WalletSettings } from '@/views/wallet/Settings';

export default function Page({ params }: { params: { walletId: string } }) {
const t = useTranslations('Index');

return (
<div>
<h1 className="my-2 text-xl font-semibold">Settings</h1>
<h1 className="my-2 text-xl font-semibold">{t('settings')}</h1>

<WalletSettings walletId={params.walletId} />
</div>
Expand Down
76 changes: 76 additions & 0 deletions src/components/LanguageToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
'use client';

import { Check, Languages } from 'lucide-react';
import { useRouter } from 'next/navigation';
import * as React from 'react';
import { useState } from 'react';

import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { SupportedLanguage } from '@/i18n';

const setCookie = (locale: SupportedLanguage) =>
(document.cookie = `locale=${locale}; max-age=31536000; path=/;`);

const deleteCookie = () =>
(document.cookie = 'locale=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;');

export function LanguageToggle() {
const { refresh } = useRouter();

const [language, setLanguage] = useState<SupportedLanguage | undefined>(
() => {
const localeCookie = document.cookie
.split('; ')
.find(c => c.startsWith('locale='))
?.split('=')[1] as SupportedLanguage | undefined;

return localeCookie;
}
);

return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Languages className="h-[1.2rem] w-[1.2rem]" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem
onClick={() => {
setCookie('en');
setLanguage('en');
refresh();
}}
>
English {language === 'en' && <Check size={14} className="ml-1" />}
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
setCookie('es');
setLanguage('es');
refresh();
}}
>
Español {language === 'es' && <Check size={14} className="ml-1" />}
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
deleteCookie();
setLanguage(undefined);
refresh();
}}
>
System {!language && <Check size={14} className="ml-1" />}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
4 changes: 3 additions & 1 deletion src/components/header/ExternalHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import Link from 'next/link';

import { ROUTES } from '@/utils/routes';

import { LanguageToggle } from '../LanguageToggle';
import { ThemeToggle } from '../ThemeToggle';
import { Button } from '../ui/button';

export const ExternalHeader = () => {
return (
<div className="mt-1 flex w-full max-w-5xl items-center justify-between text-sm">
<div className="mt-1 flex w-full max-w-5xl flex-wrap items-center justify-between text-sm">
<Link href={ROUTES.home}>
<p className="text-xl font-bold">Banco</p>
</Link>
Expand All @@ -21,6 +22,7 @@ export const ExternalHeader = () => {
<Link href={ROUTES.signup}>Sign Up</Link>
</Button>
<ThemeToggle />
<LanguageToggle />
</div>
</div>
);
Expand Down
5 changes: 4 additions & 1 deletion src/components/layout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import { ROUTES } from '@/utils/routes';

import { WalletButton } from '../button/WalletButton';
import { LanguageToggle } from '../LanguageToggle';
import { Badge } from '../ui/badge';

export const AppLayout: FC<{ children: ReactNode }> = ({ children }) => {
Expand Down Expand Up @@ -147,6 +148,7 @@ export const AppLayout: FC<{ children: ReactNode }> = ({ children }) => {
<WalletButton />
<VaultButton />
<ThemeToggle />
<LanguageToggle />
</div>

<Sheet>
Expand All @@ -161,9 +163,10 @@ export const AppLayout: FC<{ children: ReactNode }> = ({ children }) => {
</Button>
</SheetTrigger>
<SheetContent side="right" className="flex flex-col">
<div className="flex gap-2">
<div className="mt-6 flex gap-2">
<VaultButton />
<ThemeToggle />
<LanguageToggle />
</div>
</SheetContent>
</Sheet>
Expand Down
4 changes: 2 additions & 2 deletions src/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { cookies, headers } from 'next/headers';
import { getRequestConfig } from 'next-intl/server';

type SupportedLanguage = 'en' | 'es';
export type SupportedLanguage = 'en' | 'es';
const defaultLocale = 'en';

export default getRequestConfig(async () => {
let locale: SupportedLanguage;

const cookieStore = cookies();
const localeCookie = cookieStore.get('locale') as
const localeCookie = cookieStore.get('locale')?.value as
| SupportedLanguage
| undefined;

Expand Down
5 changes: 4 additions & 1 deletion src/views/app/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from 'lucide-react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useTranslations } from 'next-intl';
import { FC, useEffect, useMemo, useState } from 'react';
import { useCopyToClipboard, useLocalStorage } from 'usehooks-ts';

Expand All @@ -28,6 +29,8 @@ import { ROUTES } from '@/utils/routes';
import { WalletInfo } from '../wallet/Wallet';

const WalletDetails: FC<{ id: string }> = ({ id }) => {
const t = useTranslations('Index');

const { data } = useGetWalletDetailsQuery({
variables: { id },
});
Expand All @@ -51,7 +54,7 @@ const WalletDetails: FC<{ id: string }> = ({ id }) => {
<div className="w-full">
<div className="flex w-full items-center justify-between pb-4 md:pb-2">
<h2 className="scroll-m-20 text-xl font-semibold tracking-tight">
Wallet
{t('wallet')}
</h2>
<div className="flex gap-2">
<Button
Expand Down
5 changes: 4 additions & 1 deletion src/views/contacts/Contacts.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { Plus, User } from 'lucide-react';
import { useTranslations } from 'next-intl';
import { FC, useEffect, useState } from 'react';
import { useLocalStorage } from 'usehooks-ts';

Expand Down Expand Up @@ -64,6 +65,8 @@ const ContactCard: FC<{ contact: ContactType; cbk?: () => void }> = ({
};

export const Contacts = () => {
const t = useTranslations('Index');

const [openDrawer, setOpenDrawer] = useState(false);
const [openDialog, setOpenDialog] = useState(false);

Expand Down Expand Up @@ -94,7 +97,7 @@ export const Contacts = () => {
<div className="my-4 grid flex-1 gap-4 overflow-auto md:grid-cols-2 lg:grid-cols-4">
<div className="flex flex-col gap-2">
<div className="flex w-full items-center justify-between">
<h1 className="text-sm font-semibold md:text-lg">Contacts</h1>
<h1 className="text-sm font-semibold md:text-lg">{t('contacts')}</h1>
<div className="flex gap-2">
<Drawer open={openDrawer} onOpenChange={setOpenDrawer}>
<DrawerTrigger asChild className="flex md:hidden">
Expand Down
7 changes: 5 additions & 2 deletions src/views/wallet/Wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Loader2,
} from 'lucide-react';
import Link from 'next/link';
import { useTranslations } from 'next-intl';
import { FC, useMemo } from 'react';

import { Button } from '@/components/ui/button';
Expand Down Expand Up @@ -105,6 +106,8 @@ const BalanceCard: FC<{
};

export const WalletInfo: FC<{ id: string }> = ({ id }) => {
const t = useTranslations('Index');

const { data, loading, error } = useGetWalletQuery({ variables: { id } });

const balances = useMemo(() => {
Expand Down Expand Up @@ -189,7 +192,7 @@ export const WalletInfo: FC<{ id: string }> = ({ id }) => {
return (
<div className="w-full">
<h2 className="scroll-m-20 pb-2 pt-6 text-xl font-semibold tracking-tight first:mt-0">
Accounts
{t('accounts')}
</h2>
<div className="flex w-full flex-col gap-4 md:flex-row">
{balances.map((b, index) => (
Expand All @@ -202,7 +205,7 @@ export const WalletInfo: FC<{ id: string }> = ({ id }) => {
))}
</div>
<h2 className="scroll-m-20 pb-2 pt-6 text-xl font-semibold tracking-tight first:mt-0">
Transactions
{t('transactions')}
</h2>
<TransactionTable data={transactions} />
</div>
Expand Down

0 comments on commit b4c4ba9

Please sign in to comment.