diff --git a/app/views/chats/show.html.erb b/app/views/chats/show.html.erb
index 341eca01..cb52b632 100644
--- a/app/views/chats/show.html.erb
+++ b/app/views/chats/show.html.erb
@@ -1,35 +1,38 @@
-<%= turbo_frame_tag chat_frame do %>
- <%= turbo_stream_from @chat %>
+
+ <%= turbo_frame_tag chat_frame do %>
+ <%= turbo_stream_from @chat %>
-
<%= @chat.title %>
+
<%= @chat.title %>
-
-
- <%= render "chats/chat_nav", chat: @chat %>
-
+
+
+ <%= render "chats/chat_nav", chat: @chat %>
+
-
- <% if @chat.conversation_messages.any? %>
- <% @chat.conversation_messages.ordered.each do |message| %>
- <%= render message %>
+
+ <% if @chat.conversation_messages.any? %>
+ <% @chat.conversation_messages.ordered.each do |message| %>
+ <%= render message %>
+ <% end %>
+ <% else %>
+
+ <%= render "chats/ai_greeting", context: "chat" %>
+
<% end %>
- <% else %>
-
- <%= render "chats/ai_greeting", context: "chat" %>
-
- <% end %>
- <% if params[:thinking].present? %>
- <%= render "chats/thinking_indicator", chat: @chat %>
- <% end %>
+ <% if params[:thinking].present? %>
+ <%= render "chats/thinking_indicator", chat: @chat %>
+ <% end %>
- <% if @chat.error.present? && @chat.needs_assistant_response? %>
- <%= render "chats/error", chat: @chat %>
- <% end %>
+ <% if @chat.error.present? && @chat.needs_assistant_response? %>
+ <%= render "chats/error", chat: @chat %>
+ <% end %>
+
+
+ <%# DESKTOP - Chat form %>
+
+ <%= render "messages/chat_form", chat: @chat %>
+
-
-
- <%= render "messages/chat_form", chat: @chat %>
-
-
-<% end %>
+ <% end %>
+
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index b2634ebb..d74eb8c3 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -1,104 +1,42 @@
<%= render "layouts/shared/htmldoc" do %>
- <% sidebar_config = app_sidebar_config(Current.user) %>
+ <%= render AppLayoutComponent.new(user: Current.user) do |app_layout| %>
+ <% app_layout.with_nav_items([
+ { name: "Home", path: root_path, icon: "pie-chart", active: page_active?(root_path) },
+ { name: "Transactions", path: transactions_path, icon: "credit-card", active: page_active?(transactions_path) },
+ { name: "Budgets", path: budgets_path, icon: "map", active: page_active?(budgets_path) },
+ { name: "Assistant", path: chats_path, icon: "icon-assistant", icon_custom: true, active: page_active?(chats_path), mobile_only: true }
+ ]) %>
-
-
-
-
- <% unless controller_name == 'chats' %>
-
+ <% app_layout.with_mobile_sidebar do %>
+ <%= render(
+ "accounts/account_sidebar_tabs",
+ family: Current.family,
+ active_account_group_tab: params[:account_group_tab] || "assets"
+ ) %>
<% end %>
-
- <%= 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 %>
-
- <% end %>
+ <% app_layout.with_mobile_user_menu do %>
+ <%= render "users/user_menu", user: Current.user, placement: "bottom-end", offset: 12 %>
+ <% end %>
+
+ <% app_layout.with_desktop_user_menu do %>
+ <%= render "users/user_menu", user: Current.user %>
+ <% end %>
+
+ <% app_layout.with_left_sidebar do %>
+ <% if content_for?(:sidebar) %>
+ <%= yield :sidebar %>
+ <% else %>
+
<% end %>
+ <% end %>
- <%= 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? %>
-
- <%= render "shared/subscribe_modal" %>
-
- <% 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 %>
-
- <% if content_for?(:page_header) %>
- <%= yield :page_header %>
- <% end %>
-
- <%= yield %>
- <% end %>
- <% end %>
-
- <%# AI chat sidebar %>
+ <% app_layout.with_right_sidebar do %>
<%= 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 %>
+ class: class_names("flex flex-col h-full justify-between shrink-0 transition-all duration-300"),
+ data: { controller: "chat hotkey", turbo_permanent: true } do %>
<% if Current.user.ai_enabled? %>
<%= turbo_frame_tag chat_frame, src: chat_view_path(@chat), loading: "lazy", class: "h-full" do %>
@@ -110,26 +48,23 @@
<%= render "chats/ai_consent" %>
<% end %>
<% end %>
+ <% end %>
+
+ <% app_layout.with_breadcrumbs do %>
+ <% if content_for?(:breadcrumbs) %>
+ <%= yield :breadcrumbs %>
+ <% else %>
+ <%= render "layouts/shared/breadcrumbs", breadcrumbs: @breadcrumbs %>
+ <% end %>
+ <% end %>
+
+ <%# Main page content %>
+
+ <% if content_for?(:page_header) %>
+ <%= yield :page_header %>
+ <% end %>
+
+ <%= yield %>
-
-
-
+ <% end %>
<% end %>
diff --git a/app/views/layouts/settings.html.erb b/app/views/layouts/settings.html.erb
index 30e248c1..e4e68784 100644
--- a/app/views/layouts/settings.html.erb
+++ b/app/views/layouts/settings.html.erb
@@ -10,7 +10,7 @@
<% if content_for?(:breadcrumbs) %>
<%= yield :breadcrumbs %>
<% else %>
- <%= render "layouts/shared/breadcrumbs", breadcrumbs: @breadcrumbs, sidebar_toggle_enabled: false %>
+ <%= render "layouts/shared/breadcrumbs", breadcrumbs: @breadcrumbs %>
<% end %>
<% if content_for?(:page_title) %>
diff --git a/app/views/layouts/shared/_breadcrumbs.html.erb b/app/views/layouts/shared/_breadcrumbs.html.erb
index d48750dc..665fa4be 100644
--- a/app/views/layouts/shared/_breadcrumbs.html.erb
+++ b/app/views/layouts/shared/_breadcrumbs.html.erb
@@ -1,29 +1,17 @@
-<%# locals: (breadcrumbs:, sidebar_toggle_enabled: true) %>
+<%# locals: (breadcrumbs:) %>
-
<% end %>
+ <% if require_upgrade? %>
+ <%= render "shared/subscribe_modal" %>
+ <% end %>
+
<%= turbo_frame_tag "modal" %>
<%= turbo_frame_tag "drawer" %>
diff --git a/app/views/layouts/sidebar/_nav_item.html.erb b/app/views/layouts/sidebar/_nav_item.html.erb
deleted file mode 100644
index 9b50af74..00000000
--- a/app/views/layouts/sidebar/_nav_item.html.erb
+++ /dev/null
@@ -1,18 +0,0 @@
-<%# locals: (name:, path:, icon_key:, is_custom: false) %>
-<%= link_to path, class: "space-y-1 group block relative pb-1" do %>
-
- <%= tag.div class: class_names("w-4 h-1 lg:w-1 lg:h-4 rounded-bl-sm rounded-br-sm lg:rounded-tr-sm lg:rounded-br-sm lg:rounded-bl-none", "bg-nav-indicator" => page_active?(path)) %>
-
- <% icon_color = page_active?(path) ? "current" : "gray" %>
-
- <%= tag.div class: class_names("w-8 h-8 flex items-center justify-center mx-auto rounded-lg", page_active?(path) ? "bg-container shadow-xs text-primary" : "group-hover:bg-container-hover text-secondary") do %>
- <%= icon(icon_key, color: icon_color, custom: is_custom) %>
- <% end %>
-
-
-
- <%= tag.p class: class_names("font-medium text-[11px]", page_active?(path) ? "text-primary" : "text-secondary") do %>
- <%= name %>
- <% end %>
-
-<% end %>
diff --git a/app/views/settings/_settings_nav.html.erb b/app/views/settings/_settings_nav.html.erb
index 208017bc..0a035206 100644
--- a/app/views/settings/_settings_nav.html.erb
+++ b/app/views/settings/_settings_nav.html.erb
@@ -93,7 +93,7 @@
<% end %>
-