diff --git a/messages/en.json b/messages/en.json
index 96925c4..bb50f96 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -105,11 +105,23 @@
},
"Index": {
"accounts": "Accounts",
+ "beta": "Beta - Limit funds and use at your own risk.",
"contacts": "Contacts",
+ "create-wallet": "Create Wallet",
+ "full-refresh": "Full Refresh",
+ "help": "Help",
+ "home": "Home",
+ "loading": "Loading",
+ "logout": "Logout",
+ "new-wallet": "New Wallet",
+ "refresh": "Refresh",
+ "restore-wallet": "Restore Wallet",
+ "select-wallet": "Select Wallet",
"settings": "Settings",
"swaps": "Swaps",
"transactions": "Transactions",
- "wallet": "Wallet"
+ "wallet": "Wallet",
+ "wallets": "Wallets"
},
"Public": {
"404": {
diff --git a/messages/es.json b/messages/es.json
index dcca1a2..b1267f8 100644
--- a/messages/es.json
+++ b/messages/es.json
@@ -105,11 +105,23 @@
},
"Index": {
"accounts": "Cuentas",
+ "beta": "Beta - Limita la cantidad de fondos y usa bajo tu propio riesgo.",
"contacts": "Contactos",
+ "create-wallet": "Crear Billetera",
+ "full-refresh": "Refrescar Balance",
+ "help": "Ayuda",
+ "home": "Casa",
+ "loading": "Cargando",
+ "logout": "Salir",
+ "new-wallet": "Nueva Billetera",
+ "refresh": "Refrescar",
+ "restore-wallet": "Restaurar Billetera",
+ "select-wallet": "Seleccionar Billetera",
"settings": "ConfiguraciĆ³n",
"swaps": "Intercambios",
"transactions": "Transacciones",
- "wallet": "Billetera"
+ "wallet": "Billetera",
+ "wallets": "Billeteras"
},
"Public": {
"404": {
diff --git a/src/components/button/LogoutButton.tsx b/src/components/button/LogoutButton.tsx
index cb213cb..e3411e9 100644
--- a/src/components/button/LogoutButton.tsx
+++ b/src/components/button/LogoutButton.tsx
@@ -1,6 +1,7 @@
'use client';
import { LogOut } from 'lucide-react';
+import { useTranslations } from 'next-intl';
import { useLogoutMutation } from '@/graphql/mutations/__generated__/logout.generated';
import { useKeyStore } from '@/stores/keys';
@@ -12,6 +13,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';
import { useToast } from '../ui/use-toast';
export const LogoutButtonWithTooltip = () => {
+ const t = useTranslations('Index');
+
const { toast } = useToast();
const clearKeys = useKeyStore(s => s.clear);
@@ -35,21 +38,22 @@ export const LogoutButtonWithTooltip = () => {
- Logout
+ {t('logout')}
);
};
export const LogoutButton = () => {
+ const t = useTranslations('Index');
+
const { toast } = useToast();
const clearKeys = useKeyStore(s => s.clear);
@@ -68,14 +72,13 @@ export const LogoutButton = () => {
});
return (
-
+
+
{t('logout')}
+
);
};
diff --git a/src/components/button/RefreshWallet.tsx b/src/components/button/RefreshWallet.tsx
index db20018..2547e59 100644
--- a/src/components/button/RefreshWallet.tsx
+++ b/src/components/button/RefreshWallet.tsx
@@ -1,11 +1,12 @@
'use client';
-import { Loader2, RefreshCcw } from 'lucide-react';
+import { RefreshCw, RotateCw } from 'lucide-react';
import { FC } from 'react';
import { useRefreshWalletMutation } from '@/graphql/mutations/__generated__/refreshWallet.generated';
+import { cn } from '@/utils/cn';
-import { CommandItem } from '../ui/command';
+import { DropdownMenuItem } from '../ui/dropdown-menu';
import { useToast } from '../ui/use-toast';
export const RefreshWallet: FC<{
@@ -26,13 +27,21 @@ export const RefreshWallet: FC<{
});
return (
- refresh()} className="cursor-pointer">
- {title}
- {loading ? (
-
+ {
+ e.preventDefault();
+ refresh();
+ }}
+ >
+ {fullScan ? (
+
) : (
-
+
)}
-
+ {title}
+
);
};
diff --git a/src/components/button/VaultButtonV2.tsx b/src/components/button/VaultButtonV2.tsx
index 07ad556..fa4a4e1 100644
--- a/src/components/button/VaultButtonV2.tsx
+++ b/src/components/button/VaultButtonV2.tsx
@@ -236,7 +236,8 @@ const VaultPasswordButton: FC<{
className?: string;
variant?: Variants;
size?: 'md';
-}> = ({ lockedTitle, className, variant, size }) => {
+ unstyled?: boolean;
+}> = ({ lockedTitle, className, variant, size, unstyled }) => {
const t = useTranslations('App.Wallet.Vault');
const keys = useKeyStore(s => s.keys);
@@ -257,17 +258,21 @@ const VaultPasswordButton: FC<{
type="button"
variant={variant}
size={size}
- className={cn('flex items-center justify-center', className)}
+ className={cn(
+ 'flex items-center justify-center space-x-2',
+ className
+ )}
+ unstyled={unstyled}
>
{keys ? (
<>
-
- {t('unlocked')}
+
+ {t('unlocked')}
>
) : (
<>
-
- {lockedTitle}
+
+ {lockedTitle}
>
)}
@@ -309,6 +314,7 @@ const PasskeyVaultButton: FC<{
size?: 'md';
protectedSymmetricKey: string;
passkeyId: string;
+ unstyled?: boolean;
}> = ({
lockedTitle,
className,
@@ -316,6 +322,7 @@ const PasskeyVaultButton: FC<{
size,
protectedSymmetricKey,
passkeyId,
+ unstyled,
}) => {
const t = useTranslations('App.Wallet.Vault');
@@ -427,14 +434,15 @@ const PasskeyVaultButton: FC<{
type="button"
variant={variant}
size={size}
- className={cn('flex items-center justify-center', className)}
+ className={cn('flex items-center justify-center space-x-2', className)}
disabled={loading || addLoading}
onClick={() => {
setup({ variables: { id: passkeyId } });
}}
+ unstyled={unstyled}
>
-
- {lockedTitle}
+
+ {lockedTitle}
);
}
@@ -444,13 +452,14 @@ const PasskeyVaultButton: FC<{
type="button"
variant={variant}
size={size}
- className={cn('flex items-center justify-center', className)}
+ className={cn('flex items-center justify-center space-x-2', className)}
onClick={() => {
clearKeys();
}}
+ unstyled={unstyled}
>
-
- {t('unlocked')}
+
+ {t('unlocked')}
);
};
@@ -460,7 +469,8 @@ export const VaultButton: FC<{
className?: string;
variant?: Variants;
size?: 'md';
-}> = ({ lockedTitle, className, variant, size }) => {
+ unstyled?: boolean;
+}> = ({ lockedTitle, className, variant, size, unstyled }) => {
const t = useTranslations();
const lockedTitleFinal = lockedTitle || t('App.Wallet.Vault.locked');
@@ -473,11 +483,12 @@ export const VaultButton: FC<{
type="button"
variant={variant}
size={size}
- className={cn('flex items-center justify-center', className)}
+ className={cn('flex items-center justify-center space-x-2', className)}
disabled
+ unstyled={unstyled}
>
-
- {lockedTitleFinal}
+
+ {lockedTitleFinal}
);
}
@@ -488,11 +499,12 @@ export const VaultButton: FC<{
type="button"
variant={variant}
size={size}
- className={cn('flex items-center justify-center', className)}
+ className={cn('flex items-center justify-center space-x-2', className)}
disabled
+ unstyled={unstyled}
>
-
- {t('Common.error')}
+
+ {t('Common.error')}
);
}
@@ -506,6 +518,7 @@ export const VaultButton: FC<{
size={size}
protectedSymmetricKey={data.user.protected_symmetric_key}
passkeyId={data.user.using_passkey_id}
+ unstyled={unstyled}
/>
);
}
@@ -516,6 +529,7 @@ export const VaultButton: FC<{
className={className}
variant={variant}
size={size}
+ unstyled={unstyled}
/>
);
};
diff --git a/src/components/button/WalletButton.tsx b/src/components/button/WalletButton.tsx
index 15c1226..989f4d3 100644
--- a/src/components/button/WalletButton.tsx
+++ b/src/components/button/WalletButton.tsx
@@ -1,35 +1,45 @@
'use client';
-import { CaretSortIcon, CheckIcon } from '@radix-ui/react-icons';
-import { CircleEqual, PlusCircle, Settings } from 'lucide-react';
+import {
+ Check,
+ ChevronsUpDown,
+ Lock,
+ Plus,
+ PlusCircle,
+ Settings2,
+ Unlock,
+} from 'lucide-react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
-import { useEffect, useMemo, useState } from 'react';
+import { useTranslations } from 'next-intl';
+import { FC, useEffect, useMemo } from 'react';
import { useLocalStorage } from 'usehooks-ts';
import { Button } from '@/components/ui/button';
-import {
- Command,
- CommandGroup,
- CommandItem,
- CommandList,
-} from '@/components/ui/command';
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from '@/components/ui/popover';
import { useUserQuery } from '@/graphql/queries/__generated__/user.generated';
import { useGetAllWalletsQuery } from '@/graphql/queries/__generated__/wallet.generated';
import { useChat, useContactStore } from '@/stores/contacts';
+import { useKeyStore } from '@/stores/keys';
import { cn } from '@/utils/cn';
import { LOCALSTORAGE_KEYS } from '@/utils/constants';
import { ROUTES } from '@/utils/routes';
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from '../ui/dropdown-menu';
import { RefreshWallet } from './RefreshWallet';
+import { VaultButton } from './VaultButtonV2';
+
+export const WalletButton: FC<{ className?: string; cbk?: () => void }> = ({
+ className,
+ cbk,
+}) => {
+ const t = useTranslations('Index');
-export function WalletButton() {
- const [open, setOpen] = useState(false);
+ const keys = useKeyStore(s => s.keys);
const setCurrentContact = useContactStore(s => s.setCurrentContact);
const setCurrentPaymentOption = useChat(s => s.setCurrentPaymentOption);
@@ -66,124 +76,119 @@ export function WalletButton() {
}, [data]);
const buttonText = useMemo(() => {
- if (loading) return 'Loading...';
- if (!wallets.length) return 'Create a wallet';
+ if (loading) return t('loading') + '...';
+ if (!wallets.length) return t('create-wallet');
if (value) {
- return wallets.find(w => w.value === value)?.label || 'Select wallet...';
+ return wallets.find(w => w.value === value)?.label || t('select-wallet');
}
- }, [loading, wallets, value]);
+ }, [loading, wallets, value, t]);
if (error) return null;
if (!buttonText) return null;
return (
-
-
+
+
-
-
-
-
- {wallets.length ? (
-
- {wallets.map(w => (
- {
- setValue(currentValue);
- push(ROUTES.dashboard);
- setOpen(false);
- setCurrentContact(undefined);
- setCurrentPaymentOption(undefined);
- }}
- >
- {w.label}
-
-
- ))}
-
- ) : null}
-
- {!!value && wallets.length ? (
-
-
-
- {
- setOpen(false);
- }}
- >
-
- Settings
-
-
-
-
- ) : null}
-
- {!reachedWalletLimit ? (
-
- {
- setOpen(false);
- }}
- >
-
- New Wallet
-
-
-
- {
- setOpen(false);
- }}
- >
-
- Restore Wallet
-
-
-
-
- ) : null}
-
-
-
-
+
+
+ {!!value && wallets.length ? (
+ <>
+
+
+
+ cbk?.()}
+ className="flex items-center"
+ >
+
+ {t('settings')}
+
+
+
+
+
+ >
+ ) : null}
+
+
+ {t('wallets')}
+
+
+ {wallets.length
+ ? wallets.map(w => (
+ {
+ setValue(w.value);
+ push(ROUTES.dashboard);
+ cbk?.();
+ setCurrentContact(undefined);
+ setCurrentPaymentOption(undefined);
+ }}
+ >
+ {w.label}
+ {value === w.value ? (
+
+ ) : null}
+
+ ))
+ : null}
+
+ {!reachedWalletLimit ? (
+ <>
+
+ cbk?.()}
+ className="flex items-center"
+ >
+
+ {t('new-wallet')}
+
+
+
+ cbk?.()}
+ className="flex items-center"
+ >
+
+ {t('restore-wallet')}
+
+
+ >
+ ) : null}
+
+
);
-}
+};
diff --git a/src/components/layout/AppLayout.tsx b/src/components/layout/AppLayout.tsx
index f34a1ff..bd1ea4e 100644
--- a/src/components/layout/AppLayout.tsx
+++ b/src/components/layout/AppLayout.tsx
@@ -1,24 +1,21 @@
import {
ArrowLeftRight,
Home,
- Landmark,
LifeBuoy,
Menu,
MessageCircle,
ScrollText,
Settings,
- Settings2,
- Vault,
+ Wallet,
} from 'lucide-react';
import Link from 'next/link';
-import { FC, ReactNode, useState } from 'react';
+import { useTranslations } from 'next-intl';
+import { FC, ReactNode, useMemo, useState } from 'react';
import {
LogoutButton,
LogoutButtonWithTooltip,
} from '@/components/button/LogoutButton';
-import { VaultButton } from '@/components/button/VaultButton';
-import { ThemeToggle } from '@/components/toggle/ThemeToggle';
import { Button } from '@/components/ui/button';
import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet';
import {
@@ -26,55 +23,56 @@ import {
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip';
+import { useUserQuery } from '@/graphql/queries/__generated__/user.generated';
+import { useGetAllWalletsQuery } from '@/graphql/queries/__generated__/wallet.generated';
import { ROUTES } from '@/utils/routes';
import { WalletButton } from '../button/WalletButton';
+import { Logo } from '../Logo';
import { Badge } from '../ui/badge';
+import { Button as ButtonV2 } from '../ui/button-v2';
export const AppLayout: FC<{ children: ReactNode }> = ({ children }) => {
+ const t = useTranslations('Index');
+
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
+ const [mobileWalletMenuOpen, setMobileWalletMenuOpen] = useState(false);
+
+ const { data } = useGetAllWalletsQuery();
+ const { data: userData } = useUserQuery();
+
+ const reachedWalletLimit = useMemo(() => {
+ if (!data?.wallets.find_many || !userData?.user.wallet) return true;
+
+ return data.wallets.find_many.length >= userData.user.wallet.wallet_limit;
+ }, [data?.wallets.find_many, userData?.user.wallet]);
return (
-
-