From c1589b9758adffe6ba97fa7787f5720f0daf5ed8 Mon Sep 17 00:00:00 2001 From: Harrison Deng Date: Tue, 5 Apr 2022 03:28:12 -0500 Subject: [PATCH] Welcome page now shows current matches. --- sports-matcher/client/package.json | 2 +- .../src/components/GameInfoCardDisplay.js | 21 ---------------- .../{GameInfoCard.js => MatchInfoCard.js} | 13 +++++----- .../src/components/MatchInfoCardDisplay.js | 24 ++++++++++++++++++ sports-matcher/client/src/index.js | 3 +++ sports-matcher/client/src/pages/Welcome.js | 18 ++++++++++++- .../client/src/utils/httpClients.js | 2 +- .../server/controllers/matchController.js | 25 +++++++++++-------- 8 files changed, 68 insertions(+), 40 deletions(-) delete mode 100644 sports-matcher/client/src/components/GameInfoCardDisplay.js rename sports-matcher/client/src/components/{GameInfoCard.js => MatchInfoCard.js} (65%) create mode 100644 sports-matcher/client/src/components/MatchInfoCardDisplay.js diff --git a/sports-matcher/client/package.json b/sports-matcher/client/package.json index 1e0beaf..1e67687 100644 --- a/sports-matcher/client/package.json +++ b/sports-matcher/client/package.json @@ -16,7 +16,7 @@ "web-vitals": "^2.1.4" }, "scripts": { - "start": "NODE_ENV=development API_HOST=http://localhost:5000 react-scripts start", + "start": "NODE_ENV='development' REACT_APP_API_HOST='http://localhost:5000' react-scripts start", "build": "../scripts/build.py", "test": "react-scripts test", "eject": "react-scripts eject" diff --git a/sports-matcher/client/src/components/GameInfoCardDisplay.js b/sports-matcher/client/src/components/GameInfoCardDisplay.js deleted file mode 100644 index 29dae92..0000000 --- a/sports-matcher/client/src/components/GameInfoCardDisplay.js +++ /dev/null @@ -1,21 +0,0 @@ -import React from "react"; -import propTypes from "prop-types"; -import GameInfoCard from "./GameInfoCard"; - -export default class GameInfoCardDisplay extends React.Component { - constructor(props) { - super(props); - - } - render() { - return ( -
- {this.props.recommendedMatches.map((match) => )} -
- ); - } -} - -GameInfoCardDisplay.propTypes = { - recommendedMatches: propTypes.array, -}; \ No newline at end of file diff --git a/sports-matcher/client/src/components/GameInfoCard.js b/sports-matcher/client/src/components/MatchInfoCard.js similarity index 65% rename from sports-matcher/client/src/components/GameInfoCard.js rename to sports-matcher/client/src/components/MatchInfoCard.js index 99dccf2..f99832f 100644 --- a/sports-matcher/client/src/components/GameInfoCard.js +++ b/sports-matcher/client/src/components/MatchInfoCard.js @@ -2,14 +2,15 @@ import React from "react"; import { Button, Card } from "react-bootstrap"; import propTypes from "prop-types"; import { grammaticalListString } from "../utils/strings"; -export default class GameInfoCard extends React.Component { +export default class MatchInfoCard extends React.Component { constructor(props) { super(props); } getParticipants() { let participants = []; - this.props.match.registeredUsers.array.forEach(user => { + console.log(this.props); + this.props.match.participants.forEach(user => { participants.push(user.firstName); }); return participants; @@ -19,10 +20,10 @@ export default class GameInfoCard extends React.Component { return ( - {this.props.match.sport} - {this.props.match.sport} + {this.props.match.sport.name} + {this.props.match.title} - Join {grammaticalListString(this.getParticipants(), 4)} to play a few matches of {this.props.match.sport} at {this.props.match.location} on {this.props.match.dateTime.toLocaleDateString("en-US")}! + Join {grammaticalListString(this.getParticipants(), 4)} to play a few matches of {this.props.match.sport.name} at {this.props.match.location.toString()} on {new Date(this.props.match.when).toLocaleDateString("en-US")}! @@ -31,6 +32,6 @@ export default class GameInfoCard extends React.Component { } } -GameInfoCard.propTypes = { +MatchInfoCard.propTypes = { match: propTypes.object, }; \ No newline at end of file diff --git a/sports-matcher/client/src/components/MatchInfoCardDisplay.js b/sports-matcher/client/src/components/MatchInfoCardDisplay.js new file mode 100644 index 0000000..3dd3f7b --- /dev/null +++ b/sports-matcher/client/src/components/MatchInfoCardDisplay.js @@ -0,0 +1,24 @@ +import React from "react"; +import propTypes from "prop-types"; +import MatchInfoCard from "./MatchInfoCard"; + +export default class MatchInfoCardDisplay extends React.Component { + constructor(props) { + super(props); + } + render() { + let matches = null; + if (this.props.recommendedmatches.length > 0) { + matches = this.props.recommendedmatches.map((match) => ); + } + return ( +
+ {matches} +
+ ); + } +} + +MatchInfoCardDisplay.propTypes = { + recommendedmatches: propTypes.array, +}; \ No newline at end of file diff --git a/sports-matcher/client/src/index.js b/sports-matcher/client/src/index.js index 5620a3e..1cdb2e4 100644 --- a/sports-matcher/client/src/index.js +++ b/sports-matcher/client/src/index.js @@ -4,6 +4,9 @@ import Layout from "./Layout"; import reportWebVitals from "./reportWebVitals"; import { BrowserRouter } from "react-router-dom"; import "bootstrap/dist/css/bootstrap.min.css"; // This could be optimized by importing individual css components. + +console.log(process.env); + ReactDOM.render( diff --git a/sports-matcher/client/src/pages/Welcome.js b/sports-matcher/client/src/pages/Welcome.js index e8b0669..56562c2 100644 --- a/sports-matcher/client/src/pages/Welcome.js +++ b/sports-matcher/client/src/pages/Welcome.js @@ -1,10 +1,25 @@ import React from "react"; import { apiClient } from "../utils/httpClients"; import HomeCarousel from "../components/HomeCarousel"; +import MatchInfoCardDisplay from "../components/MatchInfoCardDisplay"; export default class Welcome extends React.Component { constructor(props) { super(props); - this.recentMatchesRequest = apiClient.get("/match/recent/15"); + this.state = { + displayedMatches: [], + }; + } + + async componentDidMount() { + await this.latestMatches(); + + } + + async latestMatches() { + let recentMatchesRes = await apiClient.get("/match/recent/15"); + if (recentMatchesRes.status === 200) { + this.setState({ displayedMatches: recentMatchesRes.data.recent }); + } } render() { @@ -19,6 +34,7 @@ export default class Welcome extends React.Component {

Available Matches

+
); diff --git a/sports-matcher/client/src/utils/httpClients.js b/sports-matcher/client/src/utils/httpClients.js index a1d3187..e512953 100644 --- a/sports-matcher/client/src/utils/httpClients.js +++ b/sports-matcher/client/src/utils/httpClients.js @@ -1,6 +1,6 @@ import axios from "axios"; export const apiClient = axios.create({ - baseURL: process.env.API_HOST, + baseURL: process.env.REACT_APP_API_HOST, timeout: 5000, }); \ No newline at end of file diff --git a/sports-matcher/server/controllers/matchController.js b/sports-matcher/server/controllers/matchController.js index 55b8fe2..e2cf3eb 100644 --- a/sports-matcher/server/controllers/matchController.js +++ b/sports-matcher/server/controllers/matchController.js @@ -27,13 +27,18 @@ MatchController.get("/search/:sport", needDatabase, async (req, res) => { MatchController.get("/recent/:limit?", needDatabase, async (req, res) => { const user = req.user; - let limit = req.params.limit; - if (limit && typeof (limit) !== "number") { - res.status(400).send("Limit parameter is not a number."); - } + let limit = parseInt(req.params.limit); if (!req.params.limit) limit = 10; + if (isNaN(limit)) { + console.log(typeof (limit)); + res.status(400).send("Limit parameter is not a number."); + return; + } if (user) { - res.status(200).send(user.participatingMatches.slice(limit)); + await user.populate("participatingMatches"); + await user.populate("participatingMatches.participants"); + await user.populate("participatingMatches.sport"); + res.status(200).send(); return; } if (isNaN(limit)) { @@ -45,7 +50,7 @@ MatchController.get("/recent/:limit?", needDatabase, async (req, res) => { return; } try { - const recent = await matchModel.find().where("publicity").gte(2).limit(limit).sort({ createDate: -1 }); + const recent = await matchModel.find().where("publicity").gte(2).limit(limit).sort({ createDate: -1 }).populate("participants").populate("sport"); res.status(200).send({ recent: recent }); } catch (err) { console.error(err); @@ -121,17 +126,17 @@ MatchController.delete("/:id", needDatabase, authenticationGuard, async (req, re await match.deleteOne(); }); -MatchController.get("/:matchId", needDatabase, async (req, res) => { - if (!req.params.matchId) { +MatchController.get("/:id", needDatabase, async (req, res) => { + if (!req.params.id) { res.status(404).send("Id must be provided to retrieve match"); return; } try { - const match = await matchModel.findById(req.params.matchId); + const match = await matchModel.findById(req.params.id).populate("sport"); if (match) { res.status(200).send(match); } else { - res.status(404).send("Could not find match with ID: " + req.params.matchId); + res.status(404).send("Could not find match with ID: " + req.params.id); } } catch (error) { res.status(500).send("Internal server error.");