diff --git a/MoneyMap/Pages/ReviewAISuggestionsWithProposals.cshtml b/MoneyMap/Pages/ReviewAISuggestionsWithProposals.cshtml
index 7e153da..222f6ff 100644
--- a/MoneyMap/Pages/ReviewAISuggestionsWithProposals.cshtml
+++ b/MoneyMap/Pages/ReviewAISuggestionsWithProposals.cshtml
@@ -2,6 +2,12 @@
@model MoneyMap.Pages.ReviewAISuggestionsWithProposalsModel
@{
ViewData["Title"] = "Review AI Suggestions";
+ ViewData["Breadcrumbs"] = new List<(string Label, string? Url)>
+ {
+ ("Transactions", Url.Page("/Transactions")),
+ ("AI Suggestions", Url.Page("/ReviewAISuggestions")),
+ ("Review Proposals", null)
+ };
}
diff --git a/MoneyMap/Pages/ReviewReceipts.cshtml b/MoneyMap/Pages/ReviewReceipts.cshtml
index d991ae3..c2935e2 100644
--- a/MoneyMap/Pages/ReviewReceipts.cshtml
+++ b/MoneyMap/Pages/ReviewReceipts.cshtml
@@ -2,6 +2,11 @@
@model MoneyMap.Pages.ReviewReceiptsModel
@{
ViewData["Title"] = "Review Receipts";
+ ViewData["Breadcrumbs"] = new List<(string Label, string? Url)>
+ {
+ ("Receipts", Url.Page("/Receipts")),
+ ("Review Mappings", null)
+ };
}
diff --git a/MoneyMap/Pages/Shared/_Layout.cshtml b/MoneyMap/Pages/Shared/_Layout.cshtml
index d6611ef..aba370c 100644
--- a/MoneyMap/Pages/Shared/_Layout.cshtml
+++ b/MoneyMap/Pages/Shared/_Layout.cshtml
@@ -22,23 +22,62 @@
Dashboard
-
- Transactions
+
+
+ Transactions
+
+
+
+
+
+ Receipts
+
+
+
+
+
+ Accounts
+
+
- Receipts
+ Budgets
-
- Accounts
+
+
@@ -47,6 +86,25 @@
+ @if (ViewData["Breadcrumbs"] is List<(string Label, string? Url)> breadcrumbs && breadcrumbs.Count > 0)
+ {
+
+ }
@RenderBody()
@@ -58,7 +116,7 @@
-
+
@await RenderSectionAsync("Scripts", required: false)
diff --git a/MoneyMap/Pages/Upload.cshtml b/MoneyMap/Pages/Upload.cshtml
index 5a3b9bc..fa90418 100644
--- a/MoneyMap/Pages/Upload.cshtml
+++ b/MoneyMap/Pages/Upload.cshtml
@@ -3,6 +3,11 @@
@{
ViewData["Title"] = "Upload Transactions";
ViewData["FullWidth"] = Model.PreviewTransactions.Any();
+ ViewData["Breadcrumbs"] = new List<(string Label, string? Url)>
+ {
+ ("Transactions", Url.Page("/Transactions")),
+ ("Upload", null)
+ };
}
Upload Transactions
diff --git a/MoneyMap/Pages/ViewReceipt.cshtml b/MoneyMap/Pages/ViewReceipt.cshtml
index 164df1e..5714772 100644
--- a/MoneyMap/Pages/ViewReceipt.cshtml
+++ b/MoneyMap/Pages/ViewReceipt.cshtml
@@ -2,6 +2,12 @@
@model MoneyMap.Pages.ViewReceiptModel
@{
ViewData["Title"] = "View Receipt";
+ ViewData["Breadcrumbs"] = new List<(string Label, string? Url)>
+ {
+ ("Transactions", Url.Page("/Transactions")),
+ ($"Transaction #{Model.Receipt.TransactionId}", Url.Page("/EditTransaction", new { id = Model.Receipt.TransactionId })),
+ ("Receipt", null)
+ };
}
diff --git a/MoneyMap/wwwroot/css/site.css b/MoneyMap/wwwroot/css/site.css
index df3bbf5..4a7a882 100644
--- a/MoneyMap/wwwroot/css/site.css
+++ b/MoneyMap/wwwroot/css/site.css
@@ -19,4 +19,40 @@ html {
body {
margin-bottom: 60px;
+}
+
+/* Active dropdown parent highlighting */
+.navbar .nav-item.dropdown .nav-link.dropdown-toggle.active-parent {
+ color: rgba(255, 255, 255, 0.9);
+}
+
+/* Breadcrumb styling */
+.breadcrumb-nav {
+ margin-bottom: 1rem;
+}
+.breadcrumb-nav .breadcrumb {
+ background: transparent;
+ padding: 0;
+ margin-bottom: 0;
+ font-size: 0.875rem;
+}
+
+/* Quick-action cards on dashboard */
+.quick-action-card {
+ transition: transform 0.15s ease, box-shadow 0.15s ease;
+ text-decoration: none;
+ color: inherit;
+}
+.quick-action-card:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.3) !important;
+}
+.quick-action-icon {
+ width: 48px;
+ height: 48px;
+ border-radius: 12px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.25rem;
}
\ No newline at end of file
diff --git a/MoneyMap/wwwroot/js/site.js b/MoneyMap/wwwroot/js/site.js
index 0937657..711cf6a 100644
--- a/MoneyMap/wwwroot/js/site.js
+++ b/MoneyMap/wwwroot/js/site.js
@@ -1,4 +1,19 @@
-// Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification
-// for details on configuring this project to bundle and minify static web assets.
-
-// Write your JavaScript code.
+// Highlight active dropdown parent when a child page is active
+(function () {
+ var path = window.location.pathname.toLowerCase().replace(/\/+$/, '') || '/';
+ document.querySelectorAll('.navbar .dropdown-menu .dropdown-item').forEach(function (item) {
+ var href = (item.getAttribute('href') || '').toLowerCase().replace(/\/+$/, '');
+ if (href && (path === href || path.startsWith(href + '/'))) {
+ item.classList.add('active');
+ var toggle = item.closest('.dropdown').querySelector('.dropdown-toggle');
+ if (toggle) toggle.classList.add('active-parent');
+ }
+ });
+ // Direct nav-links (non-dropdown)
+ document.querySelectorAll('.navbar .nav-link:not(.dropdown-toggle)').forEach(function (link) {
+ var href = (link.getAttribute('href') || '').toLowerCase().replace(/\/+$/, '');
+ if (href && path === href) {
+ link.classList.add('active');
+ }
+ });
+})();