feat(html, css, js): refactor HTML structure to improve semantics and accessibility, add header and footer to all pages, and enhance styling for better user experience

feat(js): implement utility functions for hiding and showing elements, and add event listeners for better interactivity
feat(js): create a new roulette game in TP6 with random number generation and qualifying number logic
fix(css): update styles for consistency and responsiveness across different screen sizes
This commit is contained in:
Djalim Simaila 2025-02-22 18:39:44 +01:00
parent f171492e15
commit 5ddb388348
11 changed files with 772 additions and 283 deletions

View File

@ -1,33 +1,67 @@
<!doctype html>
<head> <head>
<meta name="Acceuil"> <meta name="Acceuil" />
<meta charset="UTF-8"> <meta charset="UTF-8" />
<link rel="stylesheet" href="static/style.css"> <link rel="stylesheet" href="static/style.css" />
<script src="static/js/utils.js" defer></script>
</head> </head>
<body> <body>
<div id="main"> <header>
<div id="game_selection"> <div class="links">
<button type="" onclick="setup_game_one()">Game 1 : You guess</button> <a href="/" class="header_button">Home Page</a>
<button type="" onclick="setup_game_two()">Game 2 : The computer guesses</button> <a href="projects.html" class="header_button">Projets</a>
<a href="about.html" class="header_button">A propos de moi</a>
<a href="surprise.html" class="header_button">Surprise :)</a>
<a href="https://djalim.fr" class="header_button">Blog Perso</a>
</div>
<button id="display_header_links" onclick="toggle_all_header_links()">
</button>
</header>
<div id="main">
<div id="game_selection">
<button type="" onclick="setup_game_one()">
Game 1 : You guess
</button>
<button type="" onclick="setup_game_two()">
Game 2 : The computer guesses
</button>
</div>
<div id="game_one" class="hidden">
<h3>Which number am i thinking about ? :)</h3>
<p id="message1"></p>
<form action="javascript:;" onsubmit="process_guess()">
<input type="text" id="player_input" placeholder="type here" />
<button type="submit">Try guess</button>
</form>
<button type="button" onclick="setup_game_one()">Retry game</button>
<button type="button" onclick="back()">
Back to game selection
</button>
</div>
<div id="game_two" class="hidden">
<h3>Which number are you thinking about ? :)</h3>
<p id="message2"></p>
<button type="button" onclick="lower()"><u>L</u>ower</button>
<button type="button" onclick="greater()"><u>G</u>reater</button>
<button type="button" onclick="found()"><u>F</u>ound</button>
<button type="button" onclick="setup_game_two()">
<u>R</u>etry game
</button>
<button type="button" onclick="back()">
Back to game selection
</button>
</div>
</div> </div>
<div id="game_one" class="hidden">
<h3> Which number am i thinking about ? :)</h3> <footer>
<p id="message1"></p> <p>
<input type="text" id="player_input" placeholder="type here"> Fait par Djalim Simaila et sa haine de l'HTML, CSS, mais pas du
<button type="button" onclick="process_guess()" >Try guess</button> JavaScript ♥️
<button type="button" onclick="setup_game_one()">Retry game</button> </p>
<button type="button" onclick="back()">Back to game selection</button> <p>©2025</p>
</div> </footer>
<div id="game_two" class="hidden">
<h3> Which number are you thinking about ? :)</h3>
<p id="message2">is it big placeholder</p>
<button type="button" onclick="lower()">Lower</button>
<button type="button" onclick="greater()">Greater</button>
<button type="button" onclick="found()">Found</button>
<button type="button" onclick="setup_game_two()">Retry game</button>
<button type="button" onclick="back()">Back to game selection</button>
</div>
</div>
</body> </body>
<script src="static/js/TP3.js" defer></script>
<script src="static/js/TP3.js" defer></script>

View File

