This commit is contained in:
@@ -8,6 +8,28 @@ if (!isset($_SESSION['id']))
|
|||||||
foreach (glob('components/cart/*.php') as $file)
|
foreach (glob('components/cart/*.php') as $file)
|
||||||
require_once $file;
|
require_once $file;
|
||||||
|
|
||||||
|
require_once 'functions/catalog.php';
|
||||||
require_once 'components/head.php';
|
require_once 'components/head.php';
|
||||||
|
|
||||||
|
if (empty($_SESSION['cart'])) {
|
||||||
|
echo '
|
||||||
|
<div class="glass center md_width padding margin-top" style="height: auto;">
|
||||||
|
<h3>Your cart is empty!</h3>
|
||||||
|
<p>Check out our innovative and reliable products <a href="catalog.php">here</a>.</p>
|
||||||
|
</div>
|
||||||
|
';
|
||||||
|
} else {
|
||||||
|
if (isset($_POST['form_id'])) {
|
||||||
|
$total = calculate_total();
|
||||||
|
$items = [];
|
||||||
|
foreach ($_SESSION['cart'] as $id => $q) {
|
||||||
|
$items[fetch_product($id)['name']] = $q;
|
||||||
|
unset($_SESSION['cart'][$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo cart_confirmation($_POST['fname'], $_POST['lname'], $_POST['add'], $_POST['city'], $_POST['state'], $_POST['zip'], $total, $items);
|
||||||
|
} else
|
||||||
|
echo cart_layout();
|
||||||
|
}
|
||||||
|
|
||||||
require_once 'components/foot.php';
|
require_once 'components/foot.php';
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ foreach (glob('components/products/*.php') as $file)
|
|||||||
|
|
||||||
include_once 'components/head.php';
|
include_once 'components/head.php';
|
||||||
|
|
||||||
echo '<h1>Catalog</h1>';
|
echo '<h1 class="margin-left">Catalog</h1>';
|
||||||
|
|
||||||
echo '<div id="catalog" class="std_width center">';
|
echo '<div id="catalog" class="std_width center">';
|
||||||
echo catalog_grid(fetch_catalog());
|
echo catalog_grid(fetch_catalog());
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
echo '<div id="bg">';
|
||||||
|
|
||||||
|
for ($i = 0; $i < 50; $i++)
|
||||||
|
echo '<div id="' . $i . '" class="bubble"></div>';
|
||||||
|
|
||||||
|
echo '</div>';
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function cart_checkout($total)
|
||||||
|
{
|
||||||
|
$checkout = '
|
||||||
|
<div class="card full_width column padding shadow" style="height: auto;">
|
||||||
|
<form method="post">
|
||||||
|
<input type="hidden" name="form_id" value="checkout">
|
||||||
|
<div class="row full_width space_between margin-top margin-bottom">
|
||||||
|
<div class="column md_width">
|
||||||
|
<label for="fname">First Name:</label>
|
||||||
|
<input id="fname" name="fname" placeholder="John" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column md_width">
|
||||||
|
<label for="lname">Last Name:</label>
|
||||||
|
<input id="lname" name="lname" placeholder="Smith" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column full_width">
|
||||||
|
<label for="add">Address:</label>
|
||||||
|
<input id="add" name="add" placeholder="123 Example St" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row space_between margin-top margin-bottom">
|
||||||
|
<div class="column md_width">
|
||||||
|
<label for="city">City:</label>
|
||||||
|
<input id="city" name="city" placeholder="Salt Lake City" required>
|
||||||
|
</div>
|
||||||
|
<div class="column sm_width">
|
||||||
|
<label for="state">State:</label>
|
||||||
|
<select id="state" name="state" required>
|
||||||
|
<option value="AL">AL</option>
|
||||||
|
<option value="AK">AK</option>
|
||||||
|
<option value="AZ">AZ</option>
|
||||||
|
<option value="AR">AR</option>
|
||||||
|
<option value="CA">CA</option>
|
||||||
|
<option value="CO">CO</option>
|
||||||
|
<option value="CT">CT</option>
|
||||||
|
<option value="DE">DE</option>
|
||||||
|
<option value="FL">FL</option>
|
||||||
|
<option value="GA">GA</option>
|
||||||
|
<option value="HI">HI</option>
|
||||||
|
<option value="ID">ID</option>
|
||||||
|
<option value="IL">IL</option>
|
||||||
|
<option value="IN">IN</option>
|
||||||
|
<option value="IA">IA</option>
|
||||||
|
<option value="KS">KS</option>
|
||||||
|
<option value="KY">KY</option>
|
||||||
|
<option value="LA">LA</option>
|
||||||
|
<option value="ME">ME</option>
|
||||||
|
<option value="MD">MD</option>
|
||||||
|
<option value="MA">MA</option>
|
||||||
|
<option value="MI">MI</option>
|
||||||
|
<option value="MN">MN</option>
|
||||||
|
<option value="MS">MS</option>
|
||||||
|
<option value="MO">MO</option>
|
||||||
|
<option value="MT">MT</option>
|
||||||
|
<option value="NE">NE</option>
|
||||||
|
<option value="NV">NV</option>
|
||||||
|
<option value="NH">NH</option>
|
||||||
|
<option value="NJ">NJ</option>
|
||||||
|
<option value="NM">NM</option>
|
||||||
|
<option value="NY">NY</option>
|
||||||
|
<option value="NC">NC</option>
|
||||||
|
<option value="ND">ND</option>
|
||||||
|
<option value="OH">OH</option>
|
||||||
|
<option value="OK">OK</option>
|
||||||
|
<option value="OR">OR</option>
|
||||||
|
<option value="PA">PA</option>
|
||||||
|
<option value="RI">RI</option>
|
||||||
|
<option value="SC">SC</option>
|
||||||
|
<option value="SD">SD</option>
|
||||||
|
<option value="TN">TN</option>
|
||||||
|
<option value="TX">TX</option>
|
||||||
|
<option value="UT">UT</option>
|
||||||
|
<option value="VT">VT</option>
|
||||||
|
<option value="VA">VA</option>
|
||||||
|
<option value="WA">WA</option>
|
||||||
|
<option value="WV">WV</option>
|
||||||
|
<option value="WI">WI</option>
|
||||||
|
<option value="WY">WY</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="column sm_width">
|
||||||
|
<label for="zip">Zip Code:</label>
|
||||||
|
<input id="zip" name="zip" placeholder="84111" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="line margin-bottom"></div>
|
||||||
|
<div class="column center">
|
||||||
|
<h3 id="total">' . format_money($total) . '</h3>
|
||||||
|
<input type="submit" value="Place Order">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
';
|
||||||
|
|
||||||
|
return $checkout;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function cart_confirmation($fname, $lname, $add, $city, $state, $zip, $total, $items)
|
||||||
|
{
|
||||||
|
$con = '
|
||||||
|
<div class="glass column md_width center padding" style="height: auto;">
|
||||||
|
<h4>Shipping Details:</h4>
|
||||||
|
<p>' . $fname . ' ' . $lname . '</p>
|
||||||
|
<p>' . $add . '</p>
|
||||||
|
<p>' . $city . ', ' . $state . ' ' . $zip . '</p>
|
||||||
|
<br>
|
||||||
|
<p>Your order will spontaneously appear before you, for you convenience!</p>
|
||||||
|
<small>We fold space and time itself, to ensure the best experience for our customers!</small>
|
||||||
|
<div class="line"></div>
|
||||||
|
<h4>Your Items:</h4>
|
||||||
|
<ul>
|
||||||
|
';
|
||||||
|
|
||||||
|
foreach ($items as $name => $quantity)
|
||||||
|
$con .= '<li>x' . $quantity . ' - ' . $name . '</li>';
|
||||||
|
|
||||||
|
$con .= '
|
||||||
|
</ul>
|
||||||
|
<h5>Total: $' . $total . '</h5>
|
||||||
|
';
|
||||||
|
|
||||||
|
return $con;
|
||||||
|
}
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
function cart_item($item)
|
function cart_item($item, $q)
|
||||||
{
|
{
|
||||||
$item = '
|
$item = '
|
||||||
<div class="row">
|
<div class="row space_between full_width margin-bottom cart_item">
|
||||||
<div class="square img_container">
|
<p class="full_width left_align">' . $item['name'] . '</p>
|
||||||
|
<div class="row md_width right_align">
|
||||||
|
<input type="hidden" value="' . $item['id'] . '">
|
||||||
|
<input type="number" value="' . $q . '" class="full_width item_quantity">
|
||||||
|
<div class="column center_children">
|
||||||
|
<i class="nf nf-cod-trash"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row space_between">
|
|
||||||
<p>' . $item['description'] . '</p>
|
|
||||||
<select>
|
|
||||||
<input type="number">
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
';
|
';
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function cart_layout()
|
||||||
|
{
|
||||||
|
$total = 0;
|
||||||
|
|
||||||
|
$layout = '
|
||||||
|
<div class="grid_2x1 center std_width glass padding">
|
||||||
|
<div class="card list full_width padding shadow" style="height: 700px;">
|
||||||
|
';
|
||||||
|
|
||||||
|
foreach ($_SESSION['cart'] as $id => $q) {
|
||||||
|
$product = fetch_product($id);
|
||||||
|
$total += $product['price'] * $q;
|
||||||
|
$layout .= cart_item($product, $q);
|
||||||
|
}
|
||||||
|
|
||||||
|
$layout .= '
|
||||||
|
</div>
|
||||||
|
' . cart_checkout($total) . '
|
||||||
|
</div>
|
||||||
|
';
|
||||||
|
|
||||||
|
return $layout;
|
||||||
|
}
|
||||||
@@ -4,18 +4,25 @@
|
|||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="css/base.css">
|
<link rel="stylesheet" href="css/base.css">
|
||||||
<link rel="stylesheet" href="css/colors.css">
|
<link rel="stylesheet" href="css/colors.css">
|
||||||
|
<link rel="stylesheet" href="https://nerdfonts.com/assets/css/webfont.css">
|
||||||
|
<script src="js/index.js" defer></script>
|
||||||
<?php
|
<?php
|
||||||
switch ($_SERVER['SCRIPT_NAME']) {
|
switch ($_SERVER['SCRIPT_NAME']) {
|
||||||
case '/create-account.php':
|
case '/create-account.php':
|
||||||
echo '<script src="js/create-account.js" defer></script>';
|
echo '<script src="js/create-account.js" defer></script>';
|
||||||
break;
|
break;
|
||||||
case '/product.php':
|
case '/product.php':
|
||||||
if (!isset($_SESSION['id']))
|
echo '<script src="js/product_page.js" defer></script>';
|
||||||
echo '<script src="js/login-modal.js" defer></script>';
|
break;
|
||||||
|
case '/cart.php':
|
||||||
|
echo '<script src="js/cart.js" defer></script>';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<?php include_once 'nav.php'; ?>
|
<?php
|
||||||
|
include_once 'nav.php';
|
||||||
|
include_once 'bubbles.php';
|
||||||
|
?>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
$nav = '
|
$nav = '
|
||||||
<nav>
|
<nav class="glass">
|
||||||
<ul>
|
<ul>
|
||||||
<div class="row space_between">
|
<div class="row space_between">
|
||||||
<div>
|
<div>
|
||||||
@@ -12,7 +12,19 @@ $nav = '
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
' . (isset($_SESSION['id']) ? '<li><a href="cart.php">Cart</a></li>' : '') . '
|
';
|
||||||
|
|
||||||
|
if (isset($_SESSION['id'])) {
|
||||||
|
$nav .= '
|
||||||
|
<li>
|
||||||
|
<a href="cart.php" id="cart">
|
||||||
|
<i class="nf nf-md-cart"></i>
|
||||||
|
' . (!empty($_SESSION['cart']) ? '<div id="dotton"><small>' . count($_SESSION['cart']) . '</small></div>' : '') . '
|
||||||
|
</a>
|
||||||
|
</li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$nav .= '
|
||||||
' . (isset($_SESSION['id']) ? '<li><a href="logout.php">Logout</a></li>' : '') . '
|
' . (isset($_SESSION['id']) ? '<li><a href="logout.php">Logout</a></li>' : '') . '
|
||||||
' . (!isset($_SESSION['id']) ? '<li><a href="index.php">Login</a></li>' : '') . '
|
' . (!isset($_SESSION['id']) ? '<li><a href="index.php">Login</a></li>' : '') . '
|
||||||
' . (!isset($_SESSION['id']) ? '<li><a href="create-account.php">Signup</a></li>' : '') . '
|
' . (!isset($_SESSION['id']) ? '<li><a href="create-account.php">Signup</a></li>' : '') . '
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
function product_card($product)
|
function product_card($product)
|
||||||
{
|
{
|
||||||
$card = '
|
$card = '
|
||||||
<a class="card column center full_width padding" href="product.php?id=' . $product['id'] . '">
|
<a class="card column center full_width padding shadow" href="product.php?id=' . $product['id'] . '">
|
||||||
<div class="img_container">
|
<div class="img_container">
|
||||||
<img src="img/' . $product['image'] . '">
|
<img src="img/' . $product['image'] . '">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="column">
|
||||||
<h4>' . $product['name'] . '</h4>
|
<h5>' . $product['name'] . '</h5>
|
||||||
<h5>' . $product['price'] . '</h5>
|
<p>' . format_money($product['price']) . '</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
';
|
';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
function catalog_grid($products)
|
function catalog_grid($products)
|
||||||
{
|
{
|
||||||
$grid = '
|
$grid = '
|
||||||
<div class="grid center">
|
<div class="grid center glass padding-top padding-bottom padding-left">
|
||||||
';
|
';
|
||||||
|
|
||||||
foreach ($products as $p)
|
foreach ($products as $p)
|
||||||
|
|||||||
@@ -2,25 +2,26 @@
|
|||||||
function product_page($product)
|
function product_page($product)
|
||||||
{
|
{
|
||||||
$page = '
|
$page = '
|
||||||
<div class="product_page_card column center full_width padding">
|
<div class="product_page_card glass column center full_width padding margin-top">
|
||||||
<div class="img_container">
|
<div class="img_container">
|
||||||
<img src="img/' . $product['image'] . '">
|
<img src="img/' . $product['image'] . '">
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column card full_width padding margin-top shadow" style="height: auto;">
|
||||||
<div class="row space_between">
|
<div class="row space_between">
|
||||||
<h3>' . $product['name'] . '</h3>
|
<h3>' . $product['name'] . '</h3>
|
||||||
<h3>' . $product['price'] . '</h3>
|
<h3>' . format_money($product['price']) . '</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>' . $product['description'] . '</p>
|
<p>' . $product['description'] . '</p>
|
||||||
<form class="row" id="add_to_cart">
|
<form class="row space_between" id="add_to_cart">
|
||||||
<input type="hidden" name="is_logged_in" value="' . (isset($_SESSION['id']) ? 'true' : 'false') . '">
|
<input type="hidden" name="is_logged_in" value="' . (isset($_SESSION['id']) ? 'true' : 'false') . '" id="is_logged_in">
|
||||||
<div class="column margin">
|
<input type="hidden" name="product_id" value="' . $product['id'] . '" id="product_id">
|
||||||
|
<div class="column margin center_children">
|
||||||
<label for="quantity">Quantity:</label>
|
<label for="quantity">Quantity:</label>
|
||||||
<input type="number" value="1" id="quantity" name="quantity" min="1">
|
<input type="number" value="1" id="quantity" name="quantity" min="1" class="md_width">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="submit" value="Add to Cart" class="margin">
|
<input type="submit" class="margin" id="add_to_cart_btn" value="Add to Cart">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,23 +2,26 @@
|
|||||||
function login_form()
|
function login_form()
|
||||||
{
|
{
|
||||||
$form = '
|
$form = '
|
||||||
<div class="card center">
|
<div class="glass center center_children padding md_width">
|
||||||
<form method="post" id="login_form">
|
<form method="post" id="login_form" class="card full_width padding" style="height: auto;">
|
||||||
<div class="column center">
|
<div class="column center">
|
||||||
<div class="column">
|
<div class="column margin-bottom">
|
||||||
<label for="username">Username:</label>
|
<label for="username">Username:</label>
|
||||||
<input id="username" name="username" autofocus required>
|
<input id="username" name="username" autofocus required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column">
|
<div class="column margin-bottom">
|
||||||
<label for="password">Password:</label>
|
<label for="password">Password:</label>
|
||||||
<input id="password" type="password" name="password" required>
|
<input id="password" type="password" name="password" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="create-account.php">Signup Instead</a>
|
<a href="create-account.php" class="margin-bottom">Signup Instead</a>
|
||||||
|
|
||||||
<input type="submit" class="button submit" id="login_submit">
|
<input type="submit" class="button submit" id="login_submit">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="column center error">
|
||||||
|
<p id="invalid"></p>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
';
|
';
|
||||||
|
|||||||
@@ -2,27 +2,27 @@
|
|||||||
function signup_form()
|
function signup_form()
|
||||||
{
|
{
|
||||||
$form = '
|
$form = '
|
||||||
<div class="card center">
|
<div class="glass center md_width padding">
|
||||||
<form method="post" class="column center">
|
<form method="post" class="card column center full_width padding" style="height: auto;">
|
||||||
<div class="column">
|
<div class="column margin-bottom">
|
||||||
<label for="username">Username:</label>
|
<label for="username">Username:</label>
|
||||||
<input id="username" name="username" autofocus required>
|
<input id="username" name="username" autofocus required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column">
|
<div class="column margin-bottom">
|
||||||
<label for="password">Password:</label>
|
<label for="password">Password:</label>
|
||||||
<input id="password" type="password" name="password" required>
|
<input id="password" type="password" name="password" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column">
|
<div class="column margin-bottom">
|
||||||
<label for="v_password">Verify Password:</label>
|
<label for="v_password">Verify Password:</label>
|
||||||
<input id="v_password" type="password" name="v_password" required>
|
<input id="v_password" type="password" name="v_password" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="index.php">Login Instead</a>
|
<a href="index.php" class="margin-bottom">Login Instead</a>
|
||||||
|
|
||||||
<div class="row full_width">
|
<div class="row space_between full_width">
|
||||||
<input type="submit" class="button submit">
|
<input type="submit" class="button submit" value="Create">
|
||||||
<input type="reset" class="button">
|
<input type="reset" class="button">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+253
-33
@@ -2,38 +2,87 @@
|
|||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
@view-transition {
|
||||||
font-size: 6vw;
|
navigation: auto;
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 4vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 3vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: 2vw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
h5,
|
h5,
|
||||||
h6,
|
h6,
|
||||||
p,
|
p,
|
||||||
a,
|
a,
|
||||||
label {
|
label,
|
||||||
font-size: 1vw;
|
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 BAR **********/
|
||||||
nav {
|
|
||||||
margin-bottom: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav ul {}
|
|
||||||
|
|
||||||
nav ul li {
|
nav ul li {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -46,6 +95,121 @@ nav ul li a {
|
|||||||
text-decoration: none;
|
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 **********/
|
/********** LAYOUT CLASSES **********/
|
||||||
.absolute_h_center {
|
.absolute_h_center {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -63,6 +227,17 @@ nav ul li a {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.left_align {
|
||||||
|
align-items: left;
|
||||||
|
justify-content: left;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right_align {
|
||||||
|
align-items: right;
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -79,35 +254,72 @@ nav ul li a {
|
|||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 20% 20% 20% 20%;
|
grid-template-columns: 23% 23% 23% 23%;
|
||||||
column-gap: 75px;
|
column-gap: 2%;
|
||||||
row-gap: 25px;
|
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 **********/
|
/********** CARDS **********/
|
||||||
.card {
|
.card {
|
||||||
display: block;
|
display: block;
|
||||||
width: 250px;
|
width: 275px;
|
||||||
height: 250px;
|
height: 275px;
|
||||||
border: 1px solid black;
|
border-radius: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.product_page_card {
|
.product_page_card {
|
||||||
display: block;
|
display: block;
|
||||||
border: 1px solid black;
|
border-radius: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card .img_container img {
|
.card .img_container img {
|
||||||
min-width: 60%;
|
min-width: 50%;
|
||||||
max-width: 60%;
|
max-width: 50%;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.product_page_card .img_container img {
|
.product_page_card .img_container img {
|
||||||
min-width: 30%;
|
width: auto;
|
||||||
max-width: 30%;
|
min-height: 275px;
|
||||||
height: auto;
|
max-height: 275px;
|
||||||
border: 1px solid red;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********** MARGINS & PADDING **********/
|
/********** MARGINS & PADDING **********/
|
||||||
@@ -160,6 +372,14 @@ nav ul li a {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.md_width {
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm_width {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
/********** MODALS **********/
|
/********** MODALS **********/
|
||||||
.modal {
|
.modal {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
+91
-7
@@ -1,14 +1,34 @@
|
|||||||
:root {
|
:root {
|
||||||
--bg: #EBF2FA;
|
--bg: #ebf2fa;
|
||||||
--gold: #FFD700;
|
--bg-shade: #cedff3;
|
||||||
--brwn: #F4A460;
|
--bg-shade2: #adcaeb;
|
||||||
--blue: #1E90FF;
|
--gold: #ffd700;
|
||||||
--red: #DC143C;
|
--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 {
|
nav {
|
||||||
background-color: var(--bg);
|
border-radius: 0px !important;
|
||||||
border-bottom: 2px solid var(--gold);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nav *,
|
nav *,
|
||||||
@@ -20,9 +40,73 @@ nav *:visited {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nav ul li a:hover {
|
nav ul li a:hover {
|
||||||
|
color: var(--blue);
|
||||||
background-color: var(--gold);
|
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 {
|
body {
|
||||||
background-color: var(--bg);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,21 @@ function pretty_dump($arg)
|
|||||||
return ob_get_clean();
|
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()
|
function random_string()
|
||||||
{
|
{
|
||||||
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
|||||||
@@ -1,4 +1,74 @@
|
|||||||
<?php
|
<?php
|
||||||
|
if (isset($_POST['form_id'])) {
|
||||||
|
session_start();
|
||||||
|
require_once '../vendor/autoload.php';
|
||||||
|
// Load environment variables.
|
||||||
|
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
|
||||||
|
$dotenv->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()
|
function fetch_catalog()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
// Use environment variables for the database password and IP address.
|
// Use environment variables for the database password and IP address.
|
||||||
$db = $_ENV['DATABASE'];
|
$db = $_ENV['DB'];
|
||||||
$db_user = $_ENV['DATABASE_USER'];
|
$db_user = $_ENV['DB_UN'];
|
||||||
$db_pass = $_ENV['DATABASE_PASSWORD'];
|
$db_pass = $_ENV['DB_PW'];
|
||||||
$ip_addr = $_ENV['IP_ADDRESS'];
|
$ip_addr = $_ENV['DB_IP'];
|
||||||
|
|
||||||
// Make some constants
|
// Make some constants
|
||||||
if ($_SERVER['HTTP_HOST'] == 'localhost:2440') {
|
if ($_SERVER['HTTP_HOST'] == 'localhost:2440') {
|
||||||
@@ -26,10 +26,11 @@ function exec_stmt($stmt, $param_types, ...$args)
|
|||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$result = $stmt->get_result();
|
$result = $stmt->get_result();
|
||||||
|
|
||||||
if ($result)
|
if ($result) {
|
||||||
return $result;
|
return $result;
|
||||||
else
|
} else {
|
||||||
return mysqli_insert_id($conn);
|
return mysqli_insert_id($conn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_connection()
|
function get_connection()
|
||||||
|
|||||||
@@ -11,3 +11,7 @@ $dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
|
|||||||
$dotenv->safeLoad();
|
$dotenv->safeLoad();
|
||||||
|
|
||||||
require_once 'functions/db.php';
|
require_once 'functions/db.php';
|
||||||
|
|
||||||
|
if (isset($_SESSION['id']))
|
||||||
|
if (!isset($_SESSION['cart']))
|
||||||
|
$_SESSION['cart'] = [];
|
||||||
|
|||||||
+12
-10
@@ -1,12 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
if (isset($_POST['form_id'])) {
|
if (isset($_POST['form_id'])) {
|
||||||
require_once '../vendor/autoload.php';
|
include_once '../vendor/autoload.php';
|
||||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
|
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
|
||||||
$dotenv->safeLoad();
|
$dotenv->safeLoad();
|
||||||
|
|
||||||
require_once 'base.php';
|
include_once 'base.php';
|
||||||
require_once 'db.php';
|
include_once 'db.php';
|
||||||
|
|
||||||
switch ($_POST['form_id']) {
|
switch ($_POST['form_id']) {
|
||||||
case 'create-account':
|
case 'create-account':
|
||||||
@@ -15,6 +15,9 @@ if (isset($_POST['form_id'])) {
|
|||||||
echo json_encode($result);
|
echo json_encode($result);
|
||||||
}
|
}
|
||||||
break;
|
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)
|
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']))
|
if (!isset($user['id']))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!password_verify($password, $user['password'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$_SESSION['id'] = $user['id'];
|
$_SESSION['id'] = $user['id'];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function signup($username, $password, $verify_password)
|
function signup($username, $password, $verify_password)
|
||||||
{
|
{
|
||||||
echo 'test';
|
|
||||||
if (username_exists($username))
|
if (username_exists($username))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
echo 'username=' . $username;
|
|
||||||
|
|
||||||
if ($password != $verify_password)
|
if ($password != $verify_password)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
$user_id = exec_stmt('INSERT INTO user (username, password) VALUES (?, ?)', 'ss', $username, $password);
|
$user_id = exec_stmt('INSERT INTO user (username, password) VALUES (?, ?)', 'ss', $username, password_hash($password, PASSWORD_DEFAULT));
|
||||||
|
|
||||||
echo 'user_id=' . $user_id;
|
|
||||||
|
|
||||||
if (!isset($user_id))
|
if (!isset($user_id))
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+18
-9
@@ -1,20 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
include_once 'functions/init.php';
|
require_once 'functions/init.php';
|
||||||
require_once 'functions/user.php';
|
require_once 'functions/user.php';
|
||||||
|
|
||||||
if (isset($_POST['username']) && isset($_POST['password'])) {
|
if (isset($_POST['username']) && isset($_POST['password'])) {
|
||||||
if (login($_POST['username'], $_POST['password']))
|
if (login($_POST['username'], $_POST['password'])) {
|
||||||
header('Location: catalog.php');
|
header('Location: catalog.php');
|
||||||
else
|
} else {
|
||||||
echo '<p>Username and/or password are incorrect!</p>';
|
echo '<p>Username and/or password are incorrect!</p>';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
include_once 'components/head.php';
|
require_once 'components/head.php';
|
||||||
include_once 'components/user/login.php';
|
require_once 'components/user/login.php';
|
||||||
|
|
||||||
if (isset($_SESSION['id'])) {
|
if (isset($_SESSION['id'])) {
|
||||||
echo '<h1>Welcome to the store</h1>';
|
echo '
|
||||||
} else
|
<div id="welcome" class="glass" style="width: auto; height: auto;">
|
||||||
echo login_form();
|
<h1>Welcome to ACME!</h1>
|
||||||
|
<p><strong>Where \'Oops!\' is Part of the Plan.</strong></p>
|
||||||
|
</div>
|
||||||
|
';
|
||||||
|
|
||||||
include_once 'components/foot.php';
|
include_once 'components/bubbles.php';
|
||||||
|
} else {
|
||||||
|
echo login_form();
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once 'components/foot.php';
|
||||||
|
|||||||
@@ -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();
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,65 +1,65 @@
|
|||||||
const username_field = document.querySelector('#username');
|
const username_field = document.querySelector("#username");
|
||||||
const password_field = document.querySelector('#password');
|
const password_field = document.querySelector("#password");
|
||||||
const v_password_field = document.querySelector('#v_password');
|
const v_password_field = document.querySelector("#v_password");
|
||||||
const submit_button = document.querySelector('input[type="submit"]');
|
const submit_button = document.querySelector('input[type="submit"]');
|
||||||
|
|
||||||
const err_username = document.querySelector('#err_username');
|
const err_username = document.querySelector("#err_username");
|
||||||
const err_match = document.querySelector('#err_match');
|
const err_match = document.querySelector("#err_match");
|
||||||
const err_length = document.querySelector('#err_length');
|
const err_length = document.querySelector("#err_length");
|
||||||
const err_num = document.querySelector('#err_num');
|
const err_num = document.querySelector("#err_num");
|
||||||
|
|
||||||
function handle_input() {
|
function handle_input() {
|
||||||
const password = password_field.value;
|
const password = password_field.value;
|
||||||
const v_password = v_password_field.value;
|
const v_password = v_password_field.value;
|
||||||
if (password != v_password && v_password != '')
|
if (password != v_password && v_password != "")
|
||||||
err_match.innerText = 'Passwords do not match.';
|
err_match.innerText = "Passwords do not match.";
|
||||||
else
|
else err_match.innerText = "";
|
||||||
err_match.innerText = '';
|
|
||||||
|
|
||||||
|
|
||||||
if (password.length < 8)
|
if (password.length < 8)
|
||||||
err_length.innerText = 'Password must be at least 8 characters long.';
|
err_length.innerText = "Password must be at least 8 characters long.";
|
||||||
else
|
else err_length.innerText = "";
|
||||||
err_length.innerText = '';
|
|
||||||
|
|
||||||
const num_regex = /\d/;
|
const num_regex = /\d/;
|
||||||
if (!num_regex.test(password))
|
if (!num_regex.test(password))
|
||||||
err_num.innerText = 'Password must have at least 1 digit.';
|
err_num.innerText = "Password must have at least 1 digit.";
|
||||||
else
|
else err_num.innerText = "";
|
||||||
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;
|
submit_button.disabled = false;
|
||||||
else
|
else submit_button.disabled = true;
|
||||||
submit_button.disabled = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_username() {
|
function handle_username() {
|
||||||
const username = username_field.value;
|
const username = username_field.value;
|
||||||
|
|
||||||
fetch('functions/user.php', {
|
fetch("functions/user.php", {
|
||||||
method: 'POST',
|
method: "POST",
|
||||||
headers: {
|
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) {
|
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
|
return response.json(); // Parse response body as JSON
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then((data) => {
|
||||||
if (data['exists'] == 'True')
|
if (data["exists"] == "True")
|
||||||
err_username.innerText = 'Username is taken.';
|
err_username.innerText = "Username is taken.";
|
||||||
else
|
else err_username.innerText = "";
|
||||||
err_username.innerText = '';
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
username_field.addEventListener('blur', handle_username);
|
username_field.addEventListener("blur", handle_username);
|
||||||
password_field.addEventListener('input', handle_input);
|
password_field.addEventListener("input", handle_input);
|
||||||
v_password_field.addEventListener('input', handle_input);
|
v_password_field.addEventListener("input", handle_input);
|
||||||
submit_button.disabled = true;
|
submit_button.disabled = true;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
// }
|
||||||
@@ -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");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -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.";
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1 +0,0 @@
|
|||||||
mariadb -u root -p < setup.sql
|
|
||||||
+20
-23
@@ -6,9 +6,6 @@ CREATE TABLE IF NOT EXISTS user
|
|||||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||||
username VARCHAR(50) NOT NULL UNIQUE,
|
username VARCHAR(50) NOT NULL UNIQUE,
|
||||||
password VARCHAR(1024) NOT NULL,
|
password VARCHAR(1024) NOT NULL,
|
||||||
login_token VARCHAR(1024) NOT NULL UNIQUE,
|
|
||||||
salt VARCHAR(256) NOT NULL,
|
|
||||||
INDEX (login_token)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS product
|
CREATE TABLE IF NOT EXISTS product
|
||||||
@@ -21,23 +18,23 @@ CREATE TABLE IF NOT EXISTS product
|
|||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO product (name, description, image, price) VALUES
|
INSERT INTO product (name, description, image, price) VALUES
|
||||||
("Anvil", "A heavy steel block used for hammering and shaping metal.", "anvil.jpg", 75.00),
|
("Anvil", "Need something with a little *oomph* for your next gravity-defying endeavor? Look no further than our classic ACME Anvil! Guaranteed to make a solid impression (literally!) on any situation. Perfect for flattening pesky predators or just adding a bit of 'weight' to your plans!", "1.jpg", 75.00),
|
||||||
("Axle Grease", "A thick lubricant used to reduce friction in axles and other moving parts.", "axle_grease.jpg", 8.50),
|
("Axle Grease", "Is your super-powered contraption squeaking louder than a startled roadrunner? Slap on some ACME Axle Grease! This slick solution ensures your wheels, cogs, and doohickeys run smoother than a freshly paved desert highway. Get ready for friction-free fun!", "2.jpg", 8.50),
|
||||||
("Atom Re-Arranger", "A device of questionable scientific validity that purports to rearrange atoms.", "atom_rearranger.jpg", 499.99),
|
("Atom Re-Arranger", "Tired of things being... well, *the way they are*? The ACME Atom Re-Arranger is here to (maybe!) help! Want to turn that boulder into a bouncy castle? Or perhaps a giant rubber chicken? Results may vary wildly, but the possibilities are as limitless as your imagination (and our lawyers' disclaimers)!", "3.jpg", 499.99),
|
||||||
("Bed Springs", "Coiled metal springs used in mattresses and furniture for support.", "bed_springs.jpeg", 35.75),
|
("Bed Springs", "Dreaming of launching yourself to incredible heights? Our ACME Bed Springs aren't just for comfy naps! These high-tension coils offer *springy* potential for all sorts of acrobatic (and potentially disastrous) maneuvers. Bouncy, bouncy, fun!", "4.jpg", 35.75),
|
||||||
("Bird Seed", "A mixture of seeds formulated as food for pet birds.", "bird_seed.jpg", 12.20),
|
("Bird Seed", "Trying to befriend a certain fleet-footed fowl? ACME Bird Seed is the gourmet grub that'll have them pecking at your palm... or at least pausing for a millisecond! A strategic snack for the discerning avian acquaintance!", "5.jpg", 12.20),
|
||||||
("Blasting Powder", "An explosive material used for demolition and mining. Handle with extreme caution!", "blasting_powder.JPG", 150.00),
|
("Blasting Powder", "Need to make a *big* impact? ACME Blasting Powder delivers! Perfect for clearing obstacles, creating dramatic entrances, or any situation that calls for a significant *boom*! Handle with the utmost... well, you know. Safety first (maybe)!", "6.jpg", 150.00),
|
||||||
("Cork", "The bark of the cork oak tree, often used for bottle stoppers and insulation.", "cork.jpg", 2.50),
|
("Cork", "Sometimes, the simplest solutions are the best! ACME Corks are perfect for plugging up those pesky leaks, crafting miniature rafts, or even as makeshift nose plugs during particularly pungent pursuits. A surprisingly versatile little marvel!", "7.jpg", 2.50),
|
||||||
("Disintegration Pistol", "A fictional weapon capable of breaking down matter at a molecular level.", "disintegration_pistol.png", 299.00),
|
("Disintegration Pistol", "Poof! Be gone, varmint! The ACME Disintegration Pistol (in theory!) breaks down matter at the molecular level. Imagine the possibilities! Just point, *zap*, and say goodbye to unwanted obstacles. (Note: May not work on all cartoon characters.)", "8.jpg", 299.00),
|
||||||
("Earthquake Pills", "Pills that supposedly induce seismic activity. Effects not guaranteed.", "earthquake_pills.jpg", 55.00),
|
("Earthquake Pills", "Shake things up with ACME Earthquake Pills! Feeling like the ground beneath your feet isn't exciting enough? Pop a few of these little dynamos and get ready for some serious rumbles! Side effects may include unexpected geological activity.", "9.jpg", 55.00),
|
||||||
("Female Roadrunner costume", "A feathered costume designed to resemble a female roadrunner.", "roadrunner_costume_female.jpg", 62.99),
|
("Female Roadrunner costume", "Planning a bit of undercover ornithology? The ACME Female Roadrunner Costume is your ticket to blending in with the fastest crowd! Authentic feathers (may or may not be real), aerodynamic design (questionable), and guaranteed to turn heads (mostly in confusion)!", "10.jpg", 62.99),
|
||||||
("Giant Rubber Band", "An oversized elastic band, useful for large-scale stretching or launching.", "giant_rubber_band.jpg", 19.95),
|
("Giant Rubber Band", "Need to launch something REALLY far? The ACME Giant Rubber Band is your answer! Stretch it, aim it, and let it FLY! Perfect for sending oversized projectiles or creating hilariously oversized slingshots. Get ready for some serious *snap*!", "11.jpg", 19.95),
|
||||||
("Instant Girl", "A product that claims to instantly create a companion. Results may vary significantly.", "instant_girl.jpg", 78.30),
|
("Instant Girl", "Lonely? Wish you had a companion for your elaborate schemes? ACME Instant Girl (just add water... maybe?) promises instant companionship! Results are... well, let's just say reality might not meet expectations. But hey, it's worth a shot, right?", "12.jpg", 78.30),
|
||||||
("Iron Carrot", "A carrot made of iron. Purpose unclear.", "iron_carrot.jpeg", 22.50),
|
("Iron Carrot", "For the discerning herbivore with *very* strong teeth! The ACME Iron Carrot is a nutritional powerhouse of... iron! Its purpose remains a delightful mystery, but it's certainly a conversation starter (if you can lift it!).", "13.jpg", 22.50),
|
||||||
("Jet Propelled Unicycle", "A single-wheeled vehicle powered by a jet engine. For experienced riders only.", "jet_propelled_unicycle.jpg", 599.00),
|
("Jet Propelled Unicycle", "Experience the thrill of high-speed, single-wheeled transportation! The ACME Jet Propelled Unicycle is for the extreme adventurer (and those with excellent balance... or a good helmet!). Warning: May result in uncontrolled flight and/or sudden stops.", "14.jpg", 599.00),
|
||||||
("Out-Board Motor", "A detachable motor mounted on the outside of a boat's transom.", "outboard_motor.jpg", 210.00),
|
("Out-Board Motor", "Take your aquatic adventures to the next level with the ACME Out-Board Motor! Attach it to your bathtub, your unicycle (why not?), or any buoyant (or semi-buoyant) object for instant propulsion! Just add water (and maybe a life vest)!", "15.jpg", 210.00),
|
||||||
("Railroad Track", "A section of steel rail used for train tracks.", "railroad_track.jpeg", 315.50),
|
("Railroad Track", "Planning a high-speed chase? Lay down some ACME Railroad Track! This sturdy steel will keep your rocket sled (sold separately) on the right path... until the inevitable curve or cliff! Get ready for some serious locomotion!", "16.jpg", 315.50),
|
||||||
("Rocket Sled", "A sled propelled by a rocket engine, designed for high-speed travel on rails.", "rocket_sled.jpg", 850.00),
|
("Rocket Sled", "Need to cover ground faster than a speeding roadrunner? The ACME Rocket Sled is your ultimate high-velocity vehicle! Strap in, light the fuse, and prepare for a breathtaking (and potentially bumpy) ride! Safety goggles recommended (but rarely used).", "17.jpg", 850.00),
|
||||||
("Super Outfit", "A costume that allegedly grants the wearer extraordinary abilities. Claims not verified.", "super_outfit.jpeg", 95.00),
|
("Super Outfit", "Dreaming of superhuman feats? The ACME Super Outfit (allegedly!) grants the wearer extraordinary abilities! Strength, speed, the power to attract anvils? The possibilities are endless (and unverified)! Suit up and see what happens!", "18.jpg", 95.00),
|
||||||
("Time Space Gun", "A fictional device that manipulates the fabric of spacetime. Use with caution.", "time_space_gun.jpeg", 675.00),
|
("Time Space Gun", "Messing with the very fabric of reality? The ACME Time Space Gun (handle with *extreme* caution!) allows you to bend the rules of time and space! Want to go back and order more ACME products? Or maybe just avoid that last falling boulder? Use wisely (or not)!", "19.jpg", 675.00),
|
||||||
("X-Ray", "An electromagnetic radiation with high energy, often used for medical imaging.", "x_ray.jpeg", 1.00);
|
("X-Ray", "See right through things with the amazing ACME X-Ray! Perfect for finding hidden treasures, checking for structural weaknesses (in your opponent's plans, perhaps?), or just getting a peek at what's inside! Batteries not included (probably because we forgot to invent them yet).", "20.jpg", 1.00);
|
||||||
|
|||||||
Reference in New Issue
Block a user