This commit is contained in:
dominicjk
2024-04-15 11:04:16 -06:00
33 changed files with 1025 additions and 137 deletions

View File

@@ -78,19 +78,51 @@ app.use(
app.use(express.static(path.join(__dirname, 'resources'))); app.use(express.static(path.join(__dirname, 'resources')));
// ***************************************************** // *****************************************************
// <!-- Section 4 : API Routes --> // <!-- Section 4 : Middleware -->
// ***************************************************** // *****************************************************
/************************ // Middleware to automatically update live scoreboard
Header Scoreboard Routes const fetchMatchesData = require('./resources/middleware/navigation-bar/current-match-information');
*************************/
const fetchMatchesData = require('./resources/routes/navigation-bar/current-match-information');
app.use(fetchMatchesData); app.use(fetchMatchesData);
const convert_time = require('./resources/js/navigation-bar/scoreboard-header/convert-time'); //Middleware to automatically update in-game time abbreviations
const convert_time = require('./resources/middleware/navigation-bar/convert-time');
app.use(convert_time); app.use(convert_time);
// Leagues Page Middleware
const fetchLeaguesData = require('./resources/middleware/leagues-page/get-current-league-information');
const fetchLeagueScorerData = require('./resources/middleware/leagues-page/get-current-league-top-scorers');
app.get('/league/:leagueID', [fetchLeaguesData, fetchLeagueScorerData], (req, res) => {
// Render the Handlebars view with league data
res.render('pages/leagues-page', {
leagueID: req.params.leagueID,
leagues: res.locals.leagues,
scorers: res.locals.topScorers // Assuming fetchLeagueScorerData sets the data in res.locals.scorers
});
});
// Clubs Page Middleware
const fetchClubsData = require('./resources/middleware/clubs-page/get-current-club-information');
app.get('/club/:clubID', [fetchClubsData], (req, res) => {
// Render the Handlebars view with league data
res.render('pages/clubs-page', {
clubID: req.params.clubID,
clubs: res.locals.club
});
});
// *****************************************************
// <!-- Section 5 : API Routes -->
// *****************************************************
/************************ /************************
Login Page Routes Login Page Routes
*************************/ *************************/
@@ -98,17 +130,16 @@ app.use(convert_time);
// Redirect to the /login endpoint // Redirect to the /login endpoint
app.get('/', (req, res) => { app.get('/', (req, res) => {
res.redirect('/home'); res.redirect('/home');
}); });
// Render login page for /login route // Render login page for /login route
app.get('/login', (req, res) => { app.get('/login', (req, res) => {
res.render('pages/home'); res.render('pages/home');
}); });
// Trigger login form to check database for matching username and password // Trigger login form to check database for matching username and password
app.post('/login', async (req, res) => { app.post('/login', async (req, res) => {
try { try {
// Check if username exists in DB // Check if username exists in DB
const user = await db.oneOrNone('SELECT * FROM users WHERE username = $1', req.body.username); const user = await db.oneOrNone('SELECT * FROM users WHERE username = $1', req.body.username);
@@ -120,7 +151,7 @@ app.get('/', (req, res) => {
// Check if password from request matches with password in DB // Check if password from request matches with password in DB
const match = await bcrypt.compare(req.body.password, user.password); const match = await bcrypt.compare(req.body.password, user.password);
// Check if mathc returns no data // Check if match returns no data
if (!match) { if (!match) {
// Render the login page with the message parameter // Render the login page with the message parameter
return res.render('pages/home', { message: 'Password does not match' }); return res.render('pages/home', { message: 'Password does not match' });
@@ -132,22 +163,20 @@ app.get('/', (req, res) => {
// Redirect user to the home page // Redirect user to the home page
res.redirect('/home'); res.redirect('/home');
} catch (error) { } catch (error) {
// Direct user to login screen if no user is found with matching password // Direct user to login screen if no user is found with matching password
res.redirect('/register'); res.redirect('/register');
} }
}); });
/************************ /************************
Registration Page Routes Registration Page Routes
*************************/ *************************/
// Render registration page for /register route // Render registration page for /register route
app.get('/register', (req, res) => { app.get('/register', (req, res) => {
res.render('pages/register'); res.render('pages/register');
}); });
// Trigger Registration Form to Post // Trigger Registration Form to Post
app.post('/register', async (req, res) => { app.post('/register', async (req, res) => {
@@ -170,7 +199,6 @@ app.post('/register', async (req, res) => {
} }
}); });
/************************ /************************
Home Page Routes Home Page Routes
*************************/ *************************/
@@ -179,10 +207,22 @@ app.get('/home', (req, res) => {
res.render('pages/home'); res.render('pages/home');
}); });
/************************
League Page Routes
*************************/
// Import and call generateLeagueRoutes function // Import and call generateLeagueRoutes function
const generateLeagueRoutes = require('./resources/routes/league-pages/generate-league-routes'); const generateLeagueRoutes = require('./resources/routes/league-pages/generate-league-routes');
generateLeagueRoutes(app); generateLeagueRoutes(app);
/************************
Club Page Routes
*************************/
// Import and call generateLeagueRoutes function
const generateClubRoutes = require('./resources/routes/club-pages/generate-club-routes');
generateClubRoutes(app);
// ***************************************************** // *****************************************************
// <!-- Section 5 : Start Server--> // <!-- Section 5 : Start Server-->
// ***************************************************** // *****************************************************

View File

@@ -0,0 +1,5 @@
body {
/* background-image: url('./../img/grass-background.png'); Specify the path to your background image */
/* background-repeat: repeat; Set the background image to repeat both horizontally and vertically */
/* background-size: 1000px; Set the size of the background image for each repeat */
}

View File

@@ -0,0 +1,66 @@
#club-page-body {
display: flex;
flex-direction: column;
width: 100%;
}
#club-information-container {
height: 100px;
width: fit-content;
margin: 20px;
background: linear-gradient(to right, white, rgb(245, 245, 245), rgb(227, 227, 227)); /* Gradient from white to gray */
padding: 10px 20px; /* Adjust padding as needed */
transform: skewX(-20deg); /* Skew the banner to create a triangular side */
cursor: pointer; /* Change cursor to pointer on hover */
box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.4);
display: flex; /* Use flexbox for layout */
align-items: center; /* Center content vertically */
/* Add any other styling you need for the club information container */
}
#club-information-container::after {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 8px; /* Width of the red strip */
background-color: red; /* Red color */
}
#club-logo {
margin: 0px 30px;
transform: skewX(20deg); /* Skew the banner to create a triangular side */
}
#club-title {
transform: skewX(20deg); /* Skew the banner to create a triangular side */
margin-right: 20px;
}
#club-flag {
transform: skewX(20deg); /* Skew the banner to create a triangular side */
height: 20px;
margin-right: 200px;
}
#club-stats-container {
width: 100%;
display: flex;
flex: 1;
}
#club-stats-container .container {
margin: 0 10px;
background-color: #eaeaea; /* Example background color */
border: 1px solid gray;
border-radius: 8px;
box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.4);
/* Add any other styling you need for the club table container */
}

