Files
sure/app/views/coinbase_items/setup_accounts.html.erb
LPW dd991fa339 Add Coinbase exchange integration with CDP API support (#704)
* **Add Coinbase integration with item and account management**
- Creates migrations for `coinbase_items` and `coinbase_accounts`.
- Adds models, controllers, views, and background tasks to support account linking, syncing, and transaction handling.
- Implements Coinbase API client and adapter for seamless integration.
- Supports ActiveRecord encryption for secure credential storage.
- Adds UI components for provider setup, account management, and synchronization.

* Localize Coinbase-related UI strings, refine account linking for security, and add timeouts to Coinbase API requests.

* Localize Coinbase account handling to support native currencies (USD, EUR, GBP, etc.) across balances, trades, holdings, and transactions.

* Improve Coinbase processing with timezone-safe parsing, native currency support, and immediate holdings updates.

* Improve trend percentage formatting and enhance race condition handling for Coinbase account linking.

* Fix log message wording for orphan cleanup

* Ensure `selected_accounts` parameter is sanitized by rejecting blank entries.

* Add tests for Coinbase integration: account, item, and controller coverage

- Adds unit tests for `CoinbaseAccount` and `CoinbaseItem` models.
- Adds integration tests for `CoinbaseItemsController`.
- Introduces Stimulus `select-all` controller for UI checkbox handling.
- Localizes UI strings and logging for Coinbase integration.

* Update test fixtures to use consistent placeholder API keys and secrets

* Refine `coinbase_item` tests to ensure deterministic ordering and improve scope assertions.

* Integrate `SyncStats::Collector` into Coinbase syncer to streamline statistics collection and enhance consistency.

* Localize Coinbase sync status messages and improve sync summary test coverage.

* Update `CoinbaseItem` encryption: use deterministic encryption for `api_key` and standard for `api_secret`.

* fix schema drift

* Beta labels to lower expectations

---------

Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-01-21 22:56:39 +01:00

105 lines
4.0 KiB
Plaintext

<% content_for :title, t(".title") %>
<%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".title")) do %>
<div class="flex items-center gap-2">
<%= icon "bitcoin", class: "text-primary" %>
<span class="text-primary"><%= t(".subtitle") %></span>
</div>
<% end %>
<% dialog.with_body do %>
<%= form_with url: complete_account_setup_coinbase_item_path(@coinbase_item),
method: :post,
local: true,
id: "coinbase-setup-form",
data: {
controller: "loading-button",
action: "submit->loading-button#showLoading",
loading_button_loading_text_value: t(".creating"),
turbo_frame: "_top"
},
class: "space-y-6" do |form| %>
<div class="space-y-4">
<div class="bg-surface border border-primary p-4 rounded-lg">
<div class="flex items-start gap-3">
<%= icon "info", size: "sm", class: "text-primary mt-0.5 flex-shrink-0" %>
<div>
<p class="text-sm text-primary">
<%= t(".instructions") %>
</p>
</div>
</div>
</div>
<% if @coinbase_accounts.empty? %>
<div class="text-center py-8">
<p class="text-secondary"><%= t(".no_accounts") %></p>
</div>
<% else %>
<div data-controller="select-all">
<div class="flex items-center justify-between mb-2">
<span class="text-sm text-secondary">
<%= t(".accounts_count", count: @coinbase_accounts.count) %>
</span>
<label class="flex items-center gap-2 text-sm cursor-pointer">
<input type="checkbox"
id="coinbase-select-all"
data-action="change->select-all#toggle"
class="checkbox checkbox--dark">
<span class="text-secondary"><%= t(".select_all") %></span>
</label>
</div>
<div class="space-y-2 max-h-96 overflow-y-auto">
<% @coinbase_accounts.each do |coinbase_account| %>
<label for="cb_<%= coinbase_account.id %>" class="flex items-center gap-3 p-3 border border-primary rounded-lg hover:bg-surface transition-colors cursor-pointer">
<%= check_box_tag "selected_accounts[]",
coinbase_account.id,
false,
id: "cb_#{coinbase_account.id}",
class: "checkbox checkbox--dark",
data: { select_all_target: "checkbox" } %>
<div class="flex-1 min-w-0">
<p class="font-medium text-primary truncate">
<%= coinbase_account.name %>
</p>
<p class="text-xs text-secondary">
<%= coinbase_account.currency %>
</p>
</div>
<div class="text-right flex-shrink-0">
<p class="text-sm font-medium text-primary">
<%= number_with_delimiter(coinbase_account.current_balance || 0, delimiter: ",") %>
</p>
<p class="text-xs text-secondary">
<%= coinbase_account.currency %>
</p>
</div>
</label>
<% end %>
</div>
</div>
<% end %>
</div>
<div class="flex gap-3">
<%= render DS::Button.new(
text: t(".import_selected"),
variant: "primary",
icon: "plus",
type: "submit",
class: "flex-1",
data: { loading_button_target: "button" }
) %>
<%= render DS::Link.new(
text: t(".cancel"),
variant: "secondary",
href: accounts_path
) %>
</div>
<% end %>
<% end %>
<% end %>