Search
This commit is contained in:
@@ -40,6 +40,7 @@ a {
|
||||
color: white;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
margin-top: 4px;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
@@ -200,8 +201,17 @@ tr:nth-child(odd) {
|
||||
|
||||
h2 {
|
||||
color: #ffffff;
|
||||
font: 16px "Verdana";
|
||||
font-size: 32px;
|
||||
font: 32px "Verdana";
|
||||
margin: 0;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #CCCCCC;
|
||||
font: 24px "Verdana";
|
||||
margin: 0;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
p {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
export async function postData(url, data, token = null) {
|
||||
const elements = url.split("/");
|
||||
const end = elements[elements.length - 1];
|
||||
|
||||
const res = await fetch(end, token == null ? {
|
||||
console.log("fetching here: " + url);
|
||||
const res = await fetch(url, token == null ? {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(data)
|
||||
@@ -19,7 +17,7 @@ export async function postData(url, data, token = null) {
|
||||
|
||||
if (resultObject.logout === true) {
|
||||
alert("Session expired; please log in again.");
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "/login";
|
||||
return resultObject;
|
||||
}
|
||||
|
||||
@@ -32,13 +30,13 @@ export async function verifyLogin() {
|
||||
token = JSON.stringify(localStorage.getItem("token"));
|
||||
} catch (error) {
|
||||
alert("You are not logged in.");
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "login";
|
||||
console.log("Error encountered: " + error);
|
||||
return false;
|
||||
}
|
||||
if (!token) {
|
||||
alert("You are not logged in.");
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "/login";
|
||||
console.log("Token was null");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ document.getElementById("deleteButton").onclick = async e => {
|
||||
const resultObject = await postData("/delete", { username: true, actor: true }, window.localStorage.getItem("token"));
|
||||
window.localStorage.removeItem("token");
|
||||
alert(resultObject.message);
|
||||
window.location.href = "/login.html"
|
||||
window.location.href = "/login";
|
||||
};
|
||||
|
||||
@@ -7,14 +7,16 @@
|
||||
<body>
|
||||
<div class="center">
|
||||
<h2>Home</h2>
|
||||
<a href="search.html">Search Players</a>
|
||||
<h3 class="user-FirstName">Welcome, %</h3>
|
||||
<a href="/search">Search Players</a>
|
||||
<br>
|
||||
<a href="info.html">Personal Information</a>
|
||||
<a href="/info">Personal Information</a>
|
||||
<br>
|
||||
<button id="logoutButton">Log Out</button>
|
||||
<br>
|
||||
<button id="deleteButton" style="display: none;">Delete Account</button>
|
||||
|
||||
<script type="module" src="variables.js"></script>
|
||||
<script type="module" src="logout.js"></script>
|
||||
<script type="module" src="delete.js"></script>
|
||||
</div>
|
||||
|
||||
@@ -1 +1 @@
|
||||
<meta http-equiv="refresh" content="0; url=login.html">
|
||||
<meta http-equiv="refresh" content="0; url=/login">
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<button type="submit">Update Information</button>
|
||||
</form>
|
||||
|
||||
<a href="home.html">Return Home</a>
|
||||
<a href="/home">Return Home</a>
|
||||
</div>
|
||||
|
||||
<script type="module" src="info.js"></script>
|
||||
|
||||
@@ -6,7 +6,7 @@ const token = window.localStorage.getItem("token");
|
||||
const infoForm = document.getElementById("infoForm");
|
||||
|
||||
async function fetchPersonalInformation() {
|
||||
const userData = await postData("https://project.rochesterx.dev/getInfo", {}, token);
|
||||
const userData = await postData("/getInfo", {}, token);
|
||||
|
||||
console.log(userData);
|
||||
|
||||
@@ -29,8 +29,9 @@ async function updatePersonalInformation(e) {
|
||||
dob: document.getElementById("dobField").value
|
||||
}
|
||||
console.log(userData.dob);
|
||||
const resultObject = await postData("https://project.rochesterx.dev/setInfo", userData, token);
|
||||
const resultObject = await postData("/setInfo", userData, token);
|
||||
alert(resultObject.message);
|
||||
window.localStorage.setItem("token", resultObject.token);
|
||||
}
|
||||
|
||||
infoForm.onsubmit = updatePersonalInformation;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</form>
|
||||
<div class="register">
|
||||
<p>Don't have an account?</p>
|
||||
<a href="register.html" class="link">Register</a>
|
||||
<a href="/register" class="link">Register</a>
|
||||
</div>
|
||||
|
||||
<script type="module" src="login.js"></script>
|
||||
|
||||
@@ -10,7 +10,7 @@ if (loginForm) loginForm.onsubmit = async e => {
|
||||
});
|
||||
alert(resultObject.message);
|
||||
if (resultObject.success) {
|
||||
window.location.href = "home.html"
|
||||
window.location.href = "/home"
|
||||
localStorage.setItem("token", resultObject.token);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,5 +2,5 @@ document.getElementById("logoutButton").onclick = async e => {
|
||||
console.log("here");
|
||||
e.preventDefault();
|
||||
localStorage.removeItem("token");
|
||||
window.location.href = "login.html"
|
||||
window.location.href = "/login"
|
||||
};
|
||||
|
||||
42
public/player.html
Normal file
42
public/player.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title class="attribute-player_name">[Player name]</title>
|
||||
<link rel="stylesheet" href="../assets/css/style.css">
|
||||
<link rel="stylesheet" href="../public/assets/css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="center">
|
||||
<h2 class="attribute-player_name">[Player Name]</h2>
|
||||
|
||||
<table id="table">
|
||||
<thead id="header">
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>ID</td>
|
||||
<td>Salary</td>
|
||||
<td>Team</td>
|
||||
<td>Position</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="results">
|
||||
<tr>
|
||||
<td class="attribute-player_name">[Name]</td>
|
||||
<td class="attribute-player_id">[ID]</td>
|
||||
<td class="attribute-salary format-salary">[Salary]</td>
|
||||
<td class="attribute-team_name">[Team]</td>
|
||||
<td class="attribute-position">[Position]</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p id="nomatch" style="display: none;">No matches found.</p>
|
||||
|
||||
<br>
|
||||
|
||||
<a href="/search">Return to Player Search</a>
|
||||
</div>
|
||||
|
||||
<script type="module" src="/player.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
37
public/player.js
Normal file
37
public/player.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import { postData, verifyLogin } from "./client.js";
|
||||
import { formatSalary } from "./utils.js";
|
||||
|
||||
const searchForm = document.getElementById("searchForm");
|
||||
|
||||
const token = window.localStorage.getItem("token");
|
||||
|
||||
const tableHeader = document.getElementById("header");
|
||||
const tableBody = document.getElementById("results");
|
||||
const table = document.getElementById("table");
|
||||
const nomatch = document.getElementById("nomatch");
|
||||
|
||||
populatePlayerData();
|
||||
|
||||
async function populatePlayerData() {
|
||||
const [, , id] = window.location.pathname.split("/");
|
||||
const result = await postData("/getPlayer", { id: id }, window.localStorage.getItem("token"));
|
||||
if (result.success === false) {
|
||||
console.log("Invalid ID");
|
||||
window.location.href = "/search";
|
||||
return;
|
||||
}
|
||||
|
||||
const player = result.match;
|
||||
for (const [attribute, value] of Object.entries(player)) {
|
||||
console.log(`.attribute-${attribute}`);
|
||||
document.querySelectorAll(`.attribute-${attribute}`).forEach(element => {
|
||||
if (element.classList.contains("format-salary")) {
|
||||
element.textContent = formatSalary(value);
|
||||
return;
|
||||
}
|
||||
element.textContent = value;
|
||||
})
|
||||
};
|
||||
|
||||
console.log(player);
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
</form>
|
||||
<div class="register">
|
||||
<p>Already have an account?</p>
|
||||
<a href="login.html">Login</a>
|
||||
<a href="/login">Login</a>
|
||||
</div>
|
||||
|
||||
<script type="module" src="register.js"></script>
|
||||
|
||||
@@ -4,13 +4,13 @@ const registerForm = document.getElementById("registerForm");
|
||||
|
||||
if (registerForm) registerForm.onsubmit = async e => {
|
||||
e.preventDefault();
|
||||
let resultObject = await postData("http://project.rochesterx.dev/register", {
|
||||
let resultObject = await postData("/register", {
|
||||
username: registerForm.regUser.value,
|
||||
password: registerForm.regPass.value,
|
||||
role: registerForm.regRole.value
|
||||
});
|
||||
alert(resultObject.message);
|
||||
if (resultObject.success === true) {
|
||||
window.location.href = "login.html";
|
||||
window.location.href = "/login";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
<br>
|
||||
|
||||
<a href="home.html">Return Home</a>
|
||||
<a href="/home">Return Home</a>
|
||||
</div>
|
||||
|
||||
<script type="module" src="search.js"></script>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { postData, verifyLogin } from "./client.js";
|
||||
import { formatSalary } from "./utils.js";
|
||||
|
||||
const searchForm = document.getElementById("searchForm");
|
||||
|
||||
@@ -15,7 +16,7 @@ if (searchForm)searchForm.onsubmit = async e => {
|
||||
e.preventDefault();
|
||||
if (!verifyLogin()) return;
|
||||
|
||||
let resultObject = await postData("https://project.rochesterx.dev/getPlayers", {
|
||||
let resultObject = await postData("/getPlayers", {
|
||||
player: document.getElementById("query").value
|
||||
}, token);
|
||||
|
||||
@@ -42,7 +43,7 @@ if (searchForm)searchForm.onsubmit = async e => {
|
||||
//}
|
||||
row.innerHTML = `
|
||||
<td>${player.player_id}</td>
|
||||
<td>${player.player_name}</td>
|
||||
<td><a href="/player/${player.player_id}">${player.player_name}</a></td>
|
||||
<td>${formatSalary(player.salary)}</td>
|
||||
<td>${player.team_name}</td>
|
||||
<td>${player.position}</td>
|
||||
@@ -56,7 +57,6 @@ function updateTableVisibility() {
|
||||
if (!tableBody) return;
|
||||
|
||||
const rows = tableBody.querySelectorAll("tr");
|
||||
console.log(rows);
|
||||
if (rows == null) return;
|
||||
if (rows.length != 0) {
|
||||
table.style.display = "";
|
||||
@@ -64,45 +64,3 @@ function updateTableVisibility() {
|
||||
table.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function formatText(text) {
|
||||
if (text == null) return "—";
|
||||
|
||||
if (typeof(text) === "string") {
|
||||
return text;
|
||||
}
|
||||
else {
|
||||
return "Unknown format";
|
||||
}
|
||||
}
|
||||
function formatSalary(text) {
|
||||
if (text == null) return "—";
|
||||
|
||||
try {
|
||||
var millions = (parseInt(text, 10) / 1000000).toFixed(2);
|
||||
return `$${millions} million`;
|
||||
} catch (e) {
|
||||
return "Unknown format"
|
||||
}
|
||||
|
||||
}
|
||||
function formatDate(date) {
|
||||
if (date == null) return "—";
|
||||
|
||||
if (typeof(date) === "string") {
|
||||
return date.split("T")[0];
|
||||
}
|
||||
else {
|
||||
return "Unknown format";
|
||||
}
|
||||
}
|
||||
function formatDateTime(date) {
|
||||
if (date == null) return "—";
|
||||
|
||||
if (typeof(date) === "string") {
|
||||
return date.split("T")[0] + " at " + date.split("T")[1].split(".")[0];
|
||||
}
|
||||
else {
|
||||
return "Unknown format";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
|
||||
<br>
|
||||
|
||||
<a href="home.html">Return Home</a>
|
||||
<a href="/home">Return Home</a>
|
||||
|
||||
<script type="module" src="sections.js"></script>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { postData, verifyLogin } from "./client.js";
|
||||
|
||||
if (!verifyLogin("professor")) window.location.href = "home.html"
|
||||
if (!verifyLogin("professor")) window.location.href = "/home"
|
||||
|
||||
const sectionsHead = document.querySelector("#sections");
|
||||
|
||||
|
||||
41
public/utils.js
Normal file
41
public/utils.js
Normal file
@@ -0,0 +1,41 @@
|
||||
export function formatText(text) {
|
||||
if (text == null) return "—";
|
||||
|
||||
if (typeof(text) === "string") {
|
||||
return text;
|
||||
}
|
||||
else {
|
||||
return "Unknown format";
|
||||
}
|
||||
}
|
||||
export function formatSalary(text) {
|
||||
if (text == null) return "—";
|
||||
|
||||
try {
|
||||
var millions = (parseInt(text, 10) / 1000000).toFixed(2);
|
||||
return `$${millions} million`;
|
||||
} catch (e) {
|
||||
return "Unknown format"
|
||||
}
|
||||
|
||||
}
|
||||
export function formatDate(date) {
|
||||
if (date == null) return "—";
|
||||
|
||||
if (typeof(date) === "string") {
|
||||
return date.split("T")[0];
|
||||
}
|
||||
else {
|
||||
return "Unknown format";
|
||||
}
|
||||
}
|
||||
export function formatDateTime(date) {
|
||||
if (date == null) return "—";
|
||||
|
||||
if (typeof(date) === "string") {
|
||||
return date.split("T")[0] + " at " + date.split("T")[1].split(".")[0];
|
||||
}
|
||||
else {
|
||||
return "Unknown format";
|
||||
}
|
||||
}
|
||||
17
public/variables.js
Normal file
17
public/variables.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import { postData } from "./client.js";
|
||||
|
||||
populateuserData();
|
||||
async function populateuserData() {
|
||||
const user = await postData("/getInfo", {}, window.localStorage.getItem("token"));
|
||||
|
||||
for (const [attribute, value] of Object.entries(user)) {
|
||||
document.querySelectorAll(`.user-${attribute}`).forEach(element => {
|
||||
if (attribute === "FirstName" && value === "") {
|
||||
var text = element.textContent;
|
||||
element.textContent = text.replace("%", user.Username);
|
||||
}
|
||||
var text = element.textContent;
|
||||
element.textContent = text.replace("%", value);
|
||||
});
|
||||
}
|
||||
}
|
||||
109
server.js
109
server.js
@@ -11,6 +11,13 @@ const dev = process.argv.length > 2 && process.argv[2] == "-dev";
|
||||
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
app.use((req, res, next) =>{
|
||||
if (req.path.endsWith(".html")) {
|
||||
res.redirect(req.path.replace(".html", ""));
|
||||
return;
|
||||
}
|
||||
next();
|
||||
})
|
||||
app.use(express.static("public"))
|
||||
app.use(cors({
|
||||
origin: [
|
||||
@@ -103,11 +110,25 @@ app.post("/getPlayers", authenticate, async (req, res) => {
|
||||
|
||||
const result = await pool.request()
|
||||
.input("query", sql.VarChar, player)
|
||||
.query(`SELECT * FROM [Player, IMPORTANT] WHERE player_name LIKE '%' + @query + '%'`);
|
||||
.query(`SELECT * FROM Player WHERE player_name LIKE '%' + @query + '%'`);
|
||||
|
||||
res.status(200).json({ query: player, matches: result.recordset });
|
||||
});
|
||||
|
||||
app.post("/getPlayer", authenticate, async (req, res) => {
|
||||
const { id } = req.body;
|
||||
|
||||
const result = await pool.request()
|
||||
.input("query", sql.VarChar, id)
|
||||
.query(`SELECT * FROM Player WHERE player_id = @query`);
|
||||
|
||||
if (result.recordset.length !== 1) {
|
||||
res.status(400).json({ success: false })
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, match: result.recordset[0] });
|
||||
});
|
||||
|
||||
app.post("/getInfo", authenticate, async (req, res) => {
|
||||
const userData = req.user;
|
||||
|
||||
@@ -123,54 +144,6 @@ app.post("/getCourses", authenticate, async (req, res) => {
|
||||
res.status(200).json(courses);
|
||||
});
|
||||
|
||||
app.post("/createSection", authenticate, async (req, res) => {
|
||||
let { subject, number, days, startDate, endDate, startTime, endTime, term } = req.body;
|
||||
startTime = new Date("1970-01-01T" + startTime);
|
||||
endTime = new Date("1970-01-01T" + endTime);
|
||||
console.log(req.user);
|
||||
try {
|
||||
await pool.request()
|
||||
.input("subject", sql.VarChar(3), subject)
|
||||
.input("number", sql.Int, number)
|
||||
.input("professor", sql.Int, req.user.Id)
|
||||
.input("term", sql.VarChar(10), term)
|
||||
.input("startDate", sql.Date, startDate)
|
||||
.input("endDate", sql.Date, endDate)
|
||||
.input("startTime", sql.Time(0), startTime)
|
||||
.input("endTime", sql.Time(0), endTime)
|
||||
.input("days", sql.Int, days)
|
||||
.query(`
|
||||
INSERT INTO Sections (
|
||||
Subject,
|
||||
Number,
|
||||
ProfessorID,
|
||||
Term,
|
||||
Days,
|
||||
StartDate,
|
||||
EndDate,
|
||||
StartTime,
|
||||
EndTime
|
||||
) VALUES (
|
||||
@subject,
|
||||
@number,
|
||||
@professor,
|
||||
@term,
|
||||
@days,
|
||||
@startDate,
|
||||
@endDate,
|
||||
@startTime,
|
||||
@endTime
|
||||
)
|
||||
`);
|
||||
} catch (err) {
|
||||
if (err.message.includes("Violation of UNIQUE KEY constraint")) {
|
||||
res.status(500).send({ success: false, message: `Username "${username}" is already taken.` });
|
||||
}
|
||||
res.status(500).send({ success: false, message: err.message });
|
||||
}
|
||||
res.status(200).send({ success: true, message: "Section created successfully."});
|
||||
})
|
||||
|
||||
app.post("/setInfo", authenticate, async (req, res) => {
|
||||
const { firstName, lastName, dob } = req.body;
|
||||
|
||||
@@ -192,7 +165,18 @@ app.post("/setInfo", authenticate, async (req, res) => {
|
||||
res.status(500).json({ message: "Update request failed" })
|
||||
}
|
||||
|
||||
res.status(200).json({ message: "Information updated successfully" });
|
||||
var updatedUser = req.user;
|
||||
updatedUser.FirstName = firstName;
|
||||
updatedUser.LastName = lastName;
|
||||
updatedUser.DOB = dob;
|
||||
|
||||
const token = jwt.sign(updatedUser, JWT_SECRET);
|
||||
console.log("Issued token: " + JSON.stringify(token))
|
||||
res.status(200).send({
|
||||
success: true,
|
||||
message: "Information updated successfully",
|
||||
token
|
||||
});
|
||||
});
|
||||
|
||||
app.post("/delete", authenticate, async (req, res) => {
|
||||
@@ -219,6 +203,7 @@ app.post("/delete", authenticate, async (req, res) => {
|
||||
async function authenticate(req, res, next) {
|
||||
try {
|
||||
const authenticationHeader = req.headers["authorization"];
|
||||
console.log("authenticationheader: " + authenticationHeader);
|
||||
const token = authenticationHeader.split(" ")[1];
|
||||
|
||||
console.log(JSON.stringify(authenticationHeader));
|
||||
@@ -231,10 +216,34 @@ async function authenticate(req, res, next) {
|
||||
console.log(decoded.Username + " authenticated");
|
||||
} catch (error) {
|
||||
console.log("Authentication header missing");
|
||||
console.log(error);
|
||||
res.status(401).json({ message: "You are not logged in", error: error, logout: true });
|
||||
return;
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
app.get("/player/:id", (req, res) => {
|
||||
res.sendFile(__dirname + "/public/player.html");
|
||||
})
|
||||
|
||||
app.get("/search", (req, res) => {
|
||||
res.sendFile(__dirname + "/public/search.html");
|
||||
})
|
||||
|
||||
app.get("/home", (req, res) => {
|
||||
res.sendFile(__dirname + "/public/home.html");
|
||||
})
|
||||
|
||||
app.get("/info", (req, res) => {
|
||||
res.sendFile(__dirname + "/public/info.html");
|
||||
})
|
||||
|
||||
app.get("/register", (req, res) => {
|
||||
res.sendFile(__dirname + "/public/register.html");
|
||||
})
|
||||
|
||||
app.get("/login", (req, res) => {
|
||||
res.sendFile(__dirname + "/public/login.html");
|
||||
})
|
||||
app.listen(serverPort, "0.0.0.0", () => console.log(`Running ${dev ? "dev " : ""}server on port ${serverPort}`));
|
||||
|
||||
Reference in New Issue
Block a user