Skip to content

Commit

Permalink
Merge pull request #167 from palladians/chore/decouple-views-from-routes
Browse files Browse the repository at this point in the history
chore(wallet): refactor views and decouple views from logic
  • Loading branch information
mrcnk authored Apr 14, 2024
2 parents 99b5f8f + 59cf72c commit 98e3f63
Show file tree
Hide file tree
Showing 90 changed files with 1,875 additions and 1,244 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v20.10.0
v20.12.2
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"test:unit": "turbo run test:unit",
"test:e2e:extension": "turbo run test:e2e --filter=@palladxyz/extension",
"format": "prettier --write \"**/*.{ts,tsx,md}\" && pnpm lint:fix",
"f": "pnpm format",
"cleanup": "turbo run cleanup && rimraf node_modules",
"prepare": "husky install",
"preinstall": "npx only-allow pnpm"
Expand Down Expand Up @@ -48,5 +49,5 @@
"typescript": "^5.3.3",
"vitest": "^1.1.0"
},
"packageManager": "pnpm@8.12.1"
"packageManager": "pnpm@8.15.6"
}
8 changes: 8 additions & 0 deletions packages/features/src/about/routes/about.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useNavigate } from 'react-router-dom'

import { AboutView } from '../views/about'

export const AboutRoute = () => {
const navigate = useNavigate()
return <AboutView onGoBack={() => navigate(-1)} />
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { StoryDefault } from '@ladle/react'

import { AboutView } from './about'

export const View = () => <AboutView />
export const View = () => <AboutView onGoBack={() => console.log('go back')} />

export default {
title: 'Dashboard / About'
Expand Down
14 changes: 6 additions & 8 deletions packages/features/src/about/views/about.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useNavigate } from 'react-router-dom'

import Logo from '@/common/assets/logo.svg'
import { AppLayout } from '@/components/app-layout'
import { MetaField } from '@/components/meta-field'
Expand All @@ -20,15 +18,15 @@ const AppMeta = [
}
]

