Skip to content

Commit

Permalink
feature: Upload Images
Browse files Browse the repository at this point in the history
- Images uploaded to cloudinary on onChange Modal function
- Db retieved from cloudinary ready to be used in the onClick method
- ProgressBar changed to use props
- ImageReducer implemented and added to rootReducer
  • Loading branch information
Benny Ogidan authored and Benny Ogidan committed Nov 16, 2017
1 parent 7239071 commit dba365f
Show file tree
Hide file tree
Showing 12 changed files with 296 additions and 100 deletions.
8 changes: 8 additions & 0 deletions client/src/app/actions/actiontype.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,11 @@ export const FETCH_BOOKS_FULFILLED_BY_USER_ID = 'FETCH_BOOKS_FULFILLED_BY_USER_I

export const FETCH_BOOKS_REJECTED_BY_USER_ID = 'FETCH_BOOKS_REJECTED_BY_USER_ID';

export const UPLOAD_TO_CLOUD_IMAGE_SUCCESS = 'UPLOAD_TO_CLOUD_IMAGE_SUCCESS';

export const UPLOAD_TO_CLOUD_IMAGE_FAILURE = 'UPLOAD_TO_CLOUD_IMAGE_FAILURE';

export const CLOUDINARY_UPLOAD_PRESET = 'yn0wpv0n';

export const CLOUDINARY_UPLOAD_URL = 'https://api.cloudinary.com/v1_1/digpnxufx/upload';

39 changes: 39 additions & 0 deletions client/src/app/actions/uploadImage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import request from 'superagent';
import { showErrorNotification } from './notifications';

import {
UPLOAD_TO_CLOUD_IMAGE_SUCCESS,
UPLOAD_TO_CLOUD_IMAGE_FAILURE,
CLOUDINARY_UPLOAD_PRESET,
CLOUDINARY_UPLOAD_URL
} from './actiontype';



export const UploadImageToCloud = response => ({ type: UPLOAD_TO_CLOUD_IMAGE_SUCCESS, response });
export const UploadImageToCloudFailure = error => ({ type: UPLOAD_TO_CLOUD_IMAGE_FAILURE, error });

export const imageUploadToCloud = (username, imageData) => (dispatch) =>
{


return request.post(CLOUDINARY_UPLOAD_URL)
.field({'upload_preset': CLOUDINARY_UPLOAD_PRESET})
.field('file', imageData)
.field('public_id',`${username}`)
.then((response)=>{
dispatch(UploadImageToCloud(response.body))
return (response.body)
}).catch(error=>{
UploadImageToCloudFailure(error)
});
}


// export const imageUploadToDb = ()=> (dispatch)=>
// {

// }



6 changes: 3 additions & 3 deletions client/src/app/components/Root.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import Header from '../components/container/header/Header.jsx';
import UploadModal from './container/modal/UploadModal.jsx';
import UploadModal from '../components/presentation/common/modal/UploadModal.jsx';
// import BookCoverUpload from './presentation/common/modal/BookCoverUpload.jsx';


Expand All @@ -10,8 +10,8 @@ const Root = props => (

<Header />
{props.children}
<UploadModal />
{/* <BookCoverUpload/> */}
<UploadModal />
{/* <BookCoverU pload/> */}
</div>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import SideNav from '../../../presentation/common/SideNav/index.jsx';
import DisplayAllBorrowedBooks from '../../booklist/DisplayAllBorrowedBooks.jsx';
import DisplayAllBooks from '../../booklist/DisplayAllBooks.jsx';
// import UploadModal from '../../presentation/common/modal/UploadModal.jsx';
// import UploadModal from '../../../presentation/common/modal/UploadModal.jsx';
//import UploadModal from '../components/presentation/common/modal/UploadModal.jsx';
// import BookCoverUpload from './presentation/common/modal/BookCoverUpload.jsx';

/**
* Show User Dashboard
Expand Down
15 changes: 0 additions & 15 deletions client/src/app/components/container/modal/UploadModal.jsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import {Col, Row, ProgressBar} from 'react-materialize';

const ShowProgressBar = () => (
<Row>

<Col l={4} s={4} m={4}>
Loading....
<ProgressBar/>

</Col>
</Row>
);

export default ShowProgressBar;
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ const Book = books => (
> */}

