Skip to content

Commit

Permalink
fet-1670
Browse files Browse the repository at this point in the history
  • Loading branch information
talentlessguy committed Oct 25, 2024
1 parent 0332869 commit c67d000
Show file tree
Hide file tree
Showing 13 changed files with 928 additions and 14 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"@noble/hashes": "^1.3.2",
"@rainbow-me/rainbowkit": "2.1.2",
"@sentry/nextjs": "7.43.x",
"@splidejs/react-splide": "^0.7.12",
"@svgr/webpack": "^8.1.0",
"@tanstack/query-persist-client-core": "5.22.2",
"@tanstack/query-sync-storage-persister": "5.22.2",
Expand Down
41 changes: 28 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/confetti.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/assets/DAO.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/assets/social/SocialX.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions src/components/pages/migrate/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Splide, SplideSlide } from '@splidejs/react-splide'
import { ReactNode } from 'react'

export const Carousel = ({ children }: { children: ReactNode[] }) => {
return (
<Splide
options={{
arrows: false,
pagination: false,
gap: '16px',
perPage: 2,
fixedWidth: 312,
}}
>
{children.map((child) => (
<SplideSlide>{child}</SplideSlide>
))}
</Splide>
)
}
170 changes: 170 additions & 0 deletions src/components/pages/migrate/MigrationNamesList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { TFunction, useTranslation } from 'react-i18next'
import styled, { css } from 'styled-components'
import { useEnsAvatar } from 'wagmi'

import { NameWithRelation } from '@ensdomains/ensjs/subgraph'
import { CheckCircleSVG, Colors, DisabledSVG, PlusCircleSVG } from '@ensdomains/thorin'

import { ensAvatarConfig } from '@app/utils/query/ipfsGateway'
import { formatDurationOfDates } from '@app/utils/utils'

const tabs = ['eligible', 'ineligible', 'approved'] as const

type Tab = (typeof tabs)[number]

const icons: Record<Tab, any> = {
eligible: <PlusCircleSVG />,
ineligible: <DisabledSVG />,
approved: <CheckCircleSVG />,
}

const colors: Record<Tab, { fg: Colors; bg: Colors; hover: Colors }> = {
eligible: {
fg: 'bluePrimary',
bg: 'blueSurface',
hover: 'blueLight',
},
ineligible: {
fg: 'redPrimary',
bg: 'redSurface',
hover: 'redLight',
},
approved: {
fg: 'greenPrimary',
bg: 'greenSurface',
hover: 'greenLight',
},
}

const Container = styled.div(
({ theme }) => css`
display: flex;
flex-direction: column;
gap: ${theme.space['2']};
`,
)

const TabsContainer = styled.div(
({ theme }) => css`
display: flex;
flex-direction: row;
gap: ${theme.space['4']};
padding: ${theme.space['0.5']};
border-radius: ${theme.radii['2xLarge']};
background-color: ${theme.colors.background};
border: 4px solid ${theme.colors.background};
`,
)

const TabButton = styled.button<{ $isActive?: boolean; tab: Tab }>(
({ theme, $isActive, tab }) => css`
width: ${theme.space.full};
padding: 0 ${theme.space['4']};
height: ${theme.space['12']};
border-radius: ${theme.radii.large};
color: ${$isActive ? theme.colors[colors[tab].fg] : theme.colors.textTertiary};
background-color: ${$isActive ? theme.colors[colors[tab].bg] : theme.colors.background};
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
font-weight: ${theme.fontWeights.bold};
gap: ${theme.space['2']};
transition-property: background-color;
transition-duration: ${theme.transitionDuration['150']};
transition-timing-function: ${theme.transitionTimingFunction.inOut};
&:hover {
background-color: ${$isActive
? theme.colors[colors[tab].hover]
: theme.colors[colors[tab].bg]};
}
`,
)

const NamesGrid = styled.div(
({ theme }) => css`
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: ${theme.space['2']};
`,
)

const NameCard = styled.div(
({ theme }) => css`
background: ${theme.colors.background};
border-radius: ${theme.radii['2xLarge']};
padding: ${theme.space['8']};
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
& > span:nth-of-type(1) {
font-weight: ${theme.fontWeights.bold};
}
& > span:nth-of-type(2) {
color: ${theme.colors.textTertiary};
font-size: ${theme.fontSizes.small};
}
& > img {
border-radius: ${theme.radii.full};
}
`,
)

const nameListTabs = ['eligible', 'ineligible', 'approved'] as const

export type NameListTab = (typeof nameListTabs)[number]

const MigrationName = ({ name, t }: { name: NameWithRelation; t: TFunction }) => {
const now = new Date()
const { data: avatar } = useEnsAvatar({ ...ensAvatarConfig, name: name.name! })

const expiresIn = formatDurationOfDates({
startDate: now,
endDate: new Date(name.expiryDate?.date!),
t,
}).split(', ')[0]

return (
<NameCard>
{avatar && <img width="40" height="40" src={avatar} alt="" />}
<span>{name.name}</span>
<span>Expires in {expiresIn}</span>
</NameCard>
)
}

export const MigrationNamesList = ({
activeTab,
setTab,
names,
}: {
activeTab: NameListTab
names: NameWithRelation[]
setTab: (tab: NameListTab) => void
}) => {
const { t } = useTranslation('migrate')

return (
<Container>
<TabsContainer>
{tabs.map((tab) => (
<TabButton tab={tab} $isActive={tab === activeTab} key={tab} onClick={() => setTab(tab)}>
{icons[tab]} {t(`migration-list.${tab}`)}
</TabButton>
))}
</TabsContainer>
<NamesGrid>
{names.map((name) => (
<MigrationName {...{ name, t }} />
))}
</NamesGrid>
</Container>
)
}
28 changes: 28 additions & 0 deletions src/hooks/migration/useApprovedNamesForMigration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { erc721Abi } from 'viem'
import { usePublicClient, useReadContracts } from 'wagmi'

import { getChainContractAddress } from '@ensdomains/ensjs/contracts'
import { NameWithRelation } from '@ensdomains/ensjs/subgraph'

export const useApprovedNamesForMigration = ({
names,
}: {
names: NameWithRelation[]
}): NameWithRelation[] => {
const client = usePublicClient()

const { data } = useReadContracts({
contracts: names.map((name) => ({
address: getChainContractAddress({
client,
contract: name.wrappedOwner ? 'ensNameWrapper' : 'ensBaseRegistrarImplementation',
}),
abi: erc721Abi,
functionName: 'isApprovedForAll',
args: ['contract-go-here', true],
})),
multicallAddress: getChainContractAddress({ client, contract: 'multicall3' }),
})

return names.filter((d, i) => Boolean(data?.[i].result))
}
1 change: 1 addition & 0 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { lightTheme, RainbowKitProvider, Theme } from '@rainbow-me/rainbowkit'

import '@rainbow-me/rainbowkit/styles.css'
import '@splidejs/react-splide/css'

import { NextPage } from 'next'
import type { AppProps } from 'next/app'
Expand Down
Loading

0 comments on commit c67d000

Please sign in to comment.