mirror of
https://github.com/elisiariocouto/leggen.git
synced 2025-12-24 06:19:30 +00:00
Compare commits
2 Commits
6368b5c62c
...
7a81f9ff9c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a81f9ff9c | ||
|
|
362410c29b |
@@ -123,6 +123,7 @@ export default function TransactionsTable() {
|
|||||||
search: debouncedSearchTerm || undefined,
|
search: debouncedSearchTerm || undefined,
|
||||||
summaryOnly: false,
|
summaryOnly: false,
|
||||||
}),
|
}),
|
||||||
|
placeholderData: (previousData) => previousData,
|
||||||
});
|
});
|
||||||
|
|
||||||
const transactions = transactionsResponse?.data || [];
|
const transactions = transactionsResponse?.data || [];
|
||||||
@@ -413,9 +414,9 @@ export default function TransactionsTable() {
|
|||||||
<p className="text-xs text-muted-foreground uppercase tracking-wider">
|
<p className="text-xs text-muted-foreground uppercase tracking-wider">
|
||||||
Income
|
Income
|
||||||
</p>
|
</p>
|
||||||
<p className="text-2xl font-bold text-green-600 mt-1">
|
<BlurredValue className="text-2xl font-bold text-green-600 mt-1 block">
|
||||||
+{formatCurrency(stats.totalIncome, displayCurrency)}
|
+{formatCurrency(stats.totalIncome, displayCurrency)}
|
||||||
</p>
|
</BlurredValue>
|
||||||
</div>
|
</div>
|
||||||
<TrendingUp className="h-8 w-8 text-green-600 opacity-50" />
|
<TrendingUp className="h-8 w-8 text-green-600 opacity-50" />
|
||||||
</div>
|
</div>
|
||||||
@@ -427,9 +428,9 @@ export default function TransactionsTable() {
|
|||||||
<p className="text-xs text-muted-foreground uppercase tracking-wider">
|
<p className="text-xs text-muted-foreground uppercase tracking-wider">
|
||||||
Expenses
|
Expenses
|
||||||
</p>
|
</p>
|
||||||
<p className="text-2xl font-bold text-red-600 mt-1">
|
<BlurredValue className="text-2xl font-bold text-red-600 mt-1 block">
|
||||||
-{formatCurrency(stats.totalExpenses, displayCurrency)}
|
-{formatCurrency(stats.totalExpenses, displayCurrency)}
|
||||||
</p>
|
</BlurredValue>
|
||||||
</div>
|
</div>
|
||||||
<TrendingDown className="h-8 w-8 text-red-600 opacity-50" />
|
<TrendingDown className="h-8 w-8 text-red-600 opacity-50" />
|
||||||
</div>
|
</div>
|
||||||
@@ -441,14 +442,14 @@ export default function TransactionsTable() {
|
|||||||
<p className="text-xs text-muted-foreground uppercase tracking-wider">
|
<p className="text-xs text-muted-foreground uppercase tracking-wider">
|
||||||
Net Change
|
Net Change
|
||||||
</p>
|
</p>
|
||||||
<p
|
<BlurredValue
|
||||||
className={`text-2xl font-bold mt-1 ${
|
className={`text-2xl font-bold mt-1 block ${
|
||||||
stats.netChange >= 0 ? "text-green-600" : "text-red-600"
|
stats.netChange >= 0 ? "text-green-600" : "text-red-600"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{stats.netChange >= 0 ? "+" : ""}
|
{stats.netChange >= 0 ? "+" : ""}
|
||||||
{formatCurrency(stats.netChange, displayCurrency)}
|
{formatCurrency(stats.netChange, displayCurrency)}
|
||||||
</p>
|
</BlurredValue>
|
||||||
</div>
|
</div>
|
||||||
{stats.netChange >= 0 ? (
|
{stats.netChange >= 0 ? (
|
||||||
<TrendingUp className="h-8 w-8 text-green-600 opacity-50" />
|
<TrendingUp className="h-8 w-8 text-green-600 opacity-50" />
|
||||||
|
|||||||
@@ -32,22 +32,19 @@ export function FilterBar({
|
|||||||
className,
|
className,
|
||||||
}: FilterBarProps) {
|
}: FilterBarProps) {
|
||||||
const searchInputRef = useRef<HTMLInputElement>(null);
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
const cursorPositionRef = useRef<number | null>(null);
|
||||||
|
|
||||||
// Maintain focus on search input during re-renders
|
// Maintain focus and cursor position on search input during re-renders
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const currentInput = searchInputRef.current;
|
const currentInput = searchInputRef.current;
|
||||||
if (!currentInput) return;
|
if (!currentInput) return;
|
||||||
|
|
||||||
// Only restore focus if the search input had focus before
|
// Restore focus and cursor position after data fetches complete
|
||||||
const wasFocused = document.activeElement === currentInput;
|
if (cursorPositionRef.current !== null && document.activeElement !== currentInput) {
|
||||||
|
currentInput.focus();
|
||||||
// Use requestAnimationFrame to restore focus after React finishes rendering
|
currentInput.setSelectionRange(cursorPositionRef.current, cursorPositionRef.current);
|
||||||
if (wasFocused && document.activeElement !== currentInput) {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
currentInput.focus();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, [isSearchLoading]);
|
});
|
||||||
|
|
||||||
const hasActiveFilters =
|
const hasActiveFilters =
|
||||||
filterState.searchTerm ||
|
filterState.searchTerm ||
|
||||||
@@ -83,7 +80,16 @@ export function FilterBar({
|
|||||||
ref={searchInputRef}
|
ref={searchInputRef}
|
||||||
placeholder="Search transactions..."
|
placeholder="Search transactions..."
|
||||||
value={filterState.searchTerm}
|
value={filterState.searchTerm}
|
||||||
onChange={(e) => onFilterChange("searchTerm", e.target.value)}
|
onChange={(e) => {
|
||||||
|
cursorPositionRef.current = e.target.selectionStart;
|
||||||
|
onFilterChange("searchTerm", e.target.value);
|
||||||
|
}}
|
||||||
|
onFocus={() => {
|
||||||
|
cursorPositionRef.current = searchInputRef.current?.selectionStart ?? null;
|
||||||
|
}}
|
||||||
|
onBlur={() => {
|
||||||
|
cursorPositionRef.current = null;
|
||||||
|
}}
|
||||||
className="pl-9 pr-8 bg-background"
|
className="pl-9 pr-8 bg-background"
|
||||||
/>
|
/>
|
||||||
{isSearchLoading && (
|
{isSearchLoading && (
|
||||||
@@ -122,7 +128,16 @@ export function FilterBar({
|
|||||||
ref={searchInputRef}
|
ref={searchInputRef}
|
||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
value={filterState.searchTerm}
|
value={filterState.searchTerm}
|
||||||
onChange={(e) => onFilterChange("searchTerm", e.target.value)}
|
onChange={(e) => {
|
||||||
|
cursorPositionRef.current = e.target.selectionStart;
|
||||||
|
onFilterChange("searchTerm", e.target.value);
|
||||||
|
}}
|
||||||
|
onFocus={() => {
|
||||||
|
cursorPositionRef.current = searchInputRef.current?.selectionStart ?? null;
|
||||||
|
}}
|
||||||
|
onBlur={() => {
|
||||||
|
cursorPositionRef.current = null;
|
||||||
|
}}
|
||||||
className="pl-9 pr-8 bg-background w-full"
|
className="pl-9 pr-8 bg-background w-full"
|
||||||
/>
|
/>
|
||||||
{isSearchLoading && (
|
{isSearchLoading && (
|
||||||
|
|||||||
Reference in New Issue
Block a user