mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-09 15:35:22 +02:00
Layout simplification
This commit is contained in:
parent
fe7843b00c
commit
daaf6abe74
6 changed files with 103 additions and 174 deletions
|
@ -1,79 +0,0 @@
|
|||
<%= tag.div class: "flex flex-col lg:flex-row h-dvh lg:h-full bg-surface pt-safe",
|
||||
data: {
|
||||
controller: "app-layout",
|
||||
app_layout_user_id_value: user_id,
|
||||
app_layout_left_sidebar_class: left_sidebar_classes,
|
||||
app_layout_right_sidebar_class: right_sidebar_classes,
|
||||
} do %>
|
||||
<%# MOBILE - Popout nav menu %>
|
||||
<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">
|
||||
<%= helpers.icon("x", as_button: true, data: { action: "app-layout#closeMobileSidebar" }) %>
|
||||
</div>
|
||||
<%= mobile_sidebar %>
|
||||
</div>
|
||||
|
||||
<%# MOBILE - Top nav %>
|
||||
<nav class="lg:hidden flex justify-between items-center p-3">
|
||||
<%= helpers.icon("panel-left", as_button: true, data: { action: "app-layout#openMobileSidebar"}) %>
|
||||
|
||||
<%= link_to root_path, class: "block" do %>
|
||||
<%= image_tag "logomark-color.svg", class: "w-9 h-9 mx-auto" %>
|
||||
<% end %>
|
||||
|
||||
<%= mobile_user_menu %>
|
||||
</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">
|
||||
<% nav_items.reject { |item| item.mobile_only }.each do |nav_item| %>
|
||||
<li><%= nav_item %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<div class="pl-2 mt-auto mx-auto">
|
||||
<%= desktop_user_menu %>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<%# DESKTOP - Left sidebar %>
|
||||
<%= tag.div class: class_names("hidden py-4 overflow-y-auto shrink-0", left_sidebar_classes, "lg:block" => show_left?), data: { app_layout_target: "leftSidebar" } do %>
|
||||
<%= left_sidebar %>
|
||||
<% 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">
|
||||
<%= helpers.icon("panel-left", as_button: true, data: { action: "app-layout#toggleLeftSidebar" }) %>
|
||||
<%= breadcrumbs %>
|
||||
</div>
|
||||
<%= helpers.icon("panel-right", as_button: true, data: { action: "app-layout#toggleRightSidebar" }) %>
|
||||
</div>
|
||||
|
||||
<%= content %>
|
||||
<% end %>
|
||||
|
||||
<%# DESKTOP - Right sidebar %>
|
||||
<%= tag.div class: class_names("hidden h-full overflow-y-auto shrink-0", right_sidebar_classes, "lg:block" => show_right?), data: { app_layout_target: "rightSidebar" } do %>
|
||||
<%= right_sidebar %>
|
||||
<% end %>
|
||||
|
||||
<%# 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 %>
|
||||
<% nav_items.each do |nav_item| %>
|
||||
<%= nav_item %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
|
@ -1,40 +0,0 @@
|
|||
class AppLayoutComponent < ViewComponent::Base
|
||||
renders_many :nav_items, NavItem
|
||||
renders_one :breadcrumbs
|
||||
|
||||
# Desktop slots
|
||||
renders_one :left_sidebar
|
||||
renders_one :right_sidebar
|
||||
renders_one :desktop_user_menu
|
||||
|
||||
# Mobile slots
|
||||
renders_one :mobile_sidebar
|
||||
renders_one :mobile_user_menu
|
||||
|
||||
def initialize(user:)
|
||||
@user = user
|
||||
end
|
||||
|
||||
def show_left?
|
||||
user.show_sidebar?
|
||||
end
|
||||
|
||||
def show_right?
|
||||
user.show_ai_sidebar?
|
||||
end
|
||||
|
||||
def user_id
|
||||
user.id
|
||||
end
|
||||
|
||||
def left_sidebar_classes
|
||||
"w-[320px]"
|
||||
end
|
||||
|
||||
def right_sidebar_classes
|
||||
"w-[400px]"
|
||||
end
|
||||
|
||||
private
|
||||
attr_reader :user
|
||||
end
|
|
@ -1,12 +0,0 @@
|
|||
class AppLayoutComponent::NavItem < ViewComponent::Base
|
||||
attr_reader :name, :path, :icon, :icon_custom, :active, :mobile_only
|
||||
|
||||
def initialize(name:, path:, icon:, icon_custom: false, active: false, mobile_only: false)
|
||||
@name = name
|
||||
@path = path
|
||||
@icon = icon
|
||||
@icon_custom = icon_custom
|
||||
@active = active
|
||||
@mobile_only = mobile_only
|
||||
end
|
||||
end
|
|
@ -2,25 +2,31 @@ import { Controller } from "@hotwired/stimulus";
|
|||
|
||||
// Connects to data-controller="dialog"
|
||||
export default class extends Controller {
|
||||
static targets = ["leftSidebar", "rightSidebar", "mobileSidebar"]
|
||||
static classes = ["leftSidebar", "rightSidebar"]
|
||||
static targets = ["leftSidebar", "rightSidebar", "mobileSidebar"];
|
||||
static classes = ["leftSidebar", "rightSidebar"];
|
||||
|
||||
openMobileSidebar() {
|
||||
this.mobileSidebarTarget.classList.remove("hidden")
|
||||
this.mobileSidebarTarget.classList.remove("hidden");
|
||||
}
|
||||
|
||||
closeMobileSidebar() {
|
||||
this.mobileSidebarTarget.classList.add("hidden")
|
||||
this.mobileSidebarTarget.classList.add("hidden");
|
||||
}
|
||||
|
||||
toggleLeftSidebar() {
|
||||
this.#updateUserPreference("show_sidebar", this.leftSidebarTarget.classList.contains("hidden"))
|
||||
this.leftSidebarTarget.classList.toggle("hidden")
|
||||
this.#updateUserPreference(
|
||||
"show_sidebar",
|
||||
this.leftSidebarTarget.classList.contains("hidden"),
|
||||
);
|
||||
this.leftSidebarTarget.classList.toggle("hidden");
|
||||
}
|
||||
|
||||
toggleRightSidebar() {
|
||||
this.#updateUserPreference("show_ai_sidebar", this.rightSidebarTarget.classList.contains("hidden"))
|
||||
this.rightSidebarTarget.classList.toggle("hidden")
|
||||
this.#updateUserPreference(
|
||||
"show_ai_sidebar",
|
||||
this.rightSidebarTarget.classList.contains("hidden"),
|
||||
);
|
||||
this.rightSidebarTarget.classList.toggle("hidden");
|
||||
}
|
||||
|
||||
#updateUserPreference(field, value) {
|
|
@ -1,29 +1,68 @@
|
|||
<%= render "layouts/shared/htmldoc" do %>
|
||||
<%= 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) },
|
||||
<% 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] } %>
|
||||
|
||||
<%= render "layouts/shared/htmldoc" do %>
|
||||
<div
|
||||
class="flex flex-col lg:flex-row h-dvh lg:h-full bg-surface"
|
||||
data-controller="app-layout"
|
||||
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>
|
||||
|
||||
<% app_layout.with_mobile_sidebar do %>
|
||||
<%= render(
|
||||
"accounts/account_sidebar_tabs",
|
||||
family: Current.family,
|
||||
active_account_group_tab: params[:account_group_tab] || "assets"
|
||||
) %>
|
||||
</div>
|
||||
|
||||
<%# 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"}) %>
|
||||
|
||||
<%= link_to root_path, class: "block" do %>
|
||||
<%= image_tag "logomark-color.svg", class: "w-9 h-9 mx-auto" %>
|
||||
<% end %>
|
||||
|
||||
<% app_layout.with_mobile_user_menu do %>
|
||||
<%= render "users/user_menu", user: Current.user, placement: "bottom-end", offset: 12 %>
|
||||
<% end %>
|
||||
</nav>
|
||||
|
||||
<% app_layout.with_desktop_user_menu do %>
|
||||
<%# 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">
|
||||
<% 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="pl-2 mt-auto mx-auto">
|
||||
<%= render "users/user_menu", user: Current.user %>
|
||||
<% end %>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<% app_layout.with_left_sidebar do %>
|
||||
<%# DESKTOP - Left sidebar %>
|
||||
<%= tag.div class: class_names("hidden py-4 overflow-y-auto shrink-0 w-[320px]", "lg:block" => Current.user.show_sidebar?), data: { app_layout_target: "leftSidebar" } do %>
|
||||
<% if content_for?(:sidebar) %>
|
||||
<%= yield :sidebar %>
|
||||
<% else %>
|
||||
|
@ -33,7 +72,30 @@
|
|||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% app_layout.with_right_sidebar do %>
|
||||
<%# 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" }) %>
|
||||
|
||||
<% 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 %>
|
||||
|
||||
<%# DESKTOP - Right sidebar %>
|
||||
<%= tag.div class: class_names("hidden h-full overflow-y-auto shrink-0 w-[400px]", "lg:block" => Current.user.show_ai_sidebar?), data: { app_layout_target: "rightSidebar" } do %>
|
||||
<%= tag.div id: "chat-container",
|
||||
class: class_names("flex flex-col h-full justify-between shrink-0 transition-all duration-300"),
|
||||
data: { controller: "chat hotkey", turbo_permanent: true } do %>
|
||||
|
@ -50,21 +112,11 @@
|
|||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% app_layout.with_breadcrumbs do %>
|
||||
<% if content_for?(:breadcrumbs) %>
|
||||
<%= yield :breadcrumbs %>
|
||||
<% else %>
|
||||
<%= render "layouts/shared/breadcrumbs", breadcrumbs: @breadcrumbs %>
|
||||
<%# 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 %>
|
||||
|
||||
<%# Main page content %>
|
||||
<div>
|
||||
<% if content_for?(:page_header) %>
|
||||
<%= yield :page_header %>
|
||||
<% end %>
|
||||
|
||||
<%= yield %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<%# locals:(name:, path:, icon:, icon_custom:, active:, mobile_only: false) %>
|
||||
|
||||
<%= link_to path, class: "space-y-1 group block relative pb-1" do %>
|
||||
<div class="grow flex flex-col lg:flex-row gap-1 items-center">
|
||||
<%= 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" => active) %>
|
||||
|
@ -6,7 +8,7 @@
|
|||
"w-8 h-8 flex items-center justify-center mx-auto rounded-lg",
|
||||
active ? "bg-container shadow-xs text-primary" : "group-hover:bg-container-hover text-secondary"
|
||||
) do %>
|
||||
<%= helpers.icon(icon, color: active ? "current" : "default", custom: icon_custom) %>
|
||||
<%= icon(icon, color: active ? "current" : "default", custom: icon_custom) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue