Skip to content

Commit

Permalink
removed console.logs
Browse files Browse the repository at this point in the history
Silver1793 committed Dec 6, 2023
1 parent e0d3a46 commit 2eb5ee1
Showing 23 changed files with 493 additions and 473 deletions.
90 changes: 57 additions & 33 deletions automations/Code.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,80 @@
const getConfig = () => {
// global settings
return {
defaultChartSheetName: 'Sprint 1 - Team Plots',
logsSheetName: 'GitHub Logs',
logsSheetFields: ['repository', 'event', 'id', 'username', 'email', 'date', 'message', 'num_files', 'num_additions', 'num_deletions']
}
}
defaultChartSheetName: "Sprint 1 - Team Plots",
logsSheetName: "GitHub Logs",
logsSheetFields: [
"repository",
"event",
"id",
"username",
"email",
"date",
"message",
"num_files",
"num_additions",
"num_deletions",
],
};
};

const getSheet = () => {
const config = getConfig()
const ss = SpreadsheetApp.getActiveSpreadsheet() // container spreadsheet
let sheet = ss.getSheetByName(config.logsSheetName) // specific worksheet
const config = getConfig();
const ss = SpreadsheetApp.getActiveSpreadsheet(); // container spreadsheet
let sheet = ss.getSheetByName(config.logsSheetName); // specific worksheet
if (sheet == null) {
// create worksheet if none
sheet = ss.insertSheet(config.logsSheetName)
sheet.appendRow(config.logsSheetFields) // heading row
sheet = ss.insertSheet(config.logsSheetName);
sheet.appendRow(config.logsSheetFields); // heading row
}
return sheet
}
return sheet;
};

function doGet(e) {
// get the sheet name with the charts from the query string
const config = getConfig()
// we expect a `sheet` query string in the request
const sheetName = (e.parameter["sheet"]) ? decodeURIComponent(e.parameter["sheet"]) : config.defaultChartSheetName
Logger.log(`Loading charts from sheet: ${sheetName}`)
charts = getCharts(sheetName)
const content = generateHtml(sheetName, charts)
return HtmlService.createHtmlOutput(content)
const config = getConfig();
// we expect a `sheet` query string in the request
const sheetName = e.parameter["sheet"]
? decodeURIComponent(e.parameter["sheet"])
: config.defaultChartSheetName;
Logger.log(`Loading charts from sheet: ${sheetName}`);
charts = getCharts(sheetName);
const content = generateHtml(sheetName, charts);
return HtmlService.createHtmlOutput(content);
}

function doPost(e) {
console.log("Incoming post request")
console.log(JSON.stringify(e, null, 2))
const sheet = getSheet()
const sheet = getSheet();
const res = {
type: 'post',
e: e
}
type: "post",
e: e,
};
const commit_data = JSON.parse(e.postData.contents); // should be an array of objects
if (Array.isArray(commit_data)) {
for (let i=0; i<commit_data.length; i++) {
for (let i = 0; i < commit_data.length; i++) {
// log this commit!
const commit = commit_data[i]
console.log(JSON.stringify(commit, null, 2))
const commit = commit_data[i];
// append data array to sheet as new row
const row = [commit['repository_url'], commit['event_type'], commit['id'], commit['author_name'], commit['author_email'], commit['date'], commit['message'], commit['files'], commit['additions'], commit['deletions']]
const row = [
commit["repository_url"],
commit["event_type"],
commit["id"],
commit["author_name"],
commit["author_email"],
commit["date"],
commit["message"],
commit["files"],
commit["additions"],
commit["deletions"],
];
sheet.appendRow(row);
}
return ContentService.createTextOutput(commit_data).setMimeType(ContentService.MimeType.JSON)
}
else {
return ContentService.createTextOutput(typeof(commit_data)).setMimeType(ContentService.MimeType.TEXT)
return ContentService.createTextOutput(commit_data).setMimeType(
ContentService.MimeType.JSON
);
} else {
return ContentService.createTextOutput(typeof commit_data).setMimeType(
ContentService.MimeType.TEXT
);
}
}
42 changes: 20 additions & 22 deletions back-end/config/jwt-config.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,45 @@
const mongoose = require("mongoose")
const ObjectId = mongoose.Types.ObjectId
const User = require("../models/user")
const mongoose = require("mongoose");
const ObjectId = mongoose.Types.ObjectId;
const User = require("../models/user");

const passportJWT = require("passport-jwt")
const ExtractJwt = passportJWT.ExtractJwt
const JwtStrategy = passportJWT.Strategy
const passportJWT = require("passport-jwt");
const ExtractJwt = passportJWT.ExtractJwt;
const JwtStrategy = passportJWT.Strategy;

