diff --git a/.gitignore b/.gitignore index dddc26494..d9067c949 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,5 @@ CLAUDE.md /app/assets/builds/* !/app/assets/builds/.keep +.cursorindexingignore +.specstory/ diff --git a/app/assets/stylesheets/components/_account.scss b/app/assets/stylesheets/components/_account.scss index 09b15cc3b..fe406bc4f 100644 --- a/app/assets/stylesheets/components/_account.scss +++ b/app/assets/stylesheets/components/_account.scss @@ -125,6 +125,13 @@ } } +.c-account__input--readonly-field { + border: 1px solid #d1d5db !important; + background-color: #f9fafb; + color: #6b7280; + cursor: not-allowed; +} + .c-account__checkbox { gap: 16px; diff --git a/app/assets/stylesheets/components/_btn.scss b/app/assets/stylesheets/components/_btn.scss index 4534dbcbb..13f408fd8 100644 --- a/app/assets/stylesheets/components/_btn.scss +++ b/app/assets/stylesheets/components/_btn.scss @@ -89,4 +89,11 @@ table { font-size: rem(15px); margin: 2.5rem 0 1.5rem 0; } +} + +.c-btn--disabled, +.c-btn:disabled { + opacity: 0.5; + cursor: not-allowed; + pointer-events: none; } \ No newline at end of file diff --git a/app/assets/stylesheets/components/_notifications.scss b/app/assets/stylesheets/components/_notifications.scss index c4832f45a..7e4ffa57b 100644 --- a/app/assets/stylesheets/components/_notifications.scss +++ b/app/assets/stylesheets/components/_notifications.scss @@ -96,4 +96,46 @@ border-bottom: 1px solid $grey-200-color; } } +} + +.c-notification__empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: rem(60px) rem(20px); + text-align: center; + min-height: rem(300px); +} + +.c-notification__empty-icon { + color: #94a3b8; + margin-bottom: rem(24px); + opacity: 0.8; +} + +.c-notification__empty-icon--read { + color: #cbd5e1; + width: 48px; + height: 48px; +} + +.c-notification__empty-title { + font-size: rem(18px); + font-weight: 600; + color: #64748b; + margin: 0 0 rem(8px) 0; + line-height: 1.4; +} + +.c-notification__empty-description { + font-size: rem(14px); + color: #94a3b8; + margin: 0; + line-height: 1.5; +} + +.c-notification__empty-state--read { + min-height: rem(200px); + padding: rem(40px) rem(20px); } \ No newline at end of file diff --git a/app/components/common/auction_type_icon/component.html.erb b/app/components/common/auction_type_icon/component.html.erb index 7fa5ff7ad..0d9c6f81b 100644 --- a/app/components/common/auction_type_icon/component.html.erb +++ b/app/components/common/auction_type_icon/component.html.erb @@ -1,5 +1,5 @@ <% if english? %> - IO + IO <% else %> - PO + PO <% end %> diff --git a/app/components/common/footer/component.html.erb b/app/components/common/footer/component.html.erb index ba0d5f1cb..8d3ec4bff 100644 --- a/app/components/common/footer/component.html.erb +++ b/app/components/common/footer/component.html.erb @@ -7,7 +7,7 @@
diff --git a/app/components/pages/offers/english_auction_offer_table/component.html.erb b/app/components/pages/offers/english_auction_offer_table/component.html.erb index 4b4726b50..33578d335 100644 --- a/app/components/pages/offers/english_auction_offer_table/component.html.erb +++ b/app/components/pages/offers/english_auction_offer_table/component.html.erb @@ -24,12 +24,12 @@ <%= component 'common/table', header_collection: bidder_table_headers, options: { class: '' } do %> <%= tag.tbody do %> <% @offer.auction.offers.order(updated_at: :desc).each do |offer| %> - + <%= offer&.billing_profile&.user_id == current_user.id ? "#{offer.username} (You)" : offer.username %> <%= t('offers.price_in_currency', price: offer.price) %> - <%= I18n.l(offer.updated_at) %> + <%= offer.updated_at %> <% end %> <% end %> diff --git a/app/components/pages/offers/english_auction_offer_table/component.rb b/app/components/pages/offers/english_auction_offer_table/component.rb index e2a99f120..138565425 100644 --- a/app/components/pages/offers/english_auction_offer_table/component.rb +++ b/app/components/pages/offers/english_auction_offer_table/component.rb @@ -12,7 +12,7 @@ def initialize(offer:) def overview_table_headers [{ column: nil, caption: t('auctions.domain_name'), options: { class: '' } }, - { column: nil, caption: t('auctions.ends_at'), options: { class: '' } }, + { column: nil, caption: t('auctions.ended_at'), options: { class: '' } }, { column: nil, caption: t('offers.price'), options: { class: '' } }] end diff --git a/app/components/pages/offers/offers_table/component.rb b/app/components/pages/offers/offers_table/component.rb index 171d40586..dfafa8ba2 100644 --- a/app/components/pages/offers/offers_table/component.rb +++ b/app/components/pages/offers/offers_table/component.rb @@ -11,10 +11,13 @@ def initialize(offers:) end def header_collection - [{ column: 'auctions.domain_name', caption: t('auctions.domain_name'), options: { class: 'sorting' } }, - { column: 'auctions.platform', caption: t('auctions.type'), options: { class: 'sorting' } }, + [{ column: 'auctions.domain_name', caption: t('auctions.domain_name'), + options: { class: 'sorting' } }, + { column: 'auctions.platform', caption: t('auctions.type'), + options: { class: 'sorting' } }, { column: nil, caption: t('offers.show.your_last_offer'), options: { class: '' } }, - { column: 'offers.created_at', caption: t('offers.created_at'), options: { class: 'sorting' } }, + { column: 'offers.created_at', caption: t('offers.created_at'), + options: { class: 'sorting' } }, { column: 'auctions.ends_at', caption: t('auctions.ends_at'), options: { class: 'sorting' } }, { column: nil, caption: t('result_name'), options: {} }, diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 797f126ef..d9e16fc95 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -80,8 +80,10 @@ def clear_flash protected def authenticate_user! + Rails.logger.debug "=== authenticate_user! called, user_signed_in?: #{user_signed_in?}" return if user_signed_in? + Rails.logger.debug "=== User NOT signed in, redirecting..." store_location_for(:user, request.fullpath) if request.get? || request.head? store_location_for(:user, request.referer) unless request.get? || request.head? @@ -90,9 +92,9 @@ def authenticate_user! flash[:alert] = t('devise.failure.unauthenticated') if turbo_frame_request? - render turbo_stream: turbo_stream.action(:redirect, root_path) + render turbo_stream: turbo_stream.action(:redirect, root_path) and return false else - redirect_to new_user_session_path + redirect_to new_user_session_path and return false end end diff --git a/app/controllers/autobider_controller.rb b/app/controllers/autobider_controller.rb index 80cf4785e..26f9c3c4f 100644 --- a/app/controllers/autobider_controller.rb +++ b/app/controllers/autobider_controller.rb @@ -2,7 +2,7 @@ class AutobiderController < ApplicationController before_action :authenticate_user! before_action :set_auction, only: %i[new edit update create] before_action :allow_any_action_with_autobider - + include RecaptchaValidatable recaptcha_action 'autobidder' @@ -25,8 +25,9 @@ def update render turbo_stream: [ turbo_stream.replace('flash', partial: 'common/flash', locals: { flash: }), - turbo_stream.update('autobider-status', html: @autobider.enable ? I18n.t('english_offers.form.yep') : I18n.t('english_offers.form.nope')) - ] + turbo_stream.update('autobider-status', + html: @autobider.enable ? I18n.t('english_offers.form.yep') : I18n.t('english_offers.form.nope')) + ] end def edit diff --git a/app/controllers/english_offers_controller.rb b/app/controllers/english_offers_controller.rb index fb14eaf44..592264ff6 100644 --- a/app/controllers/english_offers_controller.rb +++ b/app/controllers/english_offers_controller.rb @@ -1,10 +1,11 @@ # frozen_string_literal: true class EnglishOffersController < ApplicationController - before_action :set_offer, only: %i[show edit update] - include BeforeRender include Offerable + + before_action :set_offer, only: %i[show edit update] + protect_from_forgery with: :null_session # order is important diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index 493f0bd1c..d2b6a6496 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -87,3 +87,6 @@ application.register("slashed-zero", SlashedZeroController); import OfferPriceValidatorController from "./offer_price_validator_controller"; application.register("offer-price-validator", OfferPriceValidatorController); + +import WishlistController from "./wishlist_controller"; +application.register("wishlist", WishlistController); \ No newline at end of file diff --git a/app/javascript/controllers/wishlist_controller.js b/app/javascript/controllers/wishlist_controller.js new file mode 100644 index 000000000..45dd849c3 --- /dev/null +++ b/app/javascript/controllers/wishlist_controller.js @@ -0,0 +1,27 @@ +import { Controller } from "@hotwired/stimulus" + +// Connects to data-controller="wishlist" +export default class extends Controller { + static targets = ["input", "submit"] + + connect() { + // Check initial state on connect + this.toggleSubmitButton() + } + + domainCheck() { + this.toggleSubmitButton() + } + + toggleSubmitButton() { + const inputValue = this.inputTarget.value.trim() + + if (inputValue.length > 0) { + this.submitTarget.disabled = false + this.submitTarget.classList.remove('c-btn--disabled') + } else { + this.submitTarget.disabled = true + this.submitTarget.classList.add('c-btn--disabled') + } + } +} diff --git a/app/views/admin/auctions/_deposit_participants.html.erb b/app/views/admin/auctions/_deposit_participants.html.erb index f514a734a..c0cef0d64 100644 --- a/app/views/admin/auctions/_deposit_participants.html.erb +++ b/app/views/admin/auctions/_deposit_participants.html.erb @@ -60,7 +60,7 @@ <% end %> <% end %> - <%= turbo_frame_tag "results" do %> + <%= turbo_frame_tag "results", autoscroll: true, data: { autoscroll_block: "start", autoscroll_behavior: "smooth" } do %>
<% if @pagy.pages > 1 %>