From c969b38520e16f82d90f92b942da1305a00e4874 Mon Sep 17 00:00:00 2001 From: VOGT VICTOR <v.vogt@etu.unistra.fr> Date: Fri, 17 Dec 2021 00:56:16 +0000 Subject: [PATCH] Feature/trans --- frontend/src/actions/Bank.actions.js | 68 ++++++++------- frontend/src/containers/Bank.container.js | 101 ++++++++-------------- frontend/src/reducers/Bank.reducer.js | 29 +++---- frontend/src/reducers/index.js | 2 + frontend/src/setupProxy.js | 2 +- 5 files changed, 88 insertions(+), 114 deletions(-) diff --git a/frontend/src/actions/Bank.actions.js b/frontend/src/actions/Bank.actions.js index d98bbc6..260aa7f 100644 --- a/frontend/src/actions/Bank.actions.js +++ b/frontend/src/actions/Bank.actions.js @@ -1,74 +1,76 @@ import {userService} from "../services/authentication.service"; -export const profileDataFetchSuccess = (data) => { +const MONEY_API_URL = 'https://money.erp.uni.princelle.org'; + +export const transactionDataFetchSuccess = (data) => { return { - type:'PROFILE_DATA_REQ_SUCCESS', + type:'TRANS_DATA_REQ_SUCCESS', data } } -export const profileDataFetchFailure = () => { +export const transactionDataFetchFailure = (message) => { return { - type:'PROFILE_DATA_REQ_FAILURE' + type:'TRANS_DATA_REQ_FAILURE', + message } } -export const updateUserSuccess = () => { +export const profileDataFetchSuccess = (data) => { return { - type:'UPDATE_USER_SUCCESS', + type:'PROFILE_DATA_REQ_SUCCESS', + data } } -export const updateUserFailure = (error) => { +export const profileDataFetchFailure = (message) => { return { - type:'UPDATE_USER_FAILURE', - message:error, + type:'PROFILE_DATA_REQ_FAILURE', + message } } -export const fetchUserData = () => { +export const fetchUserTransactions = (student_number) => { return async (dispatch) => { - const response = await fetch( "/api/me", { + const response = await fetch(MONEY_API_URL+'/transactions/get/'+student_number, { method: 'GET', - headers: { - 'Authorization': userService.getToken() - } }) if(response.ok){ response.json().then(data => { - dispatch(profileDataFetchSuccess(data)); - }).catch(err => dispatch(profileDataFetchFailure(err))); + console.log(data); + let balance = data.rows.map(data => data.amount).reduce((sum, amount) => sum + amount); + let data_sorted = data.rows.sort(function(a,b){return Date.parse(a.concluded_at) - Date.parse(b.concluded_at)}); + dispatch(transactionDataFetchSuccess({balance: balance, transactions: data_sorted})); + }).catch(err => dispatch(transactionDataFetchFailure(err))); } else{ response.json().then(error => { - dispatch(profileDataFetchFailure(error)); - }).catch(err => dispatch(profileDataFetchFailure(err))); + dispatch(transactionDataFetchFailure(error)); + }).catch(err => dispatch(transactionDataFetchFailure(err))); } return response; } } -export const changeUserData = (data) => { +export const fetchUserData = () => { return async (dispatch) => { - const response = await fetch( "/api/me/update", { - method: 'POST', + const response = await fetch( "/api/me", { + method: 'GET', headers: { - 'Authorization': userService.getToken(), - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - body: JSON.stringify(data), - }) - + 'Authorization': userService.getToken() + } + }); + if(response.ok){ - dispatch(updateUserSuccess()); - } - else{ + response.json().then(data => { + dispatch(profileDataFetchFailure(data)); + }).catch(err => dispatch(profileDataFetchFailure(err))); + } else { response.json().then(error => { - dispatch(updateUserFailure(error)); - }).catch(err => dispatch(updateUserFailure(err))); + dispatch(profileDataFetchFailure(error)); + }).catch(err => dispatch(profileDataFetchFailure(err))); } return response; diff --git a/frontend/src/containers/Bank.container.js b/frontend/src/containers/Bank.container.js index 9ec5438..eac5ad2 100644 --- a/frontend/src/containers/Bank.container.js +++ b/frontend/src/containers/Bank.container.js @@ -3,68 +3,43 @@ import React from 'react'; import logo_trans from '../icons/transaction.png'; import logo_money from '../icons/dollar.png'; import { withRouter } from 'react-router-dom' -import { Table, Button, Card, Image, Row, Col, Nav } from "react-bootstrap"; +import { Table, Button, Card, Image, Row, Col, Nav, NavItem } from "react-bootstrap"; import * as bankActions from "../actions/Bank.actions"; -import { Link} from "react-router-dom"; +import { Link } from "react-router-dom"; export class Bank extends React.Component { constructor(props) { super(props); + } - this.state = { - readOnly: true - }; - - this.switchToEditionMode = this.switchToEditionMode.bind(this); + componentDidUpdate(){ + console.log('PROFILE', this.props.profile); + console.log('BANK', this.props.bank); + console.log('PROPS', this.props); } componentDidMount(){ this.props.fetchUserData(); - this.props.reinitializeState(); - } - - componentDidUpdate(prevProps) { - if (prevProps.state !== this.props.state) { - this.setState({ - readOnly: this.props.state.updateUserSuccess - }); - } - } - - handleChange = event => { - this.setState({ - [event.target.id]: event.target.value, - }); + this.props.fetchUserTransactions(this.props.profile.me.student_number); + console.log('MOUNT PROFILE', this.props.profile); + console.log('MOUNT BANK', this.props.bank); + console.log('MOUNT PROPS', this.props); } - switchToEditionMode() { - this.setState({ - readOnly: false - }); - } - - changeUserData() { - this.props.changeUserData(this.state); - } - - render() { return ( <div> - <Row style={{ width: '95%', margin: '0 auto', marginTop:'30px' }}> - <Col xs lg="4"> - <Card className="block-example border border-dark" style={{ width: '100%', margin: '0 auto', marginTop:'200px', border:'none', textAlign: "center"}}> + <Row style={{ height: '100%', width: '95%', margin: '0 auto', marginTop:'30px' }}> + <Col lg="4" className='block-example border-right border-gray bg-light' style={{ marginTop:'20px', width: '100%', height: '100%', border: 'none', display: 'flex', justifyContent: 'center', alignItems: 'center', textAlign: 'center'}} > + <Card className='bg-light' style={{ width: '100%', height: '100%', border: 'none', display: 'flex', justifyContent: 'center', alignItems: 'center', textAlign: 'center'}}> <Card.Body> - <Card.Title>Compte</Card.Title> - <Card.Text style={{display: 'flex', justifyContent: 'center'}}> - <Image src={logo_money} alt="argent" width={50} height={50} /> + <Card.Title>Solde</Card.Title> + <Card.Img src={logo_money} alt="argent" width={50} height={50} /> + <Card.Text style={{textAlign: 'center', fontSize:'20px'}}> + {this.props.bank.account ? this.props.bank.account.balance : 'NaN'} € </Card.Text> - <div style={{display: 'flex', justifyContent: 'center', fontSize:"20px", fontWeight:"bold"}}> - <div className="p-3 block-example border border-dark rounded-pill">120 €</div> - </div> - <Button variant="primary">Ajouter des fonds </Button> </Card.Body> </Card> </Col> @@ -74,30 +49,29 @@ export class Bank extends React.Component { <Card.Title>Transactions</Card.Title> <Table hover style={{ marginTop:'50px' }}> <tbody> - <tr> - <td><Image src={logo_trans} alt="transaction" width={30} height={30} /></td> - <td colSpan="3">29/09/2021</td> - <td>-8€</td> - </tr> - <tr> - <td><Image src={logo_trans} alt="transaction" width={30} height={30} /></td> - <td colSpan="3">29/09/2021</td> - <td>-8€</td> - </tr> - <tr> - <td><Image src={logo_trans} alt="transaction" width={30} height={30} /></td> - <td colSpan="3">29/09/2021</td> - <td>-8€</td> - </tr> + { this.props.bank.account ? + this.props.bank.account.transactions.map((transaction) => { + return ( + <tr key={'trans'+transaction.id}> + <td><Image src={logo_trans} alt='transaction' width={30} height={30} /></td> + <td style={{fontStyle:'italic'}} colSpan='3'>{transaction.concluded_at}</td> + <td style={{fontStyle:'italic', color:'#242424'}} colSpan='3'>{transaction.comment}</td> + <td>{transaction.amount}€</td> + </tr> + ); + }) + : + null + } </tbody> </Table> </Card.Body> </Card> </Col> - {this.props.state.updateUserError && <div><br/>{JSON.stringify(this.props.state.updateUserErrorMessage.message)}</div>} - {this.props.state.updateUserSuccess && <div><br/>Success! You can now use your new password.</div>} + {this.props.profile.updateUserError && <div><br/>{JSON.stringify(this.props.profile.updateUserErrorMessage.message)}</div>} + {this.props.profile.updateUserSuccess && <div><br/>Success! You can now use your new password.</div>} </Row> - <footer className="footer mt-auto"> + <footer className="footer mt-auto" style={{ position:'absolute', left:0, bottom:0, right:0}}> <div className="container" style={{ textAlign : "center"}}> <Nav.Link as={Link} to="/privacy/"> Politique de confidentialité @@ -112,14 +86,15 @@ export class Bank extends React.Component { // map state from store to props const mapStateToProps = (state) => { return { - state: state.profile + profile: state.profile, + bank: state.bank } } // map actions to props const mapDispatchToProps = (dispatch) => { return { fetchUserData: () => dispatch(bankActions.fetchUserData()), - changeUserData: (data) => dispatch(bankActions.changeUserData(data)), + fetchUserTransactions: (data) => dispatch(bankActions.fetchUserTransactions(data)), reinitializeState: () => dispatch(bankActions.reinitializeState()), } } diff --git a/frontend/src/reducers/Bank.reducer.js b/frontend/src/reducers/Bank.reducer.js index b3f1b31..388d3c1 100644 --- a/frontend/src/reducers/Bank.reducer.js +++ b/frontend/src/reducers/Bank.reducer.js @@ -1,27 +1,22 @@ const INITIAL_STATE = { - me: {}, - updateUserError: false, - updateUserErrorMessage: {}, - updateUserSuccess: false, - loading: false, - profileDataError: false, + account: {balance: 0, transactions: []}, + fetchBankError: false, + fetchBankErrorMessage: {}, + loading: false } -const forgotpasswordReducer = (currentState = INITIAL_STATE, action) => { +const bankReducer = (currentState = INITIAL_STATE, action) => { + console.log('BANK REDUCER', action); switch (action.type) { case 'REINITIALIZE_STATE': - return {...currentState, updateUserError: false, updateUserErrorMessage: {}, loading:false, updateUserSuccess:false}; - case 'PROFILE_DATA_REQ_SUCCESS': - return {...currentState, me:action.data}; - case 'PROFILE_DATA_REQ_FAILURE': - return {...currentState, profileDataError: true}; - case 'UPDATE_USER_FAILURE': - return {...currentState, updateUserError:true, updateUserErrorMessage:action.message, loading: false, updateUserSuccess:false}; - case 'UPDATE_USER_SUCCESS': - return {...currentState, updateUserError:false, updateUserErrorMessage:{}, updateUserSuccess: true, loading: false}; + return {...currentState, fetchBankError: false, fetchBankErrorMessage: {}, loading:false}; + case 'TRANS_DATA_REQ_FAILURE': + return {...currentState, fetchBankError:true, fetchBankErrorMessage:action.message, loading: false}; + case 'TRANS_DATA_REQ_SUCCESS': + return {...currentState, account:action.data, fetchBankError:false, fetchBankErrorMessage:{}, loading: false}; default: return currentState; } } -export default forgotpasswordReducer; +export default bankReducer; diff --git a/frontend/src/reducers/index.js b/frontend/src/reducers/index.js index c9bd461..c8b7085 100644 --- a/frontend/src/reducers/index.js +++ b/frontend/src/reducers/index.js @@ -4,11 +4,13 @@ import appReducer from './App.reducer'; import signupReducer from './SignUp.reducer'; import loginReducer from './Login.reducer'; import profileReducer from './Profile.reducer'; +import bankReducer from './Bank.reducer'; export default combineReducers({ app:appReducer, signup:signupReducer, login:loginReducer, profile:profileReducer, + bank:bankReducer, routing:routerReducer, }) diff --git a/frontend/src/setupProxy.js b/frontend/src/setupProxy.js index 5426351..bf63d33 100644 --- a/frontend/src/setupProxy.js +++ b/frontend/src/setupProxy.js @@ -1,5 +1,5 @@ const proxy = require('http-proxy-middleware'); module.exports = function (app) { - app.use(proxy('/api', { target: 'http://localhost:8090/'})); + app.use(proxy('/api', { target: 'http://localhost:8005/'})); } -- GitLab