WIP: Feature: Mobile Responsiveness #2080

Closed
oliverqx wants to merge 37 commits from 2077-feature-mobile-responsiveness into main
46 changed files with 197 additions and 154 deletions

View File

@@ -508,6 +508,10 @@
@apply transition-all duration-300;
}
.btn--round {
@apply rounded-full p-2 sm:rounded-lg sm:px-3 sm:py-2
}
.btn--primary {
@apply button-bg-primary text-white disabled:text-gray-400;
@apply hover:button-bg-primary-hover;

View File

@@ -31,8 +31,8 @@ end
private
def radio_tab_contents(label:, icon:)
tag.div(class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-subdued group-has-checked:bg-container group-has-checked:text-gray-800 group-has-checked:shadow-sm") do
concat lucide_icon(icon, class: "w-5 h-5")
concat tag.span(label, class: "group-has-checked:font-semibold")
concat lucide_icon(icon, class: "w-[clamp(15px,1.8vw,20px)] h-[clamp(15px,1.8vw,20px)]")
concat tag.span(label, class: "group-has-checked:font-semibold text-[clamp(14px,1.5vw,16px)]")
end
end
end

View File

@@ -8,7 +8,7 @@ module MfaHelper
svg_attributes: {
width: "240",
height: "240",
viewBox: "0 0 65 65"
viewBox: "0 0 60 60"
}
)

View File

@@ -1,6 +1,6 @@
<%# locals: (date:, entries:, content:, totals: false) %>
<div id="entry-group-<%= date %>" class="bg-container-inset rounded-xl p-1 w-full" data-bulk-select-target="group">
<div id="entry-group-<%= date %>" class="bg-container-inset inline-block rounded-xl p-1 w-full" data-bulk-select-target="group">
<div class="py-2 px-4 flex items-center justify-between font-medium text-xs text-secondary">
<div class="flex pl-0.5 items-center gap-4">
<%= check_box_tag "#{date}_entries_selection",

View File

@@ -8,8 +8,8 @@
<fieldset class="bg-gray-50 rounded-lg p-1 grid grid-flow-col justify-stretch gap-x-2">
<%= radio_tab_tag form: f, name: :nature, value: :outflow, label: t(".expense"), icon: "minus-circle", checked: params[:nature] == "outflow" || params[:nature].nil? %>
<%= radio_tab_tag form: f, name: :nature, value: :inflow, label: t(".income"), icon: "plus-circle", checked: params[:nature] == "inflow" %>
<%= link_to new_transfer_path, data: { turbo_frame: :modal }, class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-subdued group-has-checked:bg-container group-has-checked:text-gray-800 group-has-checked:shadow-sm" do %>
<%= lucide_icon "arrow-right-left", class: "w-5 h-5" %>
<%= link_to new_transfer_path, data: { turbo_frame: :modal }, class: "flex px-4 py-1 text-[clamp(14px,1.5vw,16px)] rounded-lg items-center space-x-2 justify-center text-subdued group-has-checked:bg-container group-has-checked:text-gray-800 group-has-checked:shadow-sm" do %>
<%= lucide_icon "arrow-right-left", class: "w-[clamp(15px,1.8vw,20px)] h-[clamp(15px,1.8vw,20px)]" %>
<%= tag.span t(".transfer") %>
<% end %>
</fieldset>

View File

@@ -4,7 +4,7 @@
<%= turbo_frame_tag dom_id(entry) do %>
<%= turbo_frame_tag dom_id(transaction) do %>
<div class="grid grid-cols-12 items-center text-primary text-sm font-medium p-4
<div class="grid grid-cols-[repeat(12,_minmax(45px,0.25fr))] gap-4 items-center text-primary text-sm font-medium p-4
<%= @focused_record == entry || @focused_record == transaction ?
"border border-gray-900 rounded-lg" : "" %>">

View File

@@ -1,7 +1,7 @@
<%# locals: (account:, url:) %>
<%= styled_form_with model: account, url: url, scope: :account, data: { turbo: false }, class: "flex flex-col gap-4 justify-between grow" do |form| %>
<div class="grow space-y-2">
<%= styled_form_with model: account, url: url, scope: :account, data: { turbo: false }, class: "flex flex-col gap-4 justify-between grow !max-w-[100%]" do |form| %>
<div id="im-sad" class="grow space-y-2 bg=[red]">
<%= form.hidden_field :accountable_type %>
<%= form.hidden_field :return_to, value: params[:return_to] %>

View File

@@ -4,17 +4,17 @@
<div class="flex items-center gap-2">
<%= button_to sync_all_accounts_path,
disabled: Current.family.syncing?,
class: "btn btn--outline flex items-center gap-2",
class: "btn btn--outline btn--round flex items-center gap-2",
title: t(".sync") do %>
<%= lucide_icon "refresh-cw", class: "w-5 h-5" %>
<span><%= t(".sync") %></span>
<span class="hidden sm:block"><%= t(".sync") %></span>
<% end %>
<%= link_to new_account_path(return_to: accounts_path),
data: { turbo_frame: "modal" },
class: "btn btn--primary flex items-center gap-1" do %>
class: "btn btn--primary btn--round flex items-center gap-1" do %>
<%= lucide_icon("plus", class: "w-5 h-5") %>
<p class="text-sm font-medium"><%= t(".new_account") %></p>
<p class="hidden sm:block text-sm font-medium"><%= t(".new_account") %></p>
<% end %>
</div>
</div>

View File

@@ -19,7 +19,7 @@
<%= yield %>
</div>
<div class="border-t border-alpha-black-25 p-4 text-secondary text-sm flex justify-between">
<div class="border-t border-alpha-black-25 p-4 text-secondary text-sm hidden sm:flex justify-between">
<div class="flex space-x-5">
<div class="flex items-center space-x-2">
<span>Select</span>

View File

@@ -5,8 +5,8 @@
next_budget: @next_budget,
latest_budget: @latest_budget %>
<div class="flex items-start gap-4">
<div class="w-[300px] space-y-4">
<div class="flex flex-col sm:flex-row items-start gap-4">
<div class="w-full sm:w-[300px] space-y-4">
<div class="h-[300px] bg-container rounded-xl shadow-border-xs p-8">
<% if @budget.available_to_allocate.negative? %>
<%= render "budgets/over_allocation_warning", budget: @budget %>
@@ -49,7 +49,7 @@
</div>
</div>
<div class="grow bg-container rounded-xl shadow-border-xs p-4">
<div class="grow sm:w-auto w-full bg-container rounded-xl shadow-border-xs p-4">
<div class="flex items-center justify-between mb-4">
<h2 class="text-lg font-medium">Categories</h2>

View File

@@ -2,9 +2,9 @@
<header class="flex items-center justify-between">
<h1 class="text-primary text-xl font-medium"><%= t(".categories") %></h1>
<%= link_to new_category_path, class: "btn btn--primary flex items-center gap-1 justify-center", data: { turbo_frame: :modal } do %>
<%= link_to new_category_path, class: "btn btn--primary btn--round flex items-center gap-1 justify-center", data: { turbo_frame: :modal } do %>
<%= lucide_icon "plus", class: "w-5 h-5" %>
<p><%= t(".new") %></p>
<span class="hidden sm:block"><%= t(".new") %></span>
<% end %>
</header>

View File

@@ -35,9 +35,9 @@
</div>
<% end %>
<div class="pb-12">
<div class="bg-container-inset rounded-xl p-1 mb-6">
<div style="grid-template-columns: repeat(<%= @import.column_keys.count %>, 1fr)" class="grid items-center uppercase text-xs font-medium text-secondary py-3">
<div class="sm:pb-12 overflow-x-auto">
<div class="bg-container-inset rounded-xl p-1 sm:mb-6 inline-block min-w-full">
<div style="grid-template-columns: repeat(<%= @import.column_keys.count %>, minmax(150px,1fr)" class="grid items-center uppercase text-xs font-medium text-secondary py-3">
<% @import.column_keys.each do |key| %>
<div class="px-5"><%= import_col_label(key) %></div>
<% end %>

View File

@@ -11,7 +11,7 @@
<%= link_to t(".create_account"), new_account_path(return_to: import_confirm_path(import)), class: "btn btn--primary whitespace-nowrap", data: { turbo_frame: :modal } %>
</div>
<% elsif import.has_unassigned_account? %>
<div class="flex items-center justify-between p-4 mb-4 gap-4 text-secondary bg-yellow-100 border border-yellow-200 rounded-lg w-[650px]">
<div class="flex flex-col sm:flex-row items-center justify-between p-4 mb-4 gap-4 text-secondary bg-yellow-100 border border-yellow-200 rounded-lg sm:w-[650px]">
<%= 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 } %>
@@ -19,20 +19,22 @@
<% end %>
<% end %>
<div class="space-y-4">
<div class="bg-container-inset rounded-xl p-1 space-y-1 w-[650px]">
<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>
<p class="justify-self-end"><%= t(".rows_label") %></p>
</div>
<div class="space-y-4 max-w-full">
<div class="w-full overflow-x-auto">
<div class="bg-container-inset rounded-xl p-1 space-y-1 inline-block min-w-full sm:w-[650px]">
<div class="grid grid-cols-[repeat(3,_minmax(130px,_1fr))] sm:grid-cols-3 gap-4 sm: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>
<p class="justify-self-end"><%= t(".rows_label") %></p>
</div>
<div class="shadow-border-xs rounded-md divide-y divide-alpha-black-100 text-sm">
<% mappings.sort_by(&:key).each do |mapping| %>
<div class="px-5 py-3 bg-container first:rounded-tl-xl first:rounded-tr-xl last:rounded-bl-xl last:rounded-br-xl">
<%= render partial: "import/mappings/form", locals: { mapping: mapping } %>
</div>
<% end %>
<div class="shadow-border-xs rounded-md divide-y divide-alpha-black-100 text-sm">
<% mappings.sort_by(&:key).each do |mapping| %>
<div class="px-5 py-3 bg-container first:rounded-tl-xl first:rounded-tr-xl last:rounded-bl-xl last:rounded-br-xl">
<%= render partial: "import/mappings/form", locals: { mapping: mapping } %>
</div>
<% end %>
</div>
</div>
</div>

