Merge branch 'master' into microblogs-material-ui

This commit is contained in:
Clayton Wilson 2019-12-03 13:24:36 -05:00 committed by GitHub
commit 4abaa13b09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 170 additions and 79 deletions

View File

@ -331,6 +331,24 @@ exports.getUserDetails = (req, res) => {
}); });
}; };
exports.getAllHandles = (req, res) => {
var user_query = admin.firestore().collection("users");
user_query.get()
.then((allUsers) => {
let users = [];
allUsers.forEach((user) => {
users.push(user.data().handle);
});
return res.status(200).json(users);
})
.catch((err) => {
return res.status(500).json({
message:"Failed to retrieve posts from database.",
error: err
});
});
};
exports.getAuthenticatedUser = (req, res) => { exports.getAuthenticatedUser = (req, res) => {
let credentials = {}; let credentials = {};
db.doc(`/users/${req.user.handle}`) db.doc(`/users/${req.user.handle}`)

View File

@ -11,6 +11,7 @@ app.use(cors());
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
const { const {
getAuthenticatedUser, getAuthenticatedUser,
getAllHandles,
getUserDetails, getUserDetails,
getProfileInfo, getProfileInfo,
login, login,
@ -39,6 +40,10 @@ app.delete("/delete", fbAuth, deleteUser);
app.post("/getUserDetails", fbAuth, getUserDetails); app.post("/getUserDetails", fbAuth, getUserDetails);
// Returns a list of all usernames
// Used for searching
app.get("/getAllHandles", fbAuth, getAllHandles);
// Returns all profile data of the currently logged in user // Returns all profile data of the currently logged in user
app.get("/getProfileInfo", fbAuth, getProfileInfo); app.get("/getProfileInfo", fbAuth, getProfileInfo);

View File

@ -10,11 +10,13 @@
"axios": "^0.19.0", "axios": "^0.19.0",
"clsx": "^1.0.4", "clsx": "^1.0.4",
"create-react-app": "^3.1.2", "create-react-app": "^3.1.2",
"fuse.js": "^3.4.6",
"install": "^0.13.0", "install": "^0.13.0",
"jwt-decode": "^2.2.0", "jwt-decode": "^2.2.0",
"node-pre-gyp": "^0.13.0", "node-pre-gyp": "^0.13.0",
"react": "^16.9.0", "react": "^16.9.0",
"react-dom": "^16.9.0", "react-dom": "^16.9.0",
"react-modal": "^3.11.1",
"react-redux": "^7.1.1", "react-redux": "^7.1.1",
"react-router-dom": "^5.1.0", "react-router-dom": "^5.1.0",
"react-scripts": "0.9.5", "react-scripts": "0.9.5",

View File

@ -61,15 +61,28 @@ class Writing_Microblogs extends Component {
}; };
axios axios
.post("/putPost", postData, headers) .post("/putPost", postData, headers) // TODO: add topics
.then(res => { .then(res => {
alert("Post was shared successfully!"); // alert("Post was shared successfully!");
console.log(res.data); console.log(res.data);
}) })
.catch(err => { .catch(err => {
alert("An error occured."); alert("An error occured.");
console.error(err); console.error(err);
}); });
console.log(postData.microBlogTopics);
postData.microBlogTopics.forEach(topic => {
axios
.post("/putTopic", {
following: topic
})
.then(res => {
console.log(res.data);
})
.catch(err => {
console.error(err);
});
});
event.preventDefault(); event.preventDefault();
this.setState({ value: "", title: "", characterCount: 250, topics: "" }); this.setState({ value: "", title: "", characterCount: 250, topics: "" });
} }

View File

@ -1,13 +1,13 @@
/* eslint-disable */ /* eslint-disable */
import React, { Component } from 'react'; import React, { Component } from "react";
import PropTypes from 'prop-types'; import PropTypes from "prop-types";
import { connect } from 'react-redux'; import { connect } from "react-redux";
import axios from 'axios'; import axios from "axios";
// Material UI and React Router // Material UI and React Router
import Grid from '@material-ui/core/Grid'; import Grid from "@material-ui/core/Grid";
import Card from '@material-ui/core/Card'; import Card from "@material-ui/core/Card";
import CardContent from '@material-ui/core/CardContent'; import CardContent from "@material-ui/core/CardContent";
import Typography from "@material-ui/core/Typography"; import Typography from "@material-ui/core/Typography";
import withStyles from '@material-ui/styles/withStyles'; import withStyles from '@material-ui/styles/withStyles';
@ -38,7 +38,7 @@ class Home extends Component {
console.log(res.data); console.log(res.data);
this.setState({ this.setState({
posts: res.data posts: res.data
}) });
}) })
.catch(err => console.log(err)); .catch(err => console.log(err));
} }
@ -78,11 +78,12 @@ class Home extends Component {
<Quote microblog = {post.postId}></Quote> <Quote microblog = {post.postId}></Quote>
</CardContent> </CardContent>
</Card> </Card>
) ))
) : (<p>My Posts</p>); ) : (
<p>Loading post...</p>
);
return ( return authenticated ? (
authenticated ?
<Grid container spacing={16}> <Grid container spacing={16}>
<Grid item sm={4} xs={8}> <Grid item sm={4} xs={8}>
<Writing_Microblogs /> <Writing_Microblogs />
@ -91,21 +92,27 @@ class Home extends Component {
{postMarkup} {postMarkup}
</Grid> </Grid>
</Grid> </Grid>
: ) : (
<div> <div>
<div> <div>
<img src={logo} className="app-logo" alt="logo" /> <img src={logo} className="app-logo" alt="logo" />
<br/><br/> <br />
<br />
<b>Welcome to Twistter!</b> <b>Welcome to Twistter!</b>
<br/><br/> <br />
<br />
<b>See the most interesting topics people are following right now.</b> <b>See the most interesting topics people are following right now.</b>
</div> </div>
<br/><br/><br/><br/> <br />
<br />
<br />
<br />
<div> <div>
<b>Join today or sign in if you already have an account.</b> <b>Join today or sign in if you already have an account.</b>
<br/><br/> <br />
<br />
<form action="./signup"> <form action="./signup">
<button className="authButtons signup">Sign up</button> <button className="authButtons signup">Sign up</button>
</form> </form>
@ -119,7 +126,6 @@ class Home extends Component {
} }
} }
class Quote extends Component { class Quote extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -332,14 +338,13 @@ class Like extends Component {
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
user: state.user user: state.user
}) });
Home.propTypes = { Home.propTypes = {
user: PropTypes.object.isRequired, user: PropTypes.object.isRequired,
clases: PropTypes.object.isRequired clases: PropTypes.object.isRequired
} }
Like.propTypes = { Like.propTypes = {
user: PropTypes.object.isRequired user: PropTypes.object.isRequired
} }

