diff --git a/models/Users-model.js b/models/Users-model.js index 20e85a8..481ef4e 100644 --- a/models/Users-model.js +++ b/models/Users-model.js @@ -45,7 +45,8 @@ const userSchema = new Schema({ admin: { type: Boolean, default: false - } + }, + image: String }, { timestamps: true diff --git a/olympi-client/src/App.js b/olympi-client/src/App.js index 7f40a52..5469e0b 100644 --- a/olympi-client/src/App.js +++ b/olympi-client/src/App.js @@ -76,9 +76,9 @@ class App extends Component { )} /> {/* go back an check this Karina */} - - {this.state.user?.professional ? : } - + ( + this.state.user?.professional ? : + )} /> {/* go back an check this Karina */} ( diff --git a/olympi-client/src/components/Profile/BottomNavBar/BottomNavBar.css b/olympi-client/src/components/Profile/BottomNavBar/BottomNavBar.css index a962b0e..27019f2 100644 --- a/olympi-client/src/components/Profile/BottomNavBar/BottomNavBar.css +++ b/olympi-client/src/components/Profile/BottomNavBar/BottomNavBar.css @@ -2,6 +2,7 @@ z-index: 1; display: flex; height: 70px; + margin-top: 200px; background-color: #fafafa; bottom: 0px; position: fixed; diff --git a/olympi-client/src/components/Profile/PersonalBio/PersonalBio.js b/olympi-client/src/components/Profile/PersonalBio/PersonalBio.js index 0770cac..9fc71a3 100644 --- a/olympi-client/src/components/Profile/PersonalBio/PersonalBio.js +++ b/olympi-client/src/components/Profile/PersonalBio/PersonalBio.js @@ -1,114 +1,191 @@ -import React, {useEffect, useState} from 'react' +import React, {useEffect, useState, Redirect} from 'react' import "./PersonalBio.css" -import SportsIcon from '@material-ui/icons/Sports'; import Modal from "react-modal" import axios from "axios" -const baseUrl = process.env.REACT_APP_APIURL -const customStyles = { - content: { - top: '50%', - left: '50%', - right: 'auto', - bottom: 'auto', - marginRight: '-50%', - transform: 'translate(-50%, -50%)', - width: "350px", - zIndex: 1 - }, -}; -function PersonalBio({user}) { - const [profile, setProfile] = useState({ - username:"", - email:"", - city:"", - fav_exercise:"", - about:"" - }) - Modal.setAppElement(document.getElementById("root")) - let subtitle; - const [modalIsOpen, setIsOpen] = useState(false); - - function openModal() { - setIsOpen(true); - } +import authService from '../../auth/auth-service' +import VideoUpload from '../UpdateProfile/UpdateProfile' - function afterOpenModal() { - // references are now sync'd and can be accessed. - subtitle.style.color = '#f00'; - } - function closeModal() { - setIsOpen(false); - } - async function fetchUser(user) - { - await axios.get(`${baseUrl}/auth/user?id=${user}`) - .then((response) => { - if(response.status == 201) - { - - const data = response.data - setProfile({ - username: data.username, - email: data.email, - city: data.city, - fav_exercise: data.fav_exercise, - about: data.about - }) - } - }) - .catch((e) => console.log("Not Found", e)) - } - const handleChange = (event) => { - const {name, value} = event.target; - setProfile({...profile, [name]: value}); + +export default class PersonalBio extends React.Component { + + logout = (event) => { + authService.logout() + .then(response => { + this.props.updateUser(false); + }) + ; } - const onUpdate = async() => { - const result = await axios.put(`${baseUrl}/auth/updateUser?id=${user._id}`, profile) - if(result.status == 201) - { - setProfile(result.data) - setIsOpen(false) - } + + handleUpload = (event) => { + let formData = new FormData(); + formData.append('photo', event.target.files[0]); + + authService.upload(formData) + .then(response => { + this.props.updateUser(response); + }) + ; + } + + + toggle = () => { + this.setState({uploadOpen: !this.state.uploadOpen}) + } + + render() { + if (this.props.user === false) return + + return ( +<> + + + +
+
User Profile
+
Edit
+ +
{this.props.user.username}
+
{this.props.user.city}
+
{this.props.user.about}
+
+ +
+ + + + + + +
+ + + ) } - useEffect(() =>{ - fetchUser(user._id) - }, []) - return ( -
- -
User Profile
- -
Edit
- - - -

(subtitle = _subtitle)}>Edit profile

- {/* */} -
Edit your profile info
-
-

-

-

-

-

- -
-
- -
{profile.username}
-
{profile.city}
-
{profile.about}
- - - -
- ) } -export default PersonalBio + + + + + + + + + + + + + + +// //const baseUrl = process.env.REACT_APP_APIURL +// //const customStyles = { +// content: { +// top: '50%', +// left: '50%', +// right: 'auto', +// bottom: 'auto', +// marginRight: '-50%', +// transform: 'translate(-50%, -50%)', +// width: "350px", +// zIndex: 1 +// }, +// }; +// function PersonalBio({user}) { +// const [profile, setProfile] = useState({ +// username:"", +// email:"", +// city:"", +// fav_exercise:"", +// about:"" +// }) +// Modal.setAppElement(document.getElementById("root")) +// let subtitle; +// const [modalIsOpen, setIsOpen] = useState(false); + +// function openModal() { +// setIsOpen(true); +// } + +// function afterOpenModal() { +// // references are now sync'd and can be accessed. +// subtitle.style.color = '#f00'; +// } + +// function closeModal() { +// setIsOpen(false); +// } +// async function fetchUser(user) +// { +// await axios.get(`${baseUrl}/auth/user?id=${user}`) +// .then((response) => { +// if(response.status == 201) +// { + +// const data = response.data +// setProfile({ +// username: data.username, +// email: data.email, +// city: data.city, +// fav_exercise: data.fav_exercise, +// about: data.about +// }) +// } +// }) +// .catch((e) => console.log("Not Found", e)) +// } +// const handleChange = (event) => { +// const {name, value} = event.target; +// setProfile({...profile, [name]: value}); +// } +// const onUpdate = async() => { +// const result = await axios.put(`${baseUrl}/auth/updateUser?id=${user._id}`, profile) +// if(result.status == 201) +// { +// setProfile(result.data) +// setIsOpen(false) +// } +// } +// useEffect(() =>{ +// fetchUser(user._id) +// }, []) +// return ( +//
+ +//
User Profile
+ +//
Edit
+ + +// +//

(subtitle = _subtitle)}>Edit profile

+// {/* */} +//
Edit your profile info
+//
+//

+//

+//

+//

+//

+// +//
+//
+// +//
{profile.username}
+//
{profile.city}
+//
{profile.about}
+ + + +//
+// ) +// } + +// export default PersonalBio diff --git a/olympi-client/src/components/Profile/UpdateProfile/UpdateProfile.css b/olympi-client/src/components/Profile/UpdateProfile/UpdateProfile.css new file mode 100644 index 0000000..e69de29 diff --git a/olympi-client/src/components/Profile/UpdateProfile/UpdateProfile.js b/olympi-client/src/components/Profile/UpdateProfile/UpdateProfile.js new file mode 100644 index 0000000..013f2c0 --- /dev/null +++ b/olympi-client/src/components/Profile/UpdateProfile/UpdateProfile.js @@ -0,0 +1,218 @@ +import React from 'react'; + +import feedService from '../../feed/feed-service'; +import upload_icon from '../../../assets/icons/upload-button.svg'; +import close_button from '../../../assets/icons/close-button.svg'; + +const EXERCISES = [ + 'Overhead press', + 'Deadlift', + 'Squat', + 'Bench press' +] + +const UPLOAD_VIDEO_MAX_SIZE = 20; // Mib +class VideoUpload extends React.Component { + + constructor(props) { + super(props); + this.uploadInputRef = React.createRef(); + } + + // WARNING: REMOVE THIS STATE AND REPLACE WITH COMMENTED ONE BEFORE PRODUCTION + // it is use to make testing faster by pre-populate the form with fake data + state = { + open: false, + error: "", + exercise: EXERCISES[0], //default value + weight: "100", + weight_metric: "kg", //default value + rounds: "5", + reps: "10", + category: "trending", //default value + description: "Yolo description", + file: null, + isUploading: false + } + + // state = { + // open: false, + // error: "", + // exercise: EXERCISES[0], //default value + // weight: "", + // weight_metric: "kg", //default value + // rounds: "", + // reps: "", + // category: "trending", //default value + // description: "", + // file: null, + // } + + + + handleSubmit = (event) => { + event.preventDefault(); + + if( this.state.isUploading === true){ + return; + } + + this.setState({isUploading: true}); + + // we need a formData to send the file (your backend needs this format) + // so we created an empty one and file it up with the value of the state + //send we send that to the feedService with axios + + const data = new FormData() + for (let key in this.state) { + data.append(key,this.state[key]) + } + + feedService.uploadVideo(data) + .then((newVideo) => { + this.setState({error: "", file: null, description: "", reps: "", rounds: "", weight: ""}); + + // call the addVideo from parent to add the video to the feed + this.props.addVideo(newVideo); + + // close the upload form (method from parent) + this.props.toggle(); + }) + ; + } + + triggerUploadFileInput = (event) => { + event.preventDefault(); + this.uploadInputRef.current.click(); + } + + videoSizeValidation = (video) => { + const fileSize = video.size / 1024 / 1024; // in MiB + // return true if the the size is under our set limit, else false + return fileSize <= UPLOAD_VIDEO_MAX_SIZE + } + + handleChange = (event) => { + let {name, value} = event.target; + if(name === "file"){ + value = event.target.files[0] + + if(!this.videoSizeValidation(value)){ + // empty file input and display error? + console.log("file is too big!") + } + console.log(value) + } + this.setState({[name]: value}); + } + + render() { + return ( +
+ Close upload form +

Upload

+ +
+ + {/* for an error */} + {this.state.error && ( +

{this.state.error}

+ )} + +
+ +

+ + + +

+ + + +

+ +

+ + +
+
+

+ +

+

+ +

+
+

+ +

+ +

+ +

+
+ +
+ +
+ +

Category

+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ +
+ +

+ +

+
+ +

+

+

+ +
+ +
+ ) + } +} + +export default VideoUpload; \ No newline at end of file diff --git a/olympi-client/src/components/Profile/proProfile.js b/olympi-client/src/components/Profile/proProfile.js index bf890b3..228e828 100644 --- a/olympi-client/src/components/Profile/proProfile.js +++ b/olympi-client/src/components/Profile/proProfile.js @@ -6,16 +6,15 @@ import PersonalRecord from './PersonalRecord/PersonalRecord' import "./proProfile.css" import SettingsBar from './SettingsBar/SettingsBar' -export default function ProProfile(){ +export default function ProProfile( {user}){ return (
- - - + + + -
) } diff --git a/olympi-client/src/components/auth/auth-service.js b/olympi-client/src/components/auth/auth-service.js index e8e6aed..1f60429 100644 --- a/olympi-client/src/components/auth/auth-service.js +++ b/olympi-client/src/components/auth/auth-service.js @@ -52,5 +52,11 @@ export default { about }) .then(response => response.data) - } + }, + +upload(formdata) { + return this.service.post('/upload', formdata) + .then(response => response.data) +} + }; \ No newline at end of file