Skip to content

Commit

Permalink
✨ add image upload by cloudinary and 404 page
Browse files Browse the repository at this point in the history
  • Loading branch information
heytulsiprasad committed Sep 22, 2020
1 parent 5a7f97e commit ca5354d
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 44 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"import/no-named-as-default": 0,
"react/jsx-props-no-spreading": "off",
"no-confusing-arrow": "off",
"no-shadow": "off"
"no-shadow": "off",
"comma-dangle": "off"
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

# misc
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
Expand Down
5 changes: 4 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import axios from "axios";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import { connect } from "react-redux";

import "./App.css";
Expand All @@ -10,6 +10,7 @@ import PrivateRoute from "./containers/PrivateRoute";
import PublicRoute from "./containers/PublicRoute";
import Dashboard from "./containers/Dashboard";
import EditProfile from "./containers/EditProfile";
import FourOhFour from "./containers/FourOhFour";
// import store from "./redux/store";

import { setAuthState } from "./redux/actions/authActions";
Expand All @@ -28,6 +29,7 @@ const App = ({ isAuth, setAuthState }) => {
setIsLoading(true);
throw new Error(err);
});
// eslint-disable-next-line
}, []);

return (
Expand Down Expand Up @@ -62,6 +64,7 @@ const App = ({ isAuth, setAuthState }) => {
path="/login"
component={LoginContainer}
/>
<Route path="*" component={FourOhFour} />
</Switch>
</Router>
</>
Expand Down
46 changes: 42 additions & 4 deletions src/components/Profile/EditInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { connect } from "react-redux";
import { withRouter } from "react-router-dom";

import Button from "./Button";
import { InputFieldImage, InputField } from "./FormElements";
import InputField from "./InputField";
import InputFieldImage from "./InputFieldImage";
import Loading from "../Loading";
import { editUserProfile } from "../../redux/actions/authActions";
import imageUpload from "../../utils/imageUpload";

const Container = styled.div`
grid-row: 3 / 4;
Expand Down Expand Up @@ -57,7 +59,9 @@ class EditInfo extends React.Component {

componentDidUpdate(prevProps) {
if (prevProps.isLoading !== this.props.isLoading) {
const { name, email, phone, bio, image } = prevProps.user;
const {
name, email, phone, bio, image
} = prevProps.user;

this.setState((state) => ({
...state,
Expand Down Expand Up @@ -85,6 +89,31 @@ class EditInfo extends React.Component {
}));
};

imageChangeHandler = async (e) => {
const imageFile = e.target.files[0];

if (!imageFile) {
this.setState({ imageError: "Please select image. " });
return false;
}

if (!imageFile.name.match(/\.(jpg|jpeg|png|gif)$/)) {
this.setState({ imageError: "Please select a valid image." });
return false;
}

// Utils function
imageUpload(imageFile, (url) => {
this.setState((state) => ({
...state,
profile: {
...state.profile,
image: url,
},
}));
});
};

submitHandler = (e) => {
e.preventDefault();

Expand All @@ -94,7 +123,9 @@ class EditInfo extends React.Component {
};

render() {
const { name, email, phone, bio, image } = this.state.profile;
const {
name, email, phone, bio, image
} = this.state.profile;
const error = this.props.errors;

return (
Expand All @@ -108,7 +139,14 @@ class EditInfo extends React.Component {
) : (
<>
<FormContainer onSubmit={this.submitHandler}>
<InputFieldImage title="Change Photo" image={image} />
<InputFieldImage
title="Change Photo"
value={image}
id="upload-photo"
type="file"
accept="image/png, image/jpeg"
onChange={this.imageChangeHandler}
/>
<InputField
title="Name"
name="name"
Expand Down
40 changes: 40 additions & 0 deletions src/components/Profile/InputField.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from "react";
import styled from "styled-components";

const FieldContainer = styled.div`
padding-top: 1rem;
`;

const FieldTitle = styled.h2`
font-size: 13px;
line-height: 18px;
color: #4f4f4f;
margin-bottom: 5px;
`;

const FieldInput = styled.input`
border: 1px solid ${(props) => (props.error ? "red" : "#828282")};
min-width: 60%;
/* border: 1px solid #828282; */
border-radius: 12px;
padding: 15px 20px;
outline: none;
`;

const Error = styled.p`
font-size: 11px;
margin: 2px 10px;
color: red;
`;

const InputField = ({ title, children, error, ...rest }) => (
<FieldContainer>
<label>
<FieldTitle>{title}</FieldTitle>
<FieldInput error={error} {...rest} />
{error && <Error>{error}</Error>}
</label>
</FieldContainer>
);

export default InputField;
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,6 @@ const FieldContainer = styled.div`
padding-top: 1rem;
`;

const FieldTitle = styled.h2`
font-size: 13px;
line-height: 18px;
color: #4f4f4f;
margin-bottom: 5px;
`;

const FieldInput = styled.input`
border: 1px solid ${(props) => (props.error ? "red" : "#828282")};
min-width: 60%;
/* border: 1px solid #828282; */
border-radius: 12px;
padding: 15px 20px;
outline: none;
`;

const FieldLabel = styled.label``;

const ImageFieldContainer = styled.div`
display: flex;
max-width: 13rem;
Expand Down Expand Up @@ -72,29 +54,17 @@ const ImageFieldContainer = styled.div`
}
`;

const Error = styled.p`
font-size: 11px;
margin: 2px 10px;
color: red;
`;

export const InputField = ({ title, children, error, ...rest }) => (
<FieldContainer>
<FieldLabel>
<FieldTitle>{title}</FieldTitle>
<FieldInput error={error} {...rest} />
{error && <Error>{error}</Error>}
</FieldLabel>
</FieldContainer>
);
const InputFieldImage = ({ title, id, value, ...rest }) => (
// Make an action
// Store image on Redux

export const InputFieldImage = ({ title, image }) => (
<FieldContainer>
<ImageFieldContainer>
<img className="upload-image" src={image} alt="Person Profile" />
<img className="upload-image" src={value} alt="Person Profile" />
<span className="material-icons input-icon">camera_alt</span>
<input id="upload-photo" type="file" accept="image/png, image/jpeg" />
<label htmlFor="upload-photo">{title}</label>
<input id={id} {...rest} />
<label htmlFor={id}>{title}</label>
</ImageFieldContainer>
</FieldContainer>
);
export default InputFieldImage;
39 changes: 39 additions & 0 deletions src/containers/FourOhFour.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from "react";
import styled from "styled-components";

const Container = styled.div`
height: 100vh;
width: 100vw;
position: relative;
h1 {
font-weight: 400;
font-size: 36px;
line-height: 49px;
}
h2 {
font-weight: 300;
font-size: 18px;
line-height: 25px;
}
`;

const Child = styled.div`
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, 100%);
text-align: center;
`;

const FourOhFour = () => (
<Container>
<Child>
<h1>Four Oh Four</h1>
<h2>Seems like, you are lost just like me</h2>
</Child>
</Container>
);

export default FourOhFour;
2 changes: 2 additions & 0 deletions src/redux/actions/authActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ export const editUserProfile = (userdata, history) => (dispatch) => {
// Clear previous errors
dispatch(clearErrors());

console.log(userdata);

axios
.post("/profile/edit", userdata, { withCredentials: true })
.then(() => history.push("/"))
Expand Down
2 changes: 1 addition & 1 deletion src/redux/reducers/authReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
CLEAR_CURRENT_USER,
SET_AUTH_STATE,
} from "../actions/types";
import isEmpty from "./isEmpty";
import isEmpty from "../../utils/isEmpty";

const initialState = {
user: {},
Expand Down
22 changes: 22 additions & 0 deletions src/utils/imageUpload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import axios from "axios";

const imageUpload = (imageFile, callback) => {
const formData = new FormData();

formData.append("file", imageFile);
formData.append(
"upload_preset",
process.env.REACT_APP_CLOUDINARY_UPLOAD_PRESET
);

axios
.post(
`https://api.cloudinary.com/v1_1/${process.env.REACT_APP_CLOUDINARY_CLOUD_NAME}/image/upload`,
formData
)
.then((res) => res.data.secure_url)
.then((url) => callback(url))
.catch((err) => new Error(err));
};

export default imageUpload;
File renamed without changes.

0 comments on commit ca5354d

Please sign in to comment.