diff --git a/functions/handlers/topic.js b/functions/handlers/topic.js index a55f748..88e014e 100644 --- a/functions/handlers/topic.js +++ b/functions/handlers/topic.js @@ -1,20 +1,28 @@ const { admin, db } = require("../util/admin"); exports.putTopic = (req, res) => { - const newTopic = { - topic: req.body.topic - }; - - admin - .firestore() - .collection("topics") - .add(newTopic) + let new_following = []; + let userRef = db.doc(`/users/${req.userData.handle}`); + userRef + .get() .then(doc => { - const resTopic = newTopic; - return res.status(200).json(resTopic); + new_following = doc.data().followedTopics; + new_following.push(req.body.following); + + // add stuff + userRef + .set({ followedTopics: new_following }, { merge: true }) + .then(doc => { + return res + .status(201) + .json({ message: `Following ${req.body.following}` }); + }) + .catch(err => { + return res.status(500).json({ err }); + }); + return res.status(200).json({ message: "OK" }); }) .catch(err => { - console.error(err); - return res.status(500).json({ error: "something is wrong" }); + return res.status(500).json({ err }); }); }; @@ -40,21 +48,46 @@ exports.getAllTopics = (req, res) => { }; exports.deleteTopic = (req, res) => { - const topic = db.doc(`/topics/${req.params.topicId}`); - topic + let new_following = []; + let userRef = db.doc(`/users/${req.userData.handle}`); + userRef .get() .then(doc => { - if (!doc.exists) { - return res.status(404).json({ error: "Topic not found" }); - } else { - return topic.delete(); - } - }) - .then(() => { - return res.json({ message: "Topic successfully deleted!" }); + new_following = doc.data().followedTopics; + // remove username from array + new_following.forEach(function(follower, index) { + if (follower === `${req.body.unfollow}`) { + new_following.splice(index, 1); + } + }); + + // update database + userRef + .set({ followedTopics: new_following }, { merge: true }) + .then(doc => { + return res + .status(202) + .json({ message: `Successfully unfollow ${req.body.unfollow}` }); + }) + .catch(err => { + return res.status(500).json({ err }); + }); + return res.status(200).json({ message: "ok" }); }) .catch(err => { - console.error(err); - return res.status(500).json({ error: "Failed to delete topic." }); + return res.status(500).json({ err }); + }); +}; + +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/handlers/users.js b/functions/handlers/users.js index a3cea0d..283b97b 100644 --- a/functions/handlers/users.js +++ b/functions/handlers/users.js @@ -201,10 +201,10 @@ exports.deleteUser = (req, res) => { // Get the profile image filename // `https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o/${imageFileName}?alt=media` let imageFileName; - req.userData.imageUrl ? - imageFileName = req.userData.imageUrl.split('/o/')[1].split('?alt=')[0] : - imageFileName = 'no-img.png' - + req.userData.imageUrl + ? (imageFileName = req.userData.imageUrl.split("/o/")[1].split("?alt=")[0]) + : (imageFileName = "no-img.png"); + const userId = req.userData.userId; let errors = {}; @@ -221,56 +221,58 @@ exports.deleteUser = (req, res) => { let auth = admin.auth().deleteUser(userId); // Deletes database data - let data = db.collection("users").doc(`${req.user.handle}`).delete(); + let data = db + .collection("users") + .doc(`${req.user.handle}`) + .delete(); // Deletes any custom profile image let image; - if (imageFileName !== 'no-img.png') { - image = admin.storage().bucket().file(imageFileName).delete() + if (imageFileName !== "no-img.png") { + image = admin + .storage() + .bucket() + .file(imageFileName) + .delete(); } else { image = Promise.resolve(); } // Deletes all users posts - let posts = db.collection("posts") + let posts = db + .collection("posts") .where("userHandle", "==", req.user.handle) .get() - .then((query) => { - query.forEach((snap) => { + .then(query => { + query.forEach(snap => { snap.ref.delete(); }); return; - }) + }); let promises = [ - auth - .then(thenFunction('auth')) - .catch((err) => catchFunction('auth', err)), - data - .then(thenFunction('data')) - .catch((err) => catchFunction('data', err)), - image - .then(thenFunction('image')) - .catch((err) => catchFunction('image', err)), - posts - .then(thenFunction('posts')) - .catch((err) => catchFunction('image', err)) + auth.then(thenFunction("auth")).catch(err => catchFunction("auth", err)), + data.then(thenFunction("data")).catch(err => catchFunction("data", err)), + image.then(thenFunction("image")).catch(err => catchFunction("image", err)), + posts.then(thenFunction("posts")).catch(err => catchFunction("image", err)) ]; - // Wait for all promises to resolve let waitPromise = Promise.all(promises); - waitPromise.then(() => { - if (Object.keys(errors) > 0) { - return res.status(500).json(errors); - } else { - return res.status(200).json({message: `All data for ${req.userData.handle} has been deleted.`}); - } - }) - .catch((err) => { - return res.status(500).json({error: err}); - }) + waitPromise + .then(() => { + if (Object.keys(errors) > 0) { + return res.status(500).json(errors); + } else { + return res.status(200).json({ + message: `All data for ${req.userData.handle} has been deleted.` + }); + } + }) + .catch(err => { + return res.status(500).json({ error: err }); + }); }; // Returns all data in the database for the user who is currently signed in @@ -351,69 +353,142 @@ exports.getAuthenticatedUser = (req, res) => { // Must be run by the Admin user exports.verifyUser = (req, res) => { if (req.userData.handle !== "Admin") { - return res.status(403).json({error: "This must be done as Admin"}); + return res.status(403).json({ error: "This must be done as Admin" }); } db.doc(`/users/${req.body.user}`) .get() - .then((doc) => { + .then(doc => { if (doc.exists) { let verifiedUser = doc.data(); verifiedUser.verified = true; - return db.doc(`/users/${req.body.user}`).set(verifiedUser, {merge: true}); + return db + .doc(`/users/${req.body.user}`) + .set(verifiedUser, { merge: true }); } else { - return res.status(400).json({error: `User ${req.body.user} was not found`}); + return res + .status(400) + .json({ error: `User ${req.body.user} was not found` }); } }) .then(() => { - return res.status(201).json({message: `${req.body.user} is now verified`}); + return res + .status(201) + .json({ message: `${req.body.user} is now verified` }); }) - .catch((err) => { + .catch(err => { console.error(err); - return res.status(500).json({error: err.code}); + return res.status(500).json({ error: err.code }); }); -} +}; // Unverifies the user sent to the request // Must be run by admin exports.unverifyUser = (req, res) => { if (req.userData.handle !== "Admin") { - return res.status(403).json({error: "This must be done as Admin"}); + return res.status(403).json({ error: "This must be done as Admin" }); } db.doc(`/users/${req.body.user}`) .get() - .then((doc) => { + .then(doc => { if (doc.exists) { let unverifiedUser = doc.data(); unverifiedUser.verified = false; - return db.doc(`/users/${req.body.user}`).set(unverifiedUser, {merge: true}); + return db + .doc(`/users/${req.body.user}`) + .set(unverifiedUser, { merge: true }); } else { - return res.status(400).json({error: `User ${req.body.user} was not found`}); + return res + .status(400) + .json({ error: `User ${req.body.user} was not found` }); } }) .then(() => { - return res.status(201).json({message: `${req.body.user} is no longer verified`}); + return res + .status(201) + .json({ message: `${req.body.user} is no longer verified` }); }) - .catch((err) => { + .catch(err => { console.error(err); - return res.status(500).json({error: err.code}); + return res.status(500).json({ error: err.code }); }); -} +}; exports.getUserHandles = (req, res) => { - admin - .firestore() - .collection("users") + db.doc(`/users/${req.body.userHandle}`) .get() - .then(data => { - let users = []; - data.forEach(function(doc) { - users.push(doc.data().handle); - }); - return res.status(200).json(users); + .then(doc => { + if (doc.exists) { + let userHandle = doc.data().handle; + return res.status(200).json(userHandle); + } else { + return res.status(404).json({ error: "user not found" }); + } }) .catch(err => { console.error(err); return res.status(500).json({ error: "Failed to get all user handles." }); }); }; + +exports.addSubscription = (req, res) => { + let new_following = []; + let userRef = db.doc(`/users/${req.userData.handle}`); + userRef.get().then(doc => { + new_following = doc.data().following; + new_following.push(req.body.following); + + // add stuff + userRef + .set({ following: new_following }, { merge: true }) + .then(doc => { + return res + .status(201) + .json({ message: `Following ${req.body.following}` }); + }) + .catch(err => { + return res.status(500).json({ err }); + }); + return res.status(500).json({ error: "shouldn't execute" }); + }); +}; + +exports.getSubs = (req, res) => { + let data = []; + db.doc(`/users/${req.userData.handle}`) + .get() + .then(doc => { + data = doc.data().following; + return res.status(200).json({ data }); + }) + .catch(err => { + return res.status(500).json({ err }); + }); +}; + +exports.removeSub = (req, res) => { + let new_following = []; + let userRef = db.doc(`/users/${req.userData.handle}`); + userRef.get().then(doc => { + new_following = doc.data().following; + // remove username from array + new_following.forEach(function(follower, index) { + if (follower === `${req.body.unfollow}`) { + new_following.splice(index, 1); + } + }); + + // update database + userRef + .set({ following: new_following }, { merge: true }) + .then(doc => { + return res + .status(202) + .json({ message: `Successfully unfollow ${req.body.unfollow}` }); + }) + .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 cdea2d1..f4ab762 100644 --- a/functions/index.js +++ b/functions/index.js @@ -19,7 +19,10 @@ const { updateProfileInfo, verifyUser, unverifyUser, - getUserHandles + getUserHandles, + addSubscription, + getSubs, + removeSub } = require("./handlers/users"); // Adds a user to the database and registers them in firebase with @@ -34,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); @@ -53,7 +56,16 @@ app.post("/verifyUser", fbAuth, verifyUser); app.post("/unverifyUser", fbAuth, unverifyUser); // get user handles with search phase -app.get("/getUserHandles", fbAuth, getUserHandles); +app.post("/getUserHandles", fbAuth, getUserHandles); + +// get user's subscription +app.get("/getSubs", fbAuth, getSubs); + +// add user to another user's "following" data field +app.post("/addSubscription", fbAuth, addSubscription); + +// remove one subscription +app.post("/removeSub", fbAuth, removeSub); /*------------------------------------------------------------------* * handlers/post.js * @@ -78,7 +90,12 @@ app.post("/quoteWithoutPost/:postId", fbAuth, quoteWithoutPost); /*------------------------------------------------------------------* * 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); @@ -87,6 +104,9 @@ app.post("/putTopic", fbAuth, putTopic); app.get("/getAllTopics", fbAuth, getAllTopics); // delete a specific topic -app.delete("/deleteTopic/:topicId", fbAuth, deleteTopic); +app.post("/deleteTopic", fbAuth, deleteTopic); + +// get topic for this user +app.post("/getUserTopics", fbAuth, getUserTopics); exports.api = functions.https.onRequest(app); 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 { - + + -
diff --git a/twistter-frontend/src/components/layout/NavBar.js b/twistter-frontend/src/components/layout/NavBar.js index 9c720b0..f1e1b4a 100644 --- a/twistter-frontend/src/components/layout/NavBar.js +++ b/twistter-frontend/src/components/layout/NavBar.js @@ -1,71 +1,84 @@ /* eslint-disable */ -import React, { Component } from 'react'; -import { Link } from 'react-router-dom'; -import PropTypes from 'prop-types'; +import React, { Component } from "react"; +import { Link } from "react-router-dom"; +import PropTypes from "prop-types"; // Material UI stuff -import AppBar from '@material-ui/core/AppBar'; -import ToolBar from '@material-ui/core/Toolbar'; -import Button from '@material-ui/core/Button'; +import AppBar from "@material-ui/core/AppBar"; +import ToolBar from "@material-ui/core/Toolbar"; +import Button from "@material-ui/core/Button"; import withStyles from "@material-ui/core/styles/withStyles"; // Redux stuff -import { logoutUser } from '../../redux/actions/userActions'; -import { connect } from 'react-redux'; +import { logoutUser } from "../../redux/actions/userActions"; +import { connect } from "react-redux"; const styles = { - form: { - textAlign: "center" - }, - textField: { - marginBottom: 30 - }, - pageTitle: { - marginBottom: 40 - }, - button: { - positon: "relative", - marginBottom: 30 - }, - progress: { - position: "absolute" - } - }; - + form: { + textAlign: "center" + }, + textField: { + marginBottom: 30 + }, + pageTitle: { + marginBottom: 40 + }, + button: { + positon: "relative", + marginBottom: 30 + }, + progress: { + position: "absolute" + } +}; + export class Navbar extends Component { - render() { - const authenticated = this.props.user.authenticated; - return ( - - - - {authenticated && } - {!authenticated && } - {!authenticated && } - {authenticated && } - - - ) - } + render() { + const authenticated = this.props.user.authenticated; + return ( + + + + {authenticated && ( + + )} + {!authenticated && ( + + )} + {!authenticated && ( + + )} + {authenticated && ( + + )} + {authenticated && ( + + )} + + + ); + } } -const mapStateToProps = (state) => ({ - user: state.user -}) +const mapStateToProps = state => ({ + user: state.user +}); Navbar.propTypes = { - user: PropTypes.object.isRequired, - classes: PropTypes.object.isRequired -} + user: PropTypes.object.isRequired, + classes: PropTypes.object.isRequired +}; export default connect(mapStateToProps)(withStyles(styles)(Navbar)); diff --git a/twistter-frontend/src/pages/Search.js b/twistter-frontend/src/pages/Search.js index 657a654..14cbc52 100644 --- a/twistter-frontend/src/pages/Search.js +++ b/twistter-frontend/src/pages/Search.js @@ -1,17 +1,10 @@ import React, { Component } from "react"; // import props -import { TextField, Paper } from "@material-ui/core"; +import { TextField, Button } from "@material-ui/core"; import Grid from "@material-ui/core/Grid"; import Axios from "axios"; -import user from "./user.js"; -import { - BrowserRouter as Router, - Switch, - Route, - Link, - useRouteMatch -} from "react-router-dom"; +import { BrowserRouter as Router } from "react-router-dom"; export class Search extends Component { state = { @@ -19,20 +12,28 @@ export class Search extends Component { searchResult: null }; - handleSearch(event) { - Axios.get("/getUserHandles").then(res => { - this.setState({ - searchResult: res.data - }); - }); + handleSearch = () => { console.log(this.state.searchPhase); - } + Axios.post("/getUserHandles", { + userHandle: this.state.searchPhase + }) + .then(res => { + console.log(res); + + this.setState({ + searchResult: res.data + }); + }) + .catch(err => { + console.log(err); + }); + }; handleInput(event) { this.setState({ searchPhase: event.target.value }); - this.handleSearch(); + console.log(this.state.searchPhase); } handleRedirect() { @@ -41,16 +42,16 @@ export class Search extends Component { render() { let resultMarkup = this.state.searchResult ? ( - this.state.searchResult.map(result => ( - -
- {result} -
-
- )) + +
+ + {this.state.searchResult} + +
+
) : ( // console.log(this.state.searchResult) -

searching...

+

No result

); return ( @@ -65,6 +66,11 @@ export class Search extends Component { onChange={event => this.handleInput(event)} /> + + + {resultMarkup} ); diff --git a/twistter-frontend/src/pages/otherUser.js b/twistter-frontend/src/pages/otherUser.js new file mode 100644 index 0000000..f128f72 --- /dev/null +++ b/twistter-frontend/src/pages/otherUser.js @@ -0,0 +1,158 @@ +/* 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, + 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() { + axios + .post("/getUserDetails", { + handle: this.state.profile + }) + .then(res => { + this.setState({ + imageUrl: res.data.userData.imageUrl, + topics: res.data.userData.followedTopics + }); + }) + .catch(err => console.log(err)); + + axios + .get("/user") + .then(res => { + this.setState({ + following: res.data.credentials.following.includes(this.state.profile) + }); + }) + .catch(err => console.log(err)); + } + + render() { + 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 followMarkup = this.state.following ? ( + + ) : ( + + ); + + console.log(this.state.following); + + return ( + + + {imageMarkup} + {profileMarkup} + {followMarkup} + {topicsMarkup} +
+
+
+ ); + } +} + +const mapStateToProps = state => ({ + user: state.user +}); + +user.propTypes = { + user: PropTypes.object.isRequired +}; + +export default connect(mapStateToProps)(user); diff --git a/twistter-frontend/src/pages/user.js b/twistter-frontend/src/pages/user.js index cada325..0a11258 100644 --- a/twistter-frontend/src/pages/user.js +++ b/twistter-frontend/src/pages/user.js @@ -1,34 +1,74 @@ /* 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 React, { Component } from "react"; +import PropTypes from "prop-types"; +import { connect } from "react-redux"; +import axios from "axios"; +//import '../App.css'; +// Material-UI +import withStyles from "@material-ui/core/styles/withStyles"; import { makeStyles, styled } from "@material-ui/core/styles"; -import { Link } from 'react-router-dom'; +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 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'; +import AddCircle from "@material-ui/icons/AddCircle"; +import TextField from "@material-ui/core/TextField"; +import VerifiedIcon from "@material-ui/icons/CheckSharp"; +import Paper from "@material-ui/core/Paper"; +import GridList from "@material-ui/core/GridList"; +import GridListTile from "@material-ui/core/GridListTile"; +import GridListTileBar from "@material-ui/core/GridListTileBar"; +import Container from "@material-ui/core/Container"; // component -import '../App.css'; -import noImage from '../images/no-img.png'; -import Writing_Microblogs from '../Writing_Microblogs'; +import "../App.css"; +import noImage from "../images/no-img.png"; +import Writing_Microblogs from "../Writing_Microblogs"; + const MyChip = styled(Chip)({ margin: 2, color: "primary" }); +const styles = { + button: { + positon: "relative", + float: "left", + marginLeft: 30, + marginTop: 20 + }, + paper: { + // marginLeft: "10%", + // marginRight: "10%" + }, + card: { + marginBottom: 10 + }, + profileImage: { + marginTop: 20 + }, + topicsContainer: { + border: "lightgray solid 1px", + marginTop: 20, + paddingTop: 10, + paddingBottom: 10, + height: 300 + }, + addCircle: { + width: 65, + height: 65, + marginTop: 10 + }, + username: { + marginBottom: 100 + } +}; + class user extends Component { state = { profile: null, @@ -38,8 +78,11 @@ class user extends Component { }; handleDelete = topic => { + console.log(topic); axios - .delete(`/deleteTopic/${topic.id}`) + .post(`/deleteTopic`, { + unfollow: topic + }) .then(function() { location.reload(); }) @@ -51,7 +94,7 @@ class user extends Component { handleAddCircle = () => { axios .post("/putTopic", { - topic: this.state.newTopic + following: this.state.newTopic }) .then(function() { location.reload(); @@ -74,16 +117,10 @@ class user extends Component { this.setState({ profile: res.data.credentials.handle, imageUrl: res.data.credentials.imageUrl, - verified: res.data.credentials.verified ? res.data.credentials.verified : false - }); - }) - .catch(err => console.log(err)); - - axios - .get("/getAllTopics") - .then(res => { - this.setState({ - topics: res.data + verified: res.data.credentials.verified + ? res.data.credentials.verified + : false, + topics: res.data.credentials.followedTopics }); }) .catch(err => console.log(err)); @@ -91,7 +128,7 @@ class user extends Component { axios .get("/getallPostsforUser") .then(res => { - console.log(res.data); + // console.log(res.data); this.setState({ posts: res.data }) @@ -103,20 +140,28 @@ class user extends Component { } render() { + const { classes } = this.props; let authenticated = this.props.user.authenticated; - let classes = this.props; let profileMarkup = this.state.profile ? (
- @{this.state.profile} {this.state.verified ? (): (null)} -
) : (

loading username...

); - + + @{this.state.profile}{" "} + {this.state.verified ? ( + + ) : null} + + + ) : ( +

loading username...

+ ); + let topicsMarkup = this.state.topics ? ( this.state.topics.map( topic => ( this.handleDelete(topic)} /> ) // console.log({ topic }.topic.id) @@ -125,26 +170,47 @@ class user extends Component {

 loading topics...

); - let imageMarkup = this.state.imageUrl ? () : - (); - - - + let imageMarkup = this.state.imageUrl ? ( + + ) : ( + + ); + let postMarkup = this.state.posts ? ( - this.state.posts.map(post => - + this.state.posts.map(post => ( + - { - this.state.imageUrl ? () : - () - } + {this.state.imageUrl ? ( + + ) : ( + + )} + + {post.userHandle} + + + {post.createdAt} + + {post.userHandle} {post.createdAt.substring(0,10) + " " + post.createdAt.substring(11,19)}
- {post.microBlogTitle} + + {post.microBlogTitle} + {post.body}
Topics: {post.microBlogTopics.join("," + " ")} @@ -152,79 +218,87 @@ class user extends Component { Likes {post.likeCount}
- ) - ) : (

My Posts

); + )) + ) : ( +

My Posts

+ ); + + // FIX: This needs to check if user's profile page being displayed + // is the same as the user who is logged in + // Can't check for that right now, because this page is always + // showing the logged in users profile, instead of retreiving the + // profile based on the URL entered + let editButtonMarkup = true ? ( + + + + ) : null; return ( - - - {imageMarkup} - {profileMarkup} - {topicsMarkup} - this.handleChange(event)} - /> - -
- - - { - authenticated && - } +
+ {/* */} + + + + + {editButtonMarkup} + + + {/* */} + {/* */} + {imageMarkup} + {profileMarkup} + {/* */} + {/* */} + {/* {postMarkup} */} + {/* */} + {/* */} + + + + {topicsMarkup} + + this.handleChange(event)} + /> + + - - { - authenticated && - this.state.profile === 'Admin' && - } + + + + + {postMarkup} + - - {postMarkup} - - - - -        - +
); } } -const mapStateToProps = (state) => ({ +const mapStateToProps = state => ({ user: state.user -}) +}); user.propTypes = { user: PropTypes.object.isRequired -} +}; -export default connect(mapStateToProps)(user); +export default connect(mapStateToProps)(withStyles(styles)(user));