@ -1,16 +1,41 @@
<!doctype html>
<head> <head>
<meta name="Acceuil"> <meta name="Acceuil" />
<meta charset="UTF-8"> <meta charset="UTF-8" />
<link rel="stylesheet" href="static/style.css"> <link rel="stylesheet" href="static/style.css" />
<script src="static/js/utils.js" defer></script>
</head> </head>
<body> <body>
<div id="main"> <header>
<div id="pokemon_team"> <div class="links">
<img id="pokemon_frame" src="" alt=""> <a href="/" class="header_button">Home Page</a>
<p id="pokemon_name"></p> <a href="projects.html" class="header_button">Projets</a>
<p id="pokemon_desc"></p> <a href="about.html" class="header_button">A propos de moi</a>
<button type="button" onclick="chose_random_pokemon()">Check out a random pokemon</button> <a href="surprise.html" class="header_button">Surprise :)</a>
<a href="https://djalim.fr" class="header_button">Blog Perso</a>
</div>
<button id="display_header_links" onclick="toggle_all_header_links()">
</button>
</header>
<div id="main">
<div id="pokemon_team">
<img id="pokemon_frame" src="" alt="" />
<p id="pokemon_name"></p>
<p id="pokemon_desc"></p>
<button type="button" onclick="chose_random_pokemon()">
Check out a random pokemon
</button>
</div>
</div> </div>
</div>
<script src="static/js/TP4.js" defer></script> <footer>
<p>
Fait par Djalim Simaila et sa haine de l'HTML, CSS, mais pas du
JavaScript ♥️
</p>
<p>©2025</p>
</footer>
<script src="static/js/TP4.js" defer></script>
</body> </body>

View File

@ -1,27 +1,62 @@
<!doctype html>
<head> <head>
<meta name="Acceuil"> <meta name="Acceuil" />
<meta charset="UTF-8"> <meta charset="UTF-8" />
<link rel="stylesheet" href="static/style.css"> <link rel="stylesheet" href="static/style.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"> <script src="static/js/utils.js" defer></script>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"
/>
</head> </head>
<body onload="restoreList()"> <body onload="restoreList()">
<i class="fa-solid fa-trash"></i> <header>
<div id="main"> <div class="links">
<a href="/" class="header_button">Home Page</a>
<a href="projects.html" class="header_button">Projets</a>
<a href="about.html" class="header_button">A propos de moi</a>
<a href="surprise.html" class="header_button">Surprise :)</a>
<a href="https://djalim.fr" class="header_button">Blog Perso</a>
</div>
<button id="display_header_links" onclick="toggle_all_header_links()">
</button>
</header>
<h1>Grocery list</h1> <h1>Grocery list</h1>
<div>
<button id="clear_button" type="button" onclick="clear_input()"><i class="bi bi-eraser"></i></button> <form
<input type="text" id="new_item_input" placeholder="A new pair of Jordans"> action="javascript:;"
<input type="number" id="new_item_quantity" value="1" min="0"> onsubmit="addNewItemToList()"
<select id="new_item_unit"> onreset="clear_input()"
<option value="unit">unit</option> >
<option value="L">L</option> <button id="clear_button" type="reset">
<option value="KG">KG</option> <i class="bi bi-eraser"></i>
</select> </button>
</div> <input
<div id="grocery_list"> type="text"
</div> id="new_item_input"
</div> placeholder="A new pair of Jordans"
/>
<input type="number" id="new_item_quantity" value="1" min="0" />
<select id="new_item_unit">
<option value="unit">unit</option>
<option value="L">L</option>
<option value="KG">KG</option>
</select>
<button type="submit">
<i class="bi bi-plus"></i>
</button>
</form>
<div id="grocery_list"></div>
<footer>
<p>
Fait par Djalim Simaila et sa haine de l'HTML, CSS, mais pas du
JavaScript ♥️
</p>
<p>©2025</p>
</footer>
</body> </body>
<script src="static/js/TP5.js" defer></script>
<script src="static/js/TP5.js" defer></script>

49
TP6.html Normal file
View File

@ -0,0 +1,49 @@
<!doctype html>
<head>
<meta name="Acceuil" />
<meta charset="UTF-8" />
<link rel="stylesheet" href="static/style.css" />
<script src="static/js/utils.js" defer></script>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"
/>
</head>
<body>
<header>
<div class="links">
<a href="/" class="header_button">Home Page</a>
<a href="projects.html" class="header_button">Projets</a>
<a href="about.html" class="header_button">A propos de moi</a>
<a href="surprise.html" class="header_button">Surprise :)</a>
<a href="https://djalim.fr" class="header_button">Blog Perso</a>
</div>
<button id="display_header_links" onclick="toggle_all_header_links()">
</button>
</header>
<div id="setupGame">
<p>how many spins do you want to simulate</p>
<input
id="maxSpinInput"
type="number"
max="1000000"
min="1"
value="10000"
/>
<button type="" onclick="setupGame()">Start Spins</button>
</div>
<div id="currentSpin">
<h3>Current Spin</h3>
<p></p>
</div>
<div id="lastSpins"></div>
<footer>
<p>
Fait par Djalim Simaila et sa haine de l'HTML, CSS, mais pas du
JavaScript ♥️
</p>
<p>©2025</p>
</footer>
</body>
<script src="static/js/TP6.js" defer></script>

View File