View File

@@ -0,0 +1,6 @@
#club-top-scorers-container {
flex: 1;
background-color: #dcdcdc; /* Example background color */
width: 40%;
/* Add any other styling you need for the top scorers container */
}

View File

@@ -1,28 +0,0 @@
#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

@@ -0,0 +1,142 @@
/*
==============================================================
OVERALL PAGE STYLES
==============================================================
*/
#league-page-body
{
/* --- SIZE CONTAINER --- */
width: 100%; /* Set the width to the full width of screen */
padding: 10px 100px; /* Create some distance between page boundries and elements */
/* --- FORMAT CHILD ITEMS (Table and Leading Scorers Cards) --- */
display: flex; /* Enable flexbox layout */
flex-direction: column; /* Arrange child elements vertically */
}
/*
=================================
LEAGUE INFORMATION HEADER
=================================
*/
/* Stylization for League Information Header Card */
#league-information-container
{
/* --- POSITION CONTAINER --- */
align-items: center; /* Center content vertically */
margin: 20px;
/* --- SIZE CONTAINER --- */
height: 100px;
width: fit-content;
padding: 10px 20px; /* Adjust padding as needed */
/* --- STYLE CONTAINER --- */
background: linear-gradient(to right, white, rgb(245, 245, 245), rgb(227, 227, 227)); /* Gradient from white to gray */
transform: skewX(-20deg); /* Skew the banner to create a triangular side */
box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.4);
/* --- FORMAT CHILD ITEMS (logo, league name, flag) --- */
display: flex; /* Enable flexbox layout */
flex-direction: row; /* Arrange child elements horizontally */
}
/*
===========================
LEAGUE INFORMATION CHILD ITEMS
===========================
*/
/* Adds Red Diagonal Strip at the end of the #league-information-container */
#league-information-container::after
{
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 8px; /* Width of the red strip */
background-color: red; /* Red color */
}
/* Styling for League Logo in League Information Header */
#league-logo
{
margin: 0px 30px;
transform: skewX(20deg); /* Skew the banner to create a triangular side */
height: 80%;
}
/* Styling for League Title in League Information Header */
#league-title
{
transform: skewX(20deg); /* Skew the banner to create a triangular side */
margin-right: 20px;
}
/* Styling for FLag in League Information Header */
#league-flag
{
transform: skewX(20deg); /* Skew the banner to create a triangular side */
height: 20px;
margin-right: 200px;
}
/*
=============================================
CARDS IN PAGE BODY
=============================================
*/
#table-and-top-scorers-containers {
display: flex;
flex-direction: row;
}
/* Styling for Standings and Top Scorers Cards */
#table-stats-container, #top-scorers-stats-container
{
/* --- POSITION CONTAINER --- */
margin: 0 10px;
margin-bottom: 20px;
/* --- SIZE CONTAINER --- */
padding: 15px;
/* --- STYLE CONTAINER --- */
background: linear-gradient(to top, rgb(216, 216, 216), rgb(236, 236, 236), rgb(241, 240, 240));
border: 1px solid gray;
box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.5);
}
/*
==============================================================
HOVER STYLES
==============================================================
*/
/* Hover Styling for Standings and Top Scorers Cards */
#table-stats-container:hover, #top-scorers-stats-container:hover
{
transform: scale(1.01); /* Scale the row by 1.1 on hover */
box-shadow: 0px 3px 10px rgba(0, 0, 0, 0.3);
}
/*
==============================================================
DYNAMIC PAGE WIDTH STYLES
==============================================================
*/
/* Width of Screen is Less Than 950px */
@media (max-width: 1230px)
{
#table-and-top-scorers-containers {
display: flex;
flex-direction: column;
}
}

