-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trello 19 #31
base: master
Are you sure you want to change the base?
Trello 19 #31
Changes from 5 commits
a6f822b
c1262ba
bc3ad16
0a51551
e8dc5aa
ac912e7
a3f1135
6463125
ba28515
492fb9e
99f7eca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const Card: React.FC<{ className?: string }> = ({ className = '', children }) => { | ||
return <div className={`inline-block bg-light shadow-lg overflow-hidden sm:rounded-lg ${className}`}>{children}</div>; | ||
}; | ||
|
||
export default Card; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const CardBody: React.FC<{}> = ({ children }) => { | ||
return <div className="px-4 py-5 sm:px-6">{children}</div>; | ||
}; | ||
|
||
export default CardBody; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const CardFooter: React.FC<{}> = ({ children }) => { | ||
return <div className="px-4 py-3 bg-gray-50 text-right sm:px-6">{children}</div>; | ||
}; | ||
|
||
export default CardFooter; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const CardHeader: React.FC<{}> = ({ children }) => { | ||
return <div className="mx-4 px-4 py-3 text-left text-2xl border-b border-gray-200">{children}</div>; | ||
}; | ||
|
||
export default CardHeader; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export { default as Card } from './Card'; | ||
export { default as CardBody } from './CardBody'; | ||
export { default as CardFooter } from './CardFooter'; | ||
export { default as CardHeader } from './CardHeader'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React from 'react'; | ||
import { FaSearch, FaTimes } from 'react-icons/fa'; | ||
|
||
interface SearchInput { | ||
value: any; | ||
onChange: (value: string) => void; | ||
name?: string; | ||
id?: string; | ||
className?: string; | ||
placeholder?: string; | ||
} | ||
|
||
const SearchInput: React.FC<SearchInput> = ({ | ||
value, | ||
onChange, | ||
name = 'search', | ||
id = 'search', | ||
className = '', | ||
placeholder = '', | ||
}): JSX.Element => { | ||
return ( | ||
<div className="mt-1 relative"> | ||
<div className="absolute inset-y-0 right-0 p-3 text-gray-600 flex items-center"> | ||
{/** TODO: Remove this and actually use the other icons library once we get the query manager merged in */} | ||
{value ? ( | ||
<button type="button" onClick={() => onChange('')}> | ||
<FaTimes size={12} /> | ||
</button> | ||
) : ( | ||
<FaSearch size={12} /> | ||
)} | ||
</div> | ||
<input | ||
type="text" | ||
name={name} | ||
id={id} | ||
value={value} | ||
placeholder={placeholder} | ||
className={`focus:outline-none focus:ring-2 focus:ring-opacity-20 focus:ring-primary block w-full pl-7 pr-12 sm:text-sm border-gray-200 bg-gray-200 text-gray-600 rounded-full ${className}`} | ||
onChange={(event) => onChange(event.target.value)} | ||
/> | ||
</div> | ||
); | ||
}; | ||
|
||
export default SearchInput; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import SearchInput from './SearchInput'; | ||
|
||
export default SearchInput; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const Table: React.FC<{ className?: string }> = ({ className = '', children }): JSX.Element => { | ||
return <table className={`min-w-full divide-y divide-gray-200 ${className}`}>{children}</table>; | ||
}; | ||
|
||
export default Table; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const TableBody: React.FC<{ className?: string }> = ({ className = '', children }): JSX.Element => { | ||
return <tbody className={`bg-white divide-y divide-gray-200 ${className}`}>{children}</tbody>; | ||
}; | ||
|
||
export default TableBody; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const TableCell: React.FC<{ className?: string }> = ({ className = '', children }): JSX.Element => { | ||
return <td className={`px-6 py-4 whitespace-nowrap ${className}`}>{children}</td>; | ||
}; | ||
|
||
export default TableCell; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const TableHeader: React.FC<{ className?: string }> = ({ className = '', children }): JSX.Element => { | ||
return <thead className={`bg-gray-50 ${className}`}>{children}</thead>; | ||
}; | ||
|
||
export default TableHeader; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import React from 'react'; | ||
|
||
const TableHeaderCell: React.FC<{ className?: string }> = ({ className = '', children }): JSX.Element => { | ||
return ( | ||
<th | ||
scope="col" | ||
className={`px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider ${className}`} | ||
> | ||
{children} | ||
</th> | ||
); | ||
}; | ||
|
||
export default TableHeaderCell; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const TableRow: React.FC<{ className?: string }> = ({ className = '', children }): JSX.Element => { | ||
return <tr className={className}>{children}</tr>; | ||
}; | ||
|
||
export default TableRow; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export { default as Table } from './Table'; | ||
export { default as TableBody } from './TableBody'; | ||
export { default as TableCell } from './TableCell'; | ||
export { default as TableHeader } from './TableHeader'; | ||
export { default as TableHeaderCell } from './TableHeaderCell'; | ||
export { default as TableRow } from './TableRow'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './Card'; | ||
export * from './Table'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
import { Card, CardBody, CardHeader } from '../../components/common'; | ||
import SearchInput from '../../components/common/Input'; | ||
import mockDataChain from './mock-data'; | ||
|
||
type ChainType = 'evm' | 'substrate'; | ||
|
||
interface Chain { | ||
name: string; | ||
type: ChainType; | ||
project: string; | ||
url: string; | ||
credentials: { | ||
// TODO: Ask potentially BE to have structure camelCase in case or we can just disable the warning in eslint | ||
/* eslint-disable camelcase */ | ||
private_key?: string; | ||
public_key?: string; | ||
}; | ||
tracked_contracts: string[]; | ||
} | ||
|
||
const TrackedContractsList: React.FC<{}> = () => { | ||
const [chains, setChains] = useState<Chain[]>([]); | ||
const [activeChain, setActiveChain] = useState<Chain>(); | ||
const [searchChain, setSearchChain] = useState(''); | ||
|
||
useEffect(() => { | ||
setChains(mockDataChain as Chain[]); | ||
}, []); | ||
|
||
const allChains = chains | ||
.filter((data) => { | ||
if (!searchChain) { | ||
return data; | ||
} | ||
if (data.name.includes(searchChain.trim().toLocaleLowerCase())) { | ||
return data; | ||
} | ||
return null; | ||
}) | ||
.map((chain) => { | ||
return ( | ||
<div | ||
className={`focus:outline-none py-4 capitalize cursor-pointer ${ | ||
chain.name === activeChain?.name ? 'font-bold text-primary' : '' | ||
}`} | ||
role="button" | ||
onClick={() => setActiveChain(chain)} | ||
onKeyPress={() => setActiveChain(chain)} | ||
tabIndex={0} | ||
> | ||
{chain.name} | ||
</div> | ||
); | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit nicer:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I would try to move out the div view and present it as a component There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The filter like that wouldn't actually work but yeah simplifying it and moving it to a separate component. |
||
|
||
const activeContracts = | ||
activeChain && activeChain.tracked_contracts.length | ||
? activeChain.tracked_contracts.map((contract) => { | ||
return contract; | ||
}) | ||
: 'No Tracked Contracts'; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should also work
|
||
return ( | ||
<div className="container mx-auto"> | ||
<div className="flex"> | ||
<div className="flex-none mr-10 w-1/4 md:w-auto"> | ||
<Card> | ||
<div className="mx-4 px-4 py-3 max-w-md"> | ||
<SearchInput | ||
value={searchChain} | ||
onChange={(val: string) => setSearchChain(val)} | ||
placeholder="Search" | ||
className="py-3 text-lg leading-relaxed max-w-full" | ||
/> | ||
</div> | ||
<CardBody> | ||
<div className="divide-y divide-gray-100 text-secondary">{allChains}</div> | ||
</CardBody> | ||
</Card> | ||
</div> | ||
<div className="flex-1"> | ||
<Card className="w-full"> | ||
<CardBody> | ||
<CardHeader>Tracked Contracts</CardHeader> | ||
{/* <Table></Table> */} | ||
{activeContracts} | ||
</CardBody> | ||
</Card> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default TrackedContractsList; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as TrackedContractsList } from './TrackedContractsList'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// We can remove this when we can hook to the BE and get that data it's just for getting the UX ready for it | ||
const mockDataChain = [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just mocking the sample we got from Jure |
||
{ | ||
name: 'eth.mainnet', | ||
type: 'evm', | ||
project: 'eth', | ||
url: 'https://mainnet.infura.io/v3/<project_id>', | ||
credentials: {}, | ||
tracked_contracts: [], | ||
}, | ||
{ | ||
name: 'eth.dev-mainnet-fork', | ||
type: 'evm', | ||
project: 'eth', | ||
url: 'ws://localhost:8545', | ||
credentials: { | ||
private_key: '<private_key>', | ||
}, | ||
tracked_contracts: ['0x3194cBDC3dbcd3E11a07892e7bA5c3394048Cc87'], | ||
}, | ||
{ | ||
name: 'dev-canvas', | ||
type: 'substrate', | ||
project: 'canvas', | ||
url: 'ws://127.0.0.1:9944', | ||
credentials: { | ||
private_key: '<private_key>', | ||
public_key: '<public_key>', | ||
}, | ||
tracked_contracts: ['5FnDzvXcnu3RCtQ3f3RFqaQnVLfcWLZ9FvUURNoPMdmsKZXP'], | ||
}, | ||
]; | ||
export default mockDataChain; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed eslint settings in Query Builder to display a warning