Skip to content

Commit

Permalink
refactor: address qa findings, add mobile view for public delegate list
Browse files Browse the repository at this point in the history
  • Loading branch information
katamarinaki committed Aug 29, 2024
1 parent 02a7f33 commit 9fbc0f2
Show file tree
Hide file tree
Showing 15 changed files with 380 additions and 186 deletions.
4 changes: 4 additions & 0 deletions assets/avatar.com.svg.react
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<svg width="52" height="52" viewBox="0 0 52 52" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="26" cy="26" r="26" fill="black" fill-opacity="0.1"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M32.8818 19.8789C32.8818 23.697 29.8204 26.7585 25.9996 26.7585C22.1801 26.7585 19.1174 23.697 19.1174 19.8789C19.1174 16.0607 22.1801 13.0005 25.9996 13.0005C29.8204 13.0005 32.8818 16.0607 32.8818 19.8789ZM25.9996 39.0005C20.3607 39.0005 15.5996 38.084 15.5996 34.5479C15.5996 31.0106 20.3906 30.1266 25.9996 30.1266C31.6398 30.1266 36.3996 31.0431 36.3996 34.5791C36.3996 38.1165 31.6086 39.0005 25.9996 39.0005Z" fill="#3C4254" fill-opacity="0.28"/>
</svg>
50 changes: 50 additions & 0 deletions modules/delegation/providers/DelegateFromPublicListContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { createContext, FC, useCallback, useContext, useState } from 'react'
import invariant from 'tiny-invariant'

//
// Data context
//

type Value = {
selectedPublicDelegate: string | undefined
onPublicDelegateSelect: (address: string) => () => void
onPublicDelegateReset: () => void
}

const DelegateFromPublicListContext = createContext<Value | null>(null)

export const useDelegateFromPublicList = () => {
const value = useContext(DelegateFromPublicListContext)
invariant(
value,
'useDelegateFromPublicList was used outside the DelegateFromPublicListContext provider',
)
return value
}

export const DelegateFromPublicListProvider: FC = ({ children }) => {
const [selectedPublicDelegate, setSelectedPublicDelegate] = useState<string>()

const handleDelegatePick = useCallback(
(address: string) => () => {
setSelectedPublicDelegate(address)
},
[],
)

const handleDelegateReset = useCallback(() => {
setSelectedPublicDelegate(undefined)
}, [])

return (
<DelegateFromPublicListContext.Provider
value={{
selectedPublicDelegate,
onPublicDelegateSelect: handleDelegatePick,
onPublicDelegateReset: handleDelegateReset,
}}
>
{children}
</DelegateFromPublicListContext.Provider>
)
}
18 changes: 11 additions & 7 deletions modules/delegation/providers/DelegationFormContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { useDelegationFormSubmit } from '../hooks/useDelegationFormSubmit'
import { useDelegationRevoke } from '../hooks/useDelegationRevoke'
import { ToastSuccess } from '@lidofinance/lido-ui'
import { isValidAddress } from 'modules/shared/utils/addressValidation'
import { useDelegateFromPublicList } from './DelegateFromPublicListContext'