View File

@ -2,38 +2,75 @@ import React, { Component } from "react";
// import props // import props
import { TextField, Button } from "@material-ui/core"; import { TextField, Button } from "@material-ui/core";
import Grid from "@material-ui/core/Grid"; import Grid from "@material-ui/core/Grid";
import Axios from "axios"; import axios from "axios";
import Fuse from "fuse.js";
import { BrowserRouter as Router } from "react-router-dom"; import { BrowserRouter as Router } from "react-router-dom";
import CircularProgress from "@material-ui/core/CircularProgress";
const fuseOptions = {
shouldSort: true,
threshold: 0.6,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 1,
keys: []
};
let fuse;
export class Search extends Component { export class Search extends Component {
state = { state = {
searchPhase: null, handles: [],
searchResult: null // searchPhrase: null,
searchResult: null,
loading: false
}; };
handleSearch = () => { componentDidMount() {
console.log(this.state.searchPhase); this.setState({loading: true});
Axios.post("/getUserHandles", { axios.get("/getAllHandles")
userHandle: this.state.searchPhase .then((res) => {
})
.then(res => {
console.log(res);
this.setState({ this.setState({
searchResult: res.data handles: res.data,
}); loading: false
}, () => {
console.log(res.data);
fuse = new Fuse(this.state.handles, fuseOptions); // "list" is the item array
}) })
.catch(err => { })
console.log(err); }
});
};
handleInput(event) { // 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);
// });
// };
handleChange = (event) => {
let result = fuse.search(event.target.value);
let parsed = [];
result.forEach((res) => {
console.log(res)
parsed.push(this.state.handles[res])
})
this.setState({ this.setState({
searchPhase: event.target.value searchResult: parsed.length !== 0 ? parsed : "No Results"
}); })
console.log(this.state.searchPhase);
} }
handleRedirect() { handleRedirect() {
@ -41,35 +78,46 @@ export class Search extends Component {
} }
render() { render() {
let resultMarkup = this.state.searchResult ? ( let resultMarkup = this.state.searchResult && this.state.searchResult !== "No Results" ? (
this.state.searchResult.map(res =>
<Router> <Router>
<div> <div>
<a href={`/user/${this.state.searchResult}`}> <a href={`/user/${res}`}>
{this.state.searchResult} {res}
</a> </a>
</div> </div>
</Router> </Router>
) : ( )
// console.log(this.state.searchResult) )
<p> No result </p> :
); this.state.searchResult === "No Results" ?
(
<p> No results </p>
)
:
(
null
)
return ( return (
this.state.loading
?
<CircularProgress size={60} style={{marginTop: "300px"}}></CircularProgress>
:
<Grid> <Grid>
<Grid> <Grid>
<TextField <TextField
id="standard-required" id="standard-required"
label="Search" label="Username"
defaultValue="username"
margin="normal" margin="normal"
value={this.state.searchPhase} // value={this.state.searchPhrase}
onChange={event => this.handleInput(event)} onChange={this.handleChange}
/> />
</Grid> </Grid>
<Grid> <Grid>
<Button color="primary" onClick={this.handleSearch}> {/* <Button color="primary" onClick={this.handleSearch}>
Search Search
</Button> </Button> */}
</Grid> </Grid>
<Grid>{resultMarkup}</Grid> <Grid>{resultMarkup}</Grid>
</Grid> </Grid>