View File

@@ -0,0 +1,130 @@
/*
=================================
TABLE ADN HEADER CONTAINER
=================================
*/
/* Container for table and header */
#league-table-container
{
width: 60%;
justify-content: center;
align-items: center;
margin-right: 30px;
transition: transform 0.3s ease; /* Add smooth transition effect */
}
/*
=================================
TABLE CONTAINER
=================================
*/
/* Container for Table */
#table-stats-container
{
width: 100%;
}
/* Table that holds all the standing information */
#standings-table
{
width: 100%;
padding: 15px;
/* Table Header Styling */
th
{
border-bottom: 3px solid red; /* Add red bottom border */
}
/* Data in Row Style */
td
{
padding: 5px;
}
/* Every Odd Row in Table Style */
tbody tr:nth-child(odd)
{
background-color: #d2d2d2; /* Light gray for odd rows */
}
}
/*
===========================
TABLE COLUMNS STYLE
===========================
*/
/* Club Logo Column in Table Style */
#club-logo-column {
width: 25px;
/* Club Logo Style */
#table-club-logo
{
width: 25px;
margin-right: 5px;
cursor: pointer;
}
}
/* Club Name Column in Table Style */
#club-name-column
{
font-weight: 500;
cursor: pointer;
}
/* Points Column in Table Style */
#points-column
{
font-weight: bolder;
}
/*
==============================================================
HOVER STYLES
==============================================================
*/
/* Add hover effect to table rows */
#standings-table tbody tr:hover
{
/* Create border around row on hover */
border: 1px solid lightgray;
border-radius: 10px;
/* Make club logo larger on hover */
#table-club-logo
{
width: 32px;
}
/* Undeline club name on hover */
#club-name-column
{
text-decoration: underline; /* Add underline effect */
}
}
/*
==============================================================
DYNAMIC PAGE WIDTH STYLES
==============================================================
*/
/* Stlye for Screens Smaller than 1230px */
@media (max-width: 1230px)
{
#league-table-container
{
align-items: center;
width: 75%;
min-width: 580px;
}
}