//
// Data context
Expand Down Expand Up @@ -120,15 +121,15 @@ const useDelegationFormActions = (
//
export type DelegationFormProviderProps = {
mode: DelegationFormMode
presetDelegateAddress?: string
}

export const DelegationFormProvider: FC<DelegationFormProviderProps> = ({
children,
mode,
presetDelegateAddress,
}) => {
const networkData = useDelegationFormNetworkData()
const { selectedPublicDelegate, onPublicDelegateReset } =
useDelegateFromPublicList()

const formObject = useForm<DelegationFormInput>({
defaultValues: { delegateAddress: '' },
Expand All @@ -138,14 +139,17 @@ export const DelegationFormProvider: FC<DelegationFormProviderProps> = ({
useEffect(() => {
const currentValue = formObject.getValues('delegateAddress')
if (
presetDelegateAddress &&
isValidAddress(presetDelegateAddress) &&
currentValue?.toLowerCase() !== presetDelegateAddress.toLowerCase()
selectedPublicDelegate &&
isValidAddress(selectedPublicDelegate) &&
currentValue?.toLowerCase() !== selectedPublicDelegate.toLowerCase()
) {
formObject.setValue('delegateAddress', presetDelegateAddress)
formObject.setValue('delegateAddress', selectedPublicDelegate, {
shouldValidate: true,
})
onPublicDelegateReset()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [presetDelegateAddress])
}, [selectedPublicDelegate])

const {
isSubmitting,
Expand Down
12 changes: 6 additions & 6 deletions modules/delegation/ui/DelegationForm/DelegationFormStyle.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import styled from 'styled-components'
import styled, { css } from 'styled-components'
import { Button, Text } from '@lidofinance/lido-ui'

export const DelegationFormControllerStyled = styled.form<{
Expand All @@ -9,11 +9,11 @@ export const DelegationFormControllerStyled = styled.form<{
${({ $customMode }) =>
$customMode &&
`
padding: 24px 16px;
background-color: var(--lido-color-accentControlBg);
border-radius: 20px;
`}
css`
padding: 24px 16px;
background-color: var(--lido-color-accentControlBg);
border-radius: ${({ theme }) => theme.borderRadiusesMap.xl}px;
`}
`

export const DelegationSubtitleStyled = styled.div`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Text } from '@lidofinance/lido-ui'
import { Text, useBreakpoint } from '@lidofinance/lido-ui'
import { DelegationSubtitleStyled } from './DelegationFormStyle'
import { useDelegationFormData } from 'modules/delegation/providers/DelegationFormContext'

Expand All @@ -7,12 +7,13 @@ import SnapshotSvg from 'assets/snapshot.com.svg.react'

export function DelegationFormSubtitle() {
const { mode } = useDelegationFormData()
const isMobile = useBreakpoint('md')

if (mode === 'aragon') {
return (
<DelegationSubtitleStyled>
<AragonSvg />
<Text size="md" weight={700}>
<Text size={isMobile ? 'sm' : 'md'} weight={700}>
On Aragon
</Text>
</DelegationSubtitleStyled>
Expand All @@ -23,7 +24,7 @@ export function DelegationFormSubtitle() {
return (
<DelegationSubtitleStyled>
<SnapshotSvg />
<Text size="md" weight={700}>
<Text size={isMobile ? 'sm' : 'md'} weight={700}>
On Snapshot
</Text>
</DelegationSubtitleStyled>
Expand Down
75 changes: 32 additions & 43 deletions modules/delegation/ui/DelegationSettings/DelegationSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,47 @@
import { useCallback, useState } from 'react'
import { Button, Text } from '@lidofinance/lido-ui'
import { useState } from 'react'
import { Button, Text, useBreakpoint } from '@lidofinance/lido-ui'

import { FormTitle, FormWrap, Wrap } from './DelegationSettingsStyle'
import { DelegationForm } from '../DelegationForm'
import { PublicDelegateList } from '../PublicDelegateList'
import { DelegateFromPublicListProvider } from '../../providers/DelegateFromPublicListContext'

export function DelegationSettings() {
const [isSimpleModeOn, setIsSimpleModeOn] = useState(true)
const [delegateFromPublicList, setDelegateFromPublicList] = useState<string>()

const handleDelegatePick = useCallback(
(address: string) => () => {
setDelegateFromPublicList(address)
},
[],
)
const isMobile = useBreakpoint('md')

return (
<Wrap>
<FormWrap $customizable={!isSimpleModeOn}>
<FormTitle>
<Text size="xl" weight={700}>
Delegation
</Text>
{!isSimpleModeOn && (
<Button
variant="outlined"
size="xs"
onClick={() => setIsSimpleModeOn(true)}
>
Back
</Button>
)}
</FormTitle>
{isSimpleModeOn ? (
<DelegationForm
mode="simple"
presetDelegateAddress={delegateFromPublicList}
onCustomizeClick={() => setIsSimpleModeOn(false)}
/>
) : (
<>
<DelegateFromPublicListProvider>
<FormWrap $customizable={!isSimpleModeOn}>
<FormTitle>
<Text size={isMobile ? 'lg' : 'xl'} weight={700}>
Delegation
</Text>
{!isSimpleModeOn && (
<Button
variant="outlined"
size="xs"
onClick={() => setIsSimpleModeOn(true)}
>
Back
</Button>
)}
</FormTitle>
{isSimpleModeOn ? (
<DelegationForm
mode="aragon"
presetDelegateAddress={delegateFromPublicList}
mode="simple"
onCustomizeClick={() => setIsSimpleModeOn(false)}
/>
<DelegationForm
mode="snapshot"
presetDelegateAddress={delegateFromPublicList}
/>
</>
)}
</FormWrap>
<PublicDelegateList onDelegatePick={handleDelegatePick} />
) : (
<>
<DelegationForm mode="aragon" />
<DelegationForm mode="snapshot" />
</>
)}
</FormWrap>
<PublicDelegateList />
</DelegateFromPublicListProvider>
</Wrap>
)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { BREAKPOINT_MOBILE } from 'modules/globalStyles'
import { BREAKPOINT_MD, BREAKPOINT_MOBILE } from 'modules/globalStyles'
import styled from 'styled-components'

export const Wrap = styled.div`
display: flex;
gap: 20px;
justify-content: center;
align-items: flex-start;
flex-wrap: wrap;
& > div {
flex: 1;
Expand All @@ -22,7 +23,7 @@ export const Wrap = styled.div`
`

export const FormWrap = styled.div<{ $customizable: boolean }>`
border-radius: 20px;
border-radius: ${({ theme }) => theme.borderRadiusesMap.xl}px;
background-color: var(--lido-color-foreground);
display: flex;
flex-direction: column;
Expand All @@ -35,6 +36,10 @@ export const FormWrap = styled.div<{ $customizable: boolean }>`
`
padding: 32px 24px;
`}
@media (max-width: ${BREAKPOINT_MD}) {
padding: 20px;
}
`

export const FormTitle = styled.div`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Button } from '@lidofinance/lido-ui'
import styled from 'styled-components'

export const Wrap = styled.div<{ $empty?: boolean }>`
border-radius: 20px;
border-radius: ${({ theme }) => theme.borderRadiusesMap.xl}px;
background-color: var(--lido-color-foreground);
padding: 32px;
display: flex;
Expand Down
30 changes: 30 additions & 0 deletions modules/delegation/ui/PublicDelegateList/PublicDelegateAvatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Image from 'next/image'
import { AvatarWrap } from './PublicDelegateListStyle'

import AvatarSvg from 'assets/avatar.com.svg.react'

type Props = {
avatarSrc: string | null | undefined
}

export function PublicDelegateAvatar({ avatarSrc }: Props) {
if (!avatarSrc) {
return (
<AvatarWrap>
<AvatarSvg viewBox="0 0 52 52" />
</AvatarWrap>
)
}

return (
<AvatarWrap>
<Image
src={avatarSrc}
alt=""
layout="fill"
loader={({ src }) => src}
unoptimized
/>
</AvatarWrap>
)
}
Loading

0 comments on commit 9fbc0f2

Please sign in to comment.