@ -1,35 +1,75 @@
<!doctype html>
<head> <head>
<meta name="Acceuil"> <meta name="Acceuil" />
<meta charset="UTF-8"> <meta charset="UTF-8" />
<link rel="stylesheet" href="static/style.css"> <link rel="stylesheet" href="static/style.css" />
<script src="static/js/utils.js" defer></script>
</head> </head>
<body> <body>
<div id="header"> <header>
<div id=menubar> <div class="links">
<a href="" class="title_button"> Home Page </a> <a href="/" class="header_button">Home Page</a>
<a href="projects.html" class="title_button"> Projets </a> <a href="projects.html" class="header_button">Projets</a>
<a href="about.html" class="title_button"> A propos de moi </a> <a href="about.html" class="header_button">A propos de moi</a>
<a href="surprise.html" class="title_button"> Surprise :) </a> <a href="surprise.html" class="header_button">Surprise :)</a>
<a href="https://djalim.fr" class="title_button"> Blog Perso </a> <a href="https://djalim.fr" class="header_button">Blog Perso</a>
</div> </div>
<button id="display_header_links" onclick="toggle_all_header_links()">
</button>
</header>
<div id="title"> <div id="title">
<h1>I love commiting war crimes :)</h1> <h1>I love commiting war crimes :)</h1>
</div> </div>
</div>
<div id="content">
<p>
Qu'est-ce que le Lorem Ipsum?
Le Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un imprimeur anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker. <div id="content">
Pourquoi l'utiliser? <p>
Qu'est-ce que le Lorem Ipsum? Le Lorem Ipsum est simplement du faux
texte employé dans la composition et la mise en page avant
impression. Le Lorem Ipsum est le faux texte standard de
l'imprimerie depuis les années 1500, quand un imprimeur anonyme
assembla ensemble des morceaux de texte pour réaliser un livre
spécimen de polices de texte. Il n'a pas fait que survivre cinq
siècles, mais s'est aussi adapté à la bureautique informatique, sans
que son contenu n'en soit modifié. Il a été popularisé dans les
années 1960 grâce à la vente de feuilles Letraset contenant des
passages du Lorem Ipsum, et, plus récemment, par son inclusion dans
des applications de mise en page de texte, comme Aldus PageMaker.
Pourquoi l'utiliser? On sait depuis longtemps que travailler avec du
texte lisible et contenant du sens est source de distractions, et
empêche de se concentrer sur la mise en page elle-même. L'avantage
du Lorem Ipsum sur un texte générique comme 'Du texte. Du texte. Du
texte.' est qu'il possède une distribution de lettres plus ou moins
normale, et en tout cas comparable avec celle du français standard.
De nombreuses suites logicielles de mise en page ou éditeurs de
sites Web ont fait du Lorem Ipsum leur faux texte par défaut, et une
recherche pour 'Lorem Ipsum' vous conduira vers de nombreux sites
qui n'en sont encore qu'à leur phase de construction. Plusieurs
versions sont apparues avec le temps, parfois par accident, souvent
intentionnellement (histoire d'y rajouter de petits clins d'oeil,
voire des phrases embarassantes). D'où vient-il? Contrairement à une
opinion répandue, le Lorem Ipsum n'est pas simplement du texte
aléatoire. Il trouve ses racines dans une oeuvre de la littérature
latine classique datant de 45 av. J.-C., le rendant vieux de 2000
ans. Un professeur du Hampden-Sydney College, en Virginie, s'est
intéressé à un des mots latins les plus obscurs, consectetur,
extrait d'un passage du Lorem Ipsum, et en étudiant tous les usages
de ce mot dans la littérature classique, découvrit la source
incontestable du Lorem Ipsum. Il provient en fait des sections
1.10.32 et 1.10.33 du "De Finibus Bonorum et Malorum" (Des Suprêmes
Biens et des Suprêmes Maux) de Cicéron. Cet ouvrage, très populaire
pendant la Renaissance, est un traité sur la théorie de l'éthique.
Les premières lignes du Lorem Ipsum, "Lorem ipsum dolor sit
amet...", proviennent de la section
</p>
</div>
On sait depuis longtemps que travailler avec du texte lisible et contenant du sens est source de distractions, et empêche de se concentrer sur la mise en page elle-même. L'avantage du Lorem Ipsum sur un texte générique comme 'Du texte. Du texte. Du texte.' est qu'il possède une distribution de lettres plus ou moins normale, et en tout cas comparable avec celle du français standard. De nombreuses suites logicielles de mise en page ou éditeurs de sites Web ont fait du Lorem Ipsum leur faux texte par défaut, et une recherche pour 'Lorem Ipsum' vous conduira vers de nombreux sites qui n'en sont encore qu'à leur phase de construction. Plusieurs versions sont apparues avec le temps, parfois par accident, souvent intentionnellement (histoire d'y rajouter de petits clins d'oeil, voire des phrases embarassantes). <footer>
<p>
D'où vient-il? Fait par Djalim Simaila et sa haine de l'HTML, CSS, mais pas du
JavaScript ♥️
Contrairement à une opinion répandue, le Lorem Ipsum n'est pas simplement du texte aléatoire. Il trouve ses racines dans une oeuvre de la littérature latine classique datant de 45 av. J.-C., le rendant vieux de 2000 ans. Un professeur du Hampden-Sydney College, en Virginie, s'est intéressé à un des mots latins les plus obscurs, consectetur, extrait d'un passage du Lorem Ipsum, et en étudiant tous les usages de ce mot dans la littérature classique, découvrit la source incontestable du Lorem Ipsum. Il provient en fait des sections 1.10.32 et 1.10.33 du "De Finibus Bonorum et Malorum" (Des Suprêmes Biens et des Suprêmes Maux) de Cicéron. Cet ouvrage, très populaire pendant la Renaissance, est un traité sur la théorie de l'éthique. Les premières lignes du Lorem Ipsum, "Lorem ipsum dolor sit amet...", proviennent de la section </p>
</p> <p>©2025</p>
</div> </footer>
</body> </body>