<div
className="card-image"
data-tip={`<h6>Title: ${books.title}</h6> <p>Author: ${books.author}</p> <p>Category:${books.category}</p>`}
data-html
className="card-image"
data-tip={`<h6>Title: ${books.title}</h6> <p>Author: ${books.author}</p> <p>Category:${books.category}</p> <p>Description:${books.description}</p>`}
data-html data-class="booktip"
>
<img
src={books.image || 'http://res.cloudinary.com/digpnxufx/image/upload/c_scale,h_499,w_325/v1507822148' +
Expand Down
196 changes: 143 additions & 53 deletions client/src/app/components/presentation/common/modal/UploadModal.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {imageUploadToCloud, imageUploadToDb} from '../../../../actions/uploadImage';
import ShowProgressBar from '../Preloader/ShowProgressBar.jsx'

/**
* display modal with a file input field and a submit button
Expand All @@ -14,9 +17,27 @@ class UploadModal extends React.Component {
*/
constructor(props) {
super(props);
this.state = {};
this.triggerFileSelect = this.triggerFileSelect.bind(this);
this.onInputChange = this.onInputChange.bind(this);
this.state = {
username: '',
isLoading: false



};
this.triggerFileSelect = this
.triggerFileSelect
.bind(this);
this.onInputChange = this
.onInputChange
.bind(this);
this.onClick = this
.onClick
.bind(this);
}
componentWillReceiveProps(nextProps) {
if (nextProps.username && nextProps.username !== ''){
this.setState({username: nextProps.username})
}
}
/**
* handle change in file input
Expand All @@ -26,8 +47,47 @@ class UploadModal extends React.Component {
* @return {void}
*/
onInputChange(event) {
const filename = event.target.files[0].name;
this.setState({ filename });
event.preventDefault();
this.setState({isLoading: true});
// let reader = new FileReader();
const profilePic = event.target.files[0];

const fileExt = UploadModal.getFileExtension(event.target.files[0].name);
const filename = `${this.props.username}.${fileExt}` || event.target.files[0].name;


this
.props
.imageUploadToCloud(this.props.username, profilePic)
.then((response)=>{
this.setState({isLoading: false})
console.log('this should happen', response)
this.setState({filename});

}

)

}



onClick(event){
event.preventDefault();
this.setState({isLoading: true});
if(this.state.filename)
{
console.log('I am here', this.props.secure_url)
// imageUploadToDb
}

}


static getFileExtension(filename) {
return filename
.split('.')
.pop();
}
/**
* trigger file selection
Expand All @@ -36,7 +96,9 @@ class UploadModal extends React.Component {
* @return {void}
*/
triggerFileSelect() {
this.fileinput.click();
this
.fileinput
.click();
}
/**
* set content of modal
Expand All @@ -45,49 +107,67 @@ class UploadModal extends React.Component {
* @return {void}
*/
render() {
console.log(this.props, '????????' )

return (

<div id="user1" className="modal modal-fixed-footer">
<div id="user1" className="modal ">
<div className="modal-content">{this.state.content}
<h4>Change profile picture</h4> <i
className="fa fa-picture-o"
/>
<img
className="current-profile-photo responsive-img"
src={this.props.image}
alt={this.props.username}
/>
<a
className="btn-floating btn-large waves-effect waves-light teal upload"
onClick={this.triggerFileSelect}
role="button"
tabIndex="0"
><i className="fa fa-folder-open-o" />
</a>
<input
type="file"
ref={(fileinput) => { this.fileinput = fileinput; }}
id="upload-input"
onChange={this.onInputChange}
className="hidden"
/>
</div>
<div className="modal-footer">{this.state.footer}
{
(this.state.filename) ?
(
<div>
<span className="selected-file-intro">Selected File |</span>
<span className="fileName">{this.state.filename}</span>
</div>
) : null
}
<a
href="#!"
className="modal-action modal-close waves-effect waves-green btn-flat"

>Upload<i className="material-icons right">send</i></a>
<div className="modal-header">
<h4>Change profile picture</h4>
</div>
<div className="modal-innercontent">
<i className="fa fa-picture-o"/>
{!this.props.image &&
<span>
{this.state.username}
</span>
}
<a
className="btn-floating btn-large waves-effect waves-light #ef6c00 orange darken-3 upload"
onClick={this.triggerFileSelect}
role="button"
tabIndex="0"><i className="fa fa-folder-open-o"/>

<input
type="file"
ref={(fileinput) => {
this.fileinput = fileinput;
}}
id="upload-input"
onChange={this.onInputChange}
className="hidden"/>
</a>
{/* <Row>
<div className="pre-loader">
<Col l={4} s={4} m={4}>
{this.state.isLoading && <ProgressBar/>
&& <div> Loading....</div>}
</Col>
</div>
</Row> */}
<div className="pre-loader">
{this.state.isLoading && <ShowProgressBar/>}
</div>

</div>
<div className="modal-footer">{this.state.footer} {(this.state.filename)
? (
<div>
<span className="selected-file-intro">Selected File :
</span>
<span className="fileName">{this.state.filename}</span>
</div>
)
: null
}
<a
onClick={
this.onClick
}
href="#!"
className="modal-action modal-close waves-effect waves-green btn-flat">Upload<i className="material-icons right">send</i>
</a>
</div>
</div>
</div>
);
Expand All @@ -97,10 +177,20 @@ class UploadModal extends React.Component {
UploadModal.propTypes = {
updateProfilePicture: PropTypes.func,
image: PropTypes.string,
username: PropTypes.string
username: PropTypes.string.isRequired
};
// UploadModal.defaultProps = {
// image: null,
// username: null
// };
export default UploadModal;
UploadModal.defaultProps = {
image: null
};

const mapStateToProps = state => {
return {
// image: state.userReducer.user.data.userimage,
username: (state.userReducer.user.data)
? state.userReducer.user.data.username
: '',
secure_url: state.imageReducer.url
}
};

export default connect(mapStateToProps, {imageUploadToCloud})(UploadModal);
Loading

0 comments on commit dba365f

Please sign in to comment.