Skip to content
Merged
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ storybook-static/*
.sentryclirc
.env*.local

pr-review-report.md
64 changes: 30 additions & 34 deletions components/HeaderWithMenu/index.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
import { useIntercom } from "react-use-intercom"
import IconButton from "@/components/buttons/iconButton"
import GoHomeButton from "@/components/utils/GoHome"
import { ArrowLeft } from 'lucide-react'
import ChatIcon from "@/components/Icons/ChatIcon"
import dynamic from "next/dynamic"
import LayerswapMenu from "@/components/LayerswapMenu"
import { useQueryState } from "@/context/query"
import { UserStatusHeader } from "../SecretDerivation"
import useWindowDimensions from "@/hooks/useWindowDimensions"
import dynamic from "next/dynamic"

const WalletsHeader = dynamic(() => import("../Wallet/ConnectedWallets.tsx").then((comp) => comp.WalletsHeader), {
loading: () => <></>
})

function HeaderWithMenu({ goBack }: { goBack: (() => void) | undefined | null }) {
const { boot, show, update } = useIntercom()
const query = useQueryState()
const { isMobile } = useWindowDimensions()

return (
<div className="w-full grid grid-cols-5 px-6 mt-3 pb-2" >
{
goBack &&
<IconButton onClick={goBack}
aria-label="Go back"
className="-ml-2"
icon={
<ArrowLeft strokeWidth="2" />
}>
</IconButton>
}
{
!query.hideLogo && <div className='justify-self-center self-center col-start-2 col-span-3 mx-auto overflow-hidden md:hidden headerLogo'>
<GoHomeButton />
</div>
}
<div className="col-start-5 justify-self-end self-center flex items-center gap-x-1 -mr-2">
<div className="items-center justify-between sm:flex sm:items-center grid grid-cols-5 w-full sm:grid-cols-none sm:grid-none mt-2 pb-2 px-4">
<div className="self-center col-start-1 md:col-start-2 md:col-span-3 justify-self-start md:justify-self-center flex items-center gap-2">
{
goBack &&
<div className="sm:-ml-2 -ml-0">
<IconButton onClick={goBack}
aria-label="Go back"
className=" inline-flex"
icon={
<ArrowLeft strokeWidth="2" />
} />
</div>
}
{
!query.hideLogo && <div className="md:hidden mt-0.5">
<GoHomeButton />
</div>
}
</div>
<div className="col-start-5 justify-self-end self-center flex items-center gap-x-2 sm:gap-x-1">
{
isMobile
? <UserStatusHeader />
: null
}
<WalletsHeader />
<IconButton className="relative hidden md:inline" onClick={() => {
boot();
show();
update()
}}
icon={
<ChatIcon className="h-6 w-6" strokeWidth="2" />
}>
</IconButton>
<div className="fixed-width-container">
<LayerswapMenu />
</div>
<LayerswapMenu />
</div>
</div>
)
Expand Down
2 changes: 1 addition & 1 deletion components/LayerswapMenu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ const Footer = ({ children, hidden, sticky = true }: FooterProps) => {
bg-secondary-900
shadow-widget-footer
p-4
px-6
px-4
w-full ${hidden ? 'animation-slide-out' : ''}`}>
{children}
</motion.div>
Expand Down
2 changes: 2 additions & 0 deletions components/LayerswapMenu/MenuList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Menu from "./Menu";
import dynamic from "next/dynamic";
import { MenuStep } from "@/Models/Wizard";
import useWindowDimensions from "@/hooks/useWindowDimensions";
import { UserStatusMenu } from "../SecretDerivation";

const WalletsMenu = dynamic(() => import("../Wallet/ConnectedWallets.tsx").then((comp) => comp.WalletsMenu), {
loading: () => <></>
Expand All @@ -35,6 +36,7 @@ const MenuList: FC<{ goToStep: (step: MenuStep, path?: string) => void }> = ({ g
return <div className="text-sm font-medium focus:outline-none h-full">
<Menu>

<UserStatusMenu />
<WalletsMenu />


Expand Down
8 changes: 3 additions & 5 deletions components/LayerswapMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,9 @@ const Comp = () => {

return <>
<div className="text-secondary-text cursor-pointer relative">
<div className="sm:-mr-2 mr-0">
<IconButton className="inline-flex active:animate-press-down" onClick={() => setIsOpen(true)} icon={
<MenuIcon strokeWidth="2" />
} />
</div>
<IconButton className="inline-flex active:animate-press-down" onClick={() => setIsOpen(true)} icon={
<MenuIcon strokeWidth="2" />
} />
<Modal isOpen={isOpen} setIsOpen={setIsOpen}>
<ModalContent
header={
Expand Down
16 changes: 7 additions & 9 deletions components/Modal/leaflet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,20 +104,18 @@ export const Leaflet = forwardRef<HTMLDivElement, PropsWithChildren<LeafletProps
dragElastic={{ top: 0, bottom: 1 }}
dragConstraints={{ top: 0, bottom: 0 }}
>
<div className={`py-3 overflow-y-auto flex flex-col h-full z-40 ${height != 'full' ? 'bg-secondary-900 rounded-t-2xl ' : ''} pb-6`}>
<div className={`px-6 pb-2 flex justify-between items-center ${height != 'full' && 'hover:cursor-grab'}`}>
<div className={`py-3 overflow-y-auto flex flex-col h-full z-40 ${height != 'full' ? 'bg-secondary-900 rounded-t-2xl ' : ''} pb-4`}>
<div className={`px-4 pb-2 flex justify-between items-center ${height != 'full' && 'hover:cursor-grab'}`}>
<div className="text-lg text-secondary-text font-semibold">
<div>{title}</div>
</div>
<div className='-mr-2'>
<IconButton onClick={handleCloseModal} icon={
<X strokeWidth={3} />
}>
</IconButton>
</div>
<IconButton onClick={handleCloseModal} icon={
<X strokeWidth={3} />
}>
</IconButton>
</div>
<div
className='select-text max-h-full overflow-y-auto overflow-x-hidden styled-scroll px-6 h-full' id="virtualListContainer">
className='select-text max-h-full overflow-y-auto overflow-x-hidden styled-scroll px-4 h-full' id="virtualListContainer">
{children}
</div>
</div>
Expand Down
12 changes: 5 additions & 7 deletions components/Modal/modalWithoutAnimation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,16 @@ export const ModalContent = (props: ModalContentProps) => {
{header}
</div>
{showCloseButton && (
<div className="-mr-2">
<IconButton onClick={closeModal} className="active:animate-press-down" icon={
<X strokeWidth={3} />
}>
</IconButton>
</div>
<IconButton onClick={closeModal} className="active:animate-press-down" icon={
<X strokeWidth={3} />
}>
</IconButton>
)}
</div>
</div>
)}

<div className="flex flex-col w-full h-full max-h-[90dvh] px-6 styled-scroll overflow-x-hidden overflow-y-auto pb-6 z-0 openpicker">
<div className="flex flex-col w-full h-full max-h-[90dvh] px-4 styled-scroll overflow-x-hidden overflow-y-auto pb-6 z-0 openpicker">
{typeof children === 'function' ? children({ closeModal, shouldFocus }) : children}
</div>
</div>
Expand Down
55 changes: 55 additions & 0 deletions components/SecretDerivation/LoginModal/OptionSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { useConnectModal } from '@/components/WalletModal';
import useWallet from '@/hooks/useWallet';
import { Wallet } from '@/Models/WalletProvider';
import { Fingerprint, Wallet as WalletIcon } from 'lucide-react';

const OptionSelect = ({ goToStep, onConnectFinish }: { goToStep: (step: string) => void, onConnectFinish: (wallet?: Wallet) => void }) => {
const { connect } = useConnectModal()
const { providers } = useWallet();

const evmProvider = providers.find(p => p.name.toLowerCase() === 'evm');
const connectedWallets = evmProvider?.connectedWallets || [];

const selectWallet = async() => {
if(connectedWallets.length < 1) {
const wallet = await connect(evmProvider);

if(wallet) {
onConnectFinish(wallet);
return
}
}
goToStep('wallet_select')
}

return (
<>
<p className="text-sm text-secondary-text">Choose how to login.</p>
<div className="flex flex-col gap-3 mt-4">
<OptionItem onClick={() => goToStep('passkey_choice')} icon={Fingerprint} title="Passkey" description="Face ID, Touch ID, or Windows Hello" />
<OptionItem onClick={selectWallet} icon={WalletIcon} title="Wallet (EVM)" description="Select or connect an EVM wallet" />
</div>
</>
)
}


const OptionItem = ({ onClick, icon: Icon, title, description }: { onClick: () => void, icon: (props: { className: string }) => React.ReactNode, title: string, description: string }) => {
return (
<button
type="button"
onClick={onClick}
className="w-full flex items-center gap-4 p-4 rounded-xl text-left transition-all duration-200 border-2 border-secondary-700 bg-secondary-800 hover:border-secondary-600"
>
<div className="shrink-0 w-12 h-12 rounded-xl bg-secondary-500 flex items-center justify-center">
<Icon className="w-6 h-6 text-primary-text" />
</div>
<div className="flex-1 min-w-0">
<h3 className="font-semibold text-primary-text">{title}</h3>
<p className="text-sm text-secondary-text mt-0.5">{description}</p>
</div>
</button>
)
}

export default OptionSelect;
56 changes: 56 additions & 0 deletions components/SecretDerivation/LoginModal/PasskeyChoice.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useState } from 'react';
import { KeyRound, AlertTriangle } from 'lucide-react';
import SubmitButton from '../../buttons/submitButton';

interface PasskeyChoiceProps {
onUseExisting: () => void;
onCreateNew: (label?: string) => void;
noPasskeyHint?: boolean;
}

export function PasskeyChoice({ onUseExisting, onCreateNew, noPasskeyHint }: PasskeyChoiceProps) {

const handleCreateNew = () => {
onCreateNew('Train');
};

return (
<div className="flex flex-col gap-5">
<div className="flex flex-col items-center gap-3">
<div className="w-14 h-14 rounded-2xl bg-secondary-700 flex items-center justify-center">
<KeyRound className="w-8 h-8 text-primary-text" strokeWidth={2} />
</div>
<h2 className="text-xl font-bold text-primary-text text-center">Sign in with passkey</h2>
</div>

<div className="flex flex-col gap-3">
<SubmitButton
type="button"
onClick={onUseExisting}
>
Use existing passkey
</SubmitButton>
{noPasskeyHint && (
<div className="flex items-start gap-2 rounded-xl bg-red-900/40 border border-red-800/60 px-3 py-2.5">
<AlertTriangle className="w-5 h-5 text-red-400 shrink-0 mt-0.5" strokeWidth={2} />
<p className="text-red-200/90 text-sm leading-snug">
No passkey found for any related origin
</p>
</div>
)}
</div>

<div className="flex items-center gap-3">
<div className="flex-1 h-px bg-secondary-600" />
<span className="text-sm font-medium text-secondary-text uppercase">OR</span>
<div className="flex-1 h-px bg-secondary-600" />
</div>
<SubmitButton
type="button"
onClick={handleCreateNew}
>
Create new passkey
</SubmitButton>
</div>
);
}
58 changes: 58 additions & 0 deletions components/SecretDerivation/LoginModal/SelectWallet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import WalletIcon from "@/components/Icons/WalletIcon";
import shortenAddress from "@/components/utils/ShortenAddress";
import { useConnectModal } from "@/components/WalletModal";
import useWallet from "@/hooks/useWallet";
import { Wallet } from "@/Models/WalletProvider";
import { Plus } from "lucide-react";

interface WalletSelectProps {
startWalletLogin: (wallet: Wallet) => void;
}

const WalletSelect = ({ startWalletLogin }: WalletSelectProps) => {
const { providers } = useWallet();
const evmProvider = providers.find(p => p.name.toLowerCase() === 'evm');
const connectedWallets = evmProvider?.connectedWallets || [];

const { connect } = useConnectModal();

return (
<>
<p className="text-sm text-secondary-text">Select a connected EVM wallet</p>

<div className="flex flex-col gap-2 mt-4">
{connectedWallets.length === 0 && (
<div className="text-sm text-secondary-text bg-secondary-800 border border-secondary-700 rounded-xl p-4">
No EVM wallets connected.
</div>
)}
{connectedWallets.map((wallet) => (
<button
key={wallet.address}
type="button"
onClick={() => startWalletLogin(wallet)}
className="w-full flex items-center gap-3 p-3 rounded-xl border-2 border-secondary-700 bg-secondary-800 hover:border-secondary-600"
>
<div className="shrink-0 w-10 h-10 rounded-lg bg-secondary-700 flex items-center justify-center">
{wallet.icon ? <wallet.icon /> : <WalletIcon className="w-5 h-5 text-primary-text" />}
</div>
<div className="flex-1 min-w-0 text-left">
<div className="text-primary-text font-semibold">{wallet.displayName || 'EVM Wallet'}</div>
<div className="text-xs text-secondary-text">{shortenAddress(wallet.address)}</div>
</div>
</button>
))}
</div>
<button
type="button"
onClick={() => connect(evmProvider)}
className="w-full flex items-center justify-center gap-2 py-3 px-4 mt-4 rounded-xl font-semibold border-2 border-secondary-700 bg-secondary-800 text-primary-text hover:bg-secondary-700 transition-colors"
>
<Plus className="w-4 h-4" />
Connect new wallet
</button>
</>
);
};

export default WalletSelect;
Loading