View File

@@ -0,0 +1,96 @@
/*
=================================
TABLE ADN HEADER CONTAINER
=================================
*/
#top-scorers-container
{
width: 40%;
}
#top-scorers-stats-container {
/* Table Header Styling */
th
{
border-bottom: 3px solid red; /* Add red bottom border */
}
tr
{
padding: 3px;
}
/* Data in Row Style */
td
{
padding: 5px;
}
}
/*
===========================
TABLE COLUMNS STYLE
===========================
*/
#goals-column
{
text-align: center;
font-size: 20px;
font-weight: bolder;
}
#top-scorers-logo
{
width: 25px;
margin: 0 15px;
cursor: pointer;
}
#player-name-column
{
font-size: 14px;
font-weight: bold;
padding-right: 15px;
}
#club-name-column
{
padding-right: 15px;
}
/*
==============================================================
HOVER STYLES
==============================================================
*/
#top-scorers-stats-container tbody tr:hover
{
border: 1px solid lightgray;
#top-scorers-logo {
width: 32px;
}
#club-name-column {
text-decoration: underline;
}
}
/*
==============================================================
DYNAMIC PAGE WIDTH STYLES
==============================================================
*/
@media (max-width: 1230px) {
#top-scorers-container {
align-items: center;
width: 75%;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 MiB

View File

@@ -1,7 +0,0 @@
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

@@ -0,0 +1,29 @@
document.addEventListener("DOMContentLoaded", function() {
var goalDifferenceCells = document.querySelectorAll("#goal-difference-column"); // Selecting the cells in the goal_difference column
goalDifferenceCells.forEach(function(cell) {
var goalDifference = parseInt(cell.textContent);
var color;
if (goalDifference < 0)
{
// Gradually darken the text color for negative goal differences
var darkenFactor = Math.ceil(goalDifference / -10); // Calculate the darken factor
var shade = Math.max(0, 255 - darkenFactor * 25); // Calculate the shade of red
color = "rgb(" + shade + ", 0, 0)"; // Create the color value
}
else if (goalDifference > 0)
{
// Gradually darken the text color for positive goal differences
var darkenFactor = Math.floor(goalDifference / 10); // Calculate the darken factor
var shade = Math.max(0, 155 - darkenFactor * 15); // Adjusted the starting point to make greens darker
color = "rgb(0, " + shade + ", 0)"; // Create the color value
}
else
{
color = "inherit"; // If goal difference is 0, leave text color unchanged
}
cell.style.color = color; // Apply the calculated color
});
});

View File

@@ -0,0 +1,75 @@
const axios = require('axios');
// Middleware function to fetch clubs data
const fetchClubsData = async (req, res, next) => {
try {
// Extract club ID from the URL
const clubID = req.params.clubID;
// Make GET request to the API endpoint using the club ID
const response = await axios.get(`http://api.football-data.org/v4/teams/${clubID}/?offset=&limit=`, {
headers: {
'X-Auth-Token': '0aa1ed31245d4a36b1ef5a79150324b3', // Add your API key here
},
});
// Extract relevant data from the API response
const clubData = response.data;
// Attach the data to res.locals
res.locals.club = {
area: {
id: clubData.area.id,
name: clubData.area.name,
code: clubData.area.code,
club_flag: clubData.area.flag,
},
club_id: clubData.id,
name: clubData.name,
shortName: clubData.shortName,
tla: clubData.tla,
crest: clubData.crest,
address: clubData.address,
website: clubData.website,
founded: clubData.founded,
clubColors: clubData.clubColors,
venue: clubData.venue,
runningCompetitions: clubData.runningCompetitions.map(competition => ({
id: competition.id,
name: competition.name,
code: competition.code,
type: competition.type,
emblem: competition.emblem
})),
coach: {
id: clubData.coach.id,
firstName: clubData.coach.firstName,
lastName: clubData.coach.lastName,
name: clubData.coach.name,
dateOfBirth: clubData.coach.dateOfBirth,
nationality: clubData.coach.nationality,
contract: {
start: clubData.coach.contract.start,
until: clubData.coach.contract.until
}
},
squad: clubData.squad.map(player => ({
id: player.id,
name: player.name,
position: player.position,
dateOfBirth: player.dateOfBirth,
nationality: player.nationality
})),
staff: clubData.staff,
lastUpdated: clubData.lastUpdated
};
next();
} catch (error) {
console.error('Error fetching clubs data:', error);
res.locals.club = null; // Set to null if there's an error
next(); // Call next middleware or route handler
}
};
module.exports = fetchClubsData;

View File

@@ -0,0 +1,44 @@
const axios = require('axios');
// Middleware function to fetch leagues data
const fetchLeagueScorerData = async (req, res, next) => {
try {
// Extract league ID from the URL
const leagueID = req.params.leagueID;
// Make GET request to the API endpoint using the league ID
const response = await axios.get(`http://api.football-data.org/v4/competitions/${leagueID}/scorers?season&limit=20`, {
headers: {
'X-Auth-Token': '0aa1ed31245d4a36b1ef5a79150324b3', // Add your API key here
},
});
// Extract relevant data from the API response
const scorerData = response.data;
// Attach the data to res.locals
res.locals.topScorers = {
scorers: scorerData.scorers.map(player => ({
player: {
player_id: player.player.id,
player_name: player.player.name,
},
team: {
team_id: player.player.id,
team_name: player.team.name,
team_crest: player.team.crest,
},
games_played: player.playedMatches,
goals: player.goals,
}))
};
next();
} catch (error) {
console.error('Error fetching leagues data:', error);
res.locals.topScorers = null; // Set to null if there's an error
next(); // Call next middleware or route handler
}
};
module.exports = fetchLeagueScorerData;

View File

@@ -0,0 +1,52 @@
const axios = require('axios');
// Middleware function to fetch leagues data
const fetchLeaguesData = async (req, res, next) => {
try {
// Extract league ID from the URL
const leagueID = req.params.leagueID;
// Make GET request to the API endpoint using the league ID
const response = await axios.get(`http://api.football-data.org/v4/competitions/${leagueID}/standings?season`, {
headers: {
'X-Auth-Token': '0aa1ed31245d4a36b1ef5a79150324b3', // Add your API key here
},
});
// Extract relevant data from the API response
const leagueData = response.data;
// Attach the data to res.locals
res.locals.league = {
area: {
league_flag: leagueData.area.flag,
},
competition: {
league_id: leagueData.competition.id,
league_name: leagueData.competition.name,
league_emblem: leagueData.competition.emblem
},
standings: leagueData.standings[0].table.map(team => ({
table: {
league_position: team.position,
team_id: team.team.id,
team_name: team.team.name,
team_crest: team.team.crest
},
games_played: team.playedGames,
wins: team.won,
losses: team.lost,
draws: team.draw,
goal_difference: team.goalDifference,
points: team.points
}))
};
next();
} catch (error) {
console.error('Error fetching leagues data:', error);
res.locals.league = null; // Set to null if there's an error
next(); // Call next middleware or route handler
}
};
module.exports = fetchLeaguesData;

View File

@@ -0,0 +1,44 @@
const axios = require('axios');
// Middleware function to fetch leagues data
const fetchLeagueScorerData = async (req, res, next) => {
try {
// Extract league ID from the URL
const leagueID = req.params.leagueID;
// Make GET request to the API endpoint using the league ID
const response = await axios.get(`http://api.football-data.org/v4/competitions/${leagueID}/scorers?season&limit=20`, {
headers: {
'X-Auth-Token': '0aa1ed31245d4a36b1ef5a79150324b3', // Add your API key here
},
});
// Extract relevant data from the API response
const scorerData = response.data;
// Attach the data to res.locals
res.locals.topScorers = {
scorers: scorerData.scorers.map(player => ({
player: {
player_id: player.player.id,
player_name: player.player.name,
},
team: {
team_id: player.team.id,
team_name: player.team.name,
team_crest: player.team.crest,
},
games_played: player.playedMatches,
goals: player.goals,
}))
};
next();
} catch (error) {
console.error('Error fetching leagues data:', error);
res.locals.topScorers = null; // Set to null if there's an error
next(); // Call next middleware or route handler
}
};
module.exports = fetchLeagueScorerData;

View File

@@ -9,6 +9,9 @@ const convert_time = (req, res, next) => {
if (match.minute === "FINISHED") { if (match.minute === "FINISHED") {
match.minute = "FT"; match.minute = "FT";
} }
else if (match.minute === "IN_PLAY") {
match.minute = "IP"
}
else if (match.minute === "TIMED") { else if (match.minute === "TIMED") {
match.minute = "TM"; match.minute = "TM";
} }

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 generateClubRoutes(app) {
// Define a route to handle requests to "/league/:leagueName"
app.get('/club/:clubID', (req, res) => {
// Extract the league name from the URL parameters
const clubID = req.params.clubID;
// Render the league page template using Handlebars
res.render('pages/club-page', { clubID: clubID });
});
};

View File

@@ -0,0 +1,17 @@
// Add click event listener to club logos
document.querySelectorAll('#table-club-logo, #club-name, #top-scorers-logo, #club-name-column').forEach(element => {
element.addEventListener('click', (event) => {
// Get the club ID from the clicked club logo's clubID attribute
const clubId = element.getAttribute('clubID');
redirectToClubPage(clubId);
});
});
// Function to redirect to the club page
function redirectToClubPage(clubID) {
// Append the club ID to the URL
var url = "/club/" + clubID;
// Redirect to the club page
window.location.href = url;
}

View File

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

View File

@@ -0,0 +1,21 @@
const axios = require('axios');
const fetchTeamNames = async (selectedLeague) => {
try {
const response = await axios({
url: `http://api.football-data.org/v4/competitions/${selectedLeague}/teams`,
method: 'GET',
headers: {
'X-Auth-Token': '0aa1ed31245d4a36b1ef5a79150324b3',
},
});
const teams = response.data.teams.map(team => team.name);
return teams;
} catch (error) {
console.error('Error fetching teams data:', error);
return [];
}
};
module.exports = fetchTeamNames;

View File

@@ -0,0 +1,7 @@
function redirectToLeaguePage(leagueID) {
// Append the league name to the URL
var url = "/league/" + leagueID;
// Redirect to the league page
window.location.href = url;
}

View File

@@ -0,0 +1,24 @@
<div class="container" id="club-page-body">
<!-- Container for all club information (logo, name, country, etc. ) <- top 100px -->
<div class="container" id="club-information-container">
<img id="club-logo" src="{{club.crest}}" alt="{{club.name}} Emblem">
<h1 id="club-title">{{club.name}}</h2>
<img id="club-flag" src="{{club.area.club_flag}}" alt="{{club.clubData.name}} Flag">
</div>
<!-- Container to display all stats for club <- bottom rest of the container -->
<div class="container" id="club-stats-container">
<!-- Container to display club table <- split 50% -->
<div class="container" id="club-players-container">
</div>
<!-- Container to display top scorers for club <- Split 50% -->
<div class="container" id="top-scorers-container">
</div>
</div>
</div>

View File

@@ -3,32 +3,32 @@
<div class="card-container"> <div class="card-container">
<div class="row g-3" id="card-row"> <div class="row g-3" id="card-row">
<!-- 🇬🇧 Premier League --> <!-- 🇬🇧 Premier League -->
<a href="#" onclick="redirectToLeaguePage('Premier League')" class="card-link" id="league-card"> <a href="#" onclick="redirectToLeaguePage('2021')" 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> </a>
<!-- 🇪🇸 La Liga --> <!-- 🇪🇸 La Liga -->
<a href="#" onclick="redirectToLeaguePage('La Liga')" class="card-link" id="league-card"> <a href="#" onclick="redirectToLeaguePage('2014')" 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> </a>
<!-- 🇩🇪 Bundesliga --> <!-- 🇩🇪 Bundesliga -->
<a href="#" onclick="redirectToLeaguePage('Bundesliga')" class="card-link" id="league-card"> <a href="#" onclick="redirectToLeaguePage('2002')" class="card-link" id="league-card">
{{> homepage/league-card leagueName="Bundesliga" logo="./img/homepage/bundesliga/icon.png" title="./img/homepage/bundesliga/title.png"}} {{> homepage/league-card leagueName="Bundesliga" logo="./img/homepage/bundesliga/icon.png" title="./img/homepage/bundesliga/title.png"}}
</a> </a>
<!-- 🇮🇹 Serie A --> <!-- 🇮🇹 Serie A -->
<a href="#" onclick="redirectToLeaguePage('Serie A')" class="card-link" id="league-card"> <a href="#" onclick="redirectToLeaguePage('2019')" class="card-link" id="league-card">
{{> homepage/league-card leagueName="Serie A" logo="./img/homepage/serie-a/icon.png" title="./img/homepage/serie-a/title.png"}} {{> homepage/league-card leagueName="Serie A" logo="./img/homepage/serie-a/icon.png" title="./img/homepage/serie-a/title.png"}}
</a> </a>
<!-- 🇫🇷 Ligue 1 --> <!-- 🇫🇷 Ligue 1 -->
<a href="#" onclick="redirectToLeaguePage('Ligue 1')" class="card-link" id="league-card"> <a href="#" onclick="redirectToLeaguePage('2015')" class="card-link" id="league-card">
{{> homepage/league-card leagueName="Ligue 1" logo="./img/homepage/ligue-1/icon.png" title="./img/homepage/ligue-1/title.png"}} {{> homepage/league-card leagueName="Ligue 1" logo="./img/homepage/ligue-1/icon.png" title="./img/homepage/ligue-1/title.png"}}
</a> </a>
<!-- 🇧🇷 Brasileirao --> <!-- 🇧🇷 Brasileirao -->
<a href="#" onclick="redirectToLeaguePage('Brasileirao')" class="card-link" id="league-card"> <a href="#" onclick="redirectToLeaguePage('2013')" class="card-link" id="league-card">
{{> homepage/league-card leagueName="Brasileirao" logo="./img/homepage/brasileirao/icon.png" title="./img/homepage/brasileirao/title.png"}} {{> homepage/league-card leagueName="Brasileirao" logo="./img/homepage/brasileirao/icon.png" title="./img/homepage/brasileirao/title.png"}}
</a> </a>

View File

@@ -1,22 +0,0 @@
<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

@@ -0,0 +1,89 @@
<div id="league-page-body" class="page-container">
<!-- Container for all league information (logo, name, country, etc. ) <- top 100px -->
<div id="league-information-container" class="information-container">
<img id="league-logo" src="{{league.competition.league_emblem}}" alt="{{league.competition.league_name}} Emblem">
<h1 id="league-title">{{league.competition.league_name}}</h2>
<img id="league-flag" src="{{league.area.league_flag}}" alt="{{league.competition.league_name}} Flag">
</div>
<!-- Container to display all stats for league <- bottom rest of the container -->
<div id="table-and-top-scorers-containers" class="stats-container">
<!-- Container to display league table <- split 50% -->
<div id="league-table-container" class="stats-container">
<!-- Put header above table container -->
<div id="table-header-container" class="header">
<h2>Table</h2>
</div>
<!-- Container containing all league table stats -->
<div id="table-stats-container" class="stats-container">
<table id="standings-table">
<thead>
<tr>
<th>#</th>
<th></th>
<th>Club</th>
<th>GP</th>
<th>W</th>
<th>L</th>
<th>D</th>
<th>GD</th>
<th>Pts</th>
</tr>
</thead>
<tbody>
{{#each league.standings}}
<tr>
<td>{{table.league_position}}</td>
<td id="club-logo-column"><img id="table-club-logo" clubID="{{table.team_id}}" src="{{table.team_crest}}" alt="{{table.team_name}} Crest"></td>
<td><span id="club-name-column" clubID="{{table.team_id}}">{{table.team_name}}</span></td>
<td>{{games_played}}</td>
<td>{{wins}}</td>
<td>{{losses}}</td>
<td>{{draws}}</td>
<td id="goal-difference-column">{{goal_difference}}</td>
<td id="points-column">{{points}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
<!-- Container to display top scorers for league <- Split 50% -->
<div id="top-scorers-container" class="stats-container">
<div id="top-scorers-header-container" class="header">
<h2>Top Scorers</h2>
</div>
<div id="top-scorers-stats-container" class="stats-container">
<table>
<thead>
<tr>
<th>Goals</th>
<th></th>
<th>Name</th>
<th>Club</th>
<th>GP</th>
</tr>
</thead>
<tbody>
{{#each topScorers.scorers}}
<tr id="top-scorers-row">
<td id="goals-column">{{goals}}</td>
<td><img id="top-scorers-logo" clubID="{{team.team_id}}" src="{{team.team_crest}}" alt="{{table.team_name}} Crest"></img></td>
<td id="player-name-column">{{player.player_name}}</td>
<td id="club-name-column" clubID="{{team.team_id}}">{{team.team_name}}</td>
<td>{{games_played}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
</div>
</div>

View File

@@ -11,8 +11,11 @@
<script src="/js/navigation-bar/user/login.js"></script> <script src="/js/navigation-bar/user/login.js"></script>
<!-- Homepage Scripts --> <!-- Homepage Scripts -->
<script src="/js/homepage/redirect-to-league-url.js"></script> <script src="/routes/league-pages/redirect-to-league-url.js"></script>
<script src="/routes/league-pages/generate-league-routes.js"></script>
<!-- League Pages Scripts -->
<script src="/js/league-page/change-goal-difference-color.js"></script>
<script src="/routes/club-pages/redirect-to-club-url.js"></script>
</footer> </footer>

View File

@@ -5,7 +5,8 @@
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdn.jsdelivr.net https://stackpath.bootstrapcdn.com;"> <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdn.jsdelivr.net https://stackpath.bootstrapcdn.com;">
<!-- CSS on All Pages -->
<link rel="stylesheet" type="text/css" href="/css/all-pages-style.css">
<!-- Linking forms.css --> <!-- Linking forms.css -->
<link rel="stylesheet" type="text/css" href="/css/login_and_registration.css"> <link rel="stylesheet" type="text/css" href="/css/login_and_registration.css">
@@ -22,7 +23,14 @@
<link rel="stylesheet" type="text/css" href="/css/homepage/homepage.css"> <link rel="stylesheet" type="text/css" href="/css/homepage/homepage.css">
<!-- League Page Stylesheets --> <!-- League Page Stylesheets -->
<link rel="stylesheet" type="text/css" href="/css/league-page/league-page.css"> <link rel="stylesheet" type="text/css" href="/css/league-pages/league-page.css">
<link rel="stylesheet" type="text/css" href="/css/league-pages/league-table.css">
<link rel="stylesheet" type="text/css" href="/css/league-pages/top-scorers.css">
<!-- League Page Stylesheets -->
<link rel="stylesheet" type="text/css" href="/css/club-pages/club-page.css">
<link rel="stylesheet" type="text/css" href="/css/club-pages/players-table.css">
<link rel="stylesheet" type="text/css" href="/css/club-pages/club-top-scorers.css">
<title>Group 6 Final Project</title> <title>Group 6 Final Project</title>

View File

@@ -15,27 +15,27 @@
<ul class="navbar-nav mr-auto mt-2 mt-lg-0" id="navbar-list"> <ul class="navbar-nav mr-auto mt-2 mt-lg-0" id="navbar-list">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/league/premier-league">Premier League</a> <a class="nav-link" href="/league/2021">Premier League</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/league/bundesliga">Bundesliga</a> <a class="nav-link" href="/league/2002">Bundesliga</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/league/la-liga">La Liga</a> <a class="nav-link" href="/league/2014">La Liga</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/league/serie-a">Serie A</a> <a class="nav-link" href="/league/2019">Serie A</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/league/ligue-1">Ligue 1</a> <a class="nav-link" href="/league/2015">Ligue 1</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/league/brasileirao">Brasileirao</a> <a class="nav-link" href="/league/2013">Brasileirao</a>
</li> </li>
</ul> </ul>

View File

@@ -0,0 +1,20 @@
<div class="player-card" id="player-card">
<div class="player-card-body">
<table class="table">
<thead>
<tr>
<th>Player Name</th>
<th>Nationality</th>
<th>Position</th>
</tr>
</thead>
<tbody>
<tr>
<td>persons.name</td>
<td>persons.nationality</td>
<td>persons.position</td>
</tr>
</tbody>
</table>
</div>
</div>

View File

@@ -11,3 +11,9 @@
15 : 49 : overview of features and display of initial website 15 : 49 : overview of features and display of initial website
15 : 52 : discussion on database 15 : 52 : discussion on database
15 : 53 : end of meeting 15 : 53 : end of meeting
==== Meeting 3 04/11/2024 ====
16 : 00 : meeting start
16 : 01 : progress check and showcase
16 : 08 : feedback
16 : 10 : end of meeting