Skip to content

Commit 6bb73ac

Browse files
committed
Complete photo upload step
1 parent 10f9bf5 commit 6bb73ac

File tree

10 files changed

+94
-154
lines changed

10 files changed

+94
-154
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ yarn-debug.log*
2828
yarn-error.log*
2929

3030
*.csv
31-
.env.dev.js
31+
.env.dev.js
32+
.eslintcache

client/.eslintcache

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

client/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@
2121
npm-debug.log*
2222
yarn-debug.log*
2323
yarn-error.log*
24+
.eslintcache

client/src/components/CreateProfile/CreateProfile4.js

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import React, { useState, useContext } from 'react';
2+
import { useAuth0 } from '@auth0/auth0-react';
3+
import UserContext from '../../context/user/userContext';
4+
import { Button, Card } from '@material-ui/core';
5+
import PropTypes from 'prop-types';
6+
7+
const PhotoUpload = ({ userInfo, setUserInfo }) => {
8+
const serverUrl = process.env.REACT_APP_SERVER_URL;
9+
const userContext = useContext(UserContext);
10+
const { userId } = userContext;
11+
const { getAccessTokenSilently } = useAuth0();
12+
const [image, setImage] = useState(null);
13+
const [imageUrl, setImageUrl] = useState(null);
14+
15+
const handleImageSelect = async (e) => {
16+
const files = e.target.files;
17+
const formData = new FormData();
18+
formData.append('image', files[0]);
19+
setImage(formData);
20+
};
21+
22+
const handleImageSubmit = async () => {
23+
try {
24+
const token = await getAccessTokenSilently();
25+
const options = {
26+
method: 'POST',
27+
body: image,
28+
headers: {
29+
Authorization: `Bearer ${token}`,
30+
},
31+
};
32+
33+
const response = await fetch(
34+
`${serverUrl}/api/users/photos/${userId}`,
35+
options
36+
);
37+
const url = await response.json();
38+
setImage(null);
39+
await setImageUrl(url.msg);
40+
await setUserInfo({
41+
...userInfo,
42+
photos: [...userInfo.photos, url.msg],
43+
});
44+
} catch (err) {
45+
return console.error('@handleImageUpload', err.message);
46+
}
47+
};
48+
49+
return (
50+
<div>
51+
<h1>photo upload</h1>
52+
<input
53+
type='file'
54+
id='file-upload'
55+
onChange={handleImageSelect}
56+
accept='image/x-png,image/jpeg'
57+
/>
58+
<Button onClick={handleImageSubmit} disabled={imageUrl}>
59+
Add Photo
60+
</Button>
61+
{userInfo.photos.length ? (
62+
<Card style={{ maxHeight: '6rem', maxWidth: '4rem' }}>
63+
<img src={imageUrl} alt='profile' />
64+
</Card>
65+
) : null}
66+
</div>
67+
);
68+
};
69+
PhotoUpload.propTypes = {
70+
userInfo: PropTypes.object.isRequired,
71+
setUserInfo: PropTypes.func.isRequired,
72+
};
73+
export default PhotoUpload;
Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
import CreateProfile1 from './CreateProfile1';
22
import CreateProfile2 from './CreateProfile2';
33
import CreateProfile3 from './CreateProfile3';
4-
import CreateProfile4 from './CreateProfile4';
4+
import PhotoUpload from './PhotoUpload';
55
import Stepper from './Stepper';
66