// set up some JWT authentication options for passport
let jwtOptions = {
jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme("jwt"), // look for the Authorization request header
secretOrKey: process.env.JWT_SECRET, // an arbitrary string used during encryption - see the .env file
}
// console.log(jwtOptions) // debug to make sure the secret from the .env file is loaded correctly

};
// define the method that is used by passport to verify the contents (i.e. the payload) of the JWT token
const jwtVerifyToken = async function (jwt_payload, next) {
console.log("JWT payload received", jwt_payload) // debugging
console.log("JWT payload received", jwt_payload); // debugging

// check if the token has expired
const expirationDate = new Date(jwt_payload.exp * 1000) // convert from seconds to milliseconds
const expirationDate = new Date(jwt_payload.exp * 1000); // convert from seconds to milliseconds
if (expirationDate < new Date()) {
// the token has expired
return next(null, false, { message: "JWT token has expired." })
return next(null, false, { message: "JWT token has expired." });
}

// try to find a matching user in our database

// find this user in the database
const userId = new ObjectId(jwt_payload.id) // convert the string id to an ObjectId
const user = await User.findOne({ _id: userId }).exec()
const userId = new ObjectId(jwt_payload.id); // convert the string id to an ObjectId
const user = await User.findOne({ _id: userId }).exec();
if (user) {
// we found the user... keep going
next(null, user)
next(null, user);
} else {
// we didn't find the user... fail!
next(null, false, { message: "User not found" })
next(null, false, { message: "User not found" });
}
}
};

// passport can work with many authentication systems... here we are setting some middleware code for using JWT that we'll pass to passport to use
const jwtStrategy = jwtOptions => {
const strategy = new JwtStrategy(jwtOptions, jwtVerifyToken)
return strategy
}
const jwtStrategy = (jwtOptions) => {
const strategy = new JwtStrategy(jwtOptions, jwtVerifyToken);
return strategy;
};

