Skip to content

Commit

Permalink
Merge eda6761 into 38efd07
Browse files Browse the repository at this point in the history
  • Loading branch information
meelrossi committed Jan 29, 2024
2 parents 38efd07 + eda6761 commit 846a3cf
Show file tree
Hide file tree
Showing 22 changed files with 499 additions and 173 deletions.
17 changes: 17 additions & 0 deletions src/components/ENSDetailPage/ENSDetailPage.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

.fieldContainer {
display: flex;
justify-content: space-between;
align-items: start;
gap: 32px;
}

Expand Down Expand Up @@ -153,3 +155,18 @@
text-decoration: underline;
color: white;
}

.unclaimedBadge {
padding: 0 8px;
border-radius: 24px;
font-size: 14px;
line-height: 24px;
background-color: #393640;
text-transform: uppercase;
font-weight: 600;
color: white;
}

.field.disabled {
opacity: 0.4;
}
30 changes: 29 additions & 1 deletion src/components/ENSDetailPage/ENSDetailPage.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const ensSample: ENS = {
name: 'test',
subdomain: 'test',
content: '',
ensOwnerAddress: '0xtest2',
ensOwnerAddress: '0xtest1',
nftOwnerAddress: '0xtest1',
resolver: '0xtest3',
tokenId: '',
Expand Down Expand Up @@ -184,4 +184,32 @@ describe('when ens is defined', () => {
expect(onNavigateMock).toHaveBeenCalledWith('/name/test/set-land')
})
})

describe('and the ens owner is different from the nft address', () => {
beforeEach(() => {
ens = {
...ensSample,
nftOwnerAddress: '0xtest1',
ensOwnerAddress: '0xtest2'
}
})

it('should call onReclaim when reclaim button is pressed', () => {
const openModalMock = jest.fn()
const screen = renderENSDetailPage({ ens, onOpenModal: openModalMock })
const reclaimNameBtn = screen.getByRole('button', { name: t('ens_detail_page.reclaim_name') })
userEvent.click(reclaimNameBtn)
expect(openModalMock).toHaveBeenCalledWith('ReclaimNameModal', { ens })
})

it('should disable assign address button', () => {
const screen = renderENSDetailPage({ ens })
expect(screen.getByRole('button', { name: t('ens_detail_page.reclaim_for_address') })).toBeDisabled()
})

it('should disable assign location button', () => {
const screen = renderENSDetailPage({ ens })
expect(screen.getByRole('button', { name: t('ens_detail_page.reclaim_for_location') })).toBeDisabled()
})
})
})
70 changes: 40 additions & 30 deletions src/components/ENSDetailPage/ENSDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export default function ENSDetailPage(props: Props) {
[ens]
)

const shouldReclaim = ens?.ensOwnerAddress !== ens?.nftOwnerAddress

