committed files

This commit is contained in:
dominicjk
2024-04-11 08:36:52 -06:00
8260 changed files with 866980 additions and 243 deletions

View File

@@ -57,6 +57,9 @@ app.set('views', path.join(__dirname, 'views'));
app.use(bodyParser.json()); // specify the usage of JSON for parsing request body.
// initialize session variables
app.get('/welcome', (req, res) => {
res.json({status: 'success', message: 'Welcome!'});
});
app.use(
session({
secret: process.env.SESSION_SECRET,
@@ -82,22 +85,12 @@ app.use(express.static(path.join(__dirname, 'resources')));
Header Scoreboard Routes
*************************/
const fetchMatchesData = require('./resources/js/navigation-bar/scoreboard-header/current-match-routes');
const fetchMatchesData = require('./resources/routes/navigation-bar/current-match-information');
app.use(fetchMatchesData);
const convert_time = require('./resources/js/navigation-bar/scoreboard-header/convert-time');
app.use(convert_time);
/************************
Homepage Routes
*************************/
/* const { app, redirectToLeaguePage } = require('ProjectSourceCode/src/resources/js/homepage/create-league-routes.js');
// Serve static files
app.use(express.static('public')); */
/************************
Login Page Routes
*************************/
@@ -109,7 +102,7 @@ app.get('/', (req, res) => {
// Render login page for /login route
app.get('/login', (req, res) => {
res.render('pages/login');
res.render('pages/home');
});
// Trigger login form to check database for matching username and password
@@ -130,7 +123,7 @@ app.get('/', (req, res) => {
// Check if mathc returns no data
if (!match) {
// Render the login page with the message parameter
return res.render('pages/login', { message: 'Password does not match' });
return res.render('pages/home', { message: 'Password does not match' });
}
// Save user information in the session variable
@@ -155,34 +148,44 @@ app.get('/', (req, res) => {
res.render('pages/register');
});
// Trigger Registration Form to Post
app.post('/register', async (req, res) => {
try {
// Hash the password using bcrypt library
const hash = await bcrypt.hash(req.body.password, 10);
// Insert username and hashed password into the 'users' table
await db.none('INSERT INTO users (username, password) VALUES ($1, $2)', [req.body.username, hash]);
// Direct user to login screen after data has been inserted successfully
res.redirect('/login');
} catch (error) {
// If the insert fails, redirect to GET /register route
res.redirect('/register');
// Trigger Registration Form to Post
app.post('/register', async (req, res) => {
try {
if (!req.body.username || !req.body.password) {
// If username or password is missing, respond with status 400 and an error message
return res.status(400).json({ status: 'error', message: 'Invalid input' });
}
});
// Hash the password using bcrypt library
const hash = await bcrypt.hash(req.body.password, 10);
/************************
Home Page Routes
*************************/
// Insert username and hashed password into the 'users' table
await db.none('INSERT INTO users (username, password) VALUES ($1, $2)', [req.body.username, hash]);
app.get('/home', (req, res) => {
res.render('pages/home');
});
// Redirect user to the login page after successful registration
res.status(200).json({ status: 'success', message: 'Registration successful' });
} catch (error) {
// If an error occurs during registration, respond with status 500 and an error message
res.status(500).json({ status: 'error', message: 'An error occurred during registration' });
}
});
/************************
Home Page Routes
*************************/
app.get('/home', (req, res) => {
res.render('pages/home');
});
// Import and call generateLeagueRoutes function
const generateLeagueRoutes = require('./resources/routes/league-pages/generate-league-routes');
generateLeagueRoutes(app);
// *****************************************************
// <!-- Section 5 : Start Server-->
// *****************************************************
// starting the server and keeping the connection open to listen for more requests
app.listen(3000);
module.exports = app.listen(3000);
console.log('Server is listening on port 3000');

View File

@@ -1,4 +1,12 @@
CREATE TABLE users (
username VARCHAR(50) PRIMARY KEY,
password CHAR(60) NOT NULL
);
UserID SERIAL PRIMARY KEY,
Username VARCHAR(50) UNIQUE NOT NULL,
Password CHAR(60) NOT NULL
);
CREATE TABLE FavoriteTeam (
UserID INT REFERENCES users(UserID) ON DELETE CASCADE ON UPDATE CASCADE,
TeamID INT,
TeamName VARCHAR(50),
PRIMARY KEY (UserID, TeamID)
);

View File

@@ -9,7 +9,6 @@
font-family: 'Scottsdale-Italic';
display: inline-block; /* Ensure the width is based on content */
border-bottom: 1.5px solid #999696; /* Adjust the color and thickness as needed */
}
/* Position cards in the center of the screen */
@@ -24,9 +23,7 @@
width: 500px; /* Set width of the banner to 100% of viewport width */
height: 150px;
margin: 20px;
text-align: center; /* Center the content horizontally */
background: linear-gradient(to right, white, rgb(245, 245, 245), rgb(227, 227, 227)); /* Gradient from white to gray */
padding: 10px; /* Adjust padding as needed */
position: relative; /* Needed for absolute positioning */
@@ -36,21 +33,24 @@
cursor: pointer; /* Change cursor to pointer on hover */
box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.4);
/* Counter skew contents to keep inner content straight*/
#card-contents {
transform: skewX(20deg); /* Counter-skew the content to maintain its appearance */
}
display: flex; /* Use flexbox for layout */
justify-content: center; /* Center content horizontally */
align-items: center; /* Center content vertically */
}
/* Counter skew contents to keep inner content straight*/
#card-contents {
display: flex; /* Use flexbox for layout */
align-items: center; /* Align items vertically */
transform: skewX(20deg); /* Skew the banner to create a triangular side */
}
#league-card:hover {
transform: skewX(-20deg) scale(1.05); /* Increase scale on hover to make it pop */
box-shadow: 0 0 20px rgba(0, 0, 0, 0.3); /* Add box-shadow on hover for depth effect */
}
#league-card::after {
content: '';
position: absolute;
@@ -60,3 +60,22 @@
width: 1%; /* Width of the red strip */
background-color: red; /* Red color */
}
#logo {
width: 30%; /* Set width for logo */
max-height: 100px;
max-width: 100px;
margin-right: 20px;
}
.title-wrapper {
width: 70%; /* Set width for title wrapper */
}
#title-logo {
max-height: 80px;
max-width: 250px;
}