View File

@@ -8,16 +8,6 @@
<% step_mapping_class = @import.mapping_steps[step_idx] %>
<div class="space-y-12 mx-auto max-w-md mb-6">
<div class="flex justify-center items-center gap-2">
<% @import.mapping_steps.each_with_index do |step_mapping_class, idx| %>
<% is_active = step_idx == idx %>
<%= link_to url_for(step: idx + 1), class: "w-5 h-[3px] #{is_active ? 'bg-gray-900' : 'bg-gray-100'} rounded-xl hover:bg-gray-300 transition-colors duration-200" do %>
<span class="sr-only">Step <%= idx + 1 %></span>
<% end %>
<% end %>
</div>
<div class="text-center space-y-2">
<h1 class="text-3xl text-primary font-medium">
<%= t(".#{step_mapping_class.name.demodulize.underscore}_title", import_type: @import.type.underscore.humanize) %>

View File

@@ -3,10 +3,10 @@
<%= styled_form_with model: mapping,
scope: :import_mapping,
url: import_mapping_path(mapping.import, mapping),
class: "grid grid-cols-3 gap-2 items-center",
class: "grid grid-cols-[repeat(3,_minmax(130px,_1fr))] sm:grid-cols-3 gap-4 sm:gap-2 items-center",
data: { controller: "auto-submit-form" },
html: { id: dom_id(mapping, :form) } do |form| %>
<span><%= mapping.key.blank? ? "(unassigned)" : mapping.key %></span>
<span class="truncate"><%= mapping.key.blank? ? "(unassigned)" : mapping.key %></span>
<% if mapping.mappable_class.present? %>
<%= form.hidden_field :mappable_type, value: mapping.mappable_class, id: dom_id(mapping, :mappable_type) %>