useEffect(() => {
if (name) {
onFetchENS(name)
Expand All @@ -40,6 +42,10 @@ export default function ENSDetailPage(props: Props) {
onNavigate(locations.ensSelectLand(ens?.subdomain))
}, [onNavigate, ens?.subdomain])

const handleReclaim = useCallback(() => {
onOpenModal('ReclaimNameModal', { ens })
}, [onOpenModal])

const aliasField = useMemo(() => {
let field: React.ReactNode
if (alias !== ens?.name) {
Expand Down Expand Up @@ -76,11 +82,20 @@ export default function ENSDetailPage(props: Props) {
{field}
</div>
)
}, [ens?.name, avatar, alias, handleSetAsAlias])
}, [ens?.name, shouldReclaim, avatar, alias, handleSetAsAlias])

const addressField = useMemo(() => {
let field: React.ReactNode = null
if (!ens?.ensAddressRecord) {
if (shouldReclaim) {
field = (
<div className={classNames(styles.editableField, styles.disabled)}>
<span className={styles.emptyFieldPlaceholder}>{t('ens_detail_page.reclaim_for_address')}</span>
<Button compact secondary disabled className={styles.actionBtn} aria-label={t('ens_detail_page.reclaim_for_address')}>
<DCLIcon name="pencil alternate" />
</Button>
</div>
)
} else if (!ens?.ensAddressRecord) {
field = (
<div className={styles.editableField}>
<span className={styles.emptyFieldPlaceholder}>{t('ens_detail_page.assign_address')}</span>
Expand All @@ -97,7 +112,7 @@ export default function ENSDetailPage(props: Props) {
)
} else {
field = (
<span className={classNames(styles.editableField, styles.address)}>
<span className={styles.editableField}>
<span className={styles.editableFieldValue}>
<img src={ethereumImg} alt="Ethereum" />
{shorten(ens.ensAddressRecord)}
Expand All @@ -116,29 +131,28 @@ export default function ENSDetailPage(props: Props) {
)
}
return (
<div className={styles.field}>
<div className={classNames(styles.field, { [styles.disabled]: shouldReclaim })}>
<span className={styles.fieldTitle}>
{t('ens_detail_page.address')}
<Popup
on="click"
content={t('ens_detail_page.tooltips.address', {
a: (content: string) => (
<a href="https://docs.decentraland.org" rel="noreferrer" className={styles.externalLink} target="_blank">
{content}
</a>
)
})}
trigger={<DCLIcon name="info circle" />}
/>
<Popup on="click" content={t('ens_detail_page.tooltips.address')} trigger={<DCLIcon name="info circle" />} />
</span>
{field}
</div>
)
}, [ens?.ensAddressRecord, handleAssignENSAddress])
}, [ens?.ensAddressRecord, shouldReclaim, handleAssignENSAddress])

const landField = useMemo(() => {
let field: React.ReactNode = null
if (!ens?.landId) {
if (shouldReclaim) {
field = (
<div className={styles.editableField}>
<span className={styles.emptyFieldPlaceholder}>{t('ens_detail_page.reclaim_for_location')}</span>
<Button compact disabled className={styles.actionBtn} aria-label={t('ens_detail_page.reclaim_for_location')}>
<DCLIcon name="crosshairs" />
</Button>
</div>
)
} else if (!ens?.landId) {
field = (
<div className={styles.editableField}>
<span className={styles.emptyFieldPlaceholder}>{t('ens_detail_page.point_location')}</span>
Expand Down Expand Up @@ -178,25 +192,15 @@ export default function ENSDetailPage(props: Props) {
}

return (
<div className={styles.field}>
<div className={classNames(styles.field, { [styles.disabled]: shouldReclaim })}>
<span className={styles.fieldTitle}>
{t('ens_detail_page.land')}
<Popup
on="click"
content={t('ens_detail_page.tooltips.land', {
a: (content: string) => (
<a href="https://docs.decentraland.org" rel="noreferrer" className={styles.externalLink} target="_blank">
{content}
</a>
)
})}
trigger={<DCLIcon name="info circle" />}
/>
<Popup on="click" content={t('ens_detail_page.tooltips.land')} trigger={<DCLIcon name="info circle" />} />
</span>
{field}
</div>
)
}, [ens?.landId, handleAssignENS])
}, [ens?.landId, shouldReclaim, handleAssignENS])

return (
<LoggedInDetailPage activeTab={NavigationTab.NAMES} isPageFullscreen={true} isLoading={isLoading || !ens}>
Expand All @@ -219,8 +223,14 @@ export default function ENSDetailPage(props: Props) {
<CopyToClipboard role="button" text={ens?.subdomain || ''} showPopup={true} className="copy-to-clipboard">
<DCLIcon aria-label="copy name" aria-hidden="false" name="clone outline" />
</CopyToClipboard>
{ens?.ensOwnerAddress !== ens?.nftOwnerAddress ? (
<span className={styles.unclaimedBadge}>{t('ens_detail_page.unclaimed')}</span>
) : null}
</span>
</div>
<Button primary onClick={handleReclaim}>
{t('ens_detail_page.reclaim_name')}
</Button>
</div>
<div className={styles.fieldContainer}>
{aliasField}
Expand Down
16 changes: 16 additions & 0 deletions src/components/ENSListPage/ENSListPage.css
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,19 @@
border-radius: 50%;
background: var(--secondary);
}

.ENSListPage .ens-list-reclaim-icon {
margin: 0 !important;
width: fit-content;
font-size: 15px;
line-height: 15px;
}

.ENSListPage .ens-list-unclaimed-badge {
padding: 0 8px;
border-radius: 24px;
font-size: 12px;
background-color: #393640;
text-transform: uppercase;
font-weight: 600;
}
88 changes: 49 additions & 39 deletions src/components/ENSListPage/ENSListPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ export default class ENSListPage extends React.PureComponent<Props, State> {
onOpenModal('UseAsAliasModal', { newName })
}

handleReclaim = (ens: ENS) => {
const { onOpenModal } = this.props
onOpenModal('ReclaimNameModal', { ens })
}

renderSortDropdown = () => {
const { sortBy } = this.state
return (
Expand Down Expand Up @@ -130,6 +135,15 @@ export default class ENSListPage extends React.PureComponent<Props, State> {
}

renderLandLinkInfo(ens: ENS) {
if (ens.ensOwnerAddress !== ens.nftOwnerAddress) {
return (
<Button compact className="ens-list-btn" onClick={this.handleReclaim.bind(null, ens)}>
<DCLIcon name="arrow alternate circle down outline" className="ens-list-reclaim-icon" />
{t('ens_list_page.button.reclaim_land')}
</Button>
)
}

if (!ens.landId) {
return (
<Button compact className="ens-list-btn" onClick={this.handleAssignENS.bind(null, ens)}>
Expand Down Expand Up @@ -177,6 +191,35 @@ export default class ENSListPage extends React.PureComponent<Props, State> {
}
}

renderAddressInfo(ens: ENS) {
if (ens.ensOwnerAddress !== ens.nftOwnerAddress) {
return (
<Button compact className="ens-list-btn" onClick={this.handleReclaim.bind(null, ens)}>
<DCLIcon name="arrow alternate circle down outline" className="ens-list-reclaim-icon" />
{t('ens_list_page.button.reclaim_address')}
</Button>
)
}

if (ens.ensAddressRecord) {
return (
<span className="ens-list-address">
<img className="ens-list-address-icon" src={ethereumImg} alt="Ethereum" />
{shorten(ens.ensAddressRecord)}
<CopyToClipboard role="button" text={ens.ensAddressRecord} showPopup={true} className="copy-to-clipboard">
<DCLIcon aria-label="copy address" aria-hidden="false" name="clone outline" />
</CopyToClipboard>
</span>
)
}
return (
<Button compact className="ens-list-btn" onClick={this.handleAssignENSAddress.bind(null, ens)}>
<img src={addRounded} alt={t('ens_list_page.button.link_to_address')} className="ens-list-add-icon" />
{t('ens_list_page.button.link_to_address')}
</Button>
)
}

renderEnsList() {
const { ensList, hasProfileCreated } = this.props
const { page } = this.state
Expand Down Expand Up @@ -330,6 +373,9 @@ export default class ENSListPage extends React.PureComponent<Props, State> {
<CopyToClipboard role="button" text={ens.subdomain} showPopup={true} className="copy-to-clipboard">
<DCLIcon aria-label="copy subdomain" aria-hidden="false" name="clone outline" />
</CopyToClipboard>
{ens.ensOwnerAddress !== ens.nftOwnerAddress ? (
<span className="ens-list-unclaimed-badge">{t('ens_list_page.unclaimed')}</span>
) : null}
</div>
),
alias: this.isAlias(ens) ? (
Expand All @@ -353,20 +399,7 @@ export default class ENSListPage extends React.PureComponent<Props, State> {
{t('ens_list_page.button.add_to_avatar')}
</Button>
),
address: ens.ensAddressRecord ? (
<span className="ens-list-address">
<img className="ens-list-address-icon" src={ethereumImg} alt="Ethereum" />
{shorten(ens.ensAddressRecord)}
<CopyToClipboard role="button" text={ens.ensAddressRecord} showPopup={true} className="copy-to-clipboard">
<DCLIcon aria-label="copy address" aria-hidden="false" name="clone outline" />
</CopyToClipboard>
</span>
) : (
<Button compact className="ens-list-btn" onClick={this.handleAssignENSAddress.bind(null, ens)}>
<img src={addRounded} alt={t('ens_list_page.button.link_to_address')} className="ens-list-add-icon" />
{t('ens_list_page.button.link_to_address')}
</Button>
),
address: this.renderAddressInfo(ens),
land: this.renderLandLinkInfo(ens),
actions: (
<div className="ens-list-actions">
Expand Down Expand Up @@ -403,9 +436,6 @@ export default class ENSListPage extends React.PureComponent<Props, State> {
<Button primary href={`${MARKETPLACE_WEB_URL}/names/claim`} target="_blank">
{t('ens_list_page.empty_state.mint_name')}
</Button>
<Button secondary href={`${MARKETPLACE_WEB_URL}/names/browse?section=ens`} target="_blank">
{t('ens_list_page.empty_state.go_to_marketplace')}
</Button>
</div>
</div>
)
Expand Down Expand Up @@ -459,33 +489,13 @@ export default class ENSListPage extends React.PureComponent<Props, State> {
address: (
<span className="ens-list-page-table-headers">
{t('ens_list_page.table.address')}
<Popup
on="click"
content={t('ens_detail_page.tooltips.address', {
a: (content: string) => (
<a href="https://docs.decentraland.org" rel="noreferrer" className="ens-list-page-ext-link" target="_blank">
{content}
</a>
)
})}
trigger={<DCLIcon name="info circle" />}
/>
<Popup on="click" content={t('ens_detail_page.tooltips.address')} trigger={<DCLIcon name="info circle" />} />
</span>
),
land: (
<span className="ens-list-page-table-headers">
{t('ens_list_page.table.land')}
<Popup
on="click"
content={t('ens_detail_page.tooltips.land', {
a: (content: string) => (
<a href="https://docs.decentraland.org" rel="noreferrer" className="ens-list-page-ext-link" target="_blank">
{content}
</a>
)
})}
trigger={<DCLIcon name="info circle" />}
/>
<Popup on="click" content={t('ens_detail_page.tooltips.land')} trigger={<DCLIcon name="info circle" />} />
</span>
),
actions: <span className="ens-list-page-table-headers">{t('ens_list_page.table.actions')}</span>
Expand Down
Loading

0 comments on commit 846a3cf

Please sign in to comment.