//tips
//smart contract
一通りrequest newページのUIの整理。これで新たなリクエストを作成するページができた
import React ,{Component} from 'react';
import {Form,Button,Message,Input} from 'semantic-ui-react';
import Campaign from '../../../ethereum/campaign';
import web3 from '../../../ethereum/web3';
import {Link,Router} from '../../../routes';
import Layout from '../../../components/Layout';
class RequestNew extends Component{
state={
value:'',
description:'',
recipient:'',
loading:false,
errorMessage:''
};
//campaign内の新規リクエスト作成部分
//URLからアドレス取得してpropsへ
static async getInitalProps(props){
//index.jsと同じ
const {address}=props.query;
return{address};
}
onSubmit=async event=>{
event.preventDefault();
const campaign=Campaign(this.props.address);
const {description,value,recipient}=this.state;
this.setState({loading:true,errorMessage:''});
try{
const accounts= await web3.eth.getAccounts();
//.solのcreateRequest()を呼び出し
await campaign.methods.createRequest(
description,
web3.utils.toWei(value,'ether'),
recipient
).send({from:accounts[0]});
Router.pushRoute(`/campaigns/${this.props.address}/requests`)
}catch(err){
this.setState({errorMessage:err.message})
}
this.setState({loading:false});
};
render(){
return(
<Layout>
<Link route={`/campaigns/${this.props.address}/requests`}>
<a>
Back
</a>
</Link>
<h3>Create a request</h3>
<Form onSubmit={this.onSubmit} error={!!this.state.errorMessage}>
<Form.Field>
<Label>Description</Label>
<Input
value={this.state.description}
onChange={event=>
this.setState({description:event.target.value})}
/>
</Form.Field>
<Form.Field>
<Label>Value in Ethere</Label>
<Input
value={this.state.value}
onChange={event=>
this.setState({value:event.target.value})}
/>
</Form.Field>
<Form.Field>
<Label>Recipient</Label>
<Input
value={this.state.recipient}
onChange={event=>
this.setState({recipient:event.target.value})}
/>
</Form.Field>
<Message error header="Oops!" content={this.state.errorMessage}/>
<Button primary loading={this.state.loading}> Create!</Button>
</Form>
</Layout>
);
}
}
export default RequestNew;
ここからはrequest index ページを作成して、campaign内のそれぞれのrequestを表示できるようにしていく。
ただ、作成済みのrequestsを簡単に入手することはできず、(arrayが含まれていることが要因のよう)
function getRequestsCount() public view returns(uint){
return requests.length;
}
を使用してループ処理で各リクエスト情報を集約する必要があるとのこと。下記のようにpromise.allとarray().fill().map()を組み合わせることで情報は集められた。
class RequestIndex extends Component{
//campaign内の新規リクエスト作成部分
//URLからアドレス取得してpropsへ
static async getInitalProps(props){
//show.jsと比較してみるとわかりやすい
const {address}=props.query;
const campaign=Campaign(address);
//ここから全てのrequestの数を得られる
const requestCount=await campaign.methods.getRequestsCount().call();
//requestの数から情報集約する
//このrequestsの中身には各requestのdescriptionに始まり、予算額、受取人などの情報が格納される
//しかも前半はarrayで格納、後半はプロパティをそのまま格納されており、2度同じ情報を記載されている
const requests=await Promise.all(
Array(parseInt(requestCount))//array().fill().map()をすることで見やすいリストに変換できる
//[0,1,2,3,4,5,]のような感じに分けて表示してくれる
.fill()
.map((element,index)=>{
return campaign.methods.requests(index).call();
})
);
return{address,requests,requestCount};
}
同時に上記情報を格納するUIのテーブルも実装する。
ImportでTable機能を取り込んだとに
render(){
//Table部分を定義してreturn下で使えるようにする
const{Header,Row,HeaderCell,Body}=Table;
return(
<Layout>
<h3>Requests</h3>
<Link route={`/campaigns/${this.props.address}/requests/new`}>
<a>
<Button primary>Add Request</Button>
</a>
</Link>
<Table>
<Header>
<Row>
<HeaderCell> ID </HeaderCell>
<HeaderCell> Description </HeaderCell>
<HeaderCell> Amount </HeaderCell>
<HeaderCell> Recipient </HeaderCell>
<HeaderCell> Approval Count </HeaderCell>
<HeaderCell> Approve </HeaderCell>
<HeaderCell> Finalize </HeaderCell>
</Row>
</Header>
</Table>
</Layout>
各Table機能の表示部分を実際のレンダリング箇所に組み込む。
ここからさらにそれぞれのrequestに応じて行を追加させていきたいのでRequestRow.jsファイルを新たに作成し、機能として加えていく。これはページの部品部分なのでcomponentフォルダに格納。