View File

@ -1,29 +1,56 @@
<!doctype html>
<head> <head>
<meta name="Acceuil"> <meta name="Acceuil" />
<meta charset="UTF-8"> <meta charset="UTF-8" />
<link rel="stylesheet" href="static/style.css"> <link rel="stylesheet" href="static/style.css" />
<script src="static/js/utils.js" defer></script>
</head> </head>
<body> <body>
<div id="header"> <header>
<div id=menubar> <div class="links">
<a href="" class="title_button"> Home Page </a> <a href="/" class="header_button">Home Page</a>
<a href="projects.html" class="title_button"> Projets </a> <a href="projects.html" class="header_button">Projets</a>
<a href="about.html" class="title_button"> A propos de moi </a> <a href="about.html" class="header_button">A propos de moi</a>
<a href="surprise.html" class="title_button"> Surprise :) </a> <a href="surprise.html" class="header_button">Surprise :)</a>
<a href="https://djalim.fr" class="title_button"> Blog Perso </a> <a href="https://djalim.fr" class="header_button">Blog Perso</a>
</div> </div>
<div id="title"> <button id="display_header_links" onclick="toggle_all_header_links()">
<h1>Mes projets</h1>
</div> </button>
</div> </header>
<div id="content">
<div class="project_box">
<img class="project_box_thumbnail" src="static/assets/images/Da_fookin_owl-1.png" alt="placeholder">
<p class="project_box_summary">
Le Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un imprimeur anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker
</p>
</div>
</div>
</body>
<div id="title">
<h1>Mes projets</h1>
</div>
<div id="content">
<div class="project_box">
<img
class="project_box_thumbnail"
src="static/assets/images/Da_fookin_owl-1.png"
alt="placeholder"
/>
<p class="project_box_summary">
Le Lorem Ipsum est simplement du faux texte employé dans la
composition et la mise en page avant impression. Le Lorem Ipsum
est le faux texte standard de l'imprimerie depuis les années
1500, quand un imprimeur anonyme assembla ensemble des morceaux
de texte pour réaliser un livre spécimen de polices de texte. Il
n'a pas fait que survivre cinq siècles, mais s'est aussi adapté
à la bureautique informatique, sans que son contenu n'en soit
modifié. Il a été popularisé dans les années 1960 grâce à la
vente de feuilles Letraset contenant des passages du Lorem
Ipsum, et, plus récemment, par son inclusion dans des
applications de mise en page de texte, comme Aldus PageMaker
</p>
</div>
</div>
<footer>
<p>
Fait par Djalim Simaila et sa haine de l'HTML, CSS, mais pas du
JavaScript ♥️
</p>
<p>©2025</p>
</footer>
</body>

View File

