diff --git a/functions/handlers/users.js b/functions/handlers/users.js index 5350d19..3430fff 100644 --- a/functions/handlers/users.js +++ b/functions/handlers/users.js @@ -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) => { let credentials = {}; db.doc(`/users/${req.user.handle}`) diff --git a/functions/index.js b/functions/index.js index ee203eb..eab8aa9 100644 --- a/functions/index.js +++ b/functions/index.js @@ -11,6 +11,7 @@ app.use(cors()); *------------------------------------------------------------------*/ const { getAuthenticatedUser, + getAllHandles, getUserDetails, getProfileInfo, login, @@ -39,6 +40,10 @@ app.delete("/delete", fbAuth, deleteUser); 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 app.get("/getProfileInfo", fbAuth, getProfileInfo); diff --git a/twistter-frontend/package.json b/twistter-frontend/package.json index a0cec16..52e50f3 100644 --- a/twistter-frontend/package.json +++ b/twistter-frontend/package.json @@ -10,11 +10,13 @@ "axios": "^0.19.0", "clsx": "^1.0.4", "create-react-app": "^3.1.2", + "fuse.js": "^3.4.6", "install": "^0.13.0", "jwt-decode": "^2.2.0", "node-pre-gyp": "^0.13.0", "react": "^16.9.0", "react-dom": "^16.9.0", + "react-modal": "^3.11.1", "react-redux": "^7.1.1", "react-router-dom": "^5.1.0", "react-scripts": "0.9.5", diff --git a/twistter-frontend/src/pages/Search.js b/twistter-frontend/src/pages/Search.js index 14cbc52..c8409f5 100644 --- a/twistter-frontend/src/pages/Search.js +++ b/twistter-frontend/src/pages/Search.js @@ -2,38 +2,75 @@ import React, { Component } from "react"; // import props import { TextField, Button } from "@material-ui/core"; 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 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 { state = { - searchPhase: null, - searchResult: null + handles: [], + // searchPhrase: null, + searchResult: null, + loading: false }; - handleSearch = () => { - console.log(this.state.searchPhase); - Axios.post("/getUserHandles", { - userHandle: this.state.searchPhase - }) - .then(res => { - console.log(res); - - this.setState({ - searchResult: res.data - }); + componentDidMount() { + this.setState({loading: true}); + axios.get("/getAllHandles") + .then((res) => { + this.setState({ + 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({ - searchPhase: event.target.value - }); - console.log(this.state.searchPhase); + searchResult: parsed.length !== 0 ? parsed : "No Results" + }) } handleRedirect() { @@ -41,38 +78,49 @@ export class Search extends Component { } render() { - let resultMarkup = this.state.searchResult ? ( - -
- - {this.state.searchResult} - -
-
- ) : ( - // console.log(this.state.searchResult) -

No result

- ); + let resultMarkup = this.state.searchResult && this.state.searchResult !== "No Results" ? ( + this.state.searchResult.map(res => + +
+ + {res} + +
+
+ ) + ) + : + this.state.searchResult === "No Results" ? + ( +

No results

+ ) + : + ( + null + ) return ( - + this.state.loading + ? + + : - this.handleInput(event)} - /> + + + + + {/* */} + + {resultMarkup} - - - - {resultMarkup} - ); } }