From a13f70ea1aabb5797ecc88b6a0498b6c617dec4d Mon Sep 17 00:00:00 2001
From: Andrew Tomaka <atomaka@atomaka.com>
Date: Mon, 16 Jun 2025 22:35:36 -0400
Subject: [PATCH] Add user information drop down to top right (#64)

Reviewed-on: https://git.atomaka.com/atomaka/budget/pulls/64
---
 app/views/layouts/application.html.erb   | 75 ++++++++++++++++++------
 app/views/shared/_user_dropdown.html.erb | 39 ++++++++++++
 test/system/credit_card_bills_test.rb    |  2 +-
 test/system/expenses_test.rb             |  2 +-
 test/system/sessions_test.rb             |  2 +
 5 files changed, 100 insertions(+), 20 deletions(-)
 create mode 100644 app/views/shared/_user_dropdown.html.erb

diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 8441760..59e23e6 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -12,24 +12,63 @@
   </head>
 
   <body>
-    <nav class="w-100 py-4 px-6 bg-gray-900 flex items-center justify-between flex-wrap">
-      <div class="flex items-center">
-        <%= link_to root_path, class: "mr-8" do %>
-          <%= image_tag "logo.svg", alt: "Family Funds Logo", class: "h-8" %>
-        <% end %>
-        <ul class="flex">
-        <% if Current.user.registered? %>
-          <li class="mr-6"><%= link_to "Dashboard", root_path, class: "text-white" %></li>
-          <li class="mr-6"><%= link_to "Expenses", expenses_path, class: "text-white" %></li>
-          <li class="mr-6"><%= link_to "Credit Card Bills", credit_card_bills_path, class: "text-white" %></li>
-          <li class="mr-6"><%= link_to "Incomes", incomes_path, class: "text-white" %></li>
-          <li class="mr-6"><%= link_to "Members", members_path, class: "text-white" %></li>
-          <li class="mr-6"><%= link_to "Log out", session_path, data: {turbo_method: :delete}, class: "text-white" %></li>
-        <% else %>
-          <li class="mr-6"><%= link_to "Sign up", new_user_path, class: "text-white" %></li>
-          <li class="mr-6"><%= link_to "Log in", new_session_path, class: "text-white" %></li>
-        <% end %>
-      </ul>
+    <nav class="w-full py-4 px-4 md:px-6 bg-gray-900">
+      <input type="checkbox" id="mobile-menu" class="peer hidden" />
+      <div class="flex items-center justify-between">
+        <div class="flex items-center flex-shrink-0">
+          <%= link_to root_path, class: "mr-4 md:mr-8" do %>
+            <%= image_tag "logo.svg", alt: "Family Funds Logo", class: "h-8" %>
+          <% end %>
+        </div>
+
+        <!-- Desktop menu -->
+        <div class="hidden lg:flex items-center flex-grow justify-center">
+          <ul class="flex space-x-6">
+          <% if Current.user.registered? %>
+            <li><%= link_to "Dashboard", root_path, class: "text-white hover:text-gray-300" %></li>
+            <li><%= link_to "Expenses", expenses_path, class: "text-white hover:text-gray-300" %></li>
+            <li><%= link_to "Credit Card Bills", credit_card_bills_path, class: "text-white hover:text-gray-300" %></li>
+            <li><%= link_to "Incomes", incomes_path, class: "text-white hover:text-gray-300" %></li>
+            <li><%= link_to "Members", members_path, class: "text-white hover:text-gray-300" %></li>
+          <% else %>
+            <li><%= link_to "Sign up", new_user_path, class: "text-white hover:text-gray-300" %></li>
+            <li><%= link_to "Log in", new_session_path, class: "text-white hover:text-gray-300" %></li>
+          <% end %>
+          </ul>
+        </div>
+
+        <div class="flex items-center space-x-4 flex-shrink-0">
+          <!-- Hamburger menu button -->
+          <label for="mobile-menu"
+            class="lg:hidden text-white hover:text-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-300 rounded-lg p-2 cursor-pointer"
+          >
+            <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
+            </svg>
+          </label>
+
+          <% if Current.user.registered? %>
+            <%= render 'shared/user_dropdown' %>
+          <% end %>
+        </div>
+      </div>
+
+      <!-- Mobile menu -->
+      <div class="lg:hidden mt-4 hidden peer-checked:block">
+        <div class="border-t border-gray-700 pt-4">
+          <ul class="space-y-2">
+          <% if Current.user.registered? %>
+            <li><%= link_to "Dashboard", root_path, class: "block text-white hover:text-gray-300 hover:bg-gray-800 px-3 py-2 rounded-md text-base font-medium" %></li>
+            <li><%= link_to "Expenses", expenses_path, class: "block text-white hover:text-gray-300 hover:bg-gray-800 px-3 py-2 rounded-md text-base font-medium" %></li>
+            <li><%= link_to "Credit Card Bills", credit_card_bills_path, class: "block text-white hover:text-gray-300 hover:bg-gray-800 px-3 py-2 rounded-md text-base font-medium" %></li>
+            <li><%= link_to "Incomes", incomes_path, class: "block text-white hover:text-gray-300 hover:bg-gray-800 px-3 py-2 rounded-md text-base font-medium" %></li>
+            <li><%= link_to "Members", members_path, class: "block text-white hover:text-gray-300 hover:bg-gray-800 px-3 py-2 rounded-md text-base font-medium" %></li>
+          <% else %>
+            <li><%= link_to "Sign up", new_user_path, class: "block text-white hover:text-gray-300 hover:bg-gray-800 px-3 py-2 rounded-md text-base font-medium" %></li>
+            <li><%= link_to "Log in", new_session_path, class: "block text-white hover:text-gray-300 hover:bg-gray-800 px-3 py-2 rounded-md text-base font-medium" %></li>
+          <% end %>
+          </ul>
+        </div>
       </div>
     </nav>
 
diff --git a/app/views/shared/_user_dropdown.html.erb b/app/views/shared/_user_dropdown.html.erb
new file mode 100644
index 0000000..590d008
--- /dev/null
+++ b/app/views/shared/_user_dropdown.html.erb
@@ -0,0 +1,39 @@
+<div class="relative group">
+  <input type="checkbox" id="user-dropdown" class="peer hidden" />
+  <label for="user-dropdown"
+    class="flex items-center space-x-2 text-white hover:text-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-300 rounded-lg p-2 cursor-pointer"
+  >
+    <div class="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-white font-semibold text-sm flex-shrink-0">
+      <%= Current.user.email.first.upcase %>
+    </div>
+    <span class="hidden xl:block font-medium truncate max-w-48"><%= Current.user.email %></span>
+    <svg class="w-4 h-4 transform transition-transform duration-200 flex-shrink-0 peer-checked:rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
+    </svg>
+  </label>
+
+  <!-- Invisible overlay to close dropdown when clicking outside -->
+  <label for="user-dropdown" class="fixed inset-0 z-40 hidden peer-checked:block cursor-default"></label>
+
+  <div
+    class="absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg border border-gray-200 z-50 hidden peer-checked:block"
+  >
+    <div class="py-1">
+      <%= link_to user_path(Current.user), class: "flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" do %>
+        <svg class="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
+        </svg>
+        Profile
+      <% end %>
+      <hr class="my-1 border-gray-200">
+      <%= link_to session_path,
+          data: {turbo_method: :delete},
+          class: "flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" do %>
+        <svg class="w-4 h-4 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
+          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"></path>
+        </svg>
+        Log out
+      <% end %>
+    </div>
+  </div>
+</div>
\ No newline at end of file
diff --git a/test/system/credit_card_bills_test.rb b/test/system/credit_card_bills_test.rb
index 5c829c8..ec2fb7e 100644
--- a/test/system/credit_card_bills_test.rb
+++ b/test/system/credit_card_bills_test.rb
@@ -37,7 +37,7 @@ class CreditCardBillsTest < ApplicationSystemTestCase
 
   test "should destroy Credit card bill" do
     visit credit_card_bill_url(@credit_card_bill)
-    click_on "Delete credit card bill", match: :first
+    accept_prompt { click_on "Delete credit card bill", match: :first }
 
     assert_text "Credit card bill was successfully destroyed"
   end
diff --git a/test/system/expenses_test.rb b/test/system/expenses_test.rb
index d23f851..ba276bf 100644
--- a/test/system/expenses_test.rb
+++ b/test/system/expenses_test.rb
@@ -47,7 +47,7 @@ class ExpensesTest < ApplicationSystemTestCase
 
   test "should destroy Expense" do
     visit expense_url(@expense)
-    click_on "Delete expense", match: :first
+    accept_prompt { click_on "Delete expense", match: :first }
 
     assert_text "Expense was successfully destroyed"
   end
diff --git a/test/system/sessions_test.rb b/test/system/sessions_test.rb
index 958d1a5..e1d531b 100644
--- a/test/system/sessions_test.rb
+++ b/test/system/sessions_test.rb
@@ -15,6 +15,8 @@ class SessionsTest < ApplicationSystemTestCase
     login(@user.email)
 
     visit root_url
+    # Open the user dropdown by clicking the checkbox label
+    find('label[for="user-dropdown"]').click
     click_on "Log out", match: :first
 
     assert_text "Session was successfully destroyed"