View File

@@ -0,0 +1,28 @@
#league-page-body {
display: flex;
flex-direction: column;
height: 100vh;
}
#league-information-container {
height: 100px;
background-color: #f0f0f0; /* Example background color */
/* Add any other styling you need for the league information container */
}
#league-stats-container {
display: flex;
flex: 1;
}
#league-table-container {
flex: 1;
background-color: #eaeaea; /* Example background color */
/* Add any other styling you need for the league table container */
}
#top-scorers-container {
flex: 1;
background-color: #dcdcdc; /* Example background color */
/* Add any other styling you need for the top scorers container */
}

View File

@@ -1,10 +1,14 @@
#login-container {
display: none;
}
#login-page {
width: 400px;
height: fit-content;
position: absolute;
top: 150px; /* Adjust this value as needed */
right: 20px; /* Adjust this value as needed */
z-index: 10;
z-index: 5;
background: linear-gradient(to bottom, white, rgb(245, 245, 245), rgb(227, 227, 227)); /* Gradient from white to gray */
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.5);
border: 1px solid gray;

View File

@@ -35,6 +35,7 @@
#user {
width: 25px;
cursor: pointer;
transition: width 0.3s ease; /* Adding transition for smooth effect */
}

View File

@@ -1,5 +1,6 @@
.scoreboard-container {
overflow-x: auto; /* Enable horizontal scrolling */
overflow-y: hidden; /* Disable vertical scrolling */
white-space: nowrap; /* Prevent cards from wrapping to the next line */
border: 1px solid rgb(202, 2, 2);
margin: 0px;

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,25 +0,0 @@
// create-league-routes.js
const express = require('express');
const exphbs = require('express-handlebars');
const app = express();
app.engine('hbs', exphbs({ extname: '.hbs' }));
app.set('view engine', 'hbs');
// Define the redirectToLeaguePage function
function redirectToLeaguePage(leagueName) {
window.location.href = '/views/pages/league-page/league-page.hbs?leagueName=' + encodeURIComponent(leagueName);
}
// Define a route to render the league-page.hbs template
app.get('/league-page/:leagueName', (req, res) => {
const leagueName = req.params.leagueName;
// Here you might fetch data related to the clicked league
// Pass the data to the template and render it
res.render('league-page/league-page', { leagueName });
});
// Export the app and redirectToLeaguePage function
module.exports = { app, redirectToLeaguePage };

View File

@@ -0,0 +1,7 @@
function redirectToLeaguePage(leagueName) {
// Append the league name to the URL
var url = "/league/" + leagueName.toLowerCase().replace(/\s+/g, '-');
// Redirect to the league page
window.location.href = url;
}

View File

@@ -1,8 +1,10 @@
$(document).ready(function() {
// When #user is clicked
$('#user').click(function() {
// Toggle the visibility of the login container
$('#login-container').toggle();
});
});
});

