From 0c1f148fe5e1b12f0f2f121c5876da2bc06ed9d3 Mon Sep 17 00:00:00 2001 From: quoije Date: Wed, 5 Feb 2025 19:22:07 -0500 Subject: [PATCH] fix things, speed things up a little (scuffed) --- index.js | 2 + public/checklist.html | 198 +------------------------------------ public/index.html | 49 +-------- public/js/app_checklist.js | 196 ++++++++++++++++++++++++++++++++++++ public/js/app_index.js | 46 +++++++++ public/js/app_movies.js | 118 ++++++++++++++++++++++ public/js/app_register.js | 45 +++++++++ public/js/app_user-stat.js | 99 +++++++++++++++++++ public/movies.html | 121 +---------------------- public/register.html | 48 +-------- public/user-stat.html | 102 +------------------ routes/users.js | 41 -------- routes/version.js | 52 ++++++++++ 13 files changed, 563 insertions(+), 554 deletions(-) create mode 100644 public/js/app_checklist.js create mode 100644 public/js/app_index.js create mode 100644 public/js/app_movies.js create mode 100644 public/js/app_register.js create mode 100644 public/js/app_user-stat.js create mode 100644 routes/version.js diff --git a/index.js b/index.js index 6a82d19..f0a5f43 100644 --- a/index.js +++ b/index.js @@ -19,10 +19,12 @@ mongoose // Routes const userRoutes = require("./routes/users"); const movieRoutes = require("./routes/movies"); +const versionRoutes = require("./routes/version"); app.use(express.static('public')); app.use("/api/users", userRoutes); app.use("/api/movies", movieRoutes); +app.use("/api/version", versionRoutes); // Start Server const PORT = process.env.PORT || 5000; diff --git a/public/checklist.html b/public/checklist.html index 927aa1c..9099866 100644 --- a/public/checklist.html +++ b/public/checklist.html @@ -119,203 +119,7 @@ - - const targetDate = new Date('March 2, 2025'); - const currentDate = new Date(); - const timeDifference = targetDate - currentDate; - const daysLeft = Math.floor(timeDifference / (1000 * 60 * 60 * 24)); - document.getElementById('time-left').textContent = `${daysLeft} jours`; - - if (token) { - try { - const decoded = JSON.parse(atob(token.split('.')[1])); - const userName = decoded.name; - document.getElementById('user-name').textContent = userName; - const currentTime = Math.floor(Date.now() / 1000); - if (decoded.exp && decoded.exp < currentTime) { - localStorage.removeItem('auth_token'); - window.location.href = '/'; - } - } catch (error) { - localStorage.removeItem('auth_token'); - window.location.href = '/'; - } - } else { - window.location.href = '/'; - } - - const res = await fetch('/api/movies', { - method: 'GET', - headers: { 'Authorization': `Bearer ${token}` } - }); - - if (!res.ok) { - localStorage.removeItem('auth_token'); - window.location.href = '/'; - return; - } - - const movies = await res.json(); - - // Sort movies alphabetically by title - movies.sort((a, b) => a.title.localeCompare(b.title, 'fr', { sensitivity: 'base' })); - - const watchedRes = await fetch('/api/movies/watchedMovies', { - method: 'GET', - headers: { 'Authorization': `Bearer ${token}` } - }); - - let watchedMovies = []; - if (watchedRes.ok) { - watchedMovies = await watchedRes.json(); - } - - const totalMoviesCount = movies.length; - const watchedMoviesCount = watchedMovies.length; - document.getElementById('watched-ratio').innerText = `Vu: ${watchedMoviesCount} / ${totalMoviesCount} (${((watchedMoviesCount / totalMoviesCount) * 100).toFixed(1)}%)`; - - function launchConfetti() { - const duration = 3 * 1000; // 3 seconds - const animationEnd = Date.now() + duration; - const colors = ['#bb0000', '#ffffff', '#FFD700']; - - function frame() { - const timeLeft = animationEnd - Date.now(); - if (timeLeft <= 0) return; - confetti({ - particleCount: 5, - angle: 60, - spread: 55, - origin: { x: 0 } - }); - confetti({ - particleCount: 5, - angle: 120, - spread: 55, - origin: { x: 1 } - }); - requestAnimationFrame(frame); - } - frame(); - } - - function updateProgressBar(watchedCount, totalCount) { - const progressBar = document.getElementById('progress-bar'); - const percentage = (watchedCount / totalCount) * 100; - console.log(percentage); - progressBar.style.width = `${percentage}%`; - - if (percentage <= 50) { - progressBar.style.backgroundColor = `rgb(${255}, ${Math.floor((percentage / 50) * 255)}, 0)`; - } else { - progressBar.style.backgroundColor = `rgb(${Math.floor(255 - ((percentage - 50) / 50) * 255)}, 255, 0)`; - } - - progressBar.setAttribute('aria-valuenow', Math.round(percentage)); - - const videoModal = new bootstrap.Modal(document.getElementById("videoModal")); - - if (percentage === 100) { - videoModal.show(); - launchConfetti(); - document.getElementById("rewardVideo").play(); - } - } - - updateProgressBar(watchedMoviesCount, totalMoviesCount); - - const movieTableBody = document.getElementById('movie-table-body'); - movies.forEach(movie => { - const watchedMovie = watchedMovies.find(wm => wm.imdb_id === movie.imdb_id); - const watchedDate = watchedMovie ? new Date(watchedMovie.watchedDate).toLocaleString() : ''; - const movieRow = document.createElement('tr'); - movieRow.innerHTML = ` - - - - ${movie.title} - ${watchedDate} - `; - - // Set initial row color based on watched state - if (watchedMovie) { - movieRow.style.backgroundColor = 'rgba(144, 238, 144, 0.6)'; // Lighter light green with transparency - } else { - movieRow.style.backgroundColor = 'rgba(255, 99, 71, 0.6)'; // Lighter light red with transparency - } - - movieTableBody.appendChild(movieRow); - - movieRow.addEventListener('click', (event) => { - const checkbox = document.getElementById(`movie-${movie.imdb_id}`); - if (event.target.tagName !== 'INPUT') { - checkbox.checked = !checkbox.checked; - checkbox.dispatchEvent(new Event('change')); - } - }); - - const checkbox = document.getElementById(`movie-${movie.imdb_id}`); - checkbox.addEventListener('change', async (event) => { - const isChecked = event.target.checked; - const watchedDateCell = document.getElementById(`watched-date-${movie.imdb_id}`); - const row = event.target.closest('tr'); // Get the parent row - - if (isChecked) { - watchedDateCell.textContent = new Date().toLocaleString(); - row.style.backgroundColor = 'rgba(144, 238, 144, 0.6)'; // Apply light green with transparency - } else { - watchedDateCell.textContent = ''; - row.style.backgroundColor = 'rgba(255, 99, 71, 0.6)'; // Apply light red with transparency - } - - await fetch('/api/movies/users/updateWatchedMovies', { - method: 'PATCH', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${token}` - }, - body: JSON.stringify({ imdb_id: movie.imdb_id, isChecked }) - }); - - const updatedWatchedMoviesRes = await fetch('/api/movies/watchedMovies', { - method: 'GET', - headers: { 'Authorization': `Bearer ${token}` } - }); - - if (updatedWatchedMoviesRes.ok) { - const updatedWatchedMovies = await updatedWatchedMoviesRes.json(); - const updatedWatchedCount = updatedWatchedMovies.length; - document.getElementById('watched-ratio').innerText = `Vu: ${updatedWatchedCount} / ${totalMoviesCount} (${((updatedWatchedCount / totalMoviesCount) * 100).toFixed(1)}%)`; - updateProgressBar(updatedWatchedCount, totalMoviesCount); - - // Recalculate and update movies per day - const moviesLeft = totalMoviesCount - updatedWatchedCount; - const moviesPerDay = daysLeft > 0 ? (moviesLeft / daysLeft).toFixed(2) : moviesLeft; - document.getElementById('movies-per-day').textContent = `À voir par jour: ${moviesPerDay} films`; - } - }); - }); - - const moviesLeft = totalMoviesCount - watchedMoviesCount; - const moviesPerDay = daysLeft > 0 ? (moviesLeft / daysLeft).toFixed(2) : moviesLeft; - document.getElementById('movies-per-day').textContent = `À voir par jour: ${moviesPerDay} films`; - - document.getElementById('log-off').addEventListener('click', () => { - localStorage.removeItem('auth_token'); - window.location.href = '/'; - }); - - // Stop the video when the modal is closed - const videoModal = document.getElementById("videoModal"); - const rewardVideo = document.getElementById("rewardVideo"); - videoModal.addEventListener("hidden.bs.modal", function () { - rewardVideo.pause(); - rewardVideo.currentTime = 0; - }); - }; - \ No newline at end of file diff --git a/public/index.html b/public/index.html index a7a2984..e4b05bc 100644 --- a/public/index.html +++ b/public/index.html @@ -74,54 +74,7 @@ - + \ No newline at end of file diff --git a/public/js/app_checklist.js b/public/js/app_checklist.js new file mode 100644 index 0000000..db8dc33 --- /dev/null +++ b/public/js/app_checklist.js @@ -0,0 +1,196 @@ +window.onload = async function () { + const token = localStorage.getItem('auth_token'); + + const targetDate = new Date('March 2, 2025'); + const currentDate = new Date(); + const timeDifference = targetDate - currentDate; + const daysLeft = Math.floor(timeDifference / (1000 * 60 * 60 * 24)); + document.getElementById('time-left').textContent = `${daysLeft} jours`; + + if (token) { + try { + const decoded = JSON.parse(atob(token.split('.')[1])); + const userName = decoded.name; + document.getElementById('user-name').textContent = userName; + const currentTime = Math.floor(Date.now() / 1000); + if (decoded.exp && decoded.exp < currentTime) { + localStorage.removeItem('auth_token'); + window.location.href = '/'; + } + } catch (error) { + localStorage.removeItem('auth_token'); + window.location.href = '/'; + } + } else { + window.location.href = '/'; + } + + const res = await fetch('/api/movies', { + method: 'GET', + headers: { 'Authorization': `Bearer ${token}` } + }); + + if (!res.ok) { + localStorage.removeItem('auth_token'); + window.location.href = '/'; + return; + } + + const movies = await res.json(); + + // Sort movies alphabetically by title + movies.sort((a, b) => a.title.localeCompare(b.title, 'fr', { sensitivity: 'base' })); + + const watchedRes = await fetch('/api/movies/watchedMovies', { + method: 'GET', + headers: { 'Authorization': `Bearer ${token}` } + }); + + let watchedMovies = []; + if (watchedRes.ok) { + watchedMovies = await watchedRes.json(); + } + + const totalMoviesCount = movies.length; + const watchedMoviesCount = watchedMovies.length; + document.getElementById('watched-ratio').innerText = `Vu: ${watchedMoviesCount} / ${totalMoviesCount} (${((watchedMoviesCount / totalMoviesCount) * 100).toFixed(1)}%)`; + + function launchConfetti() { + const duration = 3 * 1000; // 3 seconds + const animationEnd = Date.now() + duration; + const colors = ['#bb0000', '#ffffff', '#FFD700']; + + function frame() { + const timeLeft = animationEnd - Date.now(); + if (timeLeft <= 0) return; + confetti({ + particleCount: 5, + angle: 60, + spread: 55, + origin: { x: 0 } + }); + confetti({ + particleCount: 5, + angle: 120, + spread: 55, + origin: { x: 1 } + }); + requestAnimationFrame(frame); + } + frame(); + } + + function updateProgressBar(watchedCount, totalCount) { + const progressBar = document.getElementById('progress-bar'); + const percentage = (watchedCount / totalCount) * 100; + console.log(percentage); + progressBar.style.width = `${percentage}%`; + + if (percentage <= 50) { + progressBar.style.backgroundColor = `rgb(${255}, ${Math.floor((percentage / 50) * 255)}, 0)`; + } else { + progressBar.style.backgroundColor = `rgb(${Math.floor(255 - ((percentage - 50) / 50) * 255)}, 255, 0)`; + } + + progressBar.setAttribute('aria-valuenow', Math.round(percentage)); + + const videoModal = new bootstrap.Modal(document.getElementById("videoModal")); + + if (percentage === 100) { + videoModal.show(); + launchConfetti(); + document.getElementById("rewardVideo").play(); + } + } + + updateProgressBar(watchedMoviesCount, totalMoviesCount); + + const movieTableBody = document.getElementById('movie-table-body'); + movies.forEach(movie => { + const watchedMovie = watchedMovies.find(wm => wm.imdb_id === movie.imdb_id); + const watchedDate = watchedMovie ? new Date(watchedMovie.watchedDate).toLocaleString() : ''; + const movieRow = document.createElement('tr'); + movieRow.innerHTML = ` + + + + ${movie.title} + ${watchedDate} + `; + + // Set initial row color based on watched state + if (watchedMovie) { + movieRow.style.backgroundColor = 'rgba(144, 238, 144, 0.6)'; // Lighter light green with transparency + } else { + movieRow.style.backgroundColor = 'rgba(255, 99, 71, 0.6)'; // Lighter light red with transparency + } + + movieTableBody.appendChild(movieRow); + + movieRow.addEventListener('click', (event) => { + const checkbox = document.getElementById(`movie-${movie.imdb_id}`); + if (event.target.tagName !== 'INPUT') { + checkbox.checked = !checkbox.checked; + checkbox.dispatchEvent(new Event('change')); + } + }); + + const checkbox = document.getElementById(`movie-${movie.imdb_id}`); + checkbox.addEventListener('change', async (event) => { + const isChecked = event.target.checked; + const watchedDateCell = document.getElementById(`watched-date-${movie.imdb_id}`); + const row = event.target.closest('tr'); // Get the parent row + + if (isChecked) { + watchedDateCell.textContent = new Date().toLocaleString(); + row.style.backgroundColor = 'rgba(144, 238, 144, 0.6)'; // Apply light green with transparency + } else { + watchedDateCell.textContent = ''; + row.style.backgroundColor = 'rgba(255, 99, 71, 0.6)'; // Apply light red with transparency + } + + await fetch('/api/movies/users/updateWatchedMovies', { + method: 'PATCH', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + }, + body: JSON.stringify({ imdb_id: movie.imdb_id, isChecked }) + }); + + const updatedWatchedMoviesRes = await fetch('/api/movies/watchedMovies', { + method: 'GET', + headers: { 'Authorization': `Bearer ${token}` } + }); + + if (updatedWatchedMoviesRes.ok) { + const updatedWatchedMovies = await updatedWatchedMoviesRes.json(); + const updatedWatchedCount = updatedWatchedMovies.length; + document.getElementById('watched-ratio').innerText = `Vu: ${updatedWatchedCount} / ${totalMoviesCount} (${((updatedWatchedCount / totalMoviesCount) * 100).toFixed(1)}%)`; + updateProgressBar(updatedWatchedCount, totalMoviesCount); + + // Recalculate and update movies per day + const moviesLeft = totalMoviesCount - updatedWatchedCount; + const moviesPerDay = daysLeft > 0 ? (moviesLeft / daysLeft).toFixed(2) : moviesLeft; + document.getElementById('movies-per-day').textContent = `À voir par jour: ${moviesPerDay} films`; + } + }); + }); + + const moviesLeft = totalMoviesCount - watchedMoviesCount; + const moviesPerDay = daysLeft > 0 ? (moviesLeft / daysLeft).toFixed(2) : moviesLeft; + document.getElementById('movies-per-day').textContent = `À voir par jour: ${moviesPerDay} films`; + + document.getElementById('log-off').addEventListener('click', () => { + localStorage.removeItem('auth_token'); + window.location.href = '/'; + }); + + // Stop the video when the modal is closed + const videoModal = document.getElementById("videoModal"); + const rewardVideo = document.getElementById("rewardVideo"); + videoModal.addEventListener("hidden.bs.modal", function () { + rewardVideo.pause(); + rewardVideo.currentTime = 0; + }); + }; \ No newline at end of file diff --git a/public/js/app_index.js b/public/js/app_index.js new file mode 100644 index 0000000..8097498 --- /dev/null +++ b/public/js/app_index.js @@ -0,0 +1,46 @@ +// Check if the user is already logged in by looking for auth_token in localStorage +if (localStorage.getItem('auth_token')) { + // If the token is found, redirect to /movies.html + window.location.href = '/movies.html'; + } + + // Handle login form submission + document.getElementById('login-form').addEventListener('submit', async function (e) { + e.preventDefault(); + + const email = document.getElementById('email').value; + const password = document.getElementById('password').value; + + const res = await fetch('/api/users/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email, password }) + }); + + if (res.ok) { + const data = await res.json(); + // Save the token to localStorage + localStorage.setItem('auth_token', data.token); + window.location.href = '/movies.html'; // Redirect to movies page on success + } else { + const error = await res.json(); + alert(`${error.message}`); + } + }); + + // Fetch version information from the API + async function fetchVersionInfo() { + const res = await fetch('/api/version'); + if (res.ok) { + const data = await res.json(); + // Update footer with the fetched version info + const footerText = `${data.date} - ${data.version} - ${data.message}`; + document.getElementById('footer-text').textContent = footerText; + } else { + document.getElementById('footer-text').textContent = ''; + } + } + + // Call the function to fetch and display the version info + // Doesn't work on prod, will fix later + fetchVersionInfo(); \ No newline at end of file diff --git a/public/js/app_movies.js b/public/js/app_movies.js new file mode 100644 index 0000000..4adffdf --- /dev/null +++ b/public/js/app_movies.js @@ -0,0 +1,118 @@ +window.onload = async function () { + const targetDate = new Date('March 2, 2025'); + const currentDate = new Date(); + const timeDifference = targetDate - currentDate; + const daysLeft = Math.floor(timeDifference / (1000 * 60 * 60 * 24)); + document.getElementById('time-left').textContent = `${daysLeft} jours`; + + const token = localStorage.getItem('auth_token'); + if (token) { + try { + const decoded = JSON.parse(atob(token.split('.')[1])); + const userName = decoded.name; + document.getElementById('user-name').textContent = userName; + + const currentTime = Math.floor(Date.now() / 1000); + if (decoded.exp && decoded.exp < currentTime) { + localStorage.removeItem('auth_token'); + window.location.href = '/'; + } + } catch (error) { + localStorage.removeItem('auth_token'); + window.location.href = '/'; + } + } else { + window.location.href = '/'; + } + + const res = await fetch('/api/movies', { + method: 'GET', + headers: { 'Authorization': `Bearer ${token}` }, + }); + + if (!res.ok) { + localStorage.removeItem('auth_token'); + window.location.href = '/'; + return; + } + + const movies = await res.json(); + + // Sort movies alphabetically by title + movies.sort((a, b) => a.title.localeCompare(b.title, 'fr', { sensitivity: 'base' })); + + const watchedRes = await fetch('/api/movies/watchedMovies', { + method: 'GET', + headers: { 'Authorization': `Bearer ${token}` }, + }); + + let watchedMovies = []; + if (watchedRes.ok) { + watchedMovies = await watchedRes.json(); + } + + const moviesList = document.getElementById('movies-list'); + const totalMoviesCount = movies.length; + const watchedMoviesCount = watchedMovies.length; + const ratioText = `Vu: ${watchedMoviesCount} / ${totalMoviesCount} (${((watchedMoviesCount / totalMoviesCount) * 100).toFixed(1)}%)`; + document.getElementById('watched-ratio').innerText = ratioText; + + movies.forEach(movie => { + const isChecked = watchedMovies.some(watchedMovie => watchedMovie.imdb_id === movie.imdb_id); + const watchedMovie = watchedMovies.find(wm => wm.imdb_id === movie.imdb_id); + const watchedDate = watchedMovie ? new Date(watchedMovie.watchedDate).toLocaleString() : ''; + + const movieDiv = document.createElement('div'); + movieDiv.classList.add('col-md-4', 'mb-4', 'movie-card'); + movieDiv.setAttribute('data-imdb-id', movie.imdb_id); + movieDiv.innerHTML = ` +
+ ${isChecked ? '
VISIONNÉ
' : ''} + ${movie.title} +
+
+ ${movie.title} + ⭐ ${movie.rating} +
+

${movie.category}

+

${movie.description}

+ ${isChecked ? `

Regardé le: ${watchedDate}

` : ''} +
+
`; + moviesList.appendChild(movieDiv); + }); + + document.getElementById('log-off').addEventListener('click', function () { + localStorage.removeItem('auth_token'); + window.location.href = '/'; + }); + + const filterSwitch = document.getElementById('flexSwitchCheckDefault'); + const savedFilterState = localStorage.getItem('filter-checkbox'); + const isFilterActive = savedFilterState === 'checked'; + filterSwitch.checked = isFilterActive; + + filterSwitch.addEventListener('change', function () { + const filterState = filterSwitch.checked ? 'checked' : 'unchecked'; + localStorage.setItem('filter-checkbox', filterState); + filterMovies(); + }); + + function filterMovies() { + const showUnwatchedOnly = filterSwitch.checked; + const movieCards = document.querySelectorAll('.movie-card'); + + movieCards.forEach(card => { + const imdbId = card.getAttribute('data-imdb-id'); + const isWatched = watchedMovies.some(watchedMovie => watchedMovie.imdb_id === imdbId); + + if (showUnwatchedOnly && isWatched) { + card.style.display = 'none'; + } else { + card.style.display = 'block'; + } + }); + } + + filterMovies(); + }; \ No newline at end of file diff --git a/public/js/app_register.js b/public/js/app_register.js new file mode 100644 index 0000000..0e38a8f --- /dev/null +++ b/public/js/app_register.js @@ -0,0 +1,45 @@ +// Check if the user is already logged in by looking for auth_token in localStorage +if (localStorage.getItem('auth_token')) { + // If the token is found, redirect to /movies.html + window.location.href = '/movies.html'; + } + + // Handle registration form submission + document.getElementById('register-form').addEventListener('submit', async function (e) { + e.preventDefault(); + + const name = document.getElementById('name').value; + const email = document.getElementById('email').value; + const password = document.getElementById('password').value; + const verifoof = document.getElementById('verifoof').value; + + const res = await fetch('/api/users/register', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name, email, password, verifoof }) + }); + + const responseMessageElement = document.getElementById('response-message'); + const modal = new bootstrap.Modal(document.getElementById('responseModal')); + + if (res.ok) { + const data = await res.json(); + // Show success message in the modal + responseMessageElement.textContent = data.message; + + // Show the modal + modal.show(); + + // Redirect to login after the modal is dismissed + document.getElementById('redirect-login').addEventListener('click', function () { + window.location.href = '/'; + }); + } else { + const error = await res.json(); + // Show error message in the modal + responseMessageElement.textContent = `Error: ${error.message}`; + + // Show the modal + modal.show(); + } + }); \ No newline at end of file diff --git a/public/js/app_user-stat.js b/public/js/app_user-stat.js new file mode 100644 index 0000000..82d5cc8 --- /dev/null +++ b/public/js/app_user-stat.js @@ -0,0 +1,99 @@ +window.onload = async function () { + const token = localStorage.getItem('auth_token'); + + if (token) { + try { + const decoded = JSON.parse(atob(token.split('.')[1])); // Manually decoding JWT + const userName = decoded.name; + document.getElementById('user-name').textContent = userName; + + // Verify JWT expiration + const currentTime = Math.floor(Date.now() / 1000); + if (decoded.exp && decoded.exp < currentTime) { + console.warn("Token is expired"); + localStorage.removeItem('auth_token'); + window.location.href = '/'; + } + } catch (error) { + console.error("Error decoding token:", error); + localStorage.removeItem('auth_token'); + window.location.href = '/'; + } + } else { + window.location.href = '/'; + } + + try { + const statsRes = await fetch('/api/users/stats', { + method: 'GET', + headers: { + 'Authorization': `Bearer ${token}` + } + }); + + if (!statsRes.ok) { + throw new Error('Failed to fetch user stats'); + } + + const stats = await statsRes.json(); + const userTableBody = document.getElementById('user-table-body'); + const table = document.querySelector('.user-table'); + const spinner = document.getElementById('loading-spinner'); + + // Ensure watchedRatio is treated as a number and sort in descending order + stats.sort((a, b) => parseFloat(b.watchedRatio) - parseFloat(a.watchedRatio)); + + // Clear previous rows to prevent duplication + userTableBody.innerHTML = ''; + + stats.forEach(userStat => { + const userRow = document.createElement('tr'); + userRow.innerHTML = ` + + ${userStat.name} + + ${userStat.watchedCount} + ${userStat.watchedRatio} + `; + userTableBody.appendChild(userRow); + }); + + // Hide spinner and show table after loading + spinner.style.display = 'none'; + table.style.display = 'table'; + + // Add event listener for user links + document.querySelectorAll('.user-link').forEach(link => { + link.addEventListener('click', function (event) { + event.preventDefault(); + const datasetMovies = this.dataset.movies; + console.log(datasetMovies); + const movies = JSON.parse(datasetMovies); + + // Clear the current movie list in the modal + const movieList = document.getElementById('movie-list'); + movieList.innerHTML = ''; + + // Populate the modal with the movies the user has watched + movies.forEach(movie => { + const movieItem = document.createElement('li'); + movieItem.classList.add('list-group-item'); + movieItem.textContent = movie.title; + movieList.appendChild(movieItem); + }); + + // Show the modal + const modal = new bootstrap.Modal(document.getElementById('moviesModal')); + modal.show(); + }); + }); + } catch (error) { + console.error('Error loading user statistics:', error); + } + + // Log-off functionality + document.getElementById('log-off').addEventListener('click', function() { + localStorage.removeItem('auth_token'); + window.location.href = '/'; + }); + }; \ No newline at end of file diff --git a/public/movies.html b/public/movies.html index f7d6c32..e561568 100644 --- a/public/movies.html +++ b/public/movies.html @@ -113,126 +113,7 @@ - + diff --git a/public/register.html b/public/register.html index f0f1cd5..510dc13 100644 --- a/public/register.html +++ b/public/register.html @@ -65,53 +65,7 @@ - + diff --git a/public/user-stat.html b/public/user-stat.html index 165c132..76bae8d 100644 --- a/public/user-stat.html +++ b/public/user-stat.html @@ -99,107 +99,7 @@ - + \ No newline at end of file diff --git a/routes/users.js b/routes/users.js index 36a0626..6e69ebc 100644 --- a/routes/users.js +++ b/routes/users.js @@ -7,47 +7,6 @@ const axios = require("axios"); const router = express.Router(); -// Fetch the latest commit from a GitHub repository -async function fetchLatestCommitFromGitHub() { - const githubOwner = process.env.GITHUB_OWNER; // Your GitHub username or org - const githubRepo = process.env.GITHUB_REPO; // Your repository name - - try { - const url = `https://api.github.com/repos/${githubOwner}/${githubRepo}/commits`; - const response = await axios.get(url); - - if (response.data && response.data.length > 0) { - const latestCommit = response.data[0]; - return { - sha: latestCommit.sha, - message: latestCommit.commit.message, - author: latestCommit.commit.author.name, - date: latestCommit.commit.author.date, - }; - } else { - throw new Error('No commits found.'); - } - } catch (error) { - throw new Error(`Error fetching commit: ${error.message}`); - } -} - -// Route to get the version (latest commit from GitHub) -router.get("/version", async (req, res) => { - try { - const latestCommit = await fetchLatestCommitFromGitHub(); - res.json({ - version: (latestCommit.sha).substring(0,5), - message: latestCommit.message, - author: latestCommit.author, - date: latestCommit.date, - }); - } catch (error) { - console.error("Error fetching latest commit:", error); - res.status(500).json({ message: "Error retrieving version information" }); - } -}); - // Set password for verification const woof = process.env.DOG_NAMES ? process.env.DOG_NAMES.split(",") : []; diff --git a/routes/version.js b/routes/version.js new file mode 100644 index 0000000..ffc0c84 --- /dev/null +++ b/routes/version.js @@ -0,0 +1,52 @@ +const axios = require("axios"); +const express = require("express"); +const router = express.Router(); + +// Fetch the latest commit from a GitHub repository +async function fetchLatestCommitFromGitHub() { + const githubOwner = process.env.GITHUB_OWNER; // Your GitHub username or org + const githubRepo = process.env.GITHUB_REPO; // Your repository name + + try { + const url = `https://api.github.com/repos/${githubOwner}/${githubRepo}/commits`; + + // Removed the unnecessary "body" property from the request + const response = await axios.get(url, { + headers: { + 'Content-Type': 'application/json', + } + }); + + if (response.data && response.data.length > 0) { + const latestCommit = response.data[0]; + return { + sha: latestCommit.sha, + message: latestCommit.commit.message, + author: latestCommit.commit.author.name, + date: latestCommit.commit.author.date, + }; + } else { + throw new Error('No commits found.'); + } + } catch (error) { + throw new Error(`Error fetching commit: ${error.message}`); + } + } + + // Route to get the version (latest commit from GitHub) + router.get("/", async (req, res) => { + try { + const latestCommit = await fetchLatestCommitFromGitHub(); + res.json({ + version: (latestCommit.sha).substring(0,5), + message: latestCommit.message, + author: latestCommit.author, + date: latestCommit.date, + }); + } catch (error) { + console.error("Error fetching latest commit:", error); + res.status(500).json({ message: "Error retrieving version information" }); + } + }); + + module.exports = router; \ No newline at end of file