From 258b469f1d60b14735bc1dbf63a89d6a3da66040 Mon Sep 17 00:00:00 2001 From: "E. Almqvist" Date: Fri, 22 Apr 2022 23:13:18 +0200 Subject: [PATCH] Auction views --- src/.bundle/config | 1 + src/Gemfile | 2 ++ src/Gemfile.lock | 6 ++++-- src/TODO.md | 2 ++ src/config.rb | 6 ++++-- src/const.rb | 4 ++++ src/lib/db_models.rb | 13 +++++++++---- src/routes/auction.rb | 9 ++++++++- src/views/auction/view.slim | 24 +++++++++++++++++++++--- src/views/stylesheets/style.sass | 30 +++++++++++++++++++++++++----- 10 files changed, 80 insertions(+), 17 deletions(-) diff --git a/src/.bundle/config b/src/.bundle/config index 2369228..afe7b53 100644 --- a/src/.bundle/config +++ b/src/.bundle/config @@ -1,2 +1,3 @@ --- BUNDLE_PATH: "vendor/bundle" +BUNDLE_CACHE_ALL: "false" diff --git a/src/Gemfile b/src/Gemfile index 0131223..6a8d04b 100644 --- a/src/Gemfile +++ b/src/Gemfile @@ -19,3 +19,5 @@ gem "rmagick", "~> 4.2" gem "sinatra-flash", "~> 0.3.0" gem "fileutils", "~> 1.6" + +gem "webrick", "~> 1.7" diff --git a/src/Gemfile.lock b/src/Gemfile.lock index e4ea4fa..9fffbd1 100644 --- a/src/Gemfile.lock +++ b/src/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - bcrypt (3.1.16) + bcrypt (3.1.17) colorize (0.8.1) ffi (1.15.5) fileutils (1.6.0) @@ -11,7 +11,7 @@ GEM rack (2.2.3) rack-protection (2.2.0) rack - rmagick (4.2.4) + rmagick (4.2.5) ruby2_keywords (0.0.5) sassc (2.4.0) ffi (~> 1.9) @@ -36,6 +36,7 @@ GEM sqlite3 (1.4.2) temple (0.8.2) tilt (2.0.10) + webrick (1.7.0) PLATFORMS x86_64-linux @@ -51,6 +52,7 @@ DEPENDENCIES sinatra-reloader slim sqlite3 + webrick (~> 1.7) BUNDLED WITH 2.3.10 diff --git a/src/TODO.md b/src/TODO.md index 36407ab..4811e23 100644 --- a/src/TODO.md +++ b/src/TODO.md @@ -7,6 +7,8 @@ ---------------- - Auction expiry (unable to bid after x time) - User reviews +---------------- + - Yardoc ## Refactor - Funds transfer logic for auctions? diff --git a/src/config.rb b/src/config.rb index e7e1b0a..ebee4bd 100644 --- a/src/config.rb +++ b/src/config.rb @@ -33,12 +33,14 @@ LOGIN_ERRORS = { } # Auction stuff -AH_BUYOUT_FACTOR = 1.8 +AH_BUYOUT_FACTOR = 1.8 # min buyout factor AH_BIDS_FACTOR = 1.01 # min 1% +AH_MIN_IMAGES = 1 # minimum images AUCTION_ERRORS = { titlelen: "Title length must be between #{MIN_TITLE_LEN} and #{MAX_TITLE_LEN} characters!", initprice: "The initial price must be at least #{MIN_INIT_PRICE}!", deltatime: "Time span is too short! Must be at least one day!", - bidamount: "Bid amount must be at least #{((AH_BIDS_FACTOR-1)*100).round(2)}% greater than the highest bid!" + bidamount: "Bid amount must be at least #{((AH_BIDS_FACTOR-1)*100).round(2)}% greater than the highest bid!", + imagecount: "You need to submit at least #{AH_MIN_IMAGES} image(s)!" } diff --git a/src/const.rb b/src/const.rb index 39a2e39..942ef35 100644 --- a/src/const.rb +++ b/src/const.rb @@ -59,11 +59,15 @@ MAX_NAME_LEN = 28 MIN_BIO_LEN = 0 MAX_BIO_LEN = 128 +MIN_MSG_LEN = 0 +MAX_MSG_LEN = 128 + EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/ NAME_REGEX_STR = "[a-zA-Z-_0-9 ]{#{MIN_NAME_LEN},#{MAX_NAME_LEN}}" BIO_REGEX_STR = "{#{MIN_BIO_LEN},#{MAX_BIO_LEN}}" DESC_REGEX_STR = "{#{MIN_DESC_LEN},#{MAX_DESC_LEN}}" TITLE_REGEX_STR = "{#{MIN_TITLE_LEN},#{MAX_TITLE_LEN}}" +MSG_REGEX_STR = "{#{MIN_MSG_LEN},#{MAX_MSG_LEN}}" TIME_FORMATS = { w: 604800, diff --git a/src/lib/db_models.rb b/src/lib/db_models.rb index 726e92a..93dc43a 100644 --- a/src/lib/db_models.rb +++ b/src/lib/db_models.rb @@ -368,10 +368,10 @@ class Auction < EntityModel amount = left.to_i / count if amount > 0 then result << "#{amount}#{sym.to_s}" - puts "#{sym} #{count}, #{left} : #{amount} : #{result}" left -= count*amount end end + result = result[0...2] return result.join ", " end @@ -395,6 +395,12 @@ class Auction < EntityModel return @init_price end end + + def min_new_bid + max_bid = self.max_bid + amount = max_bid.nil? ? @init_price : max_bid.amount + return amount * AH_BIDS_FACTOR + end end # Auction bids @@ -414,11 +420,10 @@ class Bid < EntityModel end def self.place(ahid, uid, amount, message) - ah = Auction.find_by_id + ah = Auction.find_by_id ahid if not ah then return false, "Invalid auction" end - max_bid = ah.max_bid - if amount >= max_bid.amount * AH_BIDS_FACTOR then + if amount >= ah.min_new_bid then payload = { auction_id: ahid, user_id: uid, diff --git a/src/routes/auction.rb b/src/routes/auction.rb index 4452e2b..7776aee 100644 --- a/src/routes/auction.rb +++ b/src/routes/auction.rb @@ -24,13 +24,20 @@ post "/auctions" do description = params[:description] init_price = params[:init_price].to_f delta_time = params[:delta_time].to_i * 3600 # hours to seconds + images = params[:images] + + # Min image count check + if images.nil? or images.length < AH_MIN_IMAGES then + flash[:error] = AUCTION_ERRORS[:imagecount] + redirect "/auctions/new" + end + # # Create the auction newid, resp = Auction.create user_id, title, description, init_price, delta_time if newid then # Save auction images - images = params[:images] images.each_with_index do |img, i| Image.save img[:tempfile].read, newid, i end diff --git a/src/views/auction/view.slim b/src/views/auction/view.slim index c9e2c2b..716ff48 100644 --- a/src/views/auction/view.slim +++ b/src/views/auction/view.slim @@ -16,8 +16,9 @@ - auction.images.each do |image| span.dot onclick="setSlide(#{image.image_order})" - #auctioninfo.card + #auctioninfo h2 = auction.title + h3 = auction.description - if auction.categories.length > 0 ul.list-container#category-list ul @@ -26,10 +27,10 @@ ul style="color: #{category.color}" = category.name - if not auction.expired? - .card.border + div h3 | Current bid: - span.green = "#{COINS_PREFIX}#{auction.current_bid}#{COINS_SUFFIX}" + span.green = "#{COINS_PREFIX}#{auction.current_bid.round 2}#{COINS_SUFFIX}" h3 | Minimum bid factor: span.gray = "#{((AH_BIDS_FACTOR-1)*100).round(2)}%" @@ -43,4 +44,21 @@ h3.red.tcenter | Auction Expired + #auctionbid.card.form-container + form action="/auctions/#{auction.id}/bids" method="post" + input type="number" name="amount" placeholder="#{auction.min_new_bid}" pattern="[0-9]+" + textarea name="message" cols="20" rows="2" title="Content length must be between #{MIN_MSG_LEN} and #{MAX_MSG_LEN} characters" pattern="#{MSG_REGEX_STR}" maxlength="#{MAX_MSG_LEN}" placeholder="Write a message for your bid!" + input type="submit" value="Bid" + + #auctionbid-container + h2 Bid History + - if auction.bids.length >= 1 + ul.list-container.card-container + - auction.bids.reverse_each do |bid| + li + h3 + | #{User.find_by_id(bid.user_id).name} bid + span + | #{COINS_PREFIX}#{bid.amount.round 2}#{COINS_SUFFIX} + h4 = "#{bid.message}" script src="/js/slides.js" type="text/javascript" diff --git a/src/views/stylesheets/style.sass b/src/views/stylesheets/style.sass index 0325fad..8ba0e7d 100644 --- a/src/views/stylesheets/style.sass +++ b/src/views/stylesheets/style.sass @@ -455,21 +455,40 @@ ul.list-container #auction-view display: grid grid-template-columns: 1fr 1fr - grid-template-rows: 1fr 1fr - grid-template-areas: "im in" "de in" + grid-template-rows: 1fr + grid-template-areas: "im in" "bi bi" + +#auctionbid-container + grid-area: bi + font-weight: normal + + ul li + display: flex + flex-direction: column + border-bottom: $border_size solid $shadow_clr + + h3 + color: $fg_clr + span + color: $green_clr + h4 + color: $gray_clr #auctioninfo grid-area: in - .card - margin-top: 2rem + div + margin-top: 1.2rem h2 padding: 0 font-size: 1.8rem h3 - font-size: 1.5rem + font-size: 1.2rem + font-weight: normal + span + font-weight: bold #category-list flex-direction: row @@ -478,6 +497,7 @@ ul.list-container padding: 0 margin-right: 1rem + .slideshow-container grid-area: im width: 40rem