export const AboutView = () => {
const navigate = useNavigate()
type AboutViewProps = {
onGoBack: () => void
}

export const AboutView = ({ onGoBack }: AboutViewProps) => {
return (
<AppLayout>
<div className="flex flex-col flex-1">
<ViewHeading
title="About"
backButton={{ onClick: () => navigate(-1) }}
/>
<ViewHeading title="About" backButton={{ onClick: onGoBack }} />
<div className="flex flex-col gap-4 flex-1 p-4">
<Card className="flex gap-4 p-4 justify-between rounded-[1rem]">
<div className="flex items-center gap-4">
Expand Down
16 changes: 16 additions & 0 deletions packages/features/src/address-book/routes/address-book.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useNavigate } from 'react-router-dom'

import { useAddressBookStore } from '@/common/store/address-book'

import { AddressBookView } from '../views/address-book'

export const AddressBookRoute = () => {
const navigate = useNavigate()
const contacts = useAddressBookStore((state) => state.contacts)
return (
<AddressBookView
contacts={contacts}
onAddClicked={() => navigate('/contacts/new')}
/>
)
}
8 changes: 8 additions & 0 deletions packages/features/src/address-book/routes/new-address.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useNavigate } from 'react-router-dom'

import { NewAddressView } from '../views/new-address'

export const NewAddressRoute = () => {
const navigate = useNavigate()
return <NewAddressView onGoBack={() => navigate(-1)} />
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { StoryDefault } from '@ladle/react'

import { AddressBookView } from './address-book'

export const View = () => <AddressBookView />
export const View = () => (
<AddressBookView contacts={[]} onAddClicked={() => console.log('back')} />
)

export default {
title: 'Dashboard / Address Book'
Expand Down
17 changes: 11 additions & 6 deletions packages/features/src/address-book/views/address-book.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { PlusIcon } from 'lucide-react'
import { useNavigate } from 'react-router-dom'

import { useAddressBookStore } from '@/common/store/address-book'
import { Contact } from '@/common/types'
import { AppLayout } from '@/components/app-layout'
import { ViewHeading } from '@/components/view-heading'

Expand All @@ -12,9 +11,15 @@ const DonatePallad = {
address: 'B62qkYa1o6Mj6uTTjDQCob7FYZspuhkm4RRQhgJg9j4koEBWiSrTQrS'
}

export const AddressBookView = () => {
const navigate = useNavigate()
const contacts = useAddressBookStore((state) => state.contacts)
type AddressBookViewProps = {
contacts: Contact[]
onAddClicked: () => void
}

export const AddressBookView = ({
contacts,
onAddClicked
}: AddressBookViewProps) => {
return (
<AppLayout>
<div className="flex flex-col flex-1">
Expand All @@ -27,7 +32,7 @@ export const AddressBookView = () => {
Add Address
</div>
),
onClick: () => navigate('/contacts/new'),
onClick: onAddClicked,
testId: 'addressBook__addAddressButton'
}}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { StoryDefault } from '@ladle/react/lib/app/exports'
import { StoryDefault } from '@ladle/react'

import { NewAddressView } from './new-address'

export const View = () => <NewAddressView />
export const View = () => (
<NewAddressView onGoBack={() => console.log('back')} />
)

export default {
title: 'Dashboard / Address Book/ New Address'
Expand Down
14 changes: 6 additions & 8 deletions packages/features/src/address-book/views/new-address.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import { useNavigate } from 'react-router-dom'

import { AppLayout } from '@/components/app-layout'
import { ViewHeading } from '@/components/view-heading'

import { NewAddressForm } from '../components/new-address-form'

export const NewAddressView = () => {
const navigate = useNavigate()
type NewAddressViewProps = {
onGoBack: () => void
}

export const NewAddressView = ({ onGoBack }: NewAddressViewProps) => {
return (
<AppLayout>
<div className="flex flex-col flex-1">
<ViewHeading
title="New Address"
backButton={{ onClick: () => navigate(-1) }}
/>
<ViewHeading title="New Address" backButton={{ onClick: onGoBack }} />
<div className="flex flex-col flex-1 p-4">
<NewAddressForm />
</div>
Expand Down
6 changes: 3 additions & 3 deletions packages/features/src/common/hooks/use-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ export const useAccount = () => {
const setVaultStateUninitialized = useAppStore(
(state) => state.setVaultStateUninitialized
)
const publicKey = currentWallet.credential.credential?.address as string
const fetchWallet = async () => {
await _syncWallet()
return getAccountsInfo(network, publicKey) // TODO: replace with getBalance
}
const publicKey = currentWallet.credential.credential?.address as string
const swr = useSWR(
publicKey ? [publicKey, 'account', network] : null,
async () => await fetchWallet(),
Expand All @@ -47,8 +47,8 @@ export const useAccount = () => {
[publicKey]
)
const stakeDelegated =
currentWallet.accountInfo['MINA'].publicKey !==
currentWallet.accountInfo['MINA'].delegate
currentWallet.accountInfo['MINA']?.publicKey !==
currentWallet.accountInfo['MINA']?.delegate
const copyWalletAddress = async () => {
await navigator.clipboard.writeText(publicKey ?? '')
toast({
Expand Down
9 changes: 4 additions & 5 deletions packages/features/src/common/store/transaction.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { Mina } from '@palladxyz/mina-core'
import { create } from 'zustand'

import { OutgoingTransaction } from '../types'

type TxKind = 'transaction' | 'staking'

type TransactionState = {
outgoingTransaction: OutgoingTransaction | null
kind: TxKind
kind: Mina.TransactionKind
}

type TransactionMutators = {
set: (outgoingTransaction: OutgoingTransaction) => void
setKind: (kind: TxKind) => void
setKind: (kind: Mina.TransactionKind) => void
}

type TransactionStore = TransactionState & TransactionMutators
Expand All @@ -22,7 +21,7 @@ const initialState = {

export const useTransactionStore = create<TransactionStore>()((set) => ({
...initialState,
kind: 'transaction',
kind: Mina.TransactionKind.PAYMENT,
set(outgoingTransaction) {
return set({ outgoingTransaction })
},
Expand Down
5 changes: 0 additions & 5 deletions packages/features/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ type Epoch = number
type ChainId = string
type PublicKey = string

export enum TxKind {
STAKE_DELEGATION = 'STAKE_DELEGATION',
PAYMENT = 'PAYMENT'
}

export enum TxSide {
INCOMING = 'INCOMING',
OUTGOING = 'OUTGOING'
Expand Down
9 changes: 8 additions & 1 deletion packages/features/src/components/app-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react'

import { useAccount } from '@/common/hooks/use-account'

import { BottomNavigation } from './bottom-navigation'
import { CommandMenu } from './command-menu'

Expand All @@ -8,14 +10,19 @@ interface AppLayoutProps {
}

export const AppLayout = ({ children }: AppLayoutProps) => {
const { lockWallet } = useAccount()
const [commandMenuOpen, setCommandMenuOpen] = React.useState(false)
const openCommandMenu = () => setCommandMenuOpen(true)
return (
<div
className="flex flex-col flex-1 bg-background gap-4"
data-testid="appLayout"
>
<CommandMenu open={commandMenuOpen} setOpen={setCommandMenuOpen} />
<CommandMenu
open={commandMenuOpen}
setOpen={setCommandMenuOpen}
lockWallet={lockWallet}
/>
<div className="animate-in fade-in flex flex-1">{children}</div>
<BottomNavigation openCommandMenu={openCommandMenu} />
</div>
Expand Down
10 changes: 6 additions & 4 deletions packages/features/src/components/command-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,18 @@ import {
CommandList
} from '@/components/ui/command'

import { useAccount } from '../common/hooks/use-account'

interface CommandMenuProps {
open: boolean
setOpen: (open: boolean) => void
lockWallet: () => void
}

export const CommandMenu = ({ open, setOpen }: CommandMenuProps) => {
export const CommandMenu = ({
open,
setOpen,
lockWallet
}: CommandMenuProps) => {
const navigate = useNavigate()
const { lockWallet } = useAccount()

const COMMAND_GROUPS = [
{
Expand Down
73 changes: 73 additions & 0 deletions packages/features/src/lock/routes/unlock-wallet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { zodResolver } from '@hookform/resolvers/zod'
import {
getSecurePersistence,
getSessionPersistence
} from '@palladxyz/persistence'
import { useVault } from '@palladxyz/vault'
import { FormEvent, useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'
import { useNavigate } from 'react-router-dom'
import { z } from 'zod'

import { passwordSchema } from '@/common/lib/validation'

import { UnlockWalletView } from '../views/unlock-wallet'

const formSchema = z.object({
spendingPassword: passwordSchema
})

export const UnlockWalletRoute = () => {
const [restartAlertVisible, setRestartAlertVisible] = useState(false)
const [showPassword, setShowPassword] = useState(false)
const navigate = useNavigate()
const unlockWalletForm = useForm({
defaultValues: {
spendingPassword: ''
},
resolver: zodResolver(formSchema)
})
const onSubmit = async ({
spendingPassword
}: {
spendingPassword: string
}) => {
await getSessionPersistence().setItem('spendingPassword', spendingPassword)
await useVault.persist.rehydrate()
setTimeout(() => {
unlockWalletForm.setError('spendingPassword', {
type: 'wrongPassword',
message: 'The spending password is wrong'
})
}, 100)
}
const togglePassword = (event: FormEvent<HTMLButtonElement>) => {
event.preventDefault()
setShowPassword(!showPassword)
}
useEffect(() => {
const unsub = useVault.persist?.onFinishHydration(async () => {
const authenticated =
(await getSecurePersistence().getItem('foo')) === 'bar'
if (!authenticated) {
await getSessionPersistence().removeItem('spendingPassword')
return unlockWalletForm.setError('spendingPassword', {
type: 'wrongPassword',
message: 'The spending password is wrong'
})
}
navigate('/dashboard')
})
return () => unsub?.()
}, [])
return (
<UnlockWalletView
form={unlockWalletForm}
onSubmit={onSubmit}
restartAlertVisible={restartAlertVisible}
setRestartAlertVisible={setRestartAlertVisible}
showPassword={showPassword}
togglePassword={togglePassword}
/>
)
}
17 changes: 16 additions & 1 deletion packages/features/src/lock/views/unlock-wallet.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import { StoryDefault } from '@ladle/react'
import { useState } from 'react'
import { useForm } from 'react-hook-form'

import { UnlockWalletView } from './unlock-wallet'

export const View = () => <UnlockWalletView />
export const View = () => {
const [restartAlertVisible, setRestartAlertVisible] = useState(false)
const form = useForm<UnlockWalletData>()
return (
<UnlockWalletView
form={form}
onSubmit={() => console.log('submit')}
restartAlertVisible={restartAlertVisible}
setRestartAlertVisible={setRestartAlertVisible}
showPassword={false}
togglePassword={() => console.log('toggle')}
/>
)
}

export default {
title: 'Dashboard / Unlock Wallet'
Expand Down
Loading

0 comments on commit 98e3f63

Please sign in to comment.