module.exports = jwtStrategy(jwtOptions, jwtVerifyToken)
module.exports = jwtStrategy(jwtOptions, jwtVerifyToken);
4 changes: 1 addition & 3 deletions back-end/db.js
Original file line number Diff line number Diff line change
@@ -4,9 +4,7 @@ require("dotenv").config();
const connect_db = async () => {
try {
const mongoURL = process.env.MONGODB_URI;
await mongoose.connect(mongoURL, {
});
console.log("Connected to database.");
await mongoose.connect(mongoURL, {});
} catch (error) {
console.error("Error connecting to database: ", error);
process.exit(1);
209 changes: 103 additions & 106 deletions back-end/routes/authentication.js
Original file line number Diff line number Diff line change
@@ -7,126 +7,123 @@ const router = express.Router();

// a route to handle user signup requests to /auth/signup
router.post("/signup", async (req, res, next) => {
console.log("/signup here")
// console.log(`Incoming signup data: ${JSON.stringify(req.body, null, 0)}`)
// grab the username and password from the POST body
const username = req.body.username;
const password = req.body.password;
const topSongs = []
const activity = []
const followers = []
const following = []
// grab the username and password from the POST body
const username = req.body.username;
const password = req.body.password;
const topSongs = [];
const activity = [];
const followers = [];
const following = [];

if (!username || !password) {
// no username or password received in the POST body... send an error
res.status(401).json({
success: false,
message: `No username or password supplied.`,
});
next();
}
if (!username || !password) {
// no username or password received in the POST body... send an error
res.status(401).json({
success: false,
message: `No username or password supplied.`,
});
next();
}

// try to create a new user
try {
const user = await new User({
username,
password,
topSongs,
activity,
followers,
following
}).save();
// user saved successfully... send a success response
console.error(`New user: ${user}`);
const token = user.generateJWT(); // generate a signed token
res.json({
success: true,
message: "User saved successfully.",
token: token,
username: user.username,
}); // send the token to the client to store
next();
} catch (err) {
// error saving user to database... send an error response
console.error(`Failed to save user: ${err}`);
res.status(500).json({
success: false,
message: "Error saving user to database.",
error: err,
});
next();
}
// try to create a new user
try {
const user = await new User({
username,
password,
topSongs,
activity,
followers,
following,
}).save();
// user saved successfully... send a success response
console.error(`New user: ${user}`);
const token = user.generateJWT(); // generate a signed token
res.json({
success: true,
message: "User saved successfully.",
token: token,
username: user.username,
}); // send the token to the client to store
next();
} catch (err) {
// error saving user to database... send an error response
console.error(`Failed to save user: ${err}`);
res.status(500).json({
success: false,
message: "Error saving user to database.",
error: err,
});
next();
}
});

// a route to handle login attempts requested to /auth/login
router.post("/login", async function (req, res, next) {
// grab the name and password that were submitted as POST body data
const username = req.body.username;
const password = req.body.password;
// console.log(`${username}, ${password}`)
// grab the name and password that were submitted as POST body data
const username = req.body.username;
const password = req.body.password;
// console.log(`${username}, ${password}`)

if (!username || !password) {
// no username or password received in the POST body... send an error
res
.status(401)
.json({ success: false, message: `No username or password supplied.` });
next();
}
if (!username || !password) {
// no username or password received in the POST body... send an error
res
.status(401)
.json({ success: false, message: `No username or password supplied.` });
next();
}

// find this user in the database
try {
const user = await User.findOne({ username: username }).exec();
// check if user was found
if (!user) {
console.error(`User not found.`);
res.status(401).json({
success: false,
message: "User not found in database.",
});
next();
}
// if user exists, check if password is correct
else if (!user.validPassword(password)) {
console.error(`Incorrect password.`);
res.status(401).json({
success: false,
message: "Incorrect password.",
});
next();
}
// user found and password is correct... send a success response
else {
console.log("User logged in successfully.");
const token = user.generateJWT(); // generate a signed token
res.json({
success: true,
message: "User logged in successfully.",
token: token,
username: user.username,
}); // send the token to the client to store
next();
}
} catch (err) {
// check error
console.error(`Error looking up user: ${err}`);
res.status(500).json({
// find this user in the database
try {
const user = await User.findOne({ username: username }).exec();
// check if user was found
if (!user) {
console.error(`User not found.`);
res.status(401).json({
success: false,
message: "User not found in database.",
});
next();
}
// if user exists, check if password is correct
else if (!user.validPassword(password)) {
console.error(`Incorrect password.`);
res.status(401).json({
success: false,
message: "Error looking up user in database.",
error: err,
});
next();
message: "Incorrect password.",
});
next();
}
// user found and password is correct... send a success response
else {
const token = user.generateJWT(); // generate a signed token
res.json({
success: true,
message: "User logged in successfully.",
token: token,
username: user.username,
}); // send the token to the client to store
next();
}
} catch (err) {
// check error
console.error(`Error looking up user: ${err}`);
res.status(500).json({
success: false,
message: "Error looking up user in database.",
error: err,
});
next();
}
});

// a route to handle logging out requests to /auth/logout
router.get("/logout", function (req, res, next) {
// nothing really to do here... logging out with JWT authentication is handled entirely by the front-end by deleting the token from the browser's memory
res.json({
success: true,
message:
"There is actually nothing to do on the server side... you simply need to delete your token from the browser's local storage!",
});
next();
// nothing really to do here... logging out with JWT authentication is handled entirely by the front-end by deleting the token from the browser's memory
res.json({
success: true,
message:
"There is actually nothing to do on the server side... you simply need to delete your token from the browser's local storage!",
});
next();
});

// export the router
61 changes: 32 additions & 29 deletions back-end/routes/comment.js
Original file line number Diff line number Diff line change
@@ -3,48 +3,51 @@ const axios = require("axios"); // middleware for making requests to APIs
const router = express.Router();
const Song = require("../models/song");
const User = require("../models/user");
const mongoose = require('mongoose');
const mongoose = require("mongoose");
require("dotenv").config();

mongoose.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});


router.post('/comments/:songArtist/:songTitle/:username/save', async (req, res) => {
try {
const song = await Song.findOne({title: req.params.songName, artist: req.params.songArtist});
const newComment = {
router.post(
"/comments/:songArtist/:songTitle/:username/save",
async (req, res) => {
try {
const song = await Song.findOne({
title: req.params.songName,
artist: req.params.songArtist,
});
const newComment = {
username: req.body.username,
comment: req.body.comment,
};
const post = song.posts.username(username);
post.comments.push(newComment);
await song.save();
res.json(newComment);
} catch (error) {
console.error("Error adding comment:", error);
res.status(500).json({ error: "Internal Server Error" });
}
const post = song.posts.username(username);
console.log(song.posts.username);
post.comments.push(newComment);
console.log(post.comments);
await song.save();
res.json(newComment);
}
catch (error) {
console.error("Error adding comment:", error);
res.status(500).json({error: "Internal Server Error"});
}
});
);

router.get('/comments/:songArtist/:songTitle/:username', async(req, res) => {
const song = await Song.findOne({title: req.params.songTitle, artist: req.params.songArtist});
router.get("/comments/:songArtist/:songTitle/:username", async (req, res) => {
const song = await Song.findOne({
title: req.params.songTitle,
artist: req.params.songArtist,
});

if (song) {
const commentData = {
comments: song.posts.comments
}
console.log(commentData);
res.json(commentData);
}
else {
res.status(500).json({"Song not found": err});
}
if (song) {
const commentData = {
comments: song.posts.comments,
};
res.json(commentData);
} else {
res.status(500).json({ "Song not found": err });
}
});

module.exports = router;
3 changes: 0 additions & 3 deletions back-end/routes/homePage.js
Original file line number Diff line number Diff line change
@@ -14,8 +14,6 @@ router.post("/", (req, res) => {
User.find({ _id: { $in: following } }, "activity")
.then((users) => {
const activities = users.map((userP) => userP.activity).flat();
console.log("here");
console.log(users);
return res.json(activities);
})
.catch((err) => {
@@ -32,5 +30,4 @@ router.post("/", (req, res) => {
});
});


module.exports = router;
5 changes: 0 additions & 5 deletions back-end/routes/myProfile.js
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@ router.get("/:username", async (req, res) => {
User.findOne({ username: user_to_find })
.then((user) => {
if (user) {
console.log(user);
res.json(user);
} else {
res.send("User not found");
@@ -32,17 +31,13 @@ router.post("/save", async (req, res) => {
const passwordChange = req.body.passwordChange;

const alreadyExists = await User.findOne({ username: usernameChange });
console.log(alreadyExists);
if (alreadyExists != null) {
console.log("here");
return res.status(409).json({
msg: "This username already exists",
});
}
console.log("AFter");
const user = await User.findOne({ username: username });
if (!user) {
console.log("User not found");
return res.status(404).json({
newUser: usernameChange,
msg: "User not found",
58 changes: 31 additions & 27 deletions back-end/routes/postRoute.js
Original file line number Diff line number Diff line change
@@ -7,54 +7,58 @@ const User = require("../models/user.js");

router.post("/:songArtist/:songTitle/:username/save", async (req, res) => {
try {
const song = await Song.findOne({title: req.params.songTitle, artist: req.params.songArtist});
const song = await Song.findOne({
title: req.params.songTitle,
artist: req.params.songArtist,
});
// check if song has a post from username
const post = song.posts.find(post => post.username == req.params.username)
const post = song.posts.find(
(post) => post.username == req.params.username
);
// if post exists, add comment to post
if (post) {
const newComment = {
username: req.body.username,
comment: req.body.comment
}
post.comments.push(newComment)
await song.save()
console.log(post)
res.json(newComment)
comment: req.body.comment,
};
post.comments.push(newComment);
await song.save();
res.json(newComment);
}
// otherwise, send 404
else{
res.status(404).send("Post not found")
else {
res.status(404).send("Post not found");
}
} catch (err) {
res.status(500).json({ "Error retrieving post": err });
}
catch (err) {
res.status(500).json({"Error retrieving post": err})
}
})
});

router.get("/:songArtist/:songTitle/:username", async (req, res) => {
try {
const song = await Song.findOne({title: req.params.songTitle, artist: req.params.songArtist});
console.log("song: ", song);
const song = await Song.findOne({
title: req.params.songTitle,
artist: req.params.songArtist,
});

// check if song has a post from username
const post = song.posts.find(post => post.username == req.params.username)
console.log("post: ", post);
const post = song.posts.find(
(post) => post.username == req.params.username
);
// if post exists, send song and post
if (post && song) {
res.json({
song: song,
post: post
})
post: post,
});
}
// otherwise, send 404
else{
res.status(404).send("Post not found")
else {
res.status(404).send("Post not found");
}
}
catch (err) {
res.status(500).json({"Error retrieving post": err})
} catch (err) {
res.status(500).json({ "Error retrieving post": err });
}
});


module.exports = router;
module.exports = router;
4 changes: 0 additions & 4 deletions back-end/routes/song.js
Original file line number Diff line number Diff line change
@@ -46,17 +46,13 @@ router.post("/:songArtist/:songTitle/save", async (req, res) => {

song.posts.push(newPost);
song.numReviews++;
console.log("before" + song.rating);

song.rating = (
(song.rating * (song.numReviews - 1) + newPost.rating) /
song.numReviews
).toFixed(1);

console.log("after" + song.rating);

await song.save();
console.log("AFTER AWAIT");
res.json(newPost);
} catch (err) {
console.error("Error posting song review:", err);
50 changes: 23 additions & 27 deletions back-end/routes/viewFollowersRoute.js
Original file line number Diff line number Diff line change
@@ -12,33 +12,29 @@ mongoose.connect(process.env.MONGODB_URI, {

// user requests
router.get("/view-followers/:userId", async (req, res) => {
const user_to_find = req.params.userId;

User.findOne({ username: user_to_find })
.then(async (user) => {
if (user) {
// Display the user information
//console.log("usernames", user.followers);
const followersData = await Promise.all(
user.followers.map(async (follower) => {
const userData = await User.findById(follower._id);
return {
username: userData.username,
};
})
)
//console.log("followersData", followersData);
res.json(followersData);
} else {
res.send("User not found");
}
})
.catch((error) => {
console.error("Error finding user:", error);
res.status(500).send("Internal Server Error");
});
});

const user_to_find = req.params.userId;

User.findOne({ username: user_to_find })
.then(async (user) => {
if (user) {
// Display the user information
const followersData = await Promise.all(
user.followers.map(async (follower) => {
const userData = await User.findById(follower._id);
return {
username: userData.username,
};
})
);
res.json(followersData);
} else {
res.send("User not found");
}
})
.catch((error) => {
console.error("Error finding user:", error);
res.status(500).send("Internal Server Error");
});
});

module.exports = router;
117 changes: 66 additions & 51 deletions front-end/src/components/Comment.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,87 @@
import {useState, useEffect} from 'react';
import {useParams} from 'react-router-dom';
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { useAuthContext } from "./AuthProvider.js";
import axios from 'axios';
import '../css/Comments.css';
import CommentPostForm from './CommentPostForm.js';
import CommentPost from './CommentPost.js';

import axios from "axios";
import "../css/Comments.css";
import CommentPostForm from "./CommentPostForm.js";
import CommentPost from "./CommentPost.js";

function Comment() {
const username = useAuthContext().user;
const [comments, setComments] = useState('');
const {songArtist, songTitle} = useParams();
const [comments, setComments] = useState("");
const { songArtist, songTitle } = useParams();
const [showForm, setShowForm] = useState(true);
const addCommentToList = comment => {
const newComments = [comment, ...comments]
setComments(newComments)
}
const addCommentToList = (comment) => {
const newComments = [comment, ...comments];
setComments(newComments);
};

useEffect(() => {
axios
.get(`http://localhost:3000/comments/${songArtist}/${songTitle}/${username}`)
.then(response => {
.get(
`http://localhost:3000/comments/${songArtist}/${songTitle}/${username}`
)
.then((response) => {
const comments = response.data;
console.log(comments);
setComments(comments);
})
.catch(err => {
console.log("Error fetching data:", err)
})
}, [songArtist, songTitle, username])
.catch((err) => {
console.log("Error fetching data:", err);
});
}, [songArtist, songTitle, username]);

useEffect(() => {
console.log(comments);
comments.localeCompare((comment) => {
if (comment.username === username) {
setShowForm(false)
setShowForm(false);
}
})
}, [comments])
});
}, [comments]);

if (comments) {
return (
<div className="Comment">
{showForm &&
<>
<h3>Add Comment:</h3>
<CommentPostForm setShowForm={setShowForm} addCommentToList={addCommentToList} songArtist={songArtist} songTitle={songTitle} username={username}/>
</>
}
<h3>Other comments:</h3>
if (comments) {
return (
<div className="Comment">
{showForm && (
<>
<h3>Add Comment:</h3>
<CommentPostForm
setShowForm={setShowForm}
addCommentToList={addCommentToList}
songArtist={songArtist}
songTitle={songTitle}
username={username}
/>
</>
)}
<h3>Other comments:</h3>
{comments.map((comment, i) => (
<CommentPost key={i} comment={comment} songArtist={songArtist} songTitle={songTitle} username={username}/>
<CommentPost
key={i}
comment={comment}
songArtist={songArtist}
songTitle={songTitle}
username={username}
/>
))}
</div>
);
}
else {
return (
<div className="Comment">
{showForm &&
<>
<CommentPostForm setShowForm={setShowForm} addCommentToList={addCommentToList} songArtist={songArtist} songTitle={songTitle} username={username}/>
</>
}
</div>
);
</div>
);
} else {
return (
<div className="Comment">
{showForm && (
<>
<CommentPostForm
setShowForm={setShowForm}
addCommentToList={addCommentToList}
songArtist={songArtist}
songTitle={songTitle}
username={username}
/>
</>
)}
</div>
);
}
}

};

export default Comment;
export default Comment;
75 changes: 39 additions & 36 deletions front-end/src/components/CommentPostForm.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,55 @@
import { useState } from 'react'
import axios from 'axios'
import { useState } from "react";
import axios from "axios";
import { useAuthContext } from "./AuthProvider.js";

const CommentPostForm = ({setShowForm, addCommentToList, songArtist, songTitle}) => {
const username = useAuthContext().user
const CommentPostForm = ({
setShowForm,
addCommentToList,
songArtist,
songTitle,
}) => {
const username = useAuthContext().user;
// create a state variable for each form field
const [comment, setComment] = useState('')

const submitForm = e => {
e.preventDefault() // prevent normal browser submit behavior
console.log("username", username)
console.log("comment", comment)

const [comment, setComment] = useState("");

const submitForm = (e) => {
e.preventDefault(); // prevent normal browser submit behavior
// send data to server... getting server host name from .env environment variables file to make it easy to swap server hosts in one place
axios
.post(`http://localhost:3000/comment/${songArtist}/${songTitle}/${username}/save`, {
username: username,
comment: comment,
})
.then(response => {
addCommentToList(response.data)
})
.catch(err => {
console.log("Error posting data:", err)
.post(
`http://localhost:3000/comment/${songArtist}/${songTitle}/${username}/save`,
{
username: username,
comment: comment,
}
)
.then((response) => {
addCommentToList(response.data);
})
.catch((err) => {
console.log("Error posting data:", err);
});

// clear form
setShowForm(false)
}
setShowForm(false);
};

return (
<form className="CommentForm" onSubmit={submitForm}>
<label for="comment">Add Comment: </label>
<textarea
id="song-comment"
value={comment}
name="song-comment"
onChange={(e) => setComment(e.target.value)}
placeholder="Enter a comment"
rows="10"
/>
<div class="button">
<input type="submit" disabled={!comment} value="Enter"/>
</div>
<textarea
id="song-comment"
value={comment}
name="song-comment"
onChange={(e) => setComment(e.target.value)}
placeholder="Enter a comment"
rows="10"
/>
<div class="button">
<input type="submit" disabled={!comment} value="Enter" />
</div>
</form>
)
}
);
};

export default CommentPostForm;

47 changes: 21 additions & 26 deletions front-end/src/components/LogIn.js
Original file line number Diff line number Diff line change
@@ -2,58 +2,53 @@ import { useState, useEffect } from "react";
import { Link, Navigate } from "react-router-dom";
import axios from "axios";
import "../css/LogIn.css";
import {useSearchParams} from 'react-router-dom';
import { useSearchParams } from "react-router-dom";
import Nav from "./Nav";

const Login = props => {
let [urlSearchParams] = useSearchParams() // get access to the URL query string parameters
const Login = (props) => {
let [urlSearchParams] = useSearchParams(); // get access to the URL query string parameters

// create state variables to hold username and password
const [response, setResponse] = useState({}) // the API will return an object with a JWT token, if the user logs in successfully
const [errorMessage, setErrorMessage] = useState("")
const [response, setResponse] = useState({}); // the API will return an object with a JWT token, if the user logs in successfully
const [errorMessage, setErrorMessage] = useState("");

// if the user got here by trying to access our Protected page, there will be a query string parameter called 'error' with the value 'protected'
useEffect(() => {
const qsError = urlSearchParams.get("error") // get any 'error' field in the URL query string
if (qsError === "protected")
setErrorMessage("Please log in first!")
}, [])
const qsError = urlSearchParams.get("error"); // get any 'error' field in the URL query string
if (qsError === "protected") setErrorMessage("Please log in first!");
}, []);

// if the user's logged-in status changes, save the token we receive from the server
useEffect(() => {
// if the user is logged-in, save the token to local storage
if (response.success && response.token) {
console.log(`User successfully logged in: ${response.username}`)
localStorage.setItem("token", response.token) // store the token into localStorage
localStorage.setItem("token", response.token); // store the token into localStorage
}
}, [response])
}, [response]);

// what to do when the user clicks the submit buton on the form
const handleSubmit = async e => {
const handleSubmit = async (e) => {
// prevent the HTML form from actually submitting... we use React's javascript code instead
e.preventDefault()
e.preventDefault();

try {
// create an object with the data we want to send to the server
const requestData = {
username: e.target.username.value, // gets the value of the field in the submitted form with name='username'
password: e.target.password.value, // gets the value of the field in the submitted form with name='password',
}
};
// send a POST request with the data to the server api to authenticate
const response = await axios.post(
`http://localhost:3000/auth/login`,
requestData
)
);
// store the response data into the data state variable
console.log(`Server response: ${JSON.stringify(response.data, null, 0)}`)
setResponse(response.data)
setResponse(response.data);
} catch (err) {
// request failed... user entered invalid credentials
setErrorMessage(
"You entered invalid credentials."
)
setErrorMessage("You entered invalid credentials.");
}
}
};

// if the user is not logged in, show the login form
if (!response.success)
@@ -96,10 +91,10 @@ const Login = props => {
</div>
<Nav isLoggedIn={false} />
</>
)
);
// otherwise, if the user has successfully logged-in, redirect them to a different page
// in this example, we simply redirect to the home page, but a real app would redirect to a page that shows content only available to logged-in users
else return <Navigate to="/" />
}
else return <Navigate to="/" />;
};

export default Login
export default Login;
4 changes: 0 additions & 4 deletions front-end/src/components/OtherUserProfile.js
Original file line number Diff line number Diff line change
@@ -36,7 +36,6 @@ function OtherUserProfile() {
const [followStatus, setFollowStatus] = useState();

useEffect(() => {
console.log("UserID: ", userId);
axios
.get(`http://localhost:3000/other-user/${userId}`)
.then((res) => {
@@ -60,8 +59,6 @@ function OtherUserProfile() {
})
.then((res) => {
setFollowStatus(res.data.status);
console.log("HERE");
console.log(res.data.status);
});
}
}, [currentuser]);
@@ -76,7 +73,6 @@ function OtherUserProfile() {
status: followStatus,
})
.then((res) => {
console.log(res.data.status);
setFollowStatus(res.data.status);
});
} catch (err) {}
3 changes: 0 additions & 3 deletions front-end/src/components/Post.js
Original file line number Diff line number Diff line change
@@ -46,13 +46,10 @@ function Post() {
.get(`http://localhost:3000/post/${songArtist}/${songTitle}/${username}`)
.then((response) => {
setSong(response.data.song);
console.log("song", song);
setPost(response.data.post);
console.log("post", post);

if (response.data.post.comments) {
setComments([...response.data.post.comments]);
console.log("set comments");
}
})
.catch((err) => {
35 changes: 17 additions & 18 deletions front-end/src/components/Protected.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React, { useState, useEffect } from "react"
import { Navigate } from "react-router-dom"
import axios from "axios"
import React, { useState, useEffect } from "react";
import { Navigate } from "react-router-dom";
import axios from "axios";

const Protected = props => {
const jwtToken = localStorage.getItem("token") // the JWT token, if we have already received one and stored it in localStorage
console.log(`JWT token: ${jwtToken}`) // debugging
const Protected = (props) => {
const jwtToken = localStorage.getItem("token"); // the JWT token, if we have already received one and stored it in localStorage

const [response, setResponse] = useState({}) // we expect the server to send us a simple object in this case
const [isLoggedIn, setIsLoggedIn] = useState(jwtToken && true) // if we already have a JWT token in local storage, set this to true, otherwise false
const [response, setResponse] = useState({}); // we expect the server to send us a simple object in this case
const [isLoggedIn, setIsLoggedIn] = useState(jwtToken && true); // if we already have a JWT token in local storage, set this to true, otherwise false

// try to load the protected data from the server when this component first renders
useEffect(() => {
@@ -16,16 +15,16 @@ const Protected = props => {
.get(`${process.env.REACT_APP_BACKEND}/protected/`, {
headers: { Authorization: `JWT ${jwtToken}` }, // pass the token, if any, to the server
})
.then(res => {
setResponse(res.data) // store the response data
.then((res) => {
setResponse(res.data); // store the response data
})
.catch(err => {
.catch((err) => {
console.log(
"The server rejected the request for this protected resource... we probably do not have a valid JWT token."
)
setIsLoggedIn(false) // update this state variable, so the component re-renders
})
}, []) // eslint-disable-line react-hooks/exhaustive-deps
);
setIsLoggedIn(false); // update this state variable, so the component re-renders
});
}, []); // eslint-disable-line react-hooks/exhaustive-deps

return (
<>
@@ -47,7 +46,7 @@ const Protected = props => {
<Navigate to="/login?error=protected" />
)}
</>
)
}
);
};

export default Protected
export default Protected;
23 changes: 11 additions & 12 deletions front-end/src/components/Search.js
Original file line number Diff line number Diff line change
@@ -2,13 +2,13 @@ import React, { useState, useEffect } from "react";
import axios from "axios";
import FeedComponent from "./FeedComponent";
import "../css/Search.css";
import Nav from './Nav';
import Nav from "./Nav";

export default function Search() {
const jwtToken = localStorage.getItem("token") // the JWT token, if we have already received one and stored it in localStorage
const jwtToken = localStorage.getItem("token"); // the JWT token, if we have already received one and stored it in localStorage

const [response, setResponse] = useState({}) // we expect the server to send us a simple object in this case
const [isLoggedIn, setIsLoggedIn] = useState(jwtToken && true) // if we already have a JWT token in local storage, set this to true, otherwise false
const [response, setResponse] = useState({}); // we expect the server to send us a simple object in this case
const [isLoggedIn, setIsLoggedIn] = useState(jwtToken && true); // if we already have a JWT token in local storage, set this to true, otherwise false

// try to load the protected data from the server when this component first renders
useEffect(() => {
@@ -17,16 +17,16 @@ export default function Search() {
.get(`http://localhost:3000/protected`, {
headers: { Authorization: `JWT ${jwtToken}` }, // pass the token, if any, to the server
})
.then(res => {
setResponse(res.data) // store the response data
.then((res) => {
setResponse(res.data); // store the response data
})
.catch(err => {
.catch((err) => {
console.log(
"The server rejected the request for this protected resource... we probably do not have a valid JWT token."
)
setIsLoggedIn(false) // update this state variable, so the component re-renders
})
}, []) // eslint-disable-line react-hooks/exhaustive-deps
);
setIsLoggedIn(false); // update this state variable, so the component re-renders
});
}, []); // eslint-disable-line react-hooks/exhaustive-deps

const [search, setSearch] = useState("");
const [data, setData] = useState([]);
@@ -51,7 +51,6 @@ export default function Search() {
`http://localhost:3000/search/artist?query=${search}`
);
const res = response.data.tracks;
console.log(res);
const tracksData = res.map((track, index) => {
return {
artistName: track.artist,
2 changes: 0 additions & 2 deletions front-end/src/components/Settings.js
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@ function Settings() {
const [username, setUsername] = useState("");
const [message, setMessage] = useState("");
const jwtToken = localStorage.getItem("token"); // the JWT token, if we have already received one and stored it in localStorage
// console.log(`JWT token: ${jwtToken}`); // debugging

const [response, setResponse] = useState({}); // we expect the server to send us a simple object in this case
const [isLoggedIn, setIsLoggedIn] = useState(jwtToken && true); // if we already have a JWT token in local storage, set this to true, otherwise false
@@ -73,7 +72,6 @@ function Settings() {
} catch (error) {
if (error.response.status === 409) {
setMessage(error.response.data.msg);
console.log(error);
setUsernameChange("");
setPasswordChange("");
} else {
11 changes: 3 additions & 8 deletions front-end/src/components/SignUp.js
Original file line number Diff line number Diff line change
@@ -4,8 +4,7 @@ import axios from "axios";
import "../css/SignUp.css";
import Nav from "./Nav";


const SignUp = props => {
const SignUp = (props) => {
// create state variables to hold username and password
const [response, setResponse] = useState({}); // the API will return an object with a JWT token, if the user logs in successfully
const [errorMessage, setErrorMessage] = useState("");
@@ -14,13 +13,12 @@ const SignUp = props => {
useEffect(() => {
// if the user is logged-in, save the token to local storage
if (response.success && response.token) {
console.log(`User successfully logged in: ${response.username}`);
localStorage.setItem("token", response.token); // store the token into localStorage
}
}, [response]);

// what to do when the user clicks the submit buton on the form
const handleSubmit = async e => {
const handleSubmit = async (e) => {
// prevent the HTML form from actually submitting... we use React's javascript code instead
e.preventDefault();

@@ -36,13 +34,10 @@ const SignUp = props => {
requestData
);
// store the response data into s the data state variable
console.log(`Server response: ${JSON.stringify(response.data, null, 0)}`);
setResponse(response.data);
} catch (err) {
// request failed... user entered invalid credentials
setErrorMessage(
"The username or password you entered are not valid."
);
setErrorMessage("The username or password you entered are not valid.");
}
};

109 changes: 62 additions & 47 deletions front-end/src/components/Song.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import {useState, useEffect} from 'react';
import {useParams} from 'react-router-dom';
import axios from 'axios';
import '../css/Song.css';
import SongPostForm from './SongPostForm.js';
import SongPost from './SongPost.js';
import Nav from './Nav';
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";
import "../css/Song.css";
import SongPostForm from "./SongPostForm.js";
import SongPost from "./SongPost.js";
import Nav from "./Nav";

function Song() {
const [username, setUsername] = useState("");
const jwtToken = localStorage.getItem("token") // the JWT token, if we have already received one and stored it in localStorage
const jwtToken = localStorage.getItem("token"); // the JWT token, if we have already received one and stored it in localStorage

const [response, setResponse] = useState({}) // we expect the server to send us a simple object in this case
const [isLoggedIn, setIsLoggedIn] = useState(jwtToken && true) // if we already have a JWT token in local storage, set this to true, otherwise false
const [response, setResponse] = useState({}); // we expect the server to send us a simple object in this case
const [isLoggedIn, setIsLoggedIn] = useState(jwtToken && true); // if we already have a JWT token in local storage, set this to true, otherwise false

// try to load the protected data from the server when this component first renders
useEffect(() => {
@@ -20,70 +20,85 @@ function Song() {
.get(`http://localhost:3000/protected`, {
headers: { Authorization: `JWT ${jwtToken}` }, // pass the token, if any, to the server
})
.then(res => {
setResponse(res.data) // store the response data
setUsername(res.data.user.username)
.then((res) => {
setResponse(res.data); // store the response data
setUsername(res.data.user.username);
})
.catch(err => {
.catch((err) => {
console.log(
"The server rejected the request for this protected resource... we probably do not have a valid JWT token."
)
setIsLoggedIn(false) // update this state variable, so the component re-renders
})
}, []) // eslint-disable-line react-hooks/exhaustive-deps
);
setIsLoggedIn(false); // update this state variable, so the component re-renders
});
}, []); // eslint-disable-line react-hooks/exhaustive-deps

const {songArtist, songTitle} = useParams()
const [song, setSong] = useState([])
const [posts, setPosts] = useState([])
const [showForm, setShowForm] = useState(true)
const addPostToList = post => {
const newPosts = [post, ...posts]
setPosts(newPosts)
}
const { songArtist, songTitle } = useParams();
const [song, setSong] = useState([]);
const [posts, setPosts] = useState([]);
const [showForm, setShowForm] = useState(true);
const addPostToList = (post) => {
const newPosts = [post, ...posts];
setPosts(newPosts);
};
//fetch info about song
useEffect(() => {
axios
.get(`http://localhost:3000/song/${songArtist}/${songTitle}`)
.then(response => {
const song = response.data
setSong(song)
setPosts([...song.posts])
// console.log("username: ", username)
})
.catch(err => {
console.log("Error fetching data:", err)
.then((response) => {
const song = response.data;
setSong(song);
setPosts([...song.posts]);
})
}, [songArtist, songTitle])
.catch((err) => {
console.log("Error fetching data:", err);
});
}, [songArtist, songTitle]);
//check if username already posted review, if so remove post form
useEffect(() => {
posts.map((post) => {
if (post.username === username) {
setShowForm(false)
setShowForm(false);
}
})
}, [username, posts])
});
}, [username, posts]);

return (
<>
<div className="Song">
<h2>{song.artist} - {song.title}</h2>
<h2>
{song.artist} - {song.title}
</h2>
<img src={song.coverSrc} alt="album cover" />
<p>{song.rating}/10</p>
{song.numReviews === 1? <p>{song.numReviews} review</p>:<p>{song.numReviews} reviews</p>}
{isLoggedIn && showForm &&
{song.numReviews === 1 ? (
<p>{song.numReviews} review</p>
) : (
<p>{song.numReviews} reviews</p>
)}
{isLoggedIn && showForm && (
<>
<h3>Review:</h3>
<SongPostForm setShowForm={setShowForm} addPostToList={addPostToList} songArtist={songArtist} songTitle={songTitle} />
<SongPostForm
setShowForm={setShowForm}
addPostToList={addPostToList}
songArtist={songArtist}
songTitle={songTitle}
/>
</>
}
)}
<h3>Other reviews:</h3>
{posts.map((post, i) => (
<SongPost key={i} post={post} songArtist={songArtist} songTitle={songTitle}/>
))}
{posts.map((post, i) => (
<SongPost
key={i}
post={post}
songArtist={songArtist}
songTitle={songTitle}
/>
))}
</div>
<Nav isLoggedIn={isLoggedIn} />
</>
);
}

export default Song;
export default Song;
8 changes: 6 additions & 2 deletions front-end/src/components/SongPostForm.js
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@ const SongPostForm = ({
}) => {
const [username, setUsername] = useState("");
const jwtToken = localStorage.getItem("token"); // the JWT token, if we have already received one and stored it in localStorage
// console.log(`JWT token: ${jwtToken}`) // debugging

const [response, setResponse] = useState({}); // we expect the server to send us a simple object in this case
const [isLoggedIn, setIsLoggedIn] = useState(jwtToken && true); // if we already have a JWT token in local storage, set this to true, otherwise false
@@ -78,7 +77,12 @@ const SongPostForm = ({
value={review}
/>
<br />
<input id="button" type="submit" disabled={!rating || !review} value="POST" />
<input
id="button"
type="submit"
disabled={!rating || !review}
value="POST"
/>
</form>
);
};
5 changes: 1 addition & 4 deletions front-end/src/components/ViewFollowers.js
Original file line number Diff line number Diff line change
@@ -34,16 +34,13 @@ function ViewFollowers() {
.get(`http://localhost:3000/view-followers/${userId}`)
.then((response) => {
setFollowers(response.data);
console.log("followers", response.data);
})
.catch((err) => {
console.log("Error fetching data:", err);
});
}, [userId]);

useEffect(() => {
console.log("set followers", userFollowers);
}, [userFollowers]);
useEffect(() => {}, [userFollowers]);

if (!userFollowers || userFollowers.length === 0) {
return (
1 change: 0 additions & 1 deletion front-end/src/components/ViewFollowing.js
Original file line number Diff line number Diff line change
@@ -34,7 +34,6 @@ function ViewFollowing() {
.get(`http://localhost:3000/view-following/${userId}`)
.then((response) => {
setFollowing(response.data);
console.log("following", userFollowing);
})
.catch((err) => {
console.log("Error fetching data:", err);

0 comments on commit 2eb5ee1

Please sign in to comment.