Skip to content
This repository has been archived by the owner on Jun 29, 2021. It is now read-only.

Commit

Permalink
Merge pull request #1 from dhedge/feat-components
Browse files Browse the repository at this point in the history
Add components for Gnosis Safe app
  • Loading branch information
edsonayllon authored Nov 25, 2020
2 parents d4b59d7 + ee34bc1 commit 5494f6c
Show file tree
Hide file tree
Showing 14 changed files with 492 additions and 103 deletions.
6 changes: 5 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,9 @@
"last 1 safari version"
]
},
"homepage": "./"
"homepage": "./",
"resolutions": {
"**/@typescript-eslint/eslint-plugin": "^4.1.1",
"**/@typescript-eslint/parser": "^4.1.1"
}
}
2 changes: 1 addition & 1 deletion app/public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"short_name": "Safe App",
"name": "Gnosis Safe App Starter",
"name": "dHedge",
"description": "Describe your Safe App here",
"iconPath": "logo.svg",
"icons": [
Expand Down
75 changes: 27 additions & 48 deletions app/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,30 @@
import React, { useCallback, useState } from 'react';
import styled from "styled-components";
import { Button, Loader, Title } from "@gnosis.pm/safe-react-components";
import { useSafe } from '@rmeissner/safe-apps-react-sdk';
import React, { useState } from "react";
import { ThemeProvider } from "styled-components";
import { theme } from "@gnosis.pm/safe-react-components";
import { Loader, Title } from "@gnosis.pm/safe-react-components";
import SafeProvider from '@rmeissner/safe-apps-react-sdk';
import GlobalStyle from "./GlobalStyle";
import StepperContainer from "containers/StepperContainer";
import { GlobalState, initialState } from 'GlobalState'

const Container = styled.form`
margin-bottom: 2rem;
width: 100%;
max-width: 480px;

display: grid;
grid-template-columns: 1fr;
grid-column-gap: 1rem;
grid-row-gap: 1rem;
`;
const App: React.FC = () => {
const [state, setState] = useState(initialState)
return (
<ThemeProvider theme={theme}>
<GlobalStyle />
<SafeProvider loading={(
<>
<Title size="md">Waiting for Safe...</Title>
<Loader size="md" />
</>
)}>
<GlobalState.Provider value={[state, setState]}>
<StepperContainer />
</GlobalState.Provider>
</SafeProvider>
</ThemeProvider>
)
}

const App: React.FC = () => {
const safe = useSafe()
const [submitting, setSubmitting] = useState(false)
const submitTx = useCallback(async () => {
setSubmitting(true)
try {
const safeTxHash = await safe.sendTransactions([
{
"to": safe.info.safeAddress,
"value": "0",
"data": "0x"
}
])
console.log({safeTxHash})
const safeTx = await safe.loadSafeTransaction(safeTxHash)
console.log({safeTx})
} catch (e) {
console.error(e)
}
setSubmitting(false)
}, [safe])
return <Container>
<Title size="md">{safe.info.safeAddress}</Title>
{submitting ?
<>
<Loader size="md" /><br/>
<Button size="lg" color="secondary" onClick={() => {setSubmitting(false)}}>Cancel</Button>
</>
:
<Button size="lg" color="primary" onClick={submitTx}>Submit</Button>
}
</Container>
};

export default App;
export default App
15 changes: 15 additions & 0 deletions app/src/GlobalState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React, { createContext } from 'react'

interface StateInterface {
activeStep?: number
}

const initialState: StateInterface = {
activeStep: 0
}

const initialContext: [StateInterface, React.Dispatch<React.SetStateAction<StateInterface>>] = [{}, () => ({})]

const GlobalState = createContext(initialContext)

export { GlobalState, initialState }
30 changes: 30 additions & 0 deletions app/src/GlobalStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,36 @@ const GlobalStyle = createGlobalStyle`
width: 100% !important;
}
.row-title {
display: flex;
flex-direction: row;
align-items: center;
}
.mg-r-small {
margin-right: 8px;
}
.mg-b-small {
margin-bottom: 16px;
}
.flex-row {
display: flex;
flex direction: row;
}
.select-width {
width: 80px;
}
.confirm-button-container {
display: flex;
flex-direction: row;
justify-content: flex-end;
padding: 16px;
}
@font-face {
font-family: 'Averta';
src: local('Averta'), local('Averta Bold'),
Expand Down
55 changes: 55 additions & 0 deletions app/src/components/Invest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { useContext, useState } from 'react'
import { Button, TextField, Select } from "@gnosis.pm/safe-react-components"
import { GlobalState } from 'GlobalState'

const items = [
{ id: '1', label: 'sUSD' }
];

const Invest: React.FC = () => {
const [state, setState] = useContext(GlobalState)
const [amount, setAmount] = useState('')
const [activeItemId, setActiveItemId] = useState('1')
const onSubmit = () => {}
return (
<form noValidate autoComplete="off" onSubmit={onSubmit}>
<div className = "flex-row">
<div className="mg-r-small select-width">
<Select
items={items}
activeItemId={activeItemId}
onItemClick={(id) => {
setActiveItemId(id);
}}
/>
</div>
<TextField
id="standard-amount"
label="Amount"
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
</div>
<div className="confirm-button-container">
<div className="mg-r-small">
<Button
size = "md"
color = "secondary"
onClick = {() => setState({ ...state, activeStep: 0 })}
>
Cancel
</Button>
</div>
<Button
size = "md"
color = "primary"
onClick = {() => setState({ ...state, activeStep: 0 })}
>
Invest
</Button>
</div>
</form>
)
}

export default Invest;
41 changes: 41 additions & 0 deletions app/src/components/SelectFund.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { useContext, useState } from 'react'
import { Button, TextField, Title } from "@gnosis.pm/safe-react-components"
import { GlobalState } from 'GlobalState'

interface Row {
pool: string;
totalReturn: string;
fees: string;
}

const createRow: (pool: string, totalReturn: string, fees: string) => Row = (pool, totalReturn, fees) => {
return { pool, totalReturn, fees }
}

const SelectFund: React.FC = () => {
const [state, setState] = useContext(GlobalState)
const [contract, setContract] = useState('');

return (
<>
<Title size="md">Enter pool contract</Title>
<TextField
id="standard-amount"
label="Pool Contract Address"
value={contract}
onChange={(e) => setContract(e.target.value)}
/>
<div className="confirm-button-container">
<Button
size = "md"
color = "primary"
onClick = {() => setState({ ...state, activeStep: 1 })}
>
Select
</Button>
</div>
</>
)
}

export default SelectFund;
42 changes: 42 additions & 0 deletions app/src/components/SelectedFund.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { useContext, useState } from 'react'
import { Button, Tab, Title, Text } from "@gnosis.pm/safe-react-components"
import { GlobalState } from 'GlobalState'
import styled from "styled-components";
import Invest from './Invest'
import Withdraw from './Withdraw'



const SelectedFund: React.FC = () => {
const [state, setState] = useContext(GlobalState)
const [selected, setSelected] = useState('1');
const poolTitle = "Convex Strategies Pool"
const percent = 34
return (
<>
<div className = "row-title">
<div className="mg-r-small">
<Title size="md">{poolTitle}</Title>
</div>
<Text size="xl" color= { percent < 0 ? "error" : 'primary'} >
{`${percent}%`}
</Text>
</div>

<div className = "mg-b-small">
<Tab
onChange={setSelected}
selectedTab={selected}
variant="outlined"
items={[
{ id: '1', label: 'Invest'},
{ id: '2', label: 'Withdraw'}
]}
/>
</div>
{ selected === '1' ? <Invest /> : <Withdraw /> }
</>
)
}

export default SelectedFund;
55 changes: 55 additions & 0 deletions app/src/components/Withdraw.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { useContext, useState } from 'react'
import { Button, TextField, Select } from "@gnosis.pm/safe-react-components"
import { GlobalState } from 'GlobalState'

const items = [
{ id: '1', label: 'Pool' }
];

const Withdraw: React.FC = () => {
const [state, setState] = useContext(GlobalState)
const [amount, setAmount] = useState('');
const [activeItemId, setActiveItemId] = useState('1')
const onSubmit = () => {}
return (
<form noValidate autoComplete="off" onSubmit={onSubmit}>
<div className = "flex-row">
<div className="mg-r-small select-width">
<Select
items={items}
activeItemId={activeItemId}
onItemClick={(id) => {
setActiveItemId(id);
}}
/>
</div>
<TextField
id="standard-amount"
label="Amount"
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
</div>
<div className="confirm-button-container">
<div className="mg-r-small">
<Button
size = "md"
color = "secondary"
onClick = {() => setState({ ...state, activeStep: 0 })}
>
Cancel
</Button>
</div>
<Button
size = "md"
color = "primary"
onClick = {() => setState({ ...state, activeStep: 0 })}
>
Withdraw
</Button>
</div>
</form>
)
}

export default Withdraw;
7 changes: 7 additions & 0 deletions app/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import SelectedFund from './SelectedFund'
import SelectFund from './SelectFund'

export {
SelectFund,
SelectedFund
}
Loading

0 comments on commit 5494f6c

Please sign in to comment.