-
+
+
diff --git a/catalog/css/base.css b/catalog/css/base.css
index ce53933..025849c 100755
--- a/catalog/css/base.css
+++ b/catalog/css/base.css
@@ -2,38 +2,87 @@
* {
margin: 0;
padding: 0;
+ box-sizing: border-box;
}
-h1 {
- font-size: 6vw;
-}
-
-h2 {
- font-size: 4vw;
-}
-
-h3 {
- font-size: 3vw;
-}
-
-h4 {
- font-size: 2vw;
+@view-transition {
+ navigation: auto;
}
+h1,
+h2,
+h3,
+h4,
h5,
h6,
p,
a,
-label {
- font-size: 1vw;
+label,
+button,
+input,
+input[type="submit"],
+input[type="number"],
+select,
+option {
+ font-family: "Comic Relief", system-ui;
+ font-weight: 400;
+ font-style: normal;
+}
+
+h1 {
+ font-size: 8vw;
+ margin-bottom: 15px;
+ font-weight: 800;
+}
+
+h2 {
+ font-size: 6vw;
+ font-weight: 700;
+}
+
+h3 {
+ font-size: 5vw;
+ font-weight: 600;
+}
+
+h4 {
+ font-size: 3vw;
+ font-weight: 500;
+}
+
+h5 {
+ font-size: 1.7vw;
+ font-weight: 500;
+}
+
+h6,
+p,
+a,
+label,
+input,
+select,
+option,
+ul li,
+i {
+ font-size: 1.3vw;
+}
+
+i {
+ text-align: center;
+ justify-self: center;
+ padding: 5px;
+}
+
+.line {
+ height: 2px;
+ border-bottom: 2px solid black;
+}
+
+.shadow {
+ box-shadow: 6px 6px 14px rgba(0, 0, 0, 0.45);
}
/********** NAV BAR **********/
-nav {
- margin-bottom: 25px;
-}
-
-nav ul {}
nav ul li {
display: inline-block;
@@ -46,6 +95,121 @@ nav ul li a {
text-decoration: none;
}
+#cart {
+ position: relative;
+}
+
+#dotton {
+ position: absolute;
+ top: 6px;
+ right: 6px;
+ border-radius: 50%;
+ height: 20px;
+ width: 20px;
+ z-index: 5;
+}
+
+#dotton * {
+ position: absolute;
+ left: 4px;
+ top: -2px;
+}
+
+#bg {
+ z-index: -1;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100vh;
+ overflow: hidden;
+ overflow-y: hidden;
+}
+
+.bubble {
+ animation: float-random 10s infinite linear;
+}
+
+@keyframes float-random {
+ 0% {
+ transform: translate(0, 0);
+ }
+
+ 50% {
+ /* We'll set the final translation in JavaScript */
+ transform: translate(var(--random-x), var(--random-y));
+ }
+
+ 100% {
+ transform: translate(0, 0);
+ }
+}
+
+@keyframes float-curve {
+ 0% {
+ transform: translate(0, 0);
+ }
+
+ 25% {
+ /* Introduce an intermediate point to create a curve */
+ transform: translate(
+ calc(var(--random-x) / 2 + var(--curve-x)),
+ calc(var(--random-y) / 2 + var(--curve-y))
+ );
+ }
+
+ 50% {
+ transform: translate(var(--random-x), var(--random-y));
+ }
+
+ 75% {
+ transform: translate(
+ calc(var(--random-x) / 2 + var(--curve-x)),
+ calc(var(--random-y) / 2 + var(--curve-y))
+ );
+ }
+
+ 100% {
+ transform: translate(0, 0);
+ }
+}
+
+/* Add slight variations to the animation for a more natural feel */
+#bg:nth-child(odd) {
+ animation-delay: 1s;
+ animation-duration: 12s;
+}
+
+#bg:nth-child(even) {
+ animation-delay: 2s;
+ animation-duration: 9s;
+}
+
+/* You can add more variations using other nth-child selectors */
+#bg:nth-child(7n) {
+ animation-delay: 0.5s;
+ animation-duration: 11s;
+}
+
+#welcome {
+ position: absolute;
+ top: 50%;
+ left: 20%;
+ border-radius: 18px;
+ padding: 25px;
+ /* Optional: Add a slightly transparent background to the welcome card itself for better readability */
+}
+
+.glass {
+ border-radius: 18px;
+ backdrop-filter: blur(50px);
+ background-color: rgba(173, 202, 235, 0.4);
+}
+
+#welcome p {
+ float: right;
+}
+
/********** LAYOUT CLASSES **********/
.absolute_h_center {
position: absolute;
@@ -63,6 +227,17 @@ nav ul li a {
justify-content: center;
}
+.left_align {
+ align-items: left;
+ justify-content: left;
+ text-align: left;
+}
+
+.right_align {
+ align-items: right;
+ justify-content: right;
+}
+
.row {
display: flex;
flex-direction: row;
@@ -79,35 +254,72 @@ nav ul li a {
.grid {
display: grid;
- grid-template-columns: 20% 20% 20% 20%;
- column-gap: 75px;
+ grid-template-columns: 23% 23% 23% 23%;
+ column-gap: 2%;
row-gap: 25px;
+ height: 600px;
+ overflow-y: scroll;
+ border-radius: 18px;
+}
+
+.grid_2x1 {
+ display: grid;
+ grid-template-columns: 48% 48%;
+ column-gap: 4%;
+}
+
+.list {
+ display: block;
+ overflow-y: auto;
+}
+
+.list * {
+ height: 35px;
+}
+
+/********** FORMS **********/
+input,
+select {
+ padding: 5px;
+ border: none;
+ outline: none;
+ border-radius: 9px;
+}
+
+input[type="submit"],
+input[type="reset"] {
+ padding-left: 25px;
+ padding-right: 25px;
+}
+
+/********** LISTS **********/
+ul li {
+ list-style: none;
}
/********** CARDS **********/
.card {
display: block;
- width: 250px;
- height: 250px;
- border: 1px solid black;
+ width: 275px;
+ height: 275px;
+ border-radius: 18px;
}
.product_page_card {
display: block;
- border: 1px solid black;
+ border-radius: 18px;
}
.card .img_container img {
- min-width: 60%;
- max-width: 60%;
+ min-width: 50%;
+ max-width: 50%;
height: auto;
}
.product_page_card .img_container img {
- min-width: 30%;
- max-width: 30%;
- height: auto;
- border: 1px solid red;
+ width: auto;
+ min-height: 275px;
+ max-height: 275px;
}
/********** MARGINS & PADDING **********/
@@ -160,6 +372,14 @@ nav ul li a {
width: 100%;
}
+.md_width {
+ width: 45%;
+}
+
+.sm_width {
+ width: 20%;
+}
+
/********** MODALS **********/
.modal {
display: none;
diff --git a/catalog/css/colors.css b/catalog/css/colors.css
index 532138a..f5da48c 100644
--- a/catalog/css/colors.css
+++ b/catalog/css/colors.css
@@ -1,14 +1,34 @@
:root {
- --bg: #EBF2FA;
- --gold: #FFD700;
- --brwn: #F4A460;
- --blue: #1E90FF;
- --red: #DC143C;
+ --bg: #ebf2fa;
+ --bg-shade: #cedff3;
+ --bg-shade2: #adcaeb;
+ --gold: #ffd700;
+ --brwn: #f4a460;
+ --blue: #1e90ff;
+ --d-blue: #0066cc;
+ --red: #dc143c;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+a,
+label,
+button,
+input,
+input[type="submit"],
+input[type="number"],
+select,
+option {
+ color: var(--d-blue);
}
nav {
- background-color: var(--bg);
- border-bottom: 2px solid var(--gold);
+ border-radius: 0px !important;
}
nav *,
@@ -20,9 +40,73 @@ nav *:visited {
}
nav ul li a:hover {
+ color: var(--blue);
background-color: var(--gold);
}
+#cart > #dotton {
+ background-color: var(--gold) !important;
+ color: var(--bg) !important;
+}
+
+#welcome h1,
+#welcome p {
+ color: var(--red);
+}
+
+a {
+ color: var(--blue);
+ transition-duration: 500ms;
+}
+
+a:hover {
+ color: var(--red);
+}
+
body {
background-color: var(--bg);
}
+
+.card {
+ background-color: var(--bg-shade);
+}
+
+a.card {
+ text-decoration: none;
+ transition-duration: 1s;
+}
+
+a.card:hover {
+ background-color: var(--bg-shade2);
+}
+
+input,
+select,
+input:focus,
+select:focus {
+ background-color: var(--bg-shade2);
+}
+
+input[type="submit"] {
+ color: var(--blue);
+ background-color: var(--gold);
+ transition-duration: 500ms;
+}
+
+input[type="submit"]:hover {
+ color: var(--bg);
+ background-color: var(--d-blue);
+}
+
+.glass {
+ background-color: rgba(255, 255, 255, 0.2);
+}
+
+.cart_item:hover > p {
+ text-decoration: underline;
+ text-decoration-color: var(--gold);
+}
+
+.cart_item i:hover {
+ color: var(--red);
+}
diff --git a/catalog/functions/base.php b/catalog/functions/base.php
index d149045..9d7dcd8 100644
--- a/catalog/functions/base.php
+++ b/catalog/functions/base.php
@@ -8,6 +8,21 @@ function pretty_dump($arg)
return ob_get_clean();
}
+function format_money($in)
+{
+ $in = '$' . $in;
+ $parts = explode('.', $in);
+ if (count($parts) == 1)
+ $in .= '.00';
+ else {
+ if (strlen($parts[1]) == 1) {
+ $in .= '0';
+ }
+ }
+
+ return $in;
+}
+
function random_string()
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
diff --git a/catalog/functions/catalog.php b/catalog/functions/catalog.php
index 33a7ebc..32cc9d3 100644
--- a/catalog/functions/catalog.php
+++ b/catalog/functions/catalog.php
@@ -1,14 +1,84 @@
safeLoad();
+ require_once 'base.php';
+ require_once 'db.php';
+
+ switch ($_POST['form_id']) {
+ case 'add_to_cart':
+ if (isset($_POST['product_id']) && isset($_POST['quantity']))
+ echo urlencode(add_to_cart($_POST['product_id'], $_POST['quantity']));
+ break;
+ case 'cart':
+ handle_cart();
+ break;
+ }
+}
+
+function handle_cart()
+{
+ if (!isset($_POST['product_id'])) {
+ echo urlencode('failure');
+ return;
+ }
+
+ $id = $_POST['product_id'];
+
+ if (isset($_POST['action'])) {
+ switch ($_POST['action']) {
+ case 'remove':
+ $_SESSION['cart'][$id] = 0;
+ unset($_SESSION['cart'][$id]);
+ echo urlencode(format_money(calculate_total()));
+ break;
+ case 'adjust':
+ $_SESSION['cart'][$id] = $_POST['quantity'];
+ echo urlencode(format_money(calculate_total()));
+ break;
+ }
+ }
+}
+
+function calculate_total()
+{
+ $total = 0;
+ foreach ($_SESSION['cart'] as $id => $q) {
+ $product = fetch_product($id);
+ $total += $product['price'] * $q;
+ }
+
+ return $total;
+}
+
+function set_quantity($id, $q)
+{
+ if (isset($_SESSION['cart'][$id]))
+ $_SESSION['cart'][$id] = $q;
+}
+
+function add_to_cart($id, $q)
+{
+ if (!isset($_SESSION['cart'][$id]))
+ $_SESSION['cart'][$id] = $q;
+ else
+ $_SESSION['cart'][$id] = $_SESSION['cart'][$id] + $q;
+
+ return count($_SESSION['cart']);
+}
function fetch_catalog()
{
- $conn = get_connection();
- $result = $conn->query('SELECT * FROM product');
- return $result;
+ $conn = get_connection();
+ $result = $conn->query('SELECT * FROM product');
+ return $result;
}
function fetch_product($id)
{
- $result = exec_stmt('SELECT * FROM product WHERE id = ?', 'i', $id);
- return $result->fetch_assoc();
+ $result = exec_stmt('SELECT * FROM product WHERE id = ?', 'i', $id);
+ return $result->fetch_assoc();
}
diff --git a/catalog/functions/db.php b/catalog/functions/db.php
index 999a72f..fff6000 100644
--- a/catalog/functions/db.php
+++ b/catalog/functions/db.php
@@ -1,9 +1,9 @@
execute();
$result = $stmt->get_result();
- if ($result)
+ if ($result) {
return $result;
- else
+ } else {
return mysqli_insert_id($conn);
+ }
}
function get_connection()
diff --git a/catalog/functions/init.php b/catalog/functions/init.php
index 577fb2a..8a9b887 100644
--- a/catalog/functions/init.php
+++ b/catalog/functions/init.php
@@ -11,3 +11,7 @@ $dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->safeLoad();
require_once 'functions/db.php';
+
+if (isset($_SESSION['id']))
+ if (!isset($_SESSION['cart']))
+ $_SESSION['cart'] = [];
diff --git a/catalog/functions/user.php b/catalog/functions/user.php
index 5da783e..721117d 100644
--- a/catalog/functions/user.php
+++ b/catalog/functions/user.php
@@ -1,12 +1,12 @@
safeLoad();
- require_once 'base.php';
- require_once 'db.php';
+ include_once 'base.php';
+ include_once 'db.php';
switch ($_POST['form_id']) {
case 'create-account':
@@ -15,6 +15,9 @@ if (isset($_POST['form_id'])) {
echo json_encode($result);
}
break;
+ case 'login':
+ if (isset($_POST['username']) && isset($_POST['password']))
+ echo json_encode(login($_POST['username'], $_POST['password']));
}
}
@@ -30,29 +33,28 @@ function username_exists($username)
function login($username, $password)
{
- $user = exec_stmt('SELECT id FROM user WHERE username = ? AND password = ?', 'ss', $username, $password)->fetch_assoc();
+ $user = exec_stmt('SELECT id, password FROM user WHERE username = ?', 's', $username)->fetch_assoc();
if (!isset($user['id']))
return false;
+ if (!password_verify($password, $user['password'])) {
+ return false;
+ }
+
$_SESSION['id'] = $user['id'];
return true;
}
function signup($username, $password, $verify_password)
{
- echo 'test';
if (username_exists($username))
return false;
- echo 'username=' . $username;
-
if ($password != $verify_password)
return false;
- $user_id = exec_stmt('INSERT INTO user (username, password) VALUES (?, ?)', 'ss', $username, $password);
-
- echo 'user_id=' . $user_id;
+ $user_id = exec_stmt('INSERT INTO user (username, password) VALUES (?, ?)', 'ss', $username, password_hash($password, PASSWORD_DEFAULT));
if (!isset($user_id))
return false;
diff --git a/catalog/index.php b/catalog/index.php
index 341d865..b9fca49 100755
--- a/catalog/index.php
+++ b/catalog/index.php
@@ -1,20 +1,29 @@
Username and/or password are incorrect!';
+ }
}
-include_once 'components/head.php';
-include_once 'components/user/login.php';
+require_once 'components/head.php';
+require_once 'components/user/login.php';
if (isset($_SESSION['id'])) {
- echo '
Welcome to the store
';
-} else
- echo login_form();
+ echo '
+
+
Welcome to ACME!
+
Where \'Oops!\' is Part of the Plan.
+
+ ';
-include_once 'components/foot.php';
+ include_once 'components/bubbles.php';
+} else {
+ echo login_form();
+}
+
+require_once 'components/foot.php';
diff --git a/catalog/js/cart.js b/catalog/js/cart.js
new file mode 100644
index 0000000..df5dc8c
--- /dev/null
+++ b/catalog/js/cart.js
@@ -0,0 +1,47 @@
+const items = document.querySelectorAll(".cart_item");
+const total = document.querySelector("h3#total");
+
+items.forEach((item) => {
+ const quantity = item.querySelector(".item_quantity");
+ const id = item.querySelector('input[type="hidden"]');
+ const delete_btn = item.querySelector("i");
+
+ quantity.addEventListener("change", () =>
+ handle_quantity_change(id.value, quantity.value, item),
+ );
+
+ delete_btn.addEventListener("click", () => remove_item(id.value, item));
+});
+
+function handle_quantity_change(id, q, item) {
+ if (parseInt(q) == 0) {
+ remove_item(id, item);
+ } else {
+ fetch("functions/catalog.php", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ body: "form_id=cart&action=adjust&product_id=" + id + "&quantity=" + q,
+ })
+ .then((response) => response.text())
+ .then((data) => {
+ total.innerText = decodeURIComponent(data);
+ });
+ }
+}
+
+function remove_item(id, item) {
+ fetch("functions/catalog.php", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ body: "form_id=cart&action=remove&product_id=" + id,
+ })
+ .then((response) => response.text())
+ .then((data) => {
+ total.innerText = decodeURIComponent(data);
+ item.remove();
+ });
+}
diff --git a/catalog/js/create-account.js b/catalog/js/create-account.js
index 531c632..debebcb 100755
--- a/catalog/js/create-account.js
+++ b/catalog/js/create-account.js
@@ -1,65 +1,65 @@
-const username_field = document.querySelector('#username');
-const password_field = document.querySelector('#password');
-const v_password_field = document.querySelector('#v_password');
+const username_field = document.querySelector("#username");
+const password_field = document.querySelector("#password");
+const v_password_field = document.querySelector("#v_password");
const submit_button = document.querySelector('input[type="submit"]');
-const err_username = document.querySelector('#err_username');
-const err_match = document.querySelector('#err_match');
-const err_length = document.querySelector('#err_length');
-const err_num = document.querySelector('#err_num');
+const err_username = document.querySelector("#err_username");
+const err_match = document.querySelector("#err_match");
+const err_length = document.querySelector("#err_length");
+const err_num = document.querySelector("#err_num");
function handle_input() {
const password = password_field.value;
const v_password = v_password_field.value;
- if (password != v_password && v_password != '')
- err_match.innerText = 'Passwords do not match.';
- else
- err_match.innerText = '';
-
+ if (password != v_password && v_password != "")
+ err_match.innerText = "Passwords do not match.";
+ else err_match.innerText = "";
if (password.length < 8)
- err_length.innerText = 'Password must be at least 8 characters long.';
- else
- err_length.innerText = '';
+ err_length.innerText = "Password must be at least 8 characters long.";
+ else err_length.innerText = "";
const num_regex = /\d/;
if (!num_regex.test(password))
- err_num.innerText = 'Password must have at least 1 digit.';
- else
- err_num.innerText = '';
+ err_num.innerText = "Password must have at least 1 digit.";
+ else err_num.innerText = "";
- if (err_match.innerText == '' && err_length.innerText == '' && err_num.innerText == '' && err_username == '' && v_password != '')
+ if (
+ err_match.innerText == "" &&
+ err_length.innerText == "" &&
+ err_num.innerText == "" &&
+ err_username.innerText == "" &&
+ v_password != ""
+ )
submit_button.disabled = false;
- else
- submit_button.disabled = true;
+ else submit_button.disabled = true;
}
function handle_username() {
const username = username_field.value;
- fetch('functions/user.php', {
- method: 'POST',
+ fetch("functions/user.php", {
+ method: "POST",
headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
+ "Content-Type": "application/x-www-form-urlencoded",
},
- body: 'form_id=create-account&username=' + username,
+ body: "form_id=create-account&username=" + username,
})
- .then(response => {
+ .then((response) => {
if (!response.ok) {
- console.log('Failed to check if username exists!');
+ console.log("Failed to check if username exists!");
}
return response.json(); // Parse response body as JSON
})
- .then(data => {
- if (data['exists'] == 'True')
- err_username.innerText = 'Username is taken.';
- else
- err_username.innerText = '';
+ .then((data) => {
+ if (data["exists"] == "True")
+ err_username.innerText = "Username is taken.";
+ else err_username.innerText = "";
});
}
-username_field.addEventListener('blur', handle_username);
-password_field.addEventListener('input', handle_input);
-v_password_field.addEventListener('input', handle_input);
+username_field.addEventListener("blur", handle_username);
+password_field.addEventListener("input", handle_input);
+v_password_field.addEventListener("input", handle_input);
submit_button.disabled = true;
diff --git a/catalog/js/index.js b/catalog/js/index.js
new file mode 100644
index 0000000..b69ca4c
--- /dev/null
+++ b/catalog/js/index.js
@@ -0,0 +1,172 @@
+const bg = document.querySelector("#bg");
+const bubbles = document.querySelectorAll(".bubble"); // Get bubbles *after* the page has loaded
+const cart_btn = document.querySelector("#add_to_cart_btn");
+
+const colors = [
+ "#cedff3",
+ "#adcaeb",
+ "#ffd700",
+ "#f4a460",
+ "#1e90ff",
+ "#dc143c",
+ "#7CFC00",
+];
+
+const text_colors = ["#f4a460", "#1e90ff", "#dc143c"];
+
+let welcome = document.querySelector("#welcome");
+if (welcome != null) {
+ let h1 = welcome.querySelector("h1");
+ let p = welcome.querySelector("p");
+
+ let color = text_colors[Math.floor(Math.random() * colors.length)];
+ h1.style.color = color;
+ p.style.color = color;
+}
+
+function initial_bubbles() {
+ bubbles.forEach((bubble) => {
+ let size = Math.ceil(Math.random() * 100) + 50;
+ let color = colors[Math.floor(Math.random() * colors.length)];
+ let x = Math.floor(Math.random() * bg.offsetWidth) - size + 100;
+ let y = Math.floor(Math.random() * bg.offsetHeight) - size + 100;
+ const delay = Math.random() * 5 + "s";
+ const duration = Math.random() * 10 * Math.random() + 15 + "s";
+
+ let randomX = (Math.random() - 0.5) * 500;
+ let randomY = (Math.random() - 0.5) * 500;
+
+ while (randomX < 0 || randomX > window.innerWidth)
+ randomX = (Math.random() - 0.5) * 500;
+
+ while (randomY < 0 || randomY > window.innerHeight)
+ randomY = (Math.random() - 0.5) * 500;
+
+ randomX = randomX + "px";
+ randomY = randomY + "px";
+
+ let a = Math.random();
+ let b = Math.random();
+ let c = Math.random();
+ let d = Math.random();
+
+ if (Math.random() > 0.5) a *= -1;
+
+ if (Math.random() > 0.5) b *= -1;
+
+ if (Math.random() > 0.5) c *= -1;
+
+ if (Math.random() > 0.5) d *= -1;
+
+ if (Math.random() > 0.5) {
+ let curveX = (Math.random() - 0.5) * 500 + "px";
+ let curveY = (Math.random() - 0.5) * 500 + "px";
+ bubble.style.setProperty("--curve-x", curveX);
+ bubble.style.setProperty("--curve-y", curveY);
+ bubble.style.animationName = "float-curve"; // Apply the curved animation
+ } else {
+ bubble.style.animationName = "float-random"; // Keep the straight animation
+ }
+
+ bubble.style.position = "absolute";
+ bubble.style.top = y + "px";
+ bubble.style.left = x + "px";
+ bubble.style.height = size + "px";
+ bubble.style.width = size + "px";
+ bubble.style.borderRadius = "50%";
+ bubble.style.backgroundColor = color;
+ bubble.style.opacity = 0.8;
+ bubble.style.setProperty("--random-x", randomX);
+ bubble.style.setProperty("--random-y", randomY);
+ bubble.style.animationDelay = delay;
+ bubble.style.animationDuration = duration;
+ bubble.style.animationTimingFunction =
+ "cubic-bezier(" + a + ", " + b + ", " + c + ", " + d + ")";
+ bubble.style.boxShadow = "6px 6px 14px rgba(0, 0, 0, 0.45)";
+ });
+}
+
+initial_bubbles();
+if (document.startViewTransition) {
+ window.navigation.addEventListener("navigate", () =>
+ document.startViewTransition(),
+ );
+}
+
+//
+// // Function to capture the current state of the bubbles
+// function captureBubbleStates() {
+// const bubbles = document.querySelectorAll(".bubble");
+// bubbleStates = Array.from(bubbles).map((bubble) => ({
+// left: bubble.style.left,
+// top: bubble.style.top,
+// width: bubble.style.width,
+// height: bubble.style.height, // Added height
+// backgroundColor: bubble.style.backgroundColor,
+// opacity: bubble.style.opacity,
+// delay: bubble.style.animationDelay,
+// dur: bubble.style.animationDuration,
+// ran_x: getComputedStyle(bubble).getPropertyValue("--random-x"),
+// ran_y: getComputedStyle(bubble).getPropertyValue("--random-y"),
+// }));
+//
+// try {
+// window.name = JSON.stringify(bubbleStates);
+// } catch (error) {
+// console.error("Error stringifying bubble states:", error);
+// window.name = ""; // Clear window.name in case of error
+// }
+// }
+//
+// // Function to apply the stored states to the new bubbles
+// function applyBubbleStates() {
+// try {
+// const storedStates = JSON.parse(window.name);
+// if (storedStates && storedStates.length > 0) {
+// const newBubbles = document.querySelectorAll(".bubble");
+// newBubbles.forEach((bubble, index) => {
+// if (storedStates[index]) {
+// bubble.style.left = storedStates[index].left;
+// bubble.style.top = storedStates[index].top;
+// bubble.style.width = storedStates[index].width;
+// bubble.style.height = storedStates[index].width;
+// bubble.style.backgroundColor = storedStates[index].backgroundColor;
+// bubble.style.borderRadius = "50%";
+// bubble.style.position = "absolute"; // Ensure they are absolutely positioned
+// bubble.style.opacity = storedStates[index].opacity;
+// bubble.style.animationDuration = storedStates[index].dur;
+// bubble.style.setProperty("--random-x", storedStates[index].ran_x);
+// bubble.style.setProperty("--random-y", storedStates[index].ran_y);
+// }
+// });
+//
+// bubbleStates = storedStates; // Update the local variable
+// } else {
+// initial_bubbles();
+// }
+// } catch (error) {
+// console.error("Error parsing window.name:", error);
+// initial_bubbles();
+// }
+// }
+//
+// // Event listeners
+// window.addEventListener("load", applyBubbleStates);
+// window.addEventListener("beforeunload", captureBubbleStates);
+//
+// // View Transitions API Handling
+// if (document.startViewTransition) {
+// window.navigation.addEventListener("navigate", (event) => {
+// const promise = Promise.resolve()
+// .then(captureBubbleStates)
+// .then(() =>
+// document.startViewTransition(async () => {
+// await event.destination.loadPromise;
+// applyBubbleStates();
+// }),
+// );
+// });
+// } else {
+// console.log("ViewTransition API not supported");
+// initial_bubbles();
+// }
diff --git a/catalog/js/login-modal.js b/catalog/js/login-modal.js
deleted file mode 100644
index e48ffac..0000000
--- a/catalog/js/login-modal.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const add_to_cart = document.querySelector('input[type="submit"]');
-
-const modal = document.querySelector('.modal');
-const username = document.querySelector('#username');
-const password = document.querySelector('#password');
-const login_button = document.querySelector('#login_submit');
-
-
-add_to_cart.addEventListener('click', (e) => {
- e.preventDefault();
-
- if (modal.classList[0] === "fade-in") {
- modal.classList.remove("fade-in");
- modal.classList.add("fade-out");
- } else {
- modal.classList.remove("fade-out");
- modal.classList.add("fade-in");
- }
-
-
- modal.addEventListener('click', () => {
- if (modal.classList[0] === "fade-in") {
- modal.classList.remove("fade-in");
- modal.classList.add("fade-out");
- } else {
- modal.classList.remove("fade-out");
- modal.classList.add("fade-in");
- }
- })
-
-});
diff --git a/catalog/js/login.js b/catalog/js/login.js
new file mode 100644
index 0000000..a3db478
--- /dev/null
+++ b/catalog/js/login.js
@@ -0,0 +1,29 @@
+const form = document.querySelector("form");
+const username_field = document.querySelector("#username");
+const password_field = document.querySelector("#password");
+const submit_button = document.querySelector('input[type="submit"]');
+
+const err = document.querySelector("#invalid");
+
+submit_button.addEventListener("click", (e) => {
+ e.preventDefault();
+
+ fetch("functions/user.php", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ body:
+ "form_id=login&username=" +
+ username_field.value +
+ "&password=" +
+ password_field.value,
+ })
+ .then((response) => {
+ return response.text(); // Parse response body as JSON
+ })
+ .then((data) => {
+ if (data == "true") form.submit();
+ else err.innerText = "Username or Password are incorrect.";
+ });
+});
diff --git a/catalog/js/product_page.js b/catalog/js/product_page.js
new file mode 100644
index 0000000..344098f
--- /dev/null
+++ b/catalog/js/product_page.js
@@ -0,0 +1,45 @@
+const is_logged_in = document.querySelector("#is_logged_in");
+const product_id = document.querySelector("#product_id");
+const quantity = document.querySelector("#quantity");
+const add_to_cart = document.querySelector('input[type="submit"]');
+
+const modal = document.querySelector(".modal");
+const username = document.querySelector("#username");
+const password = document.querySelector("#password");
+const login_button = document.querySelector("#login_submit");
+
+add_to_cart.addEventListener("click", (e) => {
+ e.preventDefault();
+
+ if (is_logged_in.value == "true") {
+ fetch("functions/catalog.php", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ body: 'form_id=add_to_cart&product_id=' + product_id.value + '&quantity=' + quantity.value,
+ })
+ .then((response) => response.text())
+ .then((data) => {
+ document.querySelector('#dotton > small').innerText = decodeURIComponent(data);
+ });
+ } else {
+ if (modal.classList[0] === "fade-in") {
+ modal.classList.remove("fade-in");
+ modal.classList.add("fade-out");
+ } else {
+ modal.classList.remove("fade-out");
+ modal.classList.add("fade-in");
+ }
+
+ modal.addEventListener("click", () => {
+ if (modal.classList[0] === "fade-in") {
+ modal.classList.remove("fade-in");
+ modal.classList.add("fade-out");
+ } else {
+ modal.classList.remove("fade-out");
+ modal.classList.add("fade-in");
+ }
+ });
+ }
+});
diff --git a/catalog/product.php b/catalog/product.php
index 367d0f4..7577cd6 100755
--- a/catalog/product.php
+++ b/catalog/product.php
@@ -1,13 +1,13 @@