View File

@@ -0,0 +1,40 @@
document.addEventListener("DOMContentLoaded", function() {
const league_select = document.getElementById('league_dropdown');
const team_select = document.getElementById('team_dropdown');
league_select.addEventListener('change', updateTeamSelect);
function updateTeamSelect() {
var selectedLeague = league_select.value;
var teamSelect = team_select;
// Clear existing options
teamSelect.innerHTML = "";
// Add options based on the selected value from the first select element
if (selectedLeague === "La Liga") {
// Add options for La Liga
addOption(teamSelect, "Option 1 for LL", "option1A");
addOption(teamSelect, "Option 2 for LL", "option2A");
} else if (selectedLeague === "Serie A") {
// Add options for Serie A
addOption(teamSelect, "Team 1 in Serie A", "option1B");
addOption(teamSelect, "Team 2 in Serie A", "option2B");
} else {
// Add options for Bundesliga
addOption(teamSelect, "Option 1 for Bun", "option1C");
addOption(teamSelect, "Option 2 for Bun", "option2C");
}
}
function addOption(selectElement, text, value) {
var option = document.createElement("option");
option.text = text;
option.value = value;
selectElement.add(option);
}
});

View File

@@ -0,0 +1,18 @@
const express = require('express');
const app = express();
// generate-league-routes.js
// Define a function to generate league routes
module.exports = function generateLeagueRoutes(app) {
// Define a route to handle requests to "/league/:leagueName"
app.get('/league/:leagueName', (req, res) => {
// Extract the league name from the URL parameters
const leagueName = req.params.leagueName;
// Render the league page template using Handlebars
res.render('pages/league-page', { leagueName: leagueName });
});
};

View File