@ -5,90 +5,135 @@ var guessedNumber;
var minimum; var minimum;
var maximum; var maximum;
function showText(element, text) {
function hide(element){
element.classList.add("hidden")
}
function unhide(element){
element.classList.remove("hidden")
}
function showText(element, text){
console.log(element);
console.log(text);
element.textContent = text; element.textContent = text;
} }
/** /**
* Represents a book. * Return a randon between min and max.
* @constructor * @param {number} min - The minimum value of the random number.
* @param {string} title - The title of the book. * @param {number} max - The maximum value of the random number.
* @param {string} author - The author of the book. * @return {number}
*/ */
function randint(min,max) { function randint(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min); return Math.floor(Math.random() * (max - min + 1) + min);
} }
function back(){ /**
* Returns to the previous state
* @return {void}
*/
function back() {
unhide(document.getElementById("game_selection")); unhide(document.getElementById("game_selection"));
hide(document.getElementById("game_one")); hide(document.getElementById("game_one"));
hide(document.getElementById("game_two")); hide(document.getElementById("game_two"));
document.removeEventListener("keydown", process_keydown);
} }
/**
function setup_game_one(){ * This function shows the first game
hide(document.getElementById("game_selection")) * @return {void}
*/
function setup_game_one() {
hide(document.getElementById("game_selection"));
unhide(document.getElementById("game_one")); unhide(document.getElementById("game_one"));
numberToGuess = randint(1,100); numberToGuess = randint(1, 100);
console.log(numberToGuess) console.log(numberToGuess);
showText(document.getElementById("message1"),"") showText(document.getElementById("message1"), "");
document.getElementById("player_input").value = ""; document.getElementById("player_input").value = "";
} }
function process_guess(){ /**
console.log("processing"); * This function is responsible for processing the player's guess in game one.
let guessedNumber = parseInt(document.getElementById("player_input").value); * It retrieves the player's input, validates it, and compares it to the number to guess.
* It also provides feedback to the player based on their guess
* @return {void}
*/
function process_guess() {
let player_input = document.getElementById("player_input");
let guessedNumber = parseInt(player_input.value);
player_input.value = "";
let message_box = document.getElementById("message1"); let message_box = document.getElementById("message1");
if (isNaN(guessedNumber)){ if (isNaN(guessedNumber)) {
showText(message_box,"Not a valid number, Try again"); showText(message_box, "Not a valid number, Try again");
} }
if (guessedNumber > numberToGuess) { if (guessedNumber > numberToGuess) {
showText(message_box,"Nop, Too high, try again"); showText(message_box, "Nop, " + guessedNumber + " is too high, try again");
} }
if (guessedNumber < numberToGuess) { if (guessedNumber < numberToGuess) {
showText(message_box,"Nop, Too low, try again"); showText(message_box, "Nop, " + guessedNumber + " is too low, try again");
} }
if (guessedNumber === numberToGuess) { if (guessedNumber === numberToGuess) {
showText(message_box,"You found it well played"); showText(message_box, "You found it well played");
} }
console.log("done processing");
}
///
function pick_number(smart=false){
if(smart) return Math.floor((minimum+maximum)/2);
return randint(minimum,maximum);
} }
function setup_game_two(){ /**
hide(document.getElementById("game_selection")) * This function tries to predict the player's number
* @param {bool} smart - use dichotomic search for guessing
* @returns {number} - the predicted number
*/
function pick_number(smart = false) {
if (smart) return Math.floor((minimum + maximum) / 2);
return randint(minimum, maximum);
}
/**
* Processes the keydown events for game two to handle player input (lower, greater, found, retry).
* @param {KeyboardEvent} event - The keyboard event object.
* @return {void}
*/
function process_keydown(event) {
switch (event.key) {
case "L":
case "l":
lower();
break;
case "G":
case "g":
greater();
break;
case "F":
case "f":
found();
break;
case "R":
case "r":
document.removeEventListener("keydown", process_keydown);
setup_game_two();
break;
}
}
function setup_game_two() {
hide(document.getElementById("game_selection"));
unhide(document.getElementById("game_two")); unhide(document.getElementById("game_two"));
minimum = 1; minimum = 1;
maximum = 100; maximum = 100;
guessedNumber = pick_number() guessedNumber = pick_number();
showText(document.getElementById("message2"),"is it "+guessedNumber+" ?") showText(
document.getElementById("message2"),
"is it " + guessedNumber + " ?",
);
document.addEventListener("keydown", process_keydown);
} }
function lower(){ function lower() {
maximum = guessedNumber - 1; maximum = guessedNumber - 1;
guessedNumber = pick_number() guessedNumber = pick_number();
showText(document.getElementById("message2"),"is it "+guessedNumber+" ?") showText(
document.getElementById("message2"),
"is it " + guessedNumber + " ?",
);
} }
function greater(){ function greater() {
minimum = guessedNumber + 1; minimum = guessedNumber + 1;
guessedNumber = pick_number() guessedNumber = pick_number();
showText(document.getElementById("message2"),"is it "+guessedNumber+" ?") showText(
document.getElementById("message2"),
"is it " + guessedNumber + " ?",
);
} }
function found(){ function found() {
showText(document.getElementById("message2"),"yay i found it") showText(document.getElementById("message2"), "yay i found it");
} }

