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 %>