mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-24 15:49:39 +02:00
* Basic plaid data model and linking * Remove institutions, add plaid items * Improve schema and Plaid provider * Add webhook verification sketch * Webhook verification * Item accounts and balances sync setup * Provide test encryption keys * Fix test * Only provide encryption keys in prod * Try defining keys in test env * Consolidate account sync logic * Add back plaid account initialization * Plaid transaction sync * Sync UI overhaul for Plaid * Add liability and investment syncing * Handle investment webhooks and process current day holdings * Remove logs * Remove "all" period select for performance * fix amount calc * Remove todo comment * Coming soon for investment historical data * Document Plaid configuration * Listen for holding updates
76 lines
3.4 KiB
Text
76 lines
3.4 KiB
Text
<%# locals: (plaid_item:) %>
|
|
|
|
<%= tag.div id: dom_id(plaid_item) do %>
|
|
<details open class="group bg-white p-4 border border-alpha-black-25 shadow-xs rounded-xl">
|
|
<summary class="flex items-center justify-between gap-2 focus-visible:outline-none">
|
|
<div class="flex items-center gap-2">
|
|
<%= lucide_icon "chevron-right", class: "group-open:transform group-open:rotate-90 text-gray-500 w-5" %>
|
|
|
|
<div class="flex items-center justify-center h-8 w-8 bg-blue-600/10 rounded-full bg-black/5">
|
|
<% if plaid_item.logo.attached? %>
|
|
<%= image_tag plaid_item.logo, class: "rounded-full h-full w-full" %>
|
|
<% else %>
|
|
<div class="flex items-center justify-center">
|
|
<%= tag.p plaid_item.name.first.upcase, class: "text-blue-600 text-xs font-medium" %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
|
|
<div class="pl-1 text-sm">
|
|
<%= tag.p plaid_item.name, class: "font-medium text-gray-900" %>
|
|
<% if plaid_item.syncing? %>
|
|
<div class="text-gray-500 flex items-center gap-1">
|
|
<%= lucide_icon "loader", class: "w-4 h-4 animate-pulse" %>
|
|
<%= tag.span t(".syncing") %>
|
|
</div>
|
|
<% elsif plaid_item.sync_error.present? %>
|
|
<div class="text-gray-500 flex items-center gap-1">
|
|
<%= lucide_icon "alert-circle", class: "w-4 h-4 text-red-500" %>
|
|
<%= tag.span t(".error"), class: "text-red-500" %>
|
|
</div>
|
|
<% else %>
|
|
<p class="text-gray-500">
|
|
<%= plaid_item.last_synced_at ? t(".status", timestamp: time_ago_in_words(plaid_item.last_synced_at)) : t(".status_never") %>
|
|
</p>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-2">
|
|
<%= button_to sync_plaid_item_path(plaid_item), disabled: plaid_item.syncing?, class: "disabled:text-gray-400 text-gray-900 flex hover:text-gray-800 items-center text-sm font-medium hover:underline" do %>
|
|
<%= lucide_icon "refresh-cw", class: "w-4 h-4" %>
|
|
<% end %>
|
|
|
|
<%= contextual_menu do %>
|
|
<div class="w-48 p-1 text-sm leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
|
|
<%= button_to plaid_item_path(plaid_item),
|
|
method: :delete,
|
|
class: "block w-full py-2 px-3 space-x-2 text-red-600 hover:bg-red-50 flex items-center rounded-lg",
|
|
data: {
|
|
turbo_confirm: {
|
|
title: t(".confirm_title"),
|
|
body: t(".confirm_body"),
|
|
accept: t(".confirm_accept")
|
|
}
|
|
} do %>
|
|
<%= lucide_icon "trash-2", class: "w-5 h-5" %>
|
|
|
|
<span><%= t(".delete") %></span>
|
|
<% end %>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</summary>
|
|
|
|
<div class="space-y-4 mt-4">
|
|
<% if plaid_item.accounts.any? %>
|
|
<%= render "accounts/index/account_groups", accounts: plaid_item.accounts %>
|
|
<% else %>
|
|
<div class="p-4 flex flex-col gap-3 items-center justify-center">
|
|
<p class="text-gray-900 font-medium text-sm"><%= t(".no_accounts_title") %></p>
|
|
<p class="text-gray-500 text-sm"><%= t(".no_accounts_description") %></p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</details>
|
|
<% end %>
|