7-
export {
8-
CreateProfile1,
9-
CreateProfile2,
10-
CreateProfile3,
11-
CreateProfile4,
12-
Stepper,
13-
};
7+
export { CreateProfile1, CreateProfile2, CreateProfile3, PhotoUpload, Stepper };
Lines changed: 7 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,11 @@
1-
import React, { useContext } from 'react';
2-
import UserContext from '../../context/user/userContext';
3-
import { useAuth0 } from '@auth0/auth0-react';
4-
import axios from 'axios';
5-
const serverUrl = process.env.REACT_APP_SERVER_URL;
6-
const HomeContent = () => {
7-
const userContext = useContext(UserContext);
8-
const { userId } = userContext;
9-
const { getAccessTokenSilently } = useAuth0();
10-
11-
const handleImageUpload = async (e) => {
12-
try {
13-
const files = e.target.files;
14-
const formData = new FormData();
15-
formData.append('image', files[0]);
16-
17-
const token = await getAccessTokenSilently();
18-
const options = {
19-
method: 'POST',
20-
body: formData,
21-
headers: {
22-
Authorization: `Bearer ${token}`,
23-
},
24-
};
25-
26-
const response = await fetch(
27-
`${serverUrl}/api/users/photos/${userId}`,
28-
options
29-
);
30-
const url = await response.json();
31-
console.log(url.msg);
32-
return url.msg;
33-
} catch (err) {
34-
return console.error('@handleImageUpload', err.message);
35-
}
36-
};
37-
38-
return (
39-
<div>
40-
<h2>What can I do next?</h2>
41-
<input
42-
type='file'
43-
id='file-upload'
44-
onChange={handleImageUpload}
45-
accept='image/x-png,image/jpeg'
46-
/>
47-
48-
<div>
49-
<div>
50-
<h6 className=''>
51-
<a
52-
target='_blank'
53-
rel='noopener noreferrer'
54-
href='https://auth0.com/docs/connections'>
55-
<i className='fas fa-link mr-2' />
56-
Configure other identity providers
57-
</a>
58-
</h6>
59-
<p>
60-
Auth0 supports social providers as Facebook, Twitter, Instagram and
61-
100+, Enterprise providers as Microsoft Office 365, Google Apps,
62-
Azure, and more. You can also use any OAuth2 Authorization Server.
63-
</p>
64-
</div>
1+
import React from 'react'; // { useContext }
2+
// import UserContext from '../../context/user/userContext';
3+
// import { useAuth0 } from '@auth0/auth0-react';
4+
// import { PhotoUpload } from '../CreateProfile';
5+
// const serverUrl = process.env.REACT_APP_SERVER_URL;
656

66-
<div />
67-
68-
<div>
69-
<h6>
70-
<a
71-
target='_blank'
72-
rel='noopener noreferrer'
73-
href='https://auth0.com/docs/multifactor-authentication'>
74-
<i className='fas fa-link mr-2' />
75-
Enable Multi-Factor Authentication
76-
</a>
77-
</h6>
78-
<p>
79-
Add an extra layer of security by enabling Multi-factor
80-
Authentication, requiring your users to provide more than one piece
81-
of identifying information. Push notifications, authenticator apps,
82-
SMS, and DUO Security are supported.
83-
</p>
84-
</div>
85-
</div>
86-
87-
<div>
88-
<div>
89-
<h6>
90-
<a
91-
target='_blank'
92-
rel='noopener noreferrer'
93-
href='https://auth0.com/docs/anomaly-detection'>
94-
<i className='fas fa-link mr-2' />
95-
Anomaly Detection
96-
</a>
97-
</h6>
98-
<p>
99-
Auth0 can detect anomalies and stop malicious attempts to access
100-
your application. Anomaly detection can alert you and your users of
101-
suspicious activity, as well as block further login attempts.
102-
</p>
103-
</div>
104-
105-
<div />
106-
107-
<div>
108-
<h6>
109-
<a
110-
target='_blank'
111-
rel='noopener noreferrer'
112-
href='https://auth0.com/docs/rules'>
113-
<i className='fas fa-link mr-2' />
114-
Learn About Rules
115-
</a>
116-
</h6>
117-
<p>
118-
Rules are JavaScript functions that execute when a user
119-
authenticates to your application. They run once the authentication
120-
process is complete, and you can use them to customize and extend
121-
Auth0's capabilities.
122-
</p>
123-
</div>
124-
</div>
125-
</div>
126-
);
7+
const HomeContent = () => {
8+
return <div>Welcome Home</div>;
1279
};
12810

12911
export default HomeContent;

client/src/views/CreateProfile.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
CreateProfile1,
99
CreateProfile2,
1010
CreateProfile3,
11-
CreateProfile4,
11+
PhotoUpload,
1212
Stepper,
1313
} from '../components/CreateProfile';
1414

@@ -100,16 +100,18 @@ const CreateProfile = () => {
100100
/>
101101
)}
102102
{step === 3 && (
103+
<PhotoUpload userInfo={userInfo} setUserInfo={setUserInfo} />
104+
)}
105+
{step === 4 && (
103106
<CreateProfile3
104107
handleInterests={handleInterests}
105108
interests={interests}
106109
/>
107110
)}
108-
{step === 4 && <CreateProfile4 />}
109111
<Stepper
110112
step={step}
111113
setStep={setStep}
112-
maxStep={3}
114+
maxStep={4}
113115
handleSubmit={handleSubmit}
114116
/>
115117
</div>

client/src/views/Landing.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const Landing = (props) => {
77
<Box display='flex' alignItems='center'>
88
<Box m='auto'>
99
<h1 style={{ marginLeft: '5rem' }}>Pupper</h1>
10-
<h2>Meet Your New Best Friend</h2>
1110
<Box as='span'>
1211
<AuthenticationButton />
1312
<SignupButton>Sign Up</SignupButton>

notes/02_photo_uploads.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,8 @@ able to upload images using postman. When trying to upload from client side I
3939
was continually getting 422 errors that the server was not able to handle this
4040
resource.
4141

42-
1. Checked headers client side and set them to 'content-type':
43-
'application/octet-stream' and that took out the errors but was not
44-
uploading.
42+
Checked headers client side and set them to 'content-type':
43+
'application/octet-stream' and that took out the errors but was not uploading.
4544

4645
I was not able to access anything in the server side req body even though I was
4746
able to log out the FormData object client side so I knew the files were in
@@ -54,7 +53,7 @@ anything until it went into the multer object.
5453
I tried about a million different headers to no avail
5554

5655
Logged out the 600 line req bodies for both the postman POST and the client side
57-
POST to see if there were any differences.
56+
POST and compared them side by side to see if there were any differences.
5857

5958
I had all but given up hope when I looked at the Postman POST request and
6059
noticed that in the body i had set the key to 'image' and the value to the file.

0 commit comments

Comments
 (0)