View File

@ -1,15 +1,25 @@
var grocery_array = [] var grocery_array = [];
function clear_input(){ /*
document.getElementById("new_item_input").value = ""; * This function will return a random number
* param min : minimum limit of the range (inclusive)
* param max: maximum limit of the range (inclusive).
* returns : Random integer within specified limits.
*/
function randint(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
} }
function addItemToList(item){ function clear_input() {
grocery_array.push(item) document.getElementById("new_item_input").value = "";
localStorage.setItem("grocery_list",JSON.stringify(grocery_array)) }
function addItemToList(item) {
grocery_array.push(item);
localStorage.setItem("grocery_list", JSON.stringify(grocery_array));
let item_box = document.createElement("div"); let item_box = document.createElement("div");
item_box.classList.add("grocery_item") item_box.classList.add("grocery_item");
let item_name_container = document.createElement("span"); let item_name_container = document.createElement("span");
item_name_container.classList.add("grocery_item_name"); item_name_container.classList.add("grocery_item_name");
@ -17,67 +27,63 @@ function addItemToList(item){
item_name_container.textContent = item; item_name_container.textContent = item;
let item_button = document.createElement("button"); let item_button = document.createElement("button");
item_button.innerHTML = "<i class='bi bi-trash'></i>" item_button.innerHTML = "<i class='bi bi-trash'></i>";
item_button.onclick = (ev) =>{ item_button.onclick = (ev) => {
let parent_div = ev.target.parentElement.closest('div'); let parent_div = ev.target.parentElement.closest("div");
let item_name; let item_name;
var children = parent_div.childNodes; var children = parent_div.childNodes;
for (var i=0; i < children.length; i++) { for (var i = 0; i < children.length; i++) {
console.log(children[i]); console.log(children[i]);
if (children[i].tagName == "SPAN") { if (children[i].tagName == "SPAN") {
item_name = children[i].textContent; item_name = children[i].textContent;
break; break;
} }
} }
grocery_array = grocery_array.filter((value) => value != item_name ); grocery_array = grocery_array.filter((value) => value != item_name);
localStorage.setItem("grocery_list",JSON.stringify(grocery_array)) localStorage.setItem("grocery_list", JSON.stringify(grocery_array));
parent_div.remove(); parent_div.remove();
} };
item_box.appendChild(item_button); item_box.appendChild(item_button);
item_box.appendChild(item_name_container); item_box.appendChild(item_name_container);
document.getElementById("grocery_list").appendChild(item_box); document.getElementById("grocery_list").appendChild(item_box);
} }
function addNewItemToList() {
function addNewItemToList(){ let input = document.getElementById("new_item_input");
let input = document.getElementById("new_item_input")
if (input.value === "") return; if (input.value === "") return;
let item = input.value; let item = input.value;
input.value = ""; input.value = "";
// quantity // quantity
let quantity = document.getElementById("new_item_quantity").value let quantity = document.getElementById("new_item_quantity").value;
// unit // unit
let e = document.getElementById("new_item_unit"); let e = document.getElementById("new_item_unit");
let text = e.options[e.selectedIndex].text; let text = e.options[e.selectedIndex].text;
switch(text){ switch (text) {
case 'L': case "L":
item = ""+ quantity + (quantity == 1 ? " liter of ":" liters of ") + item; item =
"" + quantity + (quantity == 1 ? " liter of " : " liters of ") + item;
break; break;
case 'KG': case "KG":
item = ""+ quantity + (quantity == 1 ? " kilogram of":" kilograms of ") + item; item =
"" +
quantity +
(quantity == 1 ? " kilogram of" : " kilograms of ") +
item;
break; break;
default: default:
item = "" + quantity + " " + item; item = "" + quantity + " " + item;
} }
addItemToList(item) addItemToList(item);
} }
function restoreList() {
function restoreList(){ JSON.parse(localStorage.getItem("grocery_list")).forEach((element) => {
JSON.parse(localStorage.getItem("grocery_list")).forEach(element => {
addItemToList(element); addItemToList(element);
}); });
} }
document.addEventListener('keydown', function(event) {
if (event.key === 'Enter') {
addNewItemToList();
}
});

164
static/js/TP6.js Normal file
View File

@ -0,0 +1,164 @@
/*
* TP6: Roulette
* Author: SIMAILA Djalim
* Date: 2025-01-27
* Description: A roulette game
* Version: 1.0
*/
/*
* The amount of money of a bet
* @type {Number}
* @example 1
*/
var bet = 1;
var currentSpin = 0;
/*
* Array of the n next spins
* @type {Array}
* @example [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
*/
var spinArray;
var potentialQualifyingNumbers = [];
/*
* Object containing the qualifying numbers , and the remaining spins in which they are played
* @type {Object}
* @example {10: 3, 15: 5, 20: 1}
*/
var qualifyingNumbers = {};
/**
* Array containing the wining numbers , and the winning amount
* @type {Array}
* @example [[10, 5], [15, 10], [20, 15]]
*/
var winingNumbers = [];
/**
* Array containing the qualifying number that didn't win
* @type {Array}
* @example [10,15,20]
*/
var losingNumbers = [];
var spinInterval;
function lowerBound() {
return currentSpin - 30 < 0 ? 0 : currentSpin - 30;
}
/*
* Function to generate a random array of numbers
* @param len: length of the number array
* @returns {Array} numberArray
*/
function generate_random_array(len = 30) {
let numberArray = [];
for (let i = 0; i < len; i++)
numberArray.push(Math.floor(Math.random() * 37));
return numberArray;
}
/*
* Function to check if a number is qualifying
* @param num: number to check
* @returns {Boolean} true if the number is qualifying, false otherwise
*/
function qualifyingPreprocess() {
let currentNumber = spinArray[currentSpin];
if (!spinArray.slice(lowerBound(), currentSpin).includes(currentNumber)) {
potentialQualifyingNumbers.push({
number: currentNumber,
firstOccurence: currentSpin,
secondOccurence: null,
thirdOccurence: null,
});
}
potentialQualifyingNumbers = potentialQualifyingNumbers.filter(
(potientialNumber) => currentSpin - potientialNumber.firstOccurence < 18,
);
let qualifiedIndexes = new Set();
potentialQualifyingNumbers.forEach((potentialNumber, index) => {
if (potentialNumber.number == currentNumber) {
if (potentialNumber.firstOccurence == currentSpin) return;
if (potentialNumber.secondOccurence == null)
potentialNumber.secondOccurence = currentSpin;
else if (potentialNumber.thirdOccurence == null)
potentialNumber.thirdOccurence = currentSpin;
}
if (
potentialNumber.secondOccurence != null &&
potentialNumber.thirdOccurence != null
) {
let space1 =
potentialNumber.secondOccurence - potentialNumber.firstOccurence;
let space2 =
potentialNumber.thirdOccurence - potentialNumber.secondOccurence;
if (Math.abs(space2 - space1) <= 6) {
if (
spinArray[currentSpin] !== spinArray[currentSpin - 1] &&
spinArray[currentSpin] !== spinArray[currentSpin - 2]
) {
qualifyingNumbers[potentialNumber.number] = 9;
qualifiedIndexes.add(index);
}
}
}
});
potentialQualifyingNumbers = potentialQualifyingNumbers.filter(
(_, index) => !qualifiedIndexes.has(index),
);
}
function setupGame() {
spinArray = generate_random_array(
document.getElementById("maxSpinInput").value,
);
document.getElementById("setupGame").classList.add("hidden");
spinInterval = setInterval(() => processSpin(), 100);
}
function processSpin() {
// Check if the number is qualifying
qualifyingPreprocess();
for (let number in qualifyingNumbers) {
// if the number is a wining number
if (number == currentSpin) {
// Add the wining number to the wining numbers Array
winingNumbers.push([
number,
36 * bet - (9 - qualifyingNumbers[number]), // loss
]);
}
qualifyingNumbers[number] -= 1;
if (qualifyingNumbers[number] == 0) {
losingNumbers.push(number);
delete qualifyingNumbers[number];
}
}
console.log(potentialQualifyingNumbers);
console.log(qualifyingNumbers);
console.log(winingNumbers);
console.log(losingNumbers);
currentSpin += 1;
showLastSpins();
}
function showLastSpins() {
document.getElementById("lastSpins").replaceChildren();
spinArray.slice(lowerBound(), currentSpin).forEach((number) => {
let numberDiv = document.createElement("div");
numberDiv.classList.add("spinNumber");
numberDiv.textContent = number;
document.getElementById("lastSpins").appendChild(numberDiv);
});
}

15
static/js/utils.js Normal file
View File

@ -0,0 +1,15 @@
function hide(element) {
element.classList.add("hidden");
}
function unhide(element) {
element.classList.remove("hidden");
}
function toggle_all_header_links() {
const headerLinks = document.querySelector("header > .links");
const button_link = document.querySelector("header > button");
headerLinks.classList.toggle("display_links");
button_link.textContent = headerLinks.classList.contains("display_links")
? "▲"
: "▼";
}

View File

@ -1,133 +1,182 @@
@font-face { @font-face {
font-family: JetBrainsMono; font-family: JetBrainsMono;
src: url(assets/font/JetBrainsMono-Regular.woff2) format(woff2); src: url(assets/font/JetBrainsMono-Regular.woff2) format(woff2);
} }
* { * {
font-family: JetBrainsMono; font-family: JetBrainsMono;
--color-text: #f8f8f2;
--color-background: #282a36;
--color-current-line: #44475a;
--color-purple: #bd93f9;
} }
body { body {
color:#F8F8F2; color: var(--color-text);
display: flex; display: flex;
justify-content: center; justify-content: center;
background-color: #282936; align-items: center;
flex-direction: column; background-color: var(--color-background);
flex-direction: column;
} }
#main{ header {
display: flex; display: flex;
justify-content: center; background-color: var(--color-current-line);
align-items: center; border-radius: 20px;
flex-direction: column; padding: 10px;
overflow: hidden;
& > .links {
display: flex;
justify-content: space-between;
}
} }
#pokemon_team{ @media screen and (min-width: 740px) {
display: flex; header > .links {
justify-content: center; flex-direction: row;
align-items: center; gap: 30px;
flex-direction: column; }
#display_header_links {
display: none;
}
}
@media screen and (max-width: 739px) {
header {
gap: 10px;
align-items: baseline;
& > .links {
flex-direction: column;
gap: 10px;
overlay: hidden;
transition: max-height 300ms ease-out;
max-height: 41px;
&.display_links {
max-height: 270px;
}
}
& > button {
padding: 8px 12px;
cursor: pointer;
}
}
} }
#grocery_list { .header_button {
display: flex; color: black;
flex-direction: column; padding: 10px 8px;
border-radius: 10px;
background-color: var(--color-purple);
text-decoration: none !important;
text-align: center;
} }
.header_button:hover {
#header { background-color: var(--color-purple);
display: flex;
flex-direction: column;
gap: 1rem;
justify-content: center;
} }
#title { #title {
padding : 1rem; padding: 1rem;
} }
#menubar { footer {
background-color: #44475A; display: flex;
border-radius: 20px; flex-direction: row;
padding: 10px; gap: 2rem;
display: flex; justify-content: space-evenly;
gap: 50px; background-color: var(--color-current-line);
justify-content: center; border-radius: 20px;
padding: 4px 20px;
margin-top: 20px;
}
#main {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
height: 100vh;
}
#pokemon_team {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
#grocery_list {
display: flex;
flex-direction: column;
} }
button { button {
color: black; color: black;
padding : 10px; padding: 10px;
border-radius: 10px; border-radius: 10px;
background-color: #BD93F9; background-color: var(--color-purple);
border: none; border: none;
text-decoration: none !important; text-decoration: none !important;
} }
button:hover { button:hover {
background-color: #BD93F966; background-color: var(--color-purple);
} }
.title_button {
color: black;
padding : 10px;
border-radius: 10px;
background-color: #BD93F9;
text-decoration: none !important;
}
.title_button:hover {
background-color: #BD93F966;
}
#content { #content {
background-color : #44475A; background-color: var(--color-current-line);
padding: 10px; padding: 10px;
border-radius: 20px; border-radius: 20px;
margin-left: 10rem; margin-left: 10rem;
margin-right: 10rem; margin-right: 10rem;
} }
.project_box { .project_box {
flex-direction: row; flex-direction: row;
display: flex; display: flex;
gap: 1rem; gap: 1rem;
} }
.project_box_thumbnail { .project_box_thumbnail {
width: 20rem; width: 20rem;
height: 20rem; height: 20rem;
} }
.hidden { .hidden {
display: none; display: none;
} }
input { input {
color: #F8F8F2; color: var(--color-text);
border-radius: 30px; border-radius: 30px;
border: none; border: none;
padding: 10px; padding: 10px;
background-color: #44475A; background-color: var(--color-current-line);
margin: 10px; margin: 10px;
} }
#pokemon_frame{ select {
width: 200px; color: var(--color-text);
height: 200px; border-radius: 30px;
border: none;
padding: 10px;
background-color: var(--color-current-line);
margin: 10px;
} }
.grocery_item{ #pokemon_frame {
margin: 15px; width: 200px;
height: 200px;
} }
.grocery_item_name{ .grocery_item {
padding: 10px; margin: 15px;
background-color:#44475A; }
border-color: #BD93F9;
border-radius: 10px; .grocery_item_name {
margin: 10px; padding: 10px;
background-color: var(--color-current-line);
border-color: var(--color-purple);
border-radius: 10px;
margin: 10px;
} }