Skip to content

Commit

Permalink
Update & fix modals (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
hmellor authored Apr 22, 2023
1 parent 9434066 commit 1fb0cbb
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 191 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,12 @@ service cloud.firestore {
function isLoggedIn() {
return exists(/databases/$(database)/documents/users/$(request.auth.uid))
}
match /users/{user} {
allow read, update, delete: if false;
allow create: if true;
// Make sure the uid of the requesting user matches name of the user
// document. The wildcard expression {userId} makes the userId variable
// available in rules.
match /users/{userId} {
allow read, update, delete: if request.auth != null && request.auth.uid == userId;
allow create: if request.auth != null;
}
match /auction-live/{items} {
allow get, list: if true;
Expand Down
2 changes: 1 addition & 1 deletion css/auction-website.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ html * {
border: none;
}

#info-modal-img {
.modal-body > img {
width: 100%;
}

Expand Down
45 changes: 18 additions & 27 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,8 @@
<link rel="icon" type="image/png" href="./img/favicon.ico">

<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.3.0/font/bootstrap-icons.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe" crossorigin="anonymous"></script>

<!-- Custom CSS -->
<link rel="stylesheet" href="./css/auction-website.css">
Expand All @@ -31,12 +27,12 @@
<!-- Navbar -->
<nav class="navbar navbar-dark bg-primary">
<div class="container-fluid">
<a class="navbar-brand mb-0 h1">
<a class="navbar-brand mb-0 h1 me-auto">
<img src="./img/logo.png" alt="" width="30" height="24" class="d-inline-block align-text-top">
The Markatplace
</a>
<a class="navbar-brand" id="username-display"></a>
<button id="signup-button" class="btn btn-secondary" type="submit" onclick="openLogin()">Sign up</button>
<button id="auth-button" class="btn btn-secondary">Sign up</button>
</div>
</nav>
<!-- Grid of auction items -->
Expand Down Expand Up @@ -67,14 +63,13 @@ <h5 id="login-modal-title" class="modal-title">Sign up for Markatplace Auction</
<p>The username just lets us know who's bidding!</p>
<form onsubmit="return false;">
<div class="form-floating mb-3">
<input type="username" class="form-control" id="username-input" placeholder="username"
onkeypress="if (event.key == 'Enter') {newUserLogin()}">
<input type="username" class="form-control" id="username-input" placeholder="username">
<label for="username-input">Username</label>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"
aria-label="Cancel">Cancel</button>
<button type="submit" class="btn btn-primary" onclick="newUserLogin()">Sign up</button>
<button type="submit" class="btn btn-primary">Sign up</button>
</div>
</form>
</div>
Expand All @@ -86,17 +81,16 @@ <h5 id="login-modal-title" class="modal-title">Sign up for Markatplace Auction</
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 id="info-modal-title" class="modal-title"></h5>
<h5 class="modal-title"></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p id="info-modal-desc"></p>
<img id="info-modal-img"></img>
<p></p>
<img></img>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="Close">Close</button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" aria-label="Submit bid"
onclick="openBid(this.id)">Submit bid</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#bid-modal" aria-label="Submit bid">Submit bid</button>
</div>
</div>
</div>
Expand All @@ -106,39 +100,36 @@ <h5 id="info-modal-title" class="modal-title"></h5>
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 id="bid-modal-title" class="modal-title">Place your bid</h5>
<h5 class="modal-title">Place your bid</h5>
</div>
<div class="modal-body">
<p>You are about to place a bid on <strong id="bid-modal-subtitle"></strong></p>
<p>You are about to place a bid on <strong></strong></p>
<p class="text-muted">(This is just a demo, you're not bidding real money)</p>
<form onsubmit="return false;">
<div class="form-floating mb-3">
<input type="amount" class="form-control" id="amount-input" placeholder="amount"
onkeypress="if (event.key == 'Enter') {placeBid()}">
<input type="amount" class="form-control" placeholder="amount">
<label for="amount-input">Amount</label>
<div id="bad-amount-feedback" class="invalid-feedback"></div>
<div class="invalid-feedback"></div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="Cancel">Cancel</button>
<button type="submit" class="btn btn-primary" onclick="placeBid()">Submit bid</button>
<button type="submit" class="btn btn-primary">Submit bid</button>
</div>
</div>
</div>
</div>
<!-- Custom JS -->
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="module" src="./js/auctions.js"></script>
<script type="module" src="./js/popups.js"></script>
<!-- Create anonymous account -->
<script type="module">
import { populateAuctionGrid, setClocks, dataListener } from "./js/auctions.js";
import { autoLogin } from "./js/popups.js";
import { autoSignIn } from "./js/popups.js";
populateAuctionGrid();
setClocks();
dataListener()
autoLogin();
autoSignIn();
</script>
</body>

Expand Down
133 changes: 29 additions & 104 deletions js/auctions.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,43 @@
// Imports
import { auth, db, auctions } from "./firebase.js";
import { bidModal } from "./popups.js";
import { doc, getDoc, setDoc, updateDoc, writeBatch, onSnapshot } from "https://www.gstatic.com/firebasejs/9.20.0/firebase-firestore.js";
import { auth, db } from "./firebase.js";
import { doc, setDoc, updateDoc, writeBatch, onSnapshot } from "https://www.gstatic.com/firebasejs/9.20.0/firebase-firestore.js";

// For a real auction, set this to false
let demoAuction = true;

// Random auction information
function generateRandomAuctions() {
// Random cat images
document.querySelectorAll(".card > img").forEach((img, idx) => {
img.src = "https://cataas.com/cat/cute?random=" + idx;
auctions[idx].primaryImage = img.src;
auctions[idx].secondaryImage = img.src;
});
function generateRandomAuctionData() {
let cards = document.querySelectorAll(".card")

// Random cat names
$.getJSON(
"https://random-data-api.com/api/name/random_name",
{ size: auctions.length },
function (data) {
data.forEach((elem, idx) => {
document.querySelector("#auction-" + idx + " > div > h5").innerHTML = elem.name;
auctions[idx].title = elem.name;
});
(data) => {
data.forEach((elem, i) => {
cards[i].querySelector(".title").innerText = elem.name
cards[i].dataset.bsTitle = elem.name
});
}
);
// Random lorem ipsum cat descriptions
$.getJSON(
"https://random-data-api.com/api/lorem_ipsum/random_lorem_ipsum",
{ size: auctions.length },
function (data) {
data.forEach((elem, idx) => {
document.querySelector("#auction-" + idx + " > div > p").innerHTML = elem.short_sentence;
auctions[idx].subtitle = elem.short_sentence;
auctions[idx].detail = elem.very_long_sentence;
(data) => {
data.forEach((elem, i) => {
cards[i].querySelector(".card-subtitle").innerText = elem.short_sentence
cards[i].dataset.bsSubtitle = elem.short_sentence;
cards[i].dataset.bsDetail = elem.very_long_sentence;
});
}
);
// Random end times
// Random cat images and end times
for (let i = 0; i < auctions.length; i++) {
cards[i].querySelector("img").src = "https://cataas.com/cat/cute?random=" + i;
cards[i].dataset.bsPrimaryImage = "https://cataas.com/cat/cute?random=" + i;
cards[i].dataset.bsSecondaryImage = "https://cataas.com/cat/cute?random=" + i;

let now = new Date();
let endTime = new Date().setHours(8 + i, 0, 0, 0)
if (endTime - now < 0) { endTime = new Date(endTime).setDate(now.getDate() + 1) }
Expand Down Expand Up @@ -90,81 +89,6 @@ export function setClocks() {
setTimeout(setClocks, 1000);
}

// Place a bid on an item
function placeBid() {
let nowTime = new Date().getTime();
let modalBidButton = document.querySelector("#bid-modal > div > div > div.modal-footer > button.btn.btn-primary")
modalBidButton.setAttribute('disabled', '') // disable the button while we check
let i = modalBidButton.id.match("[0-9]+");
let feedback = document.getElementById("bad-amount-feedback")
// Cleanse input
let amountElement = document.getElementById("amount-input")
let amount = Number(amountElement.value)
if (auctions[i].endTime - nowTime < 0) {
feedback.innerText = "The auction is already over!"
amountElement.classList.add("is-invalid")
setTimeout(() => {
bidModal.hide();
amountElement.classList.remove("is-invalid");
modalBidButton.removeAttribute('disabled', '');
}, 1000);
} else if (amount == 0) {
// amount was empty
feedback.innerText = "Please specify an amount!"
amountElement.classList.add("is-invalid")
modalBidButton.removeAttribute('disabled', '');
} else if (!(/^-?\d*\.?\d{0,2}$/.test(amount))) {
// field is does not contain money
feedback.innerText = "Please specify a valid amount!"
amountElement.classList.add("is-invalid")
modalBidButton.removeAttribute('disabled', '');
} else {
// Checking bid amount
// Get item and user info
let user = auth.currentUser;
let itemId = i.toString().padStart(5, "0")
// Documents to check and write to
const liveRef = doc(db, "auction-live", "items");
const storeRef = doc(db, "auction-store", itemId);
// Check live document
getDoc(liveRef).then(function (doc) {
console.log("Database read from placeBid()")
let thisItem = doc.data()[itemId];
let bids = (Object.keys(thisItem).length - 1) / 2
let currentBid = thisItem["bid" + bids]
if (amount >= 1 + currentBid) {
let keyStem = itemId + ".bid" + (bids + 1)
updateDoc(liveRef, {
[keyStem + "-uid"]: user.uid,
[keyStem]: amount,
})
console.log("Database write from placeBid()")
let storeKey = "bid" + (bids + 1)
updateDoc(storeRef, {
[storeKey]: {
"bidder-username": user.displayName,
"bidder-uid": user.uid,
"amount": amount,
time: Date().substring(0, 24)
}
})
console.log("Database write from placeBid()")
amountElement.classList.add("is-valid")
amountElement.classList.remove("is-invalid")
setTimeout(() => {
bidModal.hide();
amountElement.classList.remove("is-valid");
modalBidButton.removeAttribute('disabled', '');
}, 1000);
} else {
amountElement.classList.add("is-invalid")
feedback.innerText = "You must bid at least £" + (currentBid + 1).toFixed(2) + "!"
modalBidButton.removeAttribute('disabled', '');
}
});
}
}

function argsort(array, key) {
const arrayObject = array.map((value, idx) => { return { value, idx }; });
return arrayObject.sort((a, b) => (a.value[key] - b.value[key]));
Expand All @@ -177,6 +101,10 @@ function generateAuctionCard(auction) {

let card = document.createElement("div");
card.classList.add("card");
card.dataset.bsTitle=auction.title
card.dataset.bsDetail=auction.detail
card.dataset.bsPrimaryImage=auction.primaryImage
card.dataset.bsSecondaryImage=auction.secondaryImage
card.id = "auction-" + auction.idx
col.appendChild(card);

Expand Down Expand Up @@ -239,20 +167,18 @@ function generateAuctionCard(auction) {

let infoButton = document.createElement("button");
infoButton.type = "button"
infoButton.href = "#";
infoButton.classList.add("btn", "btn-secondary")
infoButton.dataset.bsToggle="modal"
infoButton.dataset.bsTarget="#info-modal"
infoButton.innerText = "Info";
infoButton.onclick = function () { openInfo(this.id); }
infoButton.id = "info-button-" + auction.idx
buttonGroup.appendChild(infoButton);

let bidButton = document.createElement("button");
bidButton.type = "button"
bidButton.href = "#";
bidButton.classList.add("btn", "btn-primary")
bidButton.innerText = "Submit bid";
bidButton.onclick = function () { openBid(this.id); }
bidButton.id = "bid-button-" + auction.idx
bidButton.dataset.bsToggle="modal"
bidButton.dataset.bsTarget="#bid-modal"
buttonGroup.appendChild(bidButton);

return col
Expand All @@ -266,7 +192,7 @@ export function populateAuctionGrid() {
let auctionCard = generateAuctionCard(auction);
auctionGrid.appendChild(auctionCard);
});
if (demoAuction) { generateRandomAuctions() };
if (demoAuction) { generateRandomAuctionData() };
}

function numberWithCommas(x) {
Expand Down Expand Up @@ -348,7 +274,6 @@ function resetAll() {
resetAllStore();
}

window.placeBid = placeBid
window.resetAll = resetAll
window.resetAllLive = resetAllLive
window.resetAllStore = resetAllStore
6 changes: 4 additions & 2 deletions js/firebase.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
export const auth = getAuth(app);

export const auctions = [
const auctions = [
{
primaryImage: "",
title: "",
Expand Down Expand Up @@ -117,4 +117,6 @@ export const auctions = [
secondaryImage: "",
startingPrice: 7,
endTime: 0
}]
}]

window.auctions = auctions
Loading

0 comments on commit 1fb0cbb

Please sign in to comment.