@@ -7,7 +7,7 @@ const fetchMatchesData = async (req, res, next) => {
const today = moment().format('YYYY-MM-DD'); // Get today's date in YYYY-MM-DD format
// Subtract one day to get yesterday's date
const yesterdayUnformatted = moment().subtract(3, 'days');
const yesterdayUnformatted = moment().subtract(4, 'days');
// Format yesterday's date as YYYY-MM-DD
const yesterday = yesterdayUnformatted.format('YYYY-MM-DD');

View File

@@ -4,32 +4,32 @@
<div class="row g-3" id="card-row">
<!-- 🇬🇧 Premier League -->
<a href="#" onclick="redirectToLeaguePage('Premier League')" class="card-link" id="league-card">
{{> homepage/league-card leaguename="Premier League" logo="./img/homepage/premier-league/icon.png" title="./img/homepage/premier-league/title.png"}}
{{> homepage/league-card leagueName="Premier League" logo="./img/homepage/premier-league/icon.png" title="./img/homepage/premier-league/title.png"}}
</a>
<!-- 🇪🇸 La Liga -->
<a href="#" onclick="redirectToLeaguePage('La Liga')" class="card-link" id="league-card">
{{> homepage/league-card leagueName="La Liga" logo="./img/homepage/la-liga/icon.png" title="./img/homepage/la-liga/title.png"}}
{{> homepage/league-card leagueName="La Liga" logo="./img/homepage/la-liga/icon.png" title="./img/homepage/la-liga/title.png"}}
</a>
<!-- 🇩🇪 Bundesliga -->
<a href="#" onclick="redirectToLeaguePage('Bundesliga')" class="card-link" id="league-card">
{{> homepage/league-card leagueName="Bundesliga" logo="./img/homepage/la-liga/icon.png" title="./img/homepage/la-liga/title.png"}}
{{> homepage/league-card leagueName="Bundesliga" logo="./img/homepage/bundesliga/icon.png" title="./img/homepage/bundesliga/title.png"}}
</a>
<!-- 🇮🇹 Serie A -->
<a href="#" onclick="redirectToLeaguePage('Serie A')" class="card-link" id="league-card">
{{> homepage/league-card leagueName="Serie A" logo="./img/homepage/la-liga/icon.png" title="./img/homepage/la-liga/title.png"}}
{{> homepage/league-card leagueName="Serie A" logo="./img/homepage/serie-a/icon.png" title="./img/homepage/serie-a/title.png"}}
</a>
<!-- 🇫🇷 Ligue 1 -->
<a href="#" onclick="redirectToLeaguePage('Ligue 1')" class="card-link" id="league-card">
{{> homepage/league-card leagueName="Ligue 1" logo="./img/homepage/la-liga/icon.png" title="./img/homepage/la-liga/title.png"}}
{{> homepage/league-card leagueName="Ligue 1" logo="./img/homepage/ligue-1/icon.png" title="./img/homepage/ligue-1/title.png"}}
</a>
<!-- 🇧🇷 Brasileirao -->
<a href="#" onclick="redirectToLeaguePage('Brasileirao')" class="card-link" id="league-card">
{{> homepage/league-card leagueName="Brasileirao" logo="./img/homepage/la-liga/icon.png" title="./img/homepage/la-liga/title.png"}}
{{> homepage/league-card leagueName="Brasileirao" logo="./img/homepage/brasileirao/icon.png" title="./img/homepage/brasileirao/title.png"}}
</a>
</div>

View File

@@ -0,0 +1,22 @@
<div class="container" id="league-page-body">
<!-- Container for all league information (logo, name, country, etc. ) <- top 100px -->
<div class="container" id="league-information-container">
</div>
<!-- Container to display all stats for league <- bottom rest of the container -->
<div class="container" id="league-stats-container">
<!-- Container to display league table <- split 50% -->
<div class="container" id="league-table-container">
</div>
<!-- Container to display top scorers for league <- Split 50% -->
<div class="container" id="top-scorers-container">
</div>
</div>
</div>

View File

@@ -1,16 +1,24 @@
<div class="register-page">
<div class="form-container">
<h1 class="mt-5 mb-4">Register</h1>
<form action="/register" method="POST" class="mt-3">
<div class="mb-3">
<!--- START OF FORM --->
<form action="/register" method="POST" class="mt-3"> <!-- Specify API route to DB -->
<!-- app.post('register') is found in index.js -->
<div class="mb-3" id="username-form">
<label for="username" class="form-label">Username:</label>
<input type="text" class="form-control" id="usernameInput" name="username" required>
</div>
<div class="mb-3">
<div class="mb-3" id="password-form">
<label for="password" class="form-label">Password:</label>
<input type="password" class="form-control" id="passwordInput" name="password" required>
</div>
<div class="dropdowns">
<div class="dropdowns" id="dropdowns-container">
<div>
<label class="form-label">Preferred League :</label><br>
<select id="league_dropdown">
@@ -22,15 +30,22 @@
<option>Brasilerao</option>
</select>
</div>
<!-- JavaScript is found at: ProjectSourceCode/src/resources/js/registration/league-and-team-select.js -->
<div>
<label class="form-label">Favorite Team :</label><br>
<select id="team_dropdown">
</select>
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<!--- END OF FORM --->
<p class="mt-3">Already have an account? <a href="/login">Login</a></p>
</div>
<script src = "js/registry-page/selectFunctions.js"> </script>

View File

@@ -3,13 +3,16 @@
&copy; 2024 - CSCI 3308 Group 6
</p>
<!-- Navigation Bar Scripts -->
<script src="js/navigation-bar/navigation-bar-follow.js"></script>
<script src="js/navigation-bar/user/login.js"></script>
<!-- Registration Page Scripts -->
<script src="/js/registration/league-and-team-select.js"></script>
<!-- Navigation Bar Scripts -->
<script src="/js/navigation-bar/navigation-bar-follow.js"></script>
<script src="/js/navigation-bar/user/login.js"></script>
<!-- Homepage Scripts -->
<script src="/js/homepage/redirect-to-league-url.js"></script>
<script src="/routes/league-pages/generate-league-routes.js"></script>
<!-- Include Bootstrap JavaScript -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</footer>

View File

@@ -1,18 +1,28 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<meta name="description" content="" />
<!-- Set the Content-Security-Policy header to allow inline scripts -->
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdn.jsdelivr.net https://stackpath.bootstrapcdn.com;">
<!-- Linking forms.css -->
<link rel="stylesheet" type="text/css" href="css/login_and_registration.css">
<link rel="stylesheet" type="text/css" href="css/homepage/homepage.css">
<link rel="stylesheet" type="text/css" href="/css/login_and_registration.css">
<!-- Navigation Bar Stylesheets -->
<link rel="stylesheet" type="text/css" href="css/navigation-bar/navigation-bar.css">
<link rel="stylesheet" type="text/css" href="css/navigation-bar/login.css">
<link rel="stylesheet" type="text/css" href="/css/navigation-bar/navigation-bar.css">
<link rel="stylesheet" type="text/css" href="/css/navigation-bar/login.css">
<!-- Scoreboard Header Stylesheets -->
<link rel="stylesheet" type="text/css" href="css/navigation-bar/scoreboard-header/scoreboard.css">
<link rel="stylesheet" type="text/css" href="css/navigation-bar/scoreboard-header/game-card.css">
<link rel="stylesheet" type="text/css" href="/css/navigation-bar/scoreboard-header/scoreboard.css">
<link rel="stylesheet" type="text/css" href="/css/navigation-bar/scoreboard-header/game-card.css">
<!-- Home Page Stylesheets -->
<link rel="stylesheet" type="text/css" href="/css/homepage/homepage.css">
<!-- League Page Stylesheets -->
<link rel="stylesheet" type="text/css" href="/css/league-page/league-page.css">
<title>Group 6 Final Project</title>

View File

@@ -1,7 +1,9 @@
<div class="banner">
<div class="content" id="card-contents">
<img src={{logo}} height="120">
<img src={{title}} height="80">
{{flag}}
<img id="logo" src={{logo}}>
<div class="title-wrapper">
<img id="title-logo" src={{title}}>
{{flag}}
</div>
</div>
</div>
</div>

View File

@@ -1 +0,0 @@
<h1>Hello</h1>

View File

@@ -1,27 +0,0 @@
<nav class="navbar navbar-expand-sm border-bottom">
<div class="container">
<button
class="navbar-toggler ms-auto"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbar-collapse"
aria-controls="navbar"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar-collapse">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<!-- TODO: For Discover, add a <a> tag with an attribute href to call the '/discover' API -->
<a class="nav-link" href="/home">Home</a>
</li>
</ul>
<div class="nav-item me-1">
<!-- TODO: For Logout, add a <a> tag with an attribute href to call the '/logout API -->
<a class="nav-link" href="/logout">Logout</a>
</div>
</div>
</div>
</nav>

View File

@@ -15,41 +15,41 @@
<ul class="navbar-nav mr-auto mt-2 mt-lg-0" id="navbar-list">
<li class="nav-item">
<a class="nav-link" href="#">Premier League</a>
<a class="nav-link" href="/league/premier-league">Premier League</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Bundesliga</a>
<a class="nav-link" href="/league/bundesliga">Bundesliga</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">La Liga</a>
<a class="nav-link" href="/league/la-liga">La Liga</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Serie A</a>
<a class="nav-link" href="/league/serie-a">Serie A</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Ligue 1</a>
<a class="nav-link" href="/league/ligue-1">Ligue 1</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Brasileirao</a>
<a class="nav-link" href="/league/brasileirao">Brasileirao</a>
</li>
</ul>
</div>
<div id="user" class="user-icon">
<img src="img/navigation-bar/user.png" alt="Your Image" class="img-fluid">
<img src="/img/navigation-bar/user.png" alt="Your Image" class="img-fluid">
</div>
</div>
</nav>
<!-- Container for login section -->
<div id="login-container" class="container">
<div class="container" id="login-container">
{{> navigation-bar/login}}
</div>