mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-07 06:25:19 +02:00
Pre-launch design sync with Figma spec (#2154)
* Add lookbook + viewcomponent, organize design system file * Build menu component * Button updates * More button fixes * Replace all menus with new ViewComponent * Checkpoint: fix tests, all buttons and menus converted * Split into Link and Button components for clarity * Button cleanup * Simplify custom confirmation configuration in views * Finalize button, link component API * Add toggle field to custom form builder + Component * Basic tabs component * Custom tabs, convert all menu / tab instances in app * Gem updates * Centralized icon helper * Update all icon usage to central helper * Lint fixes * Centralize all disclosure instances * Dialog replacements * Consolidation of all dialog styles * Test fixes * Fix app layout issues, move to component with slots * Layout simplification * Flakey test fix * Fix dashboard mobile issues * Finalize homepage * Lint fixes * Fix shadows and borders in dark mode * Fix tests * Remove stale class * Fix filled icon logic * Move transparent? to public interface
This commit is contained in:
parent
1aafed5f8b
commit
90a9546f32
291 changed files with 4143 additions and 3104 deletions
|
@ -13,18 +13,24 @@
|
|||
<% if @import.cleaned? %>
|
||||
<div class="bg-container border border-tertiary rounded-lg p-3 flex flex-col md:flex-row items-start md:items-center justify-between gap-2 md:gap-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<%= lucide_icon "check-circle", class: "w-4 h-4 text-green-500" %>
|
||||
<p class="text-green-500 text-sm md:text-base">Your data has been cleaned</p>
|
||||
<%= icon "check-circle", size: "sm", color: "success" %>
|
||||
<p class="text-success text-sm md:text-base">Your data has been cleaned</p>
|
||||
</div>
|
||||
|
||||
<%= link_to "Next step", import_confirm_path(@import), class: "btn btn--primary w-full md:w-auto" %>
|
||||
<%= render LinkComponent.new(
|
||||
text: "Next step",
|
||||
variant: "primary",
|
||||
href: import_confirm_path(@import),
|
||||
frame: :_top,
|
||||
class: "w-full md:w-auto"
|
||||
) %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="bg-container border border-tertiary rounded-lg p-3 flex flex-col md:flex-row items-start md:items-center justify-between gap-3 md:gap-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<%= lucide_icon "alert-triangle", class: "w-4 h-4 text-red-500 flex-shrink-0" %>
|
||||
<p class="text-red-500 text-sm hidden md:block"><%= t(".errors_notice") %></p>
|
||||
<p class="text-red-500 text-sm md:hidden"><%= t(".errors_notice_mobile") %></p>
|
||||
<%= icon "alert-triangle", size: "sm", color: "destructive" %>
|
||||
<p class="text-destructive text-sm hidden md:block"><%= t(".errors_notice") %></p>
|
||||
<p class="text-destructive text-sm md:hidden"><%= t(".errors_notice_mobile") %></p>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center w-full md:w-auto">
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
<%= form.select :amount_col_label, import.csv_headers, { include_blank: "Leave empty", label: "Balance" }, required: true %>
|
||||
<%= form.select :currency_col_label, import.csv_headers, { include_blank: "Default", label: "Currency" } %>
|
||||
|
||||
<%= form.submit "Apply configuration", class: "w-full btn btn--primary", disabled: import.complete? %>
|
||||
<%= form.submit "Apply configuration", disabled: import.complete? %>
|
||||
<% end %>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<%# locals: (import:) %>
|
||||
|
||||
<div class="flex items-center justify-between border border-secondary rounded-lg bg-green-500/5 p-5 gap-4 mb-4">
|
||||
<%= lucide_icon("check-circle", class: "w-5 h-5 shrink-0 text-green-500") %>
|
||||
<span class="text-green-500">
|
||||
<%= icon("check-circle", color: "current") %>
|
||||
</span>
|
||||
<p class="text-sm text-primary italic">We have pre-configured your Mint import for you. Please proceed to the next step.</p>
|
||||
</div>
|
||||
|
||||
|
@ -29,5 +31,5 @@
|
|||
<%= form.select :category_col_label, import.csv_headers, { include_blank: "Leave empty", label: "Category (optional)" }, disabled: import.complete? %>
|
||||
<%= form.select :tags_col_label, import.csv_headers, { include_blank: "Leave empty", label: "Tags (optional)" }, disabled: import.complete? %>
|
||||
|
||||
<%= form.submit "Apply configuration", class: "w-full btn btn--primary", disabled: import.complete? %>
|
||||
<%= form.submit "Apply configuration", disabled: import.complete? %>
|
||||
<% end %>
|
||||
|
|
|
@ -36,5 +36,5 @@
|
|||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= form.submit "Apply configuration", class: "w-full btn btn--primary", disabled: import.complete? %>
|
||||
<%= form.submit "Apply configuration", disabled: import.complete? %>
|
||||
<% end %>
|
||||
|
|
|
@ -107,7 +107,5 @@
|
|||
import.csv_headers,
|
||||
{ include_blank: "Leave empty", label: "Notes" } %>
|
||||
|
||||
<%= form.submit "Apply configuration",
|
||||
class: "w-full btn btn--primary",
|
||||
disabled: import.complete? %>
|
||||
<%= form.submit "Apply configuration", disabled: import.complete? %>
|
||||
<% end %>
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
<p class="text-sm text-secondary">We found a configuration from a previous import for this account. Would you like to apply it to this import?</p>
|
||||
|
||||
<div class="mt-4 flex gap-2 items-center">
|
||||
<%= link_to "Manually configure", import_configuration_path(@import), class: "btn btn--outline" %>
|
||||
<%= button_to "Apply template", apply_template_import_path(@import), class: "btn btn--primary", method: :put, data: { turbo_frame: :_top } %>
|
||||
<%= render LinkComponent.new(text: "Manually configure", href: import_configuration_path(@import), variant: "outline") %>
|
||||
<%= render ButtonComponent.new(text: "Apply template", href: apply_template_import_path(@import), method: :put, data: { turbo_frame: :_top }) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,18 +8,29 @@
|
|||
<% if import.requires_account? %>
|
||||
<div class="w-full max-w-full overflow-hidden mb-4">
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex items-center justify-between p-4 gap-4 text-secondary bg-red-100 border border-red-200 rounded-lg w-[650px] min-w-0">
|
||||
<div class="flex items-center justify-between p-4 gap-4 text-secondary bg-red-100 border border-red-200 rounded-lg w-[650px] min-w-0 mx-auto">
|
||||
<%= tag.p t(".no_accounts"), class: "text-sm" %>
|
||||
<%= link_to t(".create_account"), new_account_path(return_to: import_confirm_path(import)), class: "btn btn--primary whitespace-nowrap", data: { turbo_frame: :modal } %>
|
||||
|
||||
<%= render LinkComponent.new(
|
||||
text: "Create account",
|
||||
variant: "primary",
|
||||
href: new_account_path(return_to: import_confirm_path(import)),
|
||||
frame: :modal
|
||||
) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% elsif import.has_unassigned_account? %>
|
||||
<div class="w-full max-w-full overflow-hidden mb-4">
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex items-center justify-between p-4 gap-4 text-secondary bg-yellow-100 border border-yellow-200 rounded-lg w-[650px] min-w-0">
|
||||
<div class="flex items-center justify-between p-4 gap-4 text-secondary bg-yellow-100 border border-yellow-200 rounded-lg w-[650px] min-w-0 mx-auto">
|
||||
<%= tag.p t(".unassigned_account"), class: "text-sm" %>
|
||||
<%= link_to t(".create_account"), new_account_path(return_to: import_confirm_path(import)), class: "btn btn--primary whitespace-nowrap", data: { turbo_frame: :modal } %>
|
||||
<%= render LinkComponent.new(
|
||||
text: t(".create_account"),
|
||||
variant: "primary",
|
||||
href: new_account_path(return_to: import_confirm_path(import)),
|
||||
frame: :modal
|
||||
) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -29,7 +40,7 @@
|
|||
<div class="space-y-4 w-full max-w-full">
|
||||
<div class="w-full max-w-full overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<div class="bg-container-inset rounded-xl p-1 space-y-1 w-[650px] min-w-0">
|
||||
<div class="bg-container-inset rounded-xl p-1 space-y-1 w-[650px] min-w-0 mx-auto">
|
||||
<div class="grid grid-cols-3 gap-2 text-xs font-medium text-secondary uppercase px-5 py-3">
|
||||
<p><%= t(".csv_mapping_label", mapping: mapping_label(mapping_class)) %></p>
|
||||
<p><%= t(".maybe_mapping_label", mapping: mapping_label(mapping_class)) %></p>
|
||||
|
@ -48,10 +59,14 @@
|
|||
</div>
|
||||
|
||||
<div class="flex justify-center w-full">
|
||||
<%= link_to is_last_step ? import_path(import) : url_for(step: step_idx + 2), class: "btn btn--primary w-full md:w-36 flex items-center justify-between gap-2" do %>
|
||||
<span>Next</span>
|
||||
<%= lucide_icon "arrow-right", class: "w-5 h-5" %>
|
||||
<% end %>
|
||||
<%= render LinkComponent.new(
|
||||
text: "Next",
|
||||
variant: "primary",
|
||||
href: is_last_step ? import_path(import) : url_for(step: step_idx + 2),
|
||||
icon: "arrow-right",
|
||||
icon_position: "right",
|
||||
class: "w-full md:w-auto"
|
||||
) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
disabled: row.import.complete? %>
|
||||
|
||||
<% if !cell_is_valid?(row, key) %>
|
||||
<span class="absolute right-2 top-1/2 -translate-y-1/2 text-red-500 md:hidden"
|
||||
<span class="absolute right-2 top-1/2 -translate-y-1/2 text-destructive md:hidden"
|
||||
data-action="click->mobile-cell-interaction#toggleErrorMessage"
|
||||
data-mobile-cell-interaction-target="errorIcon">
|
||||
<%= lucide_icon "alert-circle", class: "w-4 h-4" %>
|
||||
data-mobile-cell-interaction-target="errorIcon">
|
||||
<%= icon "alert-circle", size: "sm", color: "destructive" %>
|
||||
</span>
|
||||
|
||||
<div class="absolute left-4 right-4 bottom-full mb-2 p-2 bg-red-50 border border-red-200 rounded-lg shadow-lg text-xs text-red-600 hidden md:hidden z-20"
|
||||
|
|
|
@ -11,65 +11,67 @@
|
|||
<p class="text-secondary text-sm"><%= t(".description") %></p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
data-controller="tabs"
|
||||
data-tabs-active-class="bg-surface shadow-sm text-primary"
|
||||
data-tabs-inactive-class="text-secondary"
|
||||
data-tabs-default-tab-value="csv-upload-tab">
|
||||
<div class="flex justify-center mb-4 w-full">
|
||||
<div class="bg-surface-inset rounded-lg p-1 flex w-full">
|
||||
<button type="button" data-id="csv-upload-tab" class="w-1/2 px-2 py-1 rounded-md text-secondary text-sm font-medium" data-tabs-target="btn" data-action="click->tabs#select">Upload CSV</button>
|
||||
<button type="button" data-id="csv-paste-tab" class="w-1/2 px-2 py-1 rounded-md text-sm text-secondary font-medium" data-tabs-target="btn" data-action="click->tabs#select">Copy & Paste</button>
|
||||
</div>
|
||||
</div>
|
||||
<%= render TabsComponent.new(active_tab: params[:tab] || "csv-upload", url_param_key: "tab", testid: "import-tabs") do |tabs| %>
|
||||
<% tabs.with_nav do |nav| %>
|
||||
<% nav.with_btn(id: "csv-upload", label: "Upload CSV") %>
|
||||
<% nav.with_btn(id: "csv-paste", label: "Copy & Paste") %>
|
||||
<% end %>
|
||||
|
||||
<% ["csv-paste-tab", "csv-upload-tab"].each do |tab| %>
|
||||
<%= tag.div id: tab, data: { tabs_target: "tab" }, class: tab == "csv-upload-tab" ? "hidden" : "" do %>
|
||||
<%= styled_form_with model: @import, scope: :import, url: import_upload_path(@import), multipart: true, class: "space-y-2" do |form| %>
|
||||
<%= form.select :col_sep, Import::SEPARATORS, label: true %>
|
||||
<% tabs.with_panel(tab_id: "csv-upload") do %>
|
||||
<%= styled_form_with model: @import, scope: :import, url: import_upload_path(@import), multipart: true, class: "space-y-2" do |form| %>
|
||||
<%= form.select :col_sep, Import::SEPARATORS, label: true %>
|
||||
|
||||
<% if @import.type == "TransactionImport" || @import.type == "TradeImport" %>
|
||||
<%= form.select :account_id, @import.family.accounts.pluck(:name, :id), { label: "Account (optional)", include_blank: "Multi-account import", selected: @import.account_id } %>
|
||||
<% end %>
|
||||
<% if @import.type == "TransactionImport" || @import.type == "TradeImport" %>
|
||||
<%= form.select :account_id, @import.family.accounts.pluck(:name, :id), { label: "Account (optional)", include_blank: "Multi-account import", selected: @import.account_id } %>
|
||||
<% end %>
|
||||
|
||||
<% if tab == "csv-paste-tab" %>
|
||||
<%= form.text_area :raw_file_str,
|
||||
<div class="flex flex-col items-center justify-center w-full h-64 border border-secondary border-dashed rounded-xl cursor-pointer" data-controller="file-upload" data-action="click->file-upload#triggerFileInput" data-file-upload-target="uploadArea">
|
||||
<div class="flex flex-col items-center justify-center pt-5 pb-6">
|
||||
<div data-file-upload-target="uploadText" class="flex flex-col items-center">
|
||||
<%= icon("plus", size: "lg", class: "mb-4 mx-auto") %>
|
||||
<p class="mb-2 text-md text-gray text-center">
|
||||
<span class="font-medium text-primary">Browse</span> to add your CSV file here
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-4 items-center hidden mb-2" data-file-upload-target="fileName">
|
||||
<span class="text-primary">
|
||||
<%= icon("file-text", size: "lg", color: "current") %>
|
||||
</span>
|
||||
<p class="text-md font-medium text-primary"></p>
|
||||
</div>
|
||||
|
||||
<%= form.file_field :csv_file, class: "hidden", "data-auto-submit-form-target": "auto", "data-file-upload-target": "input" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= form.submit "Upload CSV", disabled: @import.complete? %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% tabs.with_panel(tab_id: "csv-paste") do %>
|
||||
<%= styled_form_with model: @import, scope: :import, url: import_upload_path(@import), multipart: true, class: "space-y-2" do |form| %>
|
||||
<%= form.select :col_sep, Import::SEPARATORS, label: true %>
|
||||
|
||||
<% if @import.type == "TransactionImport" || @import.type == "TradeImport" %>
|
||||
<%= form.select :account_id, @import.family.accounts.pluck(:name, :id), { label: "Account (optional)", include_blank: "Multi-account import", selected: @import.account_id } %>
|
||||
<% end %>
|
||||
|
||||
<%= form.text_area :raw_file_str,
|
||||
rows: 10,
|
||||
required: true,
|
||||
placeholder: "Paste your CSV file contents here",
|
||||
"data-auto-submit-form-target": "auto" %>
|
||||
<% else %>
|
||||
<div class="flex flex-col items-center justify-center w-full h-64 border border-secondary border-dashed rounded-xl cursor-pointer" data-controller="file-upload" data-action="click->file-upload#triggerFileInput" data-file-upload-target="uploadArea">
|
||||
<div class="flex flex-col items-center justify-center pt-5 pb-6">
|
||||
<div data-file-upload-target="uploadText" class="flex flex-col items-center">
|
||||
<%= lucide_icon("plus", class: "w-6 h-6 mb-4 text-secondary mx-auto") %>
|
||||
<p class="mb-2 text-md text-gray text-center">
|
||||
<span class="font-medium text-primary">Browse</span> to add your CSV file here
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-center hidden" data-file-upload-target="fileName">
|
||||
<%= lucide_icon("file-text", class: "w-6 h-6 mb-4 text-primary") %>
|
||||
<p class="mb-2 text-md font-medium text-primary"></p>
|
||||
</div>
|
||||
|
||||
<%= form.file_field :csv_file, class: "hidden", "data-auto-submit-form-target": "auto", "data-file-upload-target": "input" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= form.submit "Upload CSV", disabled: @import.complete? %>
|
||||
<% end %>
|
||||
<%= form.submit "Upload CSV", disabled: @import.complete? %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
|
||||
<span class="text-secondary text-sm">
|
||||
<%= link_to "Download a sample CSV", "/imports/#{@import.id}/upload/sample_csv", class: "text-primary underline", data: { turbo: false } %> to see the required CSV format
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<span class="text-secondary text-sm">
|
||||
<%= link_to "Download a sample CSV", "/imports/#{@import.id}/upload/sample_csv", class: "text-primary underline", data: { turbo: false } %> to see the required CSV format
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue