Skip to content

Commit f0d35f3

Browse files
authored
Merge pull request #450 from ensdomains/dev
Deploy Address Page
2 parents c221711 + f3a4acd commit f0d35f3

File tree

14 files changed

+268
-192
lines changed

14 files changed

+268
-192
lines changed

src/App.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import SearchResults from './routes/SearchResults'
1414
import SingleName from './routes/SingleName'
1515
import Favourites from './routes/Favourites'
1616
import About from './routes/About'
17-
import Address from './routes/Address'
17+
import Address from './routes/AddressPage'
1818
import { TestPage } from './routes/Test'
1919
import Modal from './components/Modal/Modal'
2020
import Confirm from './components/SingleName/Confirm'

src/api/manager/resolvers.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,10 @@ async function getParent(name) {
5656

5757
async function getRegistrarEntry(name) {
5858
const nameArray = name.split('.')
59-
if (nameArray.length > 3 && nameArray[1] !== 'eth') {
59+
if (nameArray.length > 3 || nameArray[1] !== 'eth') {
6060
return {}
6161
}
62+
6263
const entry = await getEntry(nameArray[0])
6364
const {
6465
registrant,

src/components/Address/Address.js

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import React, { useEffect, useState } from 'react'
2+
import styled from '@emotion/styled'
3+
import { useQuery } from 'react-apollo'
4+
5+
import { GET_DOMAINS_OWNED_BY_ADDRESS_FROM_SUBGRAPH } from '../../graphql/queries'
6+
import DomainItem from '../DomainItem/ChildDomainItem'
7+
import { decryptName } from '../../api/labels'
8+
import AddressContainer from '../Basic/MainContainer'
9+
import DefaultTopBar from '../Basic/TopBar'
10+
import { Title } from '../Typography/Basic'
11+
import { ExternalButtonLink as DefaultExternalButtonLink } from '../Forms/Button'
12+
import { getEtherScanAddr } from '../../utils/utils'
13+
import Loader from '../Loader'
14+
15+
const NoDomainsContainer = styled('div')`
16+
display: flex;
17+
padding: 40px;
18+
flex-direction: column;
19+
justify-content: center;
20+
align-items: center;
21+
background: white;
22+
box-shadow: 3px 4px 6px 0 rgba(229, 236, 241, 0.3);
23+
border-radius: 6px;
24+
margin-bottom: 40px;
25+
26+
h2 {
27+
color: #adbbcd;
28+
font-weight: 100;
29+
margin-bottom: 0;
30+
padding: 0;
31+
margin-top: 20px;
32+
text-align: center;
33+
max-width: 500px;
34+
}
35+
36+
p {
37+
color: #2b2b2b;
38+
font-size: 18px;
39+
font-weight: 300;
40+
margin-top: 20px;
41+
line-height: 1.3em;
42+
text-align: center;
43+
max-width: 400px;
44+
}
45+
`
46+
47+
const TopBar = styled(DefaultTopBar)`
48+
margin-bottom: 40px;
49+
`
50+
51+
const ExternalButtonLink = styled(DefaultExternalButtonLink)`
52+
margin-left: 40px;
53+
`
54+
55+
const DomainsContainer = styled('div')`
56+
margin-top: 20px;
57+
padding-bottom: 30px;
58+
padding-left: 40px;
59+
padding-right: 40px;
60+
`
61+
62+
function hasNoDomains(data) {
63+
return (
64+
(data.account &&
65+
data.account.domains &&
66+
data.account.domains.length === 0) ||
67+
data.account === null
68+
)
69+
}
70+
71+
function filterOutReverse(domains) {
72+
return domains.filter(domain => domain.parent.name !== 'addr.reverse')
73+
}
74+
75+
function DomainList({ domains, address }) {
76+
const { loading, data, error } = useQuery(
77+
GET_DOMAINS_OWNED_BY_ADDRESS_FROM_SUBGRAPH,
78+
{ variables: { id: address } }
79+
)
80+
81+
if (error) {
82+
return 'Error getting domains'
83+
}
84+
85+
if (loading) {
86+
return <Loader withWrap large />
87+
}
88+
89+
if (hasNoDomains(data)) {
90+
return (
91+
<NoDomainsContainer>
92+
<h2>This address does not own any domains</h2>
93+
</NoDomainsContainer>
94+
)
95+
}
96+
97+
return (
98+
<DomainsContainer>
99+
{filterOutReverse(data.account.domains).map(domain => (
100+
<DomainItem name={decryptName(domain.name)} owner={address} />
101+
))}
102+
</DomainsContainer>
103+
)
104+
}
105+
106+
export default function Address({ address }) {
107+
let [etherScanAddr, setEtherScanAddr] = useState(null)
108+
109+
useEffect(() => {
110+
getEtherScanAddr().then(setEtherScanAddr)
111+
}, [])
112+
113+
return (
114+
<AddressContainer>
115+
<TopBar>
116+
<Title>{address}</Title>
117+
</TopBar>
118+
{etherScanAddr && (
119+
<ExternalButtonLink
120+
type="primary"
121+
target="_blank"
122+
href={`${etherScanAddr}/address/${address}`}
123+
>
124+
View on EtherScan
125+
</ExternalButtonLink>
126+
)}
127+
<DomainList address={address} />
128+
</AddressContainer>
129+
)
130+
}

src/components/Address/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Address from './Address'
2+
export default Address
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import styled from '@emotion/styled'
2+
import mq from 'mediaQuery'
3+
4+
const MainContainer = styled('div')`
5+
background: white;
6+
box-shadow: 3px 4px 6px 0 rgba(229, 236, 241, 0.3);
7+
border-radius: 0;
8+
margin-bottom: 60px;
9+
position: relative;
10+
overflow: hidden;
11+
12+
${mq.small`
13+
border-radius: 6px;
14+
`}
15+
16+
&:before {
17+
left: 0;
18+
top: 0;
19+
width: 4px;
20+
height: 100%;
21+
display: block;
22+
content: '';
23+
background: ${({ state }) => {
24+
switch (state) {
25+
case 'Owned':
26+
return '#CACACA'
27+
case 'Auction':
28+
case 'Reveal':
29+
return 'linear-gradient(-180deg, #42E068 0%, #52E5FF 100%)'
30+
case 'Yours':
31+
return '#52e5ff'
32+
case 'Open':
33+
return '#42E068'
34+
default:
35+
return '#CACACA'
36+
}
37+
}};
38+
position: absolute;
39+
}
40+
`
41+
42+
export default MainContainer

src/components/Basic/TopBar.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import styled from '@emotion/styled'
2+
3+
const TopBar = styled('div')`
4+
padding: 20px 40px;
5+
display: flex;
6+
justify-content: space-between;
7+
align-items: center;
8+
border-bottom: 1px solid #ededed;
9+
box-shadow: 0 2px 4px 0 rgba(181, 177, 177, 0.2);
10+
11+
background: ${({ percentDone }) =>
12+
percentDone
13+
? `
14+
linear-gradient(to right, rgba(128, 255, 128, 0.1) 0%, rgba(82,229,255, 0.1) ${percentDone}%,#ffffff ${percentDone}%)`
15+
: 'white'};
16+
`
17+
18+
export default TopBar
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from 'react'
2+
import styled from '@emotion/styled'
3+
import { Link } from 'react-router-dom'
4+
import { SingleNameBlockies } from '../SingleName/SingleNameBlockies'
5+
6+
const DomainLink = styled(Link)`
7+
display: flex;
8+
align-items: center;
9+
width: 100%;
10+
padding: 30px 0;
11+
color: #2b2b2b;
12+
font-size: 22px;
13+
font-weight: 100;
14+
border-bottom: 1px dashed #d3d3d3;
15+
16+
&:last-child {
17+
border: none;
18+
}
19+
`
20+
21+
export default function ChildDomainItem({
22+
name,
23+
labelhash,
24+
owner,
25+
labelName,
26+
parent
27+
}) {
28+
return (
29+
<DomainLink key={name} to={`/name/${name}`}>
30+
<SingleNameBlockies imageSize={24} address={owner} />
31+
{labelName !== null
32+
? `${name}`
33+
: `[unknown${labelhash.slice(2, 10)}].${parent}`}
34+
</DomainLink>
35+
)
36+
}

src/components/Forms/Button.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ function getButtonStyles({ type }) {
66
switch (type) {
77
case 'primary':
88
return `
9+
&:visited {
10+
color: white;
11+
}
912
&:hover {
1013
cursor: pointer;
1114
border: 2px solid #2c46a6;

src/components/SingleName/Name.js

Lines changed: 3 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,19 @@
11
import React from 'react'
22
import styled from '@emotion/styled'
33

4-
import mq, { useMediaMin } from 'mediaQuery'
4+
import { useMediaMin } from 'mediaQuery'
55
import { EMPTY_ADDRESS } from '../../utils/records'
66

77
import { Title } from '../Typography/Basic'
8+
import TopBar from '../Basic/TopBar'
89
import DefaultFavourite from '../AddFavourite/Favourite'
910
import NameDetails from './NameDetails'
1011
import NameRegister from './NameRegister'
1112
import DNSNameRegister from './DNSNameRegister'
1213
import ShortName from './ShortName'
1314
import Tabs from './Tabs'
1415
import { useAccount } from '../QueryAccount'
15-
16-
const NameContainer = styled('div')`
17-
background: white;
18-
box-shadow: 3px 4px 6px 0 rgba(229, 236, 241, 0.3);
19-
border-radius: 0;
20-
margin-bottom: 60px;
21-
position: relative;
22-
overflow: hidden;
23-
24-
${mq.small`
25-
border-radius: 6px;
26-
`}
27-
28-
&:before {
29-
left: 0;
30-
top: 0;
31-
width: 4px;
32-
height: 100%;
33-
display: block;
34-
content: '';
35-
background: ${({ state }) => {
36-
switch (state) {
37-
case 'Owned':
38-
return '#CACACA'
39-
case 'Auction':
40-
case 'Reveal':
41-
return 'linear-gradient(-180deg, #42E068 0%, #52E5FF 100%)'
42-
case 'Yours':
43-
return '#52e5ff'
44-
case 'Open':
45-
return '#42E068'
46-
default:
47-
return '#CACACA'
48-
}
49-
}};
50-
position: absolute;
51-
}
52-
`
53-
54-
const TopBar = styled('div')`
55-
padding: 20px 40px;
56-
display: flex;
57-
justify-content: space-between;
58-
align-items: center;
59-
border-bottom: 1px solid #ededed;
60-
box-shadow: 0 2px 4px 0 rgba(181, 177, 177, 0.2);
61-
62-
background: ${({ percentDone }) =>
63-
percentDone
64-
? `
65-
linear-gradient(to right, rgba(128, 255, 128, 0.1) 0%, rgba(82,229,255, 0.1) ${percentDone}%,#ffffff ${percentDone}%)`
66-
: 'white'};
67-
`
16+
import NameContainer from '../Basic/MainContainer'
6817

6918
const Owner = styled('div')`
7019
color: #ccd4da;

src/components/SingleName/NameDetails.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const Records = styled('div')`
6666
border: 1px solid #ededed;
6767
box-shadow: inset 0 0 10px 0 rgba(235, 235, 235, 0.5);
6868
padding-bottom: ${p => (p.hasRecord ? '10px' : '0')};
69-
display: ${p => (!p.isOwner && !p.hasRecord ? 'none' : 'block')};
69+
display: ${p => (!p.hasRecord ? 'none' : 'block')};
7070
`
7171

7272
const ExpirationDetailsValue = styled(DetailsValue)`
@@ -601,15 +601,13 @@ function NameDetails({ domain, isOwner, isOwnerOfParent, refetch, account }) {
601601
account={account}
602602
/>
603603
<Records hasRecord={hasAnyRecord(domain)} isOwner={isOwner}>
604-
{hasAnyRecord(domain) && isOwner && (
605-
<AddRecord
606-
emptyRecords={emptyRecords}
607-
title="Records"
608-
isOwner={isOwner}
609-
domain={domain}
610-
refetch={refetch}
611-
/>
612-
)}
604+
<AddRecord
605+
emptyRecords={emptyRecords}
606+
title="Records"
607+
isOwner={isOwner}
608+
domain={domain}
609+
refetch={refetch}
610+
/>
613611
{hasAnyRecord(domain) && (
614612
<>
615613
{!isEmpty(domain.addr) && (

0 commit comments

Comments
 (0)