mirror of
https://github.com/we-promise/sure.git
synced 2026-04-19 20:14:08 +00: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:
@@ -1,135 +1,140 @@
|
||||
<% mobile_nav_items = [
|
||||
{ name: "Home", path: root_path, icon: "pie-chart", icon_custom: false, active: page_active?(root_path) },
|
||||
{ name: "Transactions", path: transactions_path, icon: "credit-card", icon_custom: false, active: page_active?(transactions_path) },
|
||||
{ name: "Budgets", path: budgets_path, icon: "map", icon_custom: false, active: page_active?(budgets_path) },
|
||||
{ name: "Assistant", path: chats_path, icon: "icon-assistant", icon_custom: true, active: page_active?(chats_path), mobile_only: true }
|
||||
] %>
|
||||
|
||||
<% desktop_nav_items = mobile_nav_items.reject { |item| item[:mobile_only] } %>
|
||||
<% expanded_sidebar_class = "w-full" %>
|
||||
<% collapsed_sidebar_class = "w-0" %>
|
||||
|
||||
<%= render "layouts/shared/htmldoc" do %>
|
||||
<% sidebar_config = app_sidebar_config(Current.user) %>
|
||||
<div
|
||||
class="flex flex-col lg:flex-row h-dvh lg:h-full bg-surface"
|
||||
data-controller="app-layout"
|
||||
data-app-layout-expanded-sidebar-class="<%= expanded_sidebar_class %>"
|
||||
data-app-layout-collapsed-sidebar-class="<%= collapsed_sidebar_class %>"
|
||||
data-app-layout-user-id-value="<%= Current.user.id %>">
|
||||
<div
|
||||
class="hidden fixed inset-0 bg-surface z-20 h-dvh w-full p-3 overflow-y-auto transition-all duration-300"
|
||||
data-app-layout-target="mobileSidebar">
|
||||
<div class="mb-2">
|
||||
<%= icon("x", as_button: true, data: { action: "app-layout#closeMobileSidebar" }) %>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col lg:flex-row h-dvh lg:h-full bg-surface pt-safe"
|
||||
data-controller="sidebar"
|
||||
data-sidebar-user-id-value="<%= Current.user.id %>"
|
||||
data-sidebar-config-value="<%= sidebar_config.to_json %>">
|
||||
<button hidden data-controller="hotkey" data-hotkey="b" data-action="sidebar#toggleLeftPanel">Toggle accounts</button>
|
||||
<button hidden data-controller="hotkey" data-hotkey="l" data-action="sidebar#toggleRightPanel">Toggle chat</button>
|
||||
<%= render(
|
||||
"accounts/account_sidebar_tabs",
|
||||
family: Current.family,
|
||||
active_account_group_tab: params[:account_group_tab] || "assets"
|
||||
) %>
|
||||
</div>
|
||||
|
||||
<% unless controller_name == 'chats' %>
|
||||
<nav class="flex justify-between lg:justify-start lg:flex-col shrink-0 lg:w-[84px] p-3 lg:px-0 lg:py-4 lg:mr-3">
|
||||
<button data-action="sidebar#toggleLeftPanelMobile" class="lg:hidden inline-flex p-2 rounded-lg items-center justify-center hover:bg-gray-100 cursor-pointer">
|
||||
<%= icon("panel-left", color: "gray") %>
|
||||
</button>
|
||||
<%# MOBILE - Top nav %>
|
||||
<nav class="lg:hidden flex justify-between items-center p-3">
|
||||
<%= icon("panel-left", as_button: true, data: { action: "app-layout#openMobileSidebar"}) %>
|
||||
|
||||
<%# Mobile only account sidebar groups %>
|
||||
<%= tag.div class: class_names("hidden bg-surface z-20 absolute inset-0 h-dvh w-full p-4 overflow-y-auto transition-all duration-300 pt-safe"),
|
||||
data: { sidebar_target: "leftPanelMobile" } do %>
|
||||
<div id="account-sidebar-tabs" class="pt-6">
|
||||
<div class="mb-4">
|
||||
<button data-action="sidebar#toggleLeftPanelMobile">
|
||||
<%= icon("x", color: "gray") %>
|
||||
</button>
|
||||
</div>
|
||||
<%= render "accounts/account_sidebar_tabs", family: Current.family %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= link_to root_path, class: "block" do %>
|
||||
<%= image_tag "logomark-color.svg", class: "w-9 h-9 mx-auto" %>
|
||||
<% end %>
|
||||
|
||||
<div class="lg:pl-2 lg:mb-3">
|
||||
<%= render "users/user_menu", user: Current.user, placement: "bottom-end", offset: 12 %>
|
||||
</nav>
|
||||
|
||||
<%# DESKTOP - Left navbar %>
|
||||
<div class="hidden lg:block">
|
||||
<nav class="h-full flex flex-col shrink-0 w-[84px] py-4 mr-3">
|
||||
<div class="pl-2 mb-3">
|
||||
<%= link_to root_path, class: "block" do %>
|
||||
<%= image_tag "logomark-color.svg", class: "w-9 h-9 mx-auto" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<ul class="space-y-0.5 hidden lg:block">
|
||||
<li>
|
||||
<%= render "layouts/sidebar/nav_item", name: "Home", path: root_path, icon_key: "pie-chart" %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<%= render "layouts/sidebar/nav_item", name: "Transactions", path: transactions_path, icon_key: "credit-card" %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<%= render "layouts/sidebar/nav_item", name: "Budgets", path: budgets_path, icon_key: "map" %>
|
||||
</li>
|
||||
<ul class="space-y-0.5">
|
||||
<% desktop_nav_items.reject { |item| item[:mobile_only] }.each do |nav_item| %>
|
||||
<li>
|
||||
<%= render "layouts/shared/nav_item", **nav_item %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<div class="lg:pl-2 lg:mt-auto lg:mx-auto">
|
||||
<div class="lg:hidden">
|
||||
<%= render "users/user_menu", user: Current.user, placement: "bottom-end", offset: 12 %>
|
||||
</div>
|
||||
<div class="pl-2 mt-auto mx-auto flex flex-col gap-2">
|
||||
<%= render ButtonComponent.new(
|
||||
variant: "icon",
|
||||
icon: "message-circle-question",
|
||||
data: { action: "intercom#show" }
|
||||
) %>
|
||||
|
||||
<div class="hidden lg:block">
|
||||
<%= render "users/user_menu", user: Current.user %>
|
||||
</div>
|
||||
<%= render "users/user_menu", user: Current.user %>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<%# DESKTOP - Left sidebar %>
|
||||
<%= tag.div class: class_names(
|
||||
"hidden lg:block py-4 overflow-y-auto shrink-0 max-w-[320px] transition-all duration-300",
|
||||
Current.user.show_sidebar? ? expanded_sidebar_class : collapsed_sidebar_class,
|
||||
),
|
||||
data: { app_layout_target: "leftSidebar" } do %>
|
||||
<% if content_for?(:sidebar) %>
|
||||
<%= yield :sidebar %>
|
||||
<% else %>
|
||||
<div id="account-sidebar-tabs" data-turbo-permanent>
|
||||
<%= render "accounts/account_sidebar_tabs", family: Current.family, active_account_group_tab: params[:account_group_tab] || "assets" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<div class="flex justify-between lg:justify-normal grow overflow-y-auto">
|
||||
<%= tag.div class: class_names("py-4 shrink-0 h-full overflow-y-auto transition-all duration-300 hidden lg:block"),
|
||||
style: "width: #{sidebar_config.dig(:left_panel, :initial_width)}px",
|
||||
data: { sidebar_target: "leftPanel" } do %>
|
||||
<% if content_for?(:sidebar) %>
|
||||
<%= yield :sidebar %>
|
||||
<% else %>
|
||||
<div id="account-sidebar-tabs" data-turbo-permanent>
|
||||
<%= render "accounts/account_sidebar_tabs", family: Current.family %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%# SHARED - Main content %>
|
||||
<%= tag.main class: class_names("grow overflow-y-auto px-3 lg:px-10 py-4 h-full w-full mx-auto max-w-5xl"), data: { app_layout_target: "content" } do %>
|
||||
<div class="hidden lg:flex gap-2 items-center justify-between mb-6">
|
||||
<div class="flex items-center gap-2">
|
||||
<%= icon("panel-left", as_button: true, data: { action: "app-layout#toggleLeftSidebar" }) %>
|
||||
|
||||
<%= tag.main class: class_names("px-3 lg:px-10 py-4 grow h-full", require_upgrade? ? "relative overflow-hidden" : "overflow-y-auto") do %>
|
||||
<% if require_upgrade? %>
|
||||
<div class="absolute inset-0 px-3 lg:px-10 h-full w-full z-50">
|
||||
<%= render "shared/subscribe_modal" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= tag.div class: class_names("mx-auto max-w-5xl w-full h-full"), data: { sidebar_target: "content" } do %>
|
||||
<% if content_for?(:breadcrumbs) %>
|
||||
<%= yield :breadcrumbs %>
|
||||
<% else %>
|
||||
<%= render "layouts/shared/breadcrumbs", breadcrumbs: @breadcrumbs %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= icon("panel-right", as_button: true, data: { action: "app-layout#toggleRightSidebar" }) %>
|
||||
</div>
|
||||
|
||||
<% if content_for?(:page_header) %>
|
||||
<%= yield :page_header %>
|
||||
<% end %>
|
||||
|
||||
<%= yield %>
|
||||
<% end %>
|
||||
<% if content_for?(:page_header) %>
|
||||
<%= yield :page_header %>
|
||||
<% end %>
|
||||
|
||||
<%# AI chat sidebar %>
|
||||
<%= tag.div id: "chat-container",
|
||||
style: "width: #{sidebar_config.dig(:right_panel, :initial_width)}px; overflow: #{sidebar_config.dig(:right_panel, :overflow)}",
|
||||
class: class_names("flex flex-col justify-between shrink-0 transition-all duration-300 hidden lg:block"),
|
||||
data: { controller: "chat hotkey", sidebar_target: "rightPanel", turbo_permanent: true } do %>
|
||||
<%= yield %>
|
||||
<% end %>
|
||||
|
||||
<% if Current.user.ai_enabled? %>
|
||||
<%# DESKTOP - Right sidebar %>
|
||||
<%= tag.div class: class_names(
|
||||
"hidden lg:block h-full overflow-y-auto shrink-0 max-w-[400px] transition-all duration-300",
|
||||
Current.user.show_ai_sidebar? ? expanded_sidebar_class : collapsed_sidebar_class,
|
||||
),
|
||||
data: { app_layout_target: "rightSidebar" } do %>
|
||||
<%= tag.div id: "chat-container", class: "relative h-full", data: { controller: "chat hotkey", turbo_permanent: true } do %>
|
||||
<div class="flex flex-col h-full justify-between shrink-0">
|
||||
<%= turbo_frame_tag chat_frame, src: chat_view_path(@chat), loading: "lazy", class: "h-full" do %>
|
||||
<div class="flex justify-center items-center h-full">
|
||||
<%= lucide_icon("loader-circle", class: "w-5 h-5 text-secondary animate-spin") %>
|
||||
<%= icon("loader-circle", class: "animate-spin") %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= render "chats/ai_consent" %>
|
||||
</div>
|
||||
|
||||
<% unless Current.user.ai_enabled? %>
|
||||
<div class="absolute backdrop-blur-lg inset-0 h-full w-full flex flex-col justify-center items-center pl-0.5 pr-4">
|
||||
<%= render "chats/ai_consent" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<nav class="lg:hidden bg-surface md:bg-container shrink-0 z-10 pb-2 border-t border-tertiary pb-safe">
|
||||
<ul class="flex items-center justify-around gap-1">
|
||||
<li>
|
||||
<%= render "layouts/sidebar/nav_item", name: "Home", path: root_path, icon_key: "pie-chart" %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<%= render "layouts/sidebar/nav_item", name: "Transactions", path: transactions_path, icon_key: "credit-card" %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<%= render "layouts/sidebar/nav_item", name: "Budgets", path: budgets_path, icon_key: "map" %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<%= render "layouts/sidebar/nav_item", name: "Assistant", path: chats_path, icon_key: "icon-assistant", is_custom: true %>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<%# MOBILE - Bottom Nav %>
|
||||
<%= tag.nav class: "lg:hidden bg-surface shrink-0 z-10 pb-2 border-t border-tertiary pb-safe flex justify-around" do %>
|
||||
<% mobile_nav_items.each do |nav_item| %>
|
||||
<%= render "layouts/shared/nav_item", **nav_item %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
Reference in New Issue
Block a user