mirror of
https://github.com/acedanger/finance.git
synced 2025-12-06 07:00:13 -08:00
Refactor transaction components and styles
- Updated imports to use absolute paths for types and utilities. - Enhanced TransactionTable component with mobile responsiveness and card-based layout. - Improved loading and error handling in transaction fetching logic. - Refactored transaction update API to streamline validation and data preparation. - Added new styles for Radix UI components and improved global styles for better mobile experience. - Implemented collapsible sections and improved button interactions in the UI. - Updated tests to reflect changes in component structure and imports.
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
---
|
||||
import type { Account } from "../types";
|
||||
import AccountSummary from "./AccountSummary.tsx"; // Import the React component instead of the Astro one
|
||||
import AddTransactionForm from "./AddTransactionForm.tsx";
|
||||
import type { Account } from '@types';
|
||||
|
||||
interface Props {
|
||||
accounts: Account[];
|
||||
initialAccount: Account;
|
||||
accounts: Account[];
|
||||
initialAccount: Account;
|
||||
}
|
||||
|
||||
const { accounts, initialAccount } = Astro.props;
|
||||
@@ -14,18 +12,10 @@ const { accounts, initialAccount } = Astro.props;
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h2>My finances</h2>
|
||||
{/* Add button to toggle form visibility */}
|
||||
<button
|
||||
id="toggle-add-txn-btn"
|
||||
aria-expanded="false"
|
||||
aria-controls="add-transaction-section"
|
||||
>
|
||||
+ New Txn
|
||||
</button>
|
||||
</div>
|
||||
<nav class="account-nav">
|
||||
<h3>Accounts</h3>
|
||||
<select id="account-select" name="account">
|
||||
<select id="account-select" name="account" class="form-input">
|
||||
{
|
||||
accounts.map((account) => (
|
||||
<option
|
||||
@@ -39,43 +29,176 @@ const { accounts, initialAccount } = Astro.props;
|
||||
</select>
|
||||
</nav>
|
||||
|
||||
{/* Use the React AccountSummary component, remove account prop */}
|
||||
<AccountSummary client:load />
|
||||
|
||||
{/* Section to contain the React form, initially hidden */}
|
||||
<section id="add-transaction-section" class="collapsible collapsed">
|
||||
{
|
||||
/*
|
||||
Use the React component here.
|
||||
It now gets its state (currentAccountId, transactionToEdit)
|
||||
directly from the Nano Store.
|
||||
*/
|
||||
}
|
||||
<AddTransactionForm client:load />
|
||||
<!-- Add Transaction Section with Toggle - Moved up to be right after account dropdown -->
|
||||
<section id="add-transaction-section" class="add-transaction-section">
|
||||
<button
|
||||
type="button"
|
||||
class="toggle-form-btn"
|
||||
id="toggle-add-txn-btn"
|
||||
aria-controls="add-transaction-form"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Add Transaction
|
||||
</button>
|
||||
<div id="add-transaction-form" class="collapsible-form collapsed">
|
||||
<AddTransactionForm client:load />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Account Summary Section - Always visible -->
|
||||
<div class="account-summary-section" id="account-summary-section">
|
||||
<AccountSummary client:load />
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
{/* Keep the script for toggling visibility for now */}
|
||||
<script>
|
||||
const toggleButton = document.getElementById("toggle-add-txn-btn");
|
||||
const formSection = document.getElementById("add-transaction-section");
|
||||
<!-- Toggle button for sidebar on mobile -->
|
||||
<button
|
||||
type="button"
|
||||
class="sidebar-toggle"
|
||||
id="sidebar-toggle"
|
||||
aria-controls="sidebar-content"
|
||||
aria-expanded="true"
|
||||
>
|
||||
<span>Toggle sidebar</span>
|
||||
<span class="sidebar-toggle-icon">▲</span>
|
||||
</button>
|
||||
|
||||
if (toggleButton && formSection) {
|
||||
toggleButton.addEventListener("click", () => {
|
||||
const isExpanded =
|
||||
toggleButton.getAttribute("aria-expanded") === "true";
|
||||
toggleButton.setAttribute("aria-expanded", String(!isExpanded));
|
||||
formSection.classList.toggle("collapsed");
|
||||
formSection.classList.toggle("expanded");
|
||||
// Optional: Focus first field when expanding
|
||||
if (!isExpanded) {
|
||||
// Cast the result to HTMLElement before calling focus
|
||||
(
|
||||
formSection.querySelector(
|
||||
"input, select, textarea",
|
||||
) as HTMLElement
|
||||
)?.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
<script>
|
||||
// Add Transaction form toggle
|
||||
const toggleAddTxnBtn = document.getElementById("toggle-add-txn-btn");
|
||||
const addTransactionForm = document.getElementById("add-transaction-form");
|
||||
|
||||
toggleAddTxnBtn?.addEventListener("click", () => {
|
||||
const isExpanded =
|
||||
toggleAddTxnBtn.getAttribute("aria-expanded") === "true";
|
||||
toggleAddTxnBtn.setAttribute(
|
||||
"aria-expanded",
|
||||
isExpanded ? "false" : "true",
|
||||
);
|
||||
|
||||
if (isExpanded) {
|
||||
addTransactionForm?.classList.add("collapsed");
|
||||
} else {
|
||||
addTransactionForm?.classList.remove("collapsed");
|
||||
}
|
||||
});
|
||||
|
||||
// Sidebar toggle for mobile
|
||||
const sidebarToggleBtn = document.getElementById("sidebar-toggle");
|
||||
const sidebar = document.querySelector(".sidebar");
|
||||
|
||||
sidebarToggleBtn?.addEventListener("click", () => {
|
||||
const isExpanded =
|
||||
sidebarToggleBtn.getAttribute("aria-expanded") === "true";
|
||||
sidebarToggleBtn.setAttribute(
|
||||
"aria-expanded",
|
||||
isExpanded ? "false" : "true",
|
||||
);
|
||||
|
||||
if (isExpanded) {
|
||||
sidebar?.classList.add("sidebar-collapsed");
|
||||
} else {
|
||||
sidebar?.classList.remove("sidebar-collapsed");
|
||||
}
|
||||
});
|
||||
|
||||
// Check if we're on mobile and collapse sidebar by default
|
||||
const checkMobile = () => {
|
||||
const isMobile = window.innerWidth < 1024;
|
||||
|
||||
if (isMobile && sidebar && sidebarToggleBtn) {
|
||||
// Start with sidebar collapsed on mobile
|
||||
sidebar.classList.add("sidebar-collapsed");
|
||||
sidebarToggleBtn.setAttribute("aria-expanded", "false");
|
||||
} else if (sidebar && sidebarToggleBtn) {
|
||||
sidebar.classList.remove("sidebar-collapsed");
|
||||
sidebarToggleBtn.setAttribute("aria-expanded", "true");
|
||||
}
|
||||
};
|
||||
|
||||
// Check on load and window resize
|
||||
window.addEventListener("load", checkMobile);
|
||||
window.addEventListener("resize", checkMobile);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.sidebar {
|
||||
padding: 20px;
|
||||
background-color: #f9fafb;
|
||||
border-right: 1px solid #e5e7eb;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.sidebar-collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.account-nav {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.account-nav h3 {
|
||||
margin-bottom: 8px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* Ensure account summary is always visible */
|
||||
.account-summary-section {
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.add-transaction-section {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.add-transaction-section .toggle-form-btn {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.collapsible-form.collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
display: none;
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
background-color: #f9fafb;
|
||||
border: 1px solid #e5e7eb;
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
z-index: 100;
|
||||
width: auto;
|
||||
min-width: 140px;
|
||||
text-align: center;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.sidebar-toggle span {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.sidebar-toggle-icon {
|
||||
margin-left: 8px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.sidebar-toggle {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user