View File

@@ -1,6 +1,6 @@
<%# locals: (row:) %>
<div style="grid-template-columns: repeat(<%= row.import.column_keys.count %>, 1fr)" class="first:rounded-tl-lg first:rounded-tr-lg last:rounded-bl-lg last:rounded-br-lg grid divide-x divide-alpha-black-200 group">
<div style="grid-template-columns: repeat(<%= row.import.column_keys.count %>, minmax(150px,1fr)" class="first:rounded-tl-lg first:rounded-tr-lg last:rounded-bl-lg last:rounded-br-lg grid divide-x divide-alpha-black-200 group">
<% row.import.column_keys.each_with_index do |key, idx| %>
<%= turbo_frame_tag dom_id(row, key), title: row.valid? ? nil : row.errors.full_messages.join(", ") do %>
<%= form_with(

View File

@@ -4,24 +4,24 @@
<%= content_for :previous_path, imports_path %>
<div class="space-y-12">
<div class="space-y-8 sm:space-y-12">
<div class="space-y-4 mx-auto max-w-md">
<div class="text-center space-y-2">
<h1 class="text-3xl text-primary font-medium"><%= t(".title") %></h1>
<p class="text-secondary text-sm"><%= t(".description") %></p>
</div>
<div data-controller="tabs" data-tabs-active-class="bg-container" data-tabs-default-tab-value="csv-paste-tab">
<div data-controller="tabs" data-tabs-active-class="bg-container" data-tabs-default-tab-value="csv-upload-tab">
<div class="flex justify-center mb-4">
<div class="tab-item-active rounded-lg inline-flex p-1 space-x-2 text-sm text-primary font-medium">
<button type="button" data-id="csv-paste-tab" class="p-2 rounded-lg" data-tabs-target="btn" data-action="click->tabs#select">Copy & Paste</button>
<button type="button" data-id="csv-upload-tab" class="p-2 rounded-lg" data-tabs-target="btn" data-action="click->tabs#select">Upload CSV</button>
<div class="tab-item-active rounded-lg grid grid-cols-2 p-1 gap-2 text-xs text-primary font-medium w-full">
<button type="button" data-id="csv-upload-tab" class="py-2 rounded-lg" data-tabs-target="btn" data-action="click->tabs#select">Upload CSV</button>
<button type="button" data-id="csv-paste-tab" class="py-2 rounded-lg" data-tabs-target="btn" data-action="click->tabs#select">Copy & Paste</button>
</div>
</div>
<% ["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| %>
<%= styled_form_with model: @import, scope: :import, url: import_upload_path(@import), multipart: true, class: "space-y-4 sm:space-y-2" do |form| %>
<%= form.select :col_sep, Import::SEPARATORS, label: true %>
<% if @import.type == "TransactionImport" || @import.type == "TradeImport" %>
@@ -35,9 +35,16 @@
placeholder: "Paste your CSV file contents here",
"data-auto-submit-form-target": "auto" %>
<% else %>
<label for="import_csv_file" class="flex flex-col items-center justify-center w-full h-56 border-2 border-secondary border-dashed rounded-lg cursor-pointer bg-container-inset">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<%= form.file_field :csv_file, class: "ml-32", "data-auto-submit-form-target": "auto" %>
<label for="import_csv_file" class="flex flex-col items-center justify-center w-full h-56 border-1 border-secondary border-dashed rounded-lg cursor-pointer bg-container-inset">
<div class="flex flex-col items-center justify-center space-y-2 pt-5 pb-6">
<%= lucide_icon "plus", class: "w-4 h-4 text-secondary" %>
<span class="leading-none m-0">
Browse <span class="text-secondary">to add your CSV file here </span>
</span>
<%= form.file_field :csv_file,
class: "hidden",
"data-auto-submit-form-target": "auto"
%>
</div>
</label>
<% end %>
@@ -49,7 +56,7 @@
</div>
</div>
<div class="bg-alpha-black-25 rounded-xl p-1 mt-5 mx-auto max-w-7xl">
<div class="bg-alpha-black-25 rounded-xl p-1 mt-2 mx-auto max-w-7xl">
<div class="text-secondary p-2 mb-2">
<div class="flex gap-2 mb-2">
<%= lucide_icon("info", class: "w-5 h-5 shrink-0") %>

View File

@@ -8,7 +8,8 @@
{ name: "Confirm", path: import_path(import), is_complete: import.complete?, step_number: 5 }
].reject { |step| step[:name] == "Map" && import.mapping_steps.empty? } %>
<ul class="flex items-center gap-2">
<% content_for :header_nav do %>
<ul class="hidden sm:flex items-center gap-2">
<% steps.each_with_index do |step, idx| %>
<li class="flex items-center gap-2 group">
<% is_current = request.path == step[:path] %>
@@ -38,3 +39,13 @@
</li>
<% end %>
</ul>
<% end %>
<% content_for :mobile_nav do %>
<div class="sm:hidden flex justify-center items-center gap-2">
<% current_step = steps.find { |step| request.path == step[:path] } %>
<% if current_step %>
<span>Step <%= current_step[:step_number] %> of <%= steps.length %></span>
<% end %>
</div>
<% end %>

View File

@@ -1,35 +1,38 @@
<%# locals: (headers: [], rows: [], caption: nil) %>
<div class="overflow-x-auto">
<div class="border border-secondary rounded-md shadow-border-xs text-sm bg-container w-full">
<div class="grid border-b border-b-alpha-black-200" style="grid-template-columns: repeat(<%= headers.length %>, minmax(0, 1fr))">
<div class="overflow-x-auto w-full">
<div class="border border-secondary rounded-md shadow-border-xs text-sm bg-container inline-block min-w-full">
<div class="grid border-b border-b-alpha-black-200 p-1" style="grid-template-columns: repeat(<%= headers.length %>, minmax(130px, 1fr))">
<% headers.each_with_index do |header, index| %>
<div class="
bg-container-inset px-3 py-2.5 font-medium whitespace-nowrap overflow-x-auto
bg-container-inset px-3 py-2.5 font-medium whitespace-nowrap sm:overflow-x-auto
first:rounded-tl-md last:rounded-tr-md
<%= "border-r border-r-alpha-black-200" unless index == headers.length - 1 %>
">
<%= header %>
<div class="truncate">
<%= header %>
</div>
</div>
<% end %>
</div>
<% rows.each_with_index do |row, row_index| %>
<div class="grid <%= "border-b border-b-alpha-black-200" if row_index < rows.length - 1 || caption %>" style="grid-template-columns: repeat(<%= headers.length %>, minmax(0, 1fr))">
<div class="grid <%= "border-b border-b-alpha-black-200" if row_index < rows.length - 1 || caption %>" style="grid-template-columns: repeat(<%= headers.length %>, minmax(130px, 1fr))">
<% row.each_with_index do |(header, value), col_index| %>
<div class="
px-3 py-2.5 whitespace-nowrap overflow-x-auto flex items-start
px-3 py-2.5 whitespace-nowrap overflow-x-hidden flex items-start
<%= "border-r border-r-alpha-black-200" unless col_index == row.length - 1 %>
<%= "rounded-bl-md" if !caption && row_index == rows.length - 1 && col_index == 0 %>
<%= "rounded-br-md" if !caption && row_index == rows.length - 1 && col_index == row.length - 1 %>
">
<%= value %>
<div class="truncate">
<%= value %>
</div>
</div>
<% end %>
</div>
<% end %>
<% if caption %>
<div class="px-3 py-2.5 text-center text-xs text-primary rounded-b-md italic bg-container-inset overflow-x-auto">
<div class="px-3 py-2.5 text-center text-xs text-primary rounded-b-md italic bg-container-inset sm:x-overflow-auto text-ellipsis">
<%= caption %>
</div>
<% end %>

View File

@@ -1,9 +1,9 @@
<div class="flex items-center justify-between">
<h1 class="text-xl font-medium text-primary"><%= t(".title") %></h1>
<%= link_to new_import_path, class: "btn btn--primary flex items-center gap-2", data: { turbo_frame: :modal } do %>
<%= link_to new_import_path, class: "btn btn--primary btn--round flex items-center gap-2", data: { turbo_frame: :modal } do %>
<%= lucide_icon("plus", class: "w-5 h-5") %>
<span><%= t(".new") %></span>
<span class="hidden sm:block"><%= t(".new") %></span>
<% end %>
</div>

View File

@@ -1,5 +1,5 @@
<%= modal do %>
<div class="p-4 space-y-4 max-w-[420px]">
<div class="p-4 space-y-4 sm:max-w-[420px]">
<div class="space-y-2">
<div class="flex justify-between items-center">
<h2 class="font-medium text-primary"><%= t(".title") %></h2>

View File

@@ -14,7 +14,8 @@
<% end %>
</header>
<main class="grow px-8 pt-12 pb-32 overflow-y-auto">
<main class="grow px-4 sm:px-8 pt-12 pb-10 sm:pb-32 overflow-y-auto">
<%= yield :mobile_nav %>
<%= yield %>
</main>
</div>

View File

@@ -1,10 +1,10 @@
<%= render "layouts/shared/htmldoc" do %>
<div class="flex h-full bg-surface">
<div class="p-4 w-96 shrink-0 h-full overflow-y-auto">
<div class="hidden sm:block p-4 w-96 shrink-0 h-full overflow-y-auto">
<%= render "settings/settings_nav" %>
</div>
<main class="py-4 px-10 grow flex h-full overflow-y-auto">
<main class="sm:py-4 px-4 sm:px-10 grow flex h-full overflow-y-auto">
<div class="relative max-w-4xl mx-auto flex flex-col w-full h-full">
<div class="grow space-y-4 overflow-y-auto -mx-1 px-1 pb-12">
<% if content_for?(:breadcrumbs) %>
@@ -20,9 +20,13 @@
<% end %>
<%= yield %>
<div class="sm:hidden block mt-4">
<%= settings_nav_footer %>
</div>
</div>
<div class="mt-4">
<div class="hidden sm:block mt-4">
<%= settings_nav_footer %>
</div>
</div>

View File

@@ -1,6 +1,6 @@
<%# locals: (breadcrumbs:, sidebar_toggle_enabled: true) %>
<nav class="flex items-center gap-2 mb-6">
<nav class="hidden sm:flex items-center gap-2 mb-6">
<% if sidebar_toggle_enabled %>
<button data-action="sidebar#toggleLeftPanel" class="hidden p-2 lg:inline-flex rounded-lg items-center justify-center hover:bg-container-inset cursor-pointer">
<%= icon("panel-left", color: "gray") %>

View File

@@ -1,9 +1,9 @@
<header class="flex items-center justify-between">
<h1 class="text-primary text-xl font-medium"><%= t(".title") %></h1>
<%= link_to new_merchant_path, class: "btn btn--primary flex items-center gap-1 justify-center", data: { turbo_frame: :modal } do %>
<%= link_to new_merchant_path, class: "btn btn--primary btn--round flex items-center gap-1 justify-center", data: { turbo_frame: :modal } do %>
<%= lucide_icon "plus", class: "w-5 h-5" %>
<p><%= t(".new") %></p>
<span class="hidden sm:block"><%= t(".new") %></span>
<% end %>
</header>

View File

@@ -11,7 +11,7 @@
<h1 class="text-primary text-xl font-medium mb-4"><%= t(".page_title") %></h1>
<%= settings_section title: t(".scan_title"), subtitle: t(".scan_description") do %>
<div class="space-y-6">
<div>
<div class="w-full flex justify-center items-center">
<%= generate_mfa_qr_code(Current.user.provisioning_uri) %>
</div>
@@ -57,7 +57,7 @@
placeholder: t(".code_placeholder") %>
<div class="flex justify-end mt-4">
<%= f.submit t(".verify_button"), class: "btn btn--primary" %>
<%= f.submit t(".verify_button"), class: "btn btn--primary w-full sm:w-auto" %>
</div>
</div>
<% end %>

View File

@@ -1,4 +1,4 @@
<header class="flex justify-between items-center p-4">
<header class="hidden sm:flex justify-between items-center p-4 ">
<%= image_tag "logo.svg", class: "h-[22px]" %>
<div class="flex items-center gap-2">
<%= lucide_icon "log-in", class: "w-5 h-5 shrink-0 text-secondary gap-2" %>

View File

@@ -2,8 +2,8 @@
<%= render "onboardings/header" %>
<div class="grow max-w-lg w-full mx-auto bg-gray-25 flex flex-col justify-center" data-controller="onboarding">
<div>
<div class="space-y-1 mb-6">
<div class="p-4">
<div class="space-y-1 mb-6 text-center sm:text-start">
<h1 class="text-2xl font-medium"><%= t(".title") %></h1>
<p class="text-secondary text-sm"><%= t(".subtitle") %></p>
</div>
@@ -40,7 +40,7 @@
<% placeholder_series = Series.from_raw_values(placeholder_series_data) %>
<div class="flex items-center w-2/5">
<div class="hidden sm:flex items-center w-2/5">
<div class="h-12 w-full">
<div
id="previewChart"
@@ -54,7 +54,7 @@
</div>
</div>
<p class="text-secondary text-xs mb-4"><%= t(".preview") %></p>
<p class="text-secondary text-xs mb-4 text-center sm:text-start"><%= t(".preview") %></p>
<%= styled_form_with model: @user, data: { turbo: false } do |form| %>
<%= form.hidden_field :onboarded_at, value: Time.current %>

View File

@@ -2,8 +2,8 @@
<%= render "onboardings/header" %>
<div class="grow max-w-lg w-full mx-auto bg-gray-25 flex flex-col justify-center">
<div>
<div class="space-y-1 mb-6">
<div class="p-4">
<div class="space-y-1 mb-6 text-center sm:text-start">
<h1 class="text-2xl font-medium"><%= t(".title") %></h1>
<p class="text-secondary text-sm"><%= t(".subtitle") %></p>
</div>
@@ -13,13 +13,13 @@
<%= form.hidden_field :onboarded_at, value: Time.current if @invitation %>
<div class="space-y-4 mb-4">
<p class="text-secondary text-xs"><%= t(".profile_image") %></p>
<p class="text-secondary text-xs hidden sm:block"><%= t(".profile_image") %></p>
<%= render "settings/user_avatar_field", form: form, user: @user %>
</div>
<div class="flex justify-between items-center gap-4 mb-4">
<%= form.text_field :first_name, placeholder: t(".first_name"), label: t(".first_name"), container_class: "bg-container w-1/2", required: true %>
<%= form.text_field :last_name, placeholder: t(".last_name"), label: t(".last_name"), container_class: "bg-container w-1/2", required: true %>
<div class="flex flex-col sm:flex-row justify-between items-center gap-4 mb-4">
<%= form.text_field :first_name, placeholder: t(".first_name"), label: t(".first_name"), container_class: "bg-container sm:w-1/2", required: true %>
<%= form.text_field :last_name, placeholder: t(".last_name"), label: t(".last_name"), container_class: "bg-container sm:w-1/2", required: true %>
</div>
<% unless @invitation %>
<div class="space-y-4 mb-4">

View File

@@ -1,8 +1,8 @@
<%= content_for :page_title, t(".title") %>
<div class="bg-container shadow-border-xs rounded-xl p-4 grow overflow-y-auto">
<div class="flex justify-between gap-4 mb-12 last:mb-0">
<div class="w-1/3">
<div class="flex flex-col sm:flex-row justify-between gap-4 mb-12 last:mb-0">
<div class="order-2 sm:order-1 sm:w-1/3">
<div class="px-3 flex items-center gap-3">
<div class="text-white shrink-0 w-9 h-9">
<%= image_tag @release_notes[:avatar], class: "rounded-full w-full h-full object-cover" %>
@@ -13,7 +13,7 @@
</div>
</div>
</div>
<div class="w-2/3 text-secondary text-sm prose prose--github-release-notes">
<div class="order-1 sm:order-2 w-full sm:w-2/3 text-secondary text-sm prose prose--github-release-notes">
<h2 class="mb-5 text-xl text-primary"><%= @release_notes[:name] %></h2>
<%= @release_notes[:body].html_safe %>
</div>

View File

@@ -1,7 +1,7 @@
<% content_for :page_header do %>
<div class="space-y-1 mb-6">
<h1 class="text-3xl font-medium text-primary">Welcome back, <%= Current.user.first_name %></h1>
<p class="text-gray-500">Here's what's happening with your finances</p>
<p class="text-gray-500">Heres your financial briefing</p>
</div>
<% end %>

View File

@@ -19,7 +19,7 @@
<% end %>
</div>
</div>
<%= form_with url: root_path, method: :get, class: "flex items-center gap-4", data: { controller: "auto-submit-form" } do |form| %>
<%= form_with url: root_path, method: :get, class: "flex items-start sm:items-center gap-4", data: { controller: "auto-submit-form" } do |form| %>
<%= period_select form: form, selected: period %>
<% end %>
</div>

View File

@@ -3,13 +3,13 @@
<div class="bg-container shadow-border-xs rounded-xl p-4">
<h2 class="text-lg font-medium text-primary mb-1">Leave feedback</h2>
<p class="text-sm text-secondary mb-4">Let us know if you have any specific feedback. Feel free to include links to videos or screenshots.</p>
<div class="flex gap-2">
<%= link_to "https://github.com/maybe-finance/maybe/discussions/categories/feature-requests", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<div class="flex flex-col sm:flex-row gap-2">
<%= link_to "https://github.com/maybe-finance/maybe/discussions/categories/feature-requests", target: "_blank", rel: "noopener noreferrer", class: "w-full sm:w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= image_tag "github-icon.svg", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-primary">Write a feature request</span>
<% end %>
<% if self_hosted? %>
<%= link_to "https://github.com/maybe-finance/maybe/issues/new?assignees=&labels=bug&template=bug_report.md&title=", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= link_to "https://github.com/maybe-finance/maybe/issues/new?assignees=&labels=bug&template=bug_report.md&title=", target: "_blank", rel: "noopener noreferrer", class: "w-full sm:w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= image_tag "github-icon.svg", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-primary">File a bug report</span>
<% end %>
@@ -20,7 +20,7 @@
<% end %>
<% end %>
<%= link_to "https://link.maybe.co/discord", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= link_to "https://link.maybe.co/discord", target: "_blank", rel: "noopener noreferrer", class: "w-full sm:w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= image_tag "discord-icon.svg", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-primary">Discuss Maybe with others</span>
<% end %>

View File

@@ -1,6 +1,6 @@
<%# locals: (form:, user:) %>
<div class="flex items-center gap-4" data-controller="profile-image-preview">
<div class="flex flex-col sm:flex-row items-center gap-4" data-controller="profile-image-preview">
<div class="relative flex justify-center items-center bg-gray-50 w-24 h-24 rounded-full border-alpha-black-300 border border-dashed">
<%# The image preview once user has uploaded a new file %>
@@ -34,19 +34,26 @@
</button>
</div>
<div>
<%= form.hidden_field :delete_profile_image, value: "0", data: { profile_image_preview_target: "deleteProfileImage" } %>
<div class="sm:block flex flex-col justify-center items-center gap-2">
<%= form.hidden_field :delete_profile_image, value: "0", data: { profile_image_preview_target: "deleteProfileImage" } %>
<p class="mb-3"><%= t(".accepted_formats") %></p>
<div class="flex flex-col gap-2 text-center sm:text-left">
<%= form.label :profile_image, class: "btn btn--outline flex items-center gap-2 justify-center sm:justify-start order-1 sm:order-2" do %>
<%= lucide_icon "camera", class: "w-4 h-4" %>
<span>
<%= user.profile_image.attached? ? t(".change") : t(".choose") %>
</span>
<% end %>
<%= form.label :profile_image, t(".choose"),
class: "btn btn--outline inline-block" %>
<%= form.file_field :profile_image,
accept: "image/png, image/jpeg",
class: "hidden px-3 py-2 bg-gray-50 text-primary rounded-md text-sm font-medium",
data: {
profile_image_preview_target: "input",
action: "change->profile-image-preview#showFileInputPreview"
} %>
</div>
<p class="text-xs text-subdued order-2 sm:order-1"><%= t(".accepted_formats") %></p>
</div>
<%= form.file_field :profile_image,
accept: "image/png, image/jpeg",
class: "hidden px-3 py-2 bg-gray-50 text-primary rounded-md text-sm font-medium",
data: {
profile_image_preview_target: "input",
action: "change->profile-image-preview#showFileInputPreview"
} %>
</div>
</div>

View File

@@ -1,19 +1,22 @@
<% if Current.user.admin? %>
<div class="space-y-4">
<div class="flex items-center justify-between">
<div class="w-2/3">
<div class="flex flex-col space-y-4 sm:flex-row items-center justify-between">
<div class="sm:w-2/3">
<h3 class="font-medium text-primary"><%= t("settings.hostings.show.clear_cache") %></h3>
<p class="text-secondary text-sm"><%= t("settings.hostings.show.clear_cache_warning") %></p>
</div>
<%=
button_to t("settings.hostings.show.clear_cache"), clear_cache_settings_hosting_path, method: :delete,
class: "bg-orange-500 text-white text-sm font-medium rounded-lg px-4 py-2",
data: { turbo_confirm: {
title: t("settings.hostings.show.confirm_clear_cache.title"),
body: t("settings.hostings.show.confirm_clear_cache.body"),
accept: t("settings.hostings.show.clear_cache"),
acceptClass: "w-full bg-orange-500 text-white rounded-xl text-center p-[10px] border mb-2"
}}
button_to t("settings.hostings.show.clear_cache"), clear_cache_settings_hosting_path,
form: { class: "w-full sm:w-auto" },
method: :delete,
class: "bg-orange-500 text-white text-sm font-medium w-full rounded-lg px-4 py-2",
data: { turbo_confirm: {
form: { class: "w-full sm:w-auto" },
title: t("settings.hostings.show.confirm_clear_cache.title"),
body: t("settings.hostings.show.confirm_clear_cache.body"),
accept: t("settings.hostings.show.clear_cache"),
acceptClass: "w-full bg-orange-500 text-white rounded-xl text-center p-[10px] border mb-2"
}}
%>
</div>
</div>

View File

@@ -129,14 +129,15 @@
<%= settings_section title: t(".danger_zone_title") do %>
<div class="space-y-4">
<% if Current.user.admin? %>
<div class="flex items-center justify-between">
<div class="w-2/3">
<div class="flex flex-col sm:flex-row space-y-4 items-center sm:justify-between">
<div class="sm:w-2/3">
<h3 class="font-medium text-primary"><%= t(".reset_account") %></h3>
<p class="text-secondary text-sm"><%= t(".reset_account_warning") %></p>
</div>
<%=
button_to t(".reset_account"), reset_user_path(@user), method: :delete,
class: "btn btn--destructive",
form: { class: "w-full sm:w-auto" },
class: "btn btn--destructive w-full",
data: { turbo_confirm: {
title: t(".confirm_reset.title"),
body: t(".confirm_reset.body"),
@@ -146,14 +147,15 @@
%>
</div>
<% end %>
<div class="flex items-center justify-between">
<div class="flex flex-col sm:flex-row space-y-4 items-center sm:justify-between">
<div>
<h3 class="font-medium text-primary"><%= t(".delete_account") %></h3>
<p class="text-secondary text-sm"><%= t(".delete_account_warning") %></p>
</div>
<%=
button_to t(".delete_account"), user_path(@user), method: :delete,
class: "btn btn--destructive",
form: { class: "w-full sm:w-auto" },
class: "btn btn--destructive w-full",
data: { turbo_confirm: {
title: t(".confirm_delete.title"),
body: t(".confirm_delete.body"),
@@ -163,4 +165,4 @@
%>
</div>
</div>
<% end %>
<% end %>

View File

@@ -2,13 +2,13 @@
<%= settings_section title: t(".mfa_title"), subtitle: t(".mfa_description") do %>
<div class="space-y-4">
<div class="p-3 shadow-border-xs bg-container rounded-lg flex justify-between items-center">
<div class="flex items-center gap-3">
<div class="w-9 h-9 rounded-full bg-gray-25 flex justify-center items-center">
<div class="p-3 space-y-4 sm:space-y-0 shadow-border-xs bg-container rounded-lg flex flex-col sm:flex-row justify-between items-center">
<div class="flex items-center justify-between gap-3">
<div class="order-2 sm:order-1 flex-grow flex-shrink-0 w-9 h-9 rounded-full bg-gray-25 flex justify-center items-center">
<%= lucide_icon "shield-check", class: "w-5 h-5 text-secondary" %>
</div>
<div class="text-sm space-y-1">
<div class="order-1 sm:order-2 text-sm space-y-1">
<% if Current.user.otp_required? %>
<p class="text-primary">Two-factor authentication is <span class="font-medium text-green-600">enabled</span></p>
<p class="text-secondary">Your account is protected with an additional layer of security.</p>
@@ -21,8 +21,9 @@
<% if Current.user.otp_required? %>
<%= button_to t(".disable_mfa"), disable_mfa_path,
form: { class: "w-full sm:w-auto" },
method: :delete,
class: "btn btn--secondary flex items-center gap-1",
class: "btn btn--secondary w-full flex items-center gap-1",
data: { turbo_confirm: {
title: t(".disable_mfa_confirm"),
body: t(".disable_mfa_confirm"),
@@ -31,7 +32,7 @@
} } %>
<% else %>
<%= link_to t(".enable_mfa"), new_mfa_path,
class: "btn btn--primary flex items-center gap-1" %>
class: "btn btn--primary w-full sm:w-auto flex justify-center items-center gap-1" %>
<% end %>
</div>
</div>

View File

@@ -1,7 +1,7 @@
<%# locals: (content:, reload_on_close: false) %>
<%= turbo_frame_tag "drawer" do %>
<dialog class="ml-auto bg-container shadow-border-xs rounded-2xl max-w-[480px] h-full w-full mt-4 mr-4 focus-visible:outline-hidden"
<dialog class="ml-auto bg-container shadow-border-xs sm:rounded-2xl max-w-full sm:max-w-[480px] max-h-[100vh] h-full w-full sm:mt-4 sm:mr-4 focus-visible:outline-hidden"
data-controller="modal"
data-action="mousedown->modal#clickOutside"
data-modal-reload-on-close-value="<%= reload_on_close %>">

View File

@@ -1,6 +1,6 @@
<%# locals: (content:, classes:) -%>
<%= turbo_frame_tag "modal" do %>
<dialog class="m-auto bg-container shadow-border-xs rounded-2xl max-w-[580px] w-min-content h-fit overflow-visible <%= classes %>" data-controller="modal" data-action="mousedown->modal#clickOutside">
<dialog class="h-[100vh] max-h-[100vh] sm:m-auto bg-container shadow-border-xs sm:rounded-2xl max-w-[100%] sm:max-w-[580px] sm:w-min-content sm:h-fit overflow-visible <%= classes %>" data-controller="modal" data-action="mousedown->modal#clickOutside">
<div class="flex flex-col">
<%= content %>
</div>

View File

@@ -1,7 +1,7 @@
<%# locals: (title:, content:, subtitle: nil) %>
<%= modal do %>
<article class="mx-auto w-full p-4 space-y-4 min-w-[450px]">
<article class="mx-auto w-full p-4 space-y-4 sm:min-w-[450px]">
<div class="space-y-2">
<header class="flex justify-between items-center">
<h2 class="font-medium"><%= title %></h2>

View File

@@ -1,9 +1,9 @@
<header class="flex items-center justify-between">
<h1 class="text-primary text-xl font-medium"><%= t(".tags") %></h1>
<%= link_to new_tag_path, class: "btn btn--primary flex items-center gap-1 justify-center", data: { turbo_frame: :modal } do %>
<%= link_to new_tag_path, class: "btn btn--primary btn--round flex items-center gap-1 justify-center", data: { turbo_frame: :modal } do %>
<%= lucide_icon "plus", class: "w-5 h-5" %>
<p><%= t(".new") %></p>
<span class="hidden sm:block"><%= t(".new") %></span>
<% end %>
</header>

View File

@@ -3,20 +3,23 @@
<div class="flex items-center gap-5">
<div class="flex items-center gap-2">
<%= contextual_menu do %>
<div class="block sm:hidden">
<%= contextual_menu_modal_action_item t(".import_transactions"), new_import_path, icon: "download", turbo_frame: "modal" %>
</div>
<%= contextual_menu_modal_action_item t(".edit_categories"), categories_path, icon: "shapes", turbo_frame: :_top %>
<%= contextual_menu_modal_action_item t(".edit_tags"), tags_path, icon: "tags", turbo_frame: :_top %>
<%= contextual_menu_modal_action_item t(".edit_merchants"), merchants_path, icon: "store", turbo_frame: :_top %>
<%= contextual_menu_modal_action_item t(".edit_imports"), imports_path, icon: "hard-drive-upload", turbo_frame: :_top %>
<% end %>
<%= link_to new_import_path, class: "btn btn--outline flex items-center gap-2", data: { turbo_frame: "modal" } do %>
<%= link_to new_import_path, class: "hidden sm:block btn btn--outline flex items-center gap-2", data: { turbo_frame: "modal" } do %>
<%= lucide_icon("download", class: "text-secondary w-4 h-4") %>
<p class="text-sm font-medium text-primary"><%= t(".import") %></p>
<% end %>
<%= link_to new_account_transaction_path, class: "btn btn--primary flex items-center gap-2", data: { turbo_frame: :modal } do %>
<%= link_to new_account_transaction_path, class: "btn btn--primary btn--round flex items-center gap-2", data: { turbo_frame: :modal } do %>
<%= lucide_icon("plus", class: "w-5 h-5") %>
<p class="text-sm font-medium">New transaction</p>
<p class="hidden sm:block text-sm font-medium">New transaction</p>
<% end %>
</div>
</div>

View File

@@ -1,5 +1,5 @@
<%# locals: (totals:) %>
<div class="grid grid-cols-3 bg-container rounded-xl shadow-border-xs divide-x divide-alpha-black-100">
<div class="grid grid-rows-3 sm:grid-cols-3 sm:grid-rows-1 bg-container rounded-xl shadow-border-xs divide-y sm:divide-y-0 sm:divide-x divide-alpha-black-100">
<div class="p-4 space-y-2">
<p class="text-sm text-secondary">Total transactions</p>
<p class="text-primary font-medium text-xl" id="total-transactions"><%= totals.transactions_count.round(0) %></p>

View File

@@ -7,7 +7,7 @@
data-controller="bulk-select"
data-bulk-select-singular-label-value="<%= t(".transaction") %>"
data-bulk-select-plural-label-value="<%= t(".transactions") %>"
class="flex flex-col bg-container rounded-xl shadow-border-xs p-4">
class="flex flex-col bg-container rounded-xl shadow-border-xs p-4 w-full overflow-x-auto">
<%= render "transactions/searches/search" %>
<div id="entry-selection-bar" data-bulk-select-target="selectionBar" class="flex justify-center hidden">
@@ -15,8 +15,9 @@
</div>
<% if @pagy.count > 0 %>
<div class="grow overflow-y-auto">
<div class="grid grid-cols-12 bg-container-inset rounded-xl px-5 py-3 text-xs uppercase font-medium text-secondary items-center mb-4">
<div class="w-full overflow-x-auto">
<div class="inline-block bg-container-inset min-w-ful sm:w-full rounded-xl px-5 py-3 text-xs uppercase font-medium text-secondary items-center mb-4">
<div class="grid grid-cols-[repeat(12,_minmax(45px,0.25fr))] gap-4">
<div class="pl-0.5 col-span-8 flex items-center gap-4">
<%= check_box_tag "selection_entry",
class: "checkbox checkbox--light",
@@ -27,12 +28,14 @@
<p class="col-span-2">category</p>
<p class="col-span-2 justify-self-end">amount</p>
</div>
<div class="space-y-6">
</div>
<div class="inline-block space-y-6 min-w-full">
<%= entries_by_date(@transactions.map(&:entry), totals: true) do |entries| %>
<%= render entries %>
<% end %>
</div>
</div>
</div>
<% else %>
<%= render "account/entries/empty" %>
<% end %>

View File

@@ -10,7 +10,7 @@ en:
locale: Language
preview: Preview how data displays based on preferences.
submit: Complete
subtitle: Let's configure your preferences.
subtitle: Set your preferences to help personalize your experience.
title: Configure your preferences
profile:
country: Country

View File

@@ -97,4 +97,6 @@ en:
previous: Back
user_avatar_field:
accepted_formats: JPG or PNG. 5MB max.
choose: Choose
choose: Upload photo
optional: optional
change: Change photo