From c8aa1fd050753fed297c6a0a61dc3993bf1236b8 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 19 Nov 2019 13:57:24 -0500 Subject: [PATCH 1/3] Added page to display other users' profile --- twistter-frontend/src/App.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/twistter-frontend/src/App.js b/twistter-frontend/src/App.js index aeec8ee..9e29d2e 100644 --- a/twistter-frontend/src/App.js +++ b/twistter-frontend/src/App.js @@ -19,8 +19,6 @@ import { logoutUser, getUserData } from "./redux/actions/userActions"; // Components import AuthRoute from "./util/AuthRoute"; -// axios.defaults.baseURL = 'http://localhost:5006/twistter-e4649/us-central1/api'; - // Pages import home from "./pages/Home"; import signup from "./pages/Signup"; @@ -33,6 +31,7 @@ import editProfile from "./pages/editProfile"; import userLine from "./Userline.js"; import verify from "./pages/verify"; import Search from "./pages/Search.js"; +import otherUser from "./pages/otherUser"; const theme = createMuiTheme(themeObject); @@ -65,11 +64,10 @@ class App extends Component {
- {/* AuthRoute checks if the user is logged in and if they are it redirects them to /home */} - + @@ -77,11 +75,11 @@ class App extends Component { - + + -
From 42c53fdbc4ad9b0817c49ab8221e7044d63c7ff1 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 19 Nov 2019 15:56:39 -0500 Subject: [PATCH 2/3] Add profile image, topics for other user page --- functions/handlers/topic.js | 13 +++ functions/index.js | 12 +- twistter-frontend/src/pages/otherUser.js | 138 +++++++++++++++++++++++ 3 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 twistter-frontend/src/pages/otherUser.js diff --git a/functions/handlers/topic.js b/functions/handlers/topic.js index a55f748..bb5b9f1 100644 --- a/functions/handlers/topic.js +++ b/functions/handlers/topic.js @@ -58,3 +58,16 @@ exports.deleteTopic = (req, res) => { return res.status(500).json({ error: "Failed to delete topic." }); }); }; + +exports.getUserTopics = (req, res) => { + let data = []; + db.doc(`/users/${req.body.handle}`) + .get() + .then(doc => { + data = doc.data().followedTopics; + return res.status(200).json({ data }); + }) + .catch(err => { + return res.status(500).json({ err }); + }); +}; diff --git a/functions/index.js b/functions/index.js index 86231d0..bf18777 100644 --- a/functions/index.js +++ b/functions/index.js @@ -37,7 +37,7 @@ app.post("/login", login); //Deletes user account app.delete("/delete", fbAuth, deleteUser); -app.get("/getUser", fbAuth, getUserDetails); +app.post("/getUserDetails", fbAuth, getUserDetails); // Returns all profile data of the currently logged in user app.get("/getProfileInfo", fbAuth, getProfileInfo); @@ -82,7 +82,12 @@ app.post("/putPost", fbAuth, putPost); /*------------------------------------------------------------------* * handlers/topic.js * *------------------------------------------------------------------*/ -const { putTopic, getAllTopics, deleteTopic } = require("./handlers/topic"); +const { + putTopic, + getAllTopics, + deleteTopic, + getUserTopics +} = require("./handlers/topic"); // add topic to database app.post("/putTopic", fbAuth, putTopic); @@ -93,4 +98,7 @@ app.get("/getAllTopics", fbAuth, getAllTopics); // delete a specific topic app.delete("/deleteTopic/:topicId", fbAuth, deleteTopic); +// get topic for this user +app.post("/getUserTopics", fbAuth, getUserTopics); + exports.api = functions.https.onRequest(app); diff --git a/twistter-frontend/src/pages/otherUser.js b/twistter-frontend/src/pages/otherUser.js new file mode 100644 index 0000000..5a1aa21 --- /dev/null +++ b/twistter-frontend/src/pages/otherUser.js @@ -0,0 +1,138 @@ +/* eslint-disable */ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { connect } from "react-redux"; +import axios from "axios"; +//import '../App.css'; + +// Material UI and React Router +import { makeStyles, styled } from "@material-ui/core/styles"; +import { Link } from "react-router-dom"; +import Card from "@material-ui/core/Card"; +import CardMedia from "@material-ui/core/CardMedia"; +import CardContent from "@material-ui/core/CardContent"; +import Button from "@material-ui/core/Button"; +import Grid from "@material-ui/core/Grid"; + +import Chip from "@material-ui/core/Chip"; +import Typography from "@material-ui/core/Typography"; +import AddCircle from "@material-ui/icons/AddCircle"; +import TextField from "@material-ui/core/TextField"; +import VerifiedIcon from "@material-ui/icons/CheckSharp"; + +// component +import "../App.css"; +import noImage from "../images/no-img.png"; +import Writing_Microblogs from "../Writing_Microblogs"; +const MyChip = styled(Chip)({ + margin: 2, + color: "primary" +}); + +class user extends Component { + state = { + profile: window.location.pathname.split("/").pop(), + imageUrl: null, + topics: null, + following: null // boolean value + }; + + componentDidMount() { + console.log(this.state.profile); + axios + .post("/getUserDetails", { + handle: this.state.profile + }) + .then(res => { + console.log(res.data.userData); + this.setState({ + imageUrl: res.data.userData.imageUrl, + topics: res.data.userData.followedTopics + }); + }) + .catch(err => console.log(err)); + + axios + .get("/getallPostsforUser") + .then(res => { + console.log(res.data); + this.setState({ + posts: res.data + }); + }) + .catch(err => console.log(err)); + } + + render() { + let authenticated = this.props.user.authenticated; + let classes = this.props; + + let profileMarkup = this.state.profile ? ( +
+ + @{this.state.profile}{" "} + {this.state.verified ? ( + + ) : null} + +
+ ) : ( +

loading username...

+ ); + let topicsMarkup = this.state.topics ? ( + this.state.topics.map( + topic => // console.log({ topic }.topic.id) + ) + ) : ( +

 loading topics...

+ ); + + let imageMarkup = this.state.imageUrl ? ( + + ) : ( + + ); + + let postMarkup = this.state.posts ? ( + this.state.posts.map(post => ( + + + + {this.state.imageUrl ? ( + + ) : ( + + )} + + + + )) + ) : ( +

My Posts

+ ); + + return ( + + + {imageMarkup} + {profileMarkup} + {topicsMarkup} +
+
+ + {postMarkup} + +
+ ); + } +} + +const mapStateToProps = state => ({ + user: state.user +}); + +user.propTypes = { + user: PropTypes.object.isRequired +}; + +export default connect(mapStateToProps)(user); From 2de3da928abf8b414f4ffb216f41622e2328cbe8 Mon Sep 17 00:00:00 2001 From: Leon Liang Date: Tue, 19 Nov 2019 19:03:28 -0500 Subject: [PATCH 3/3] added UI for follow and unfollow other user --- functions/handlers/users.js | 2 + functions/index.js | 2 +- twistter-frontend/src/pages/otherUser.js | 74 +++++++++++++++--------- 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/functions/handlers/users.js b/functions/handlers/users.js index 2fdcd51..84463c2 100644 --- a/functions/handlers/users.js +++ b/functions/handlers/users.js @@ -450,6 +450,7 @@ exports.addSubscription = (req, res) => { .catch(err => { return res.status(500).json({ err }); }); + return res.status(500).json({ error: "shouldn't execute" }); }); }; @@ -489,5 +490,6 @@ exports.removeSub = (req, res) => { .catch(err => { return res.status(500).json({ err }); }); + return res.status(500).json({ error: "shouldn't execute" }); }); }; diff --git a/functions/index.js b/functions/index.js index bf18777..eb87142 100644 --- a/functions/index.js +++ b/functions/index.js @@ -65,7 +65,7 @@ app.get("/getSubs", fbAuth, getSubs); app.post("/addSubscription", fbAuth, addSubscription); // remove one subscription -app.delete("/removeSub", fbAuth, removeSub); +app.post("/removeSub", fbAuth, removeSub); /*------------------------------------------------------------------* * handlers/post.js * diff --git a/twistter-frontend/src/pages/otherUser.js b/twistter-frontend/src/pages/otherUser.js index 5a1aa21..f128f72 100644 --- a/twistter-frontend/src/pages/otherUser.js +++ b/twistter-frontend/src/pages/otherUser.js @@ -24,6 +24,7 @@ import VerifiedIcon from "@material-ui/icons/CheckSharp"; import "../App.css"; import noImage from "../images/no-img.png"; import Writing_Microblogs from "../Writing_Microblogs"; + const MyChip = styled(Chip)({ margin: 2, color: "primary" @@ -34,17 +35,48 @@ class user extends Component { profile: window.location.pathname.split("/").pop(), imageUrl: null, topics: null, - following: null // boolean value + user: null, + following: null + }; + + handleSub = () => { + if (this.state.following === true) { + axios + .post("/removeSub", { + unfollow: this.state.profile + }) + .then(res => { + console.log("removed sub"); + this.setState({ + following: false + }); + }) + .catch(function(err) { + console.log(err); + }); + } else { + axios + .post("/addSubscription", { + following: this.state.profile + }) + .then(res => { + console.log("adding sub"); + this.setState({ + following: true + }); + }) + .catch(function(err) { + console.log(err); + }); + } }; componentDidMount() { - console.log(this.state.profile); axios .post("/getUserDetails", { handle: this.state.profile }) .then(res => { - console.log(res.data.userData); this.setState({ imageUrl: res.data.userData.imageUrl, topics: res.data.userData.followedTopics @@ -53,20 +85,16 @@ class user extends Component { .catch(err => console.log(err)); axios - .get("/getallPostsforUser") + .get("/user") .then(res => { - console.log(res.data); this.setState({ - posts: res.data + following: res.data.credentials.following.includes(this.state.profile) }); }) .catch(err => console.log(err)); } render() { - let authenticated = this.props.user.authenticated; - let classes = this.props; - let profileMarkup = this.state.profile ? (
@@ -93,35 +121,27 @@ class user extends Component { ); - let postMarkup = this.state.posts ? ( - this.state.posts.map(post => ( - - - - {this.state.imageUrl ? ( - - ) : ( - - )} - - - - )) + let followMarkup = this.state.following ? ( + ) : ( -

My Posts

+ ); + console.log(this.state.following); + return ( {imageMarkup} {profileMarkup} + {followMarkup} {topicsMarkup}
- - {postMarkup} -
); }