mirror of
https://github.com/elisiariocouto/leggen.git
synced 2025-12-29 02:49:13 +00:00
Compare commits
4 Commits
b3eab6ae26
...
2b69b1e27b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b69b1e27b | ||
|
|
4dec8113fe | ||
|
|
28534e97c0 | ||
|
|
43b6f32145 |
@@ -16,6 +16,40 @@ import { formatCurrency, formatDate } from "../lib/utils";
|
|||||||
import LoadingSpinner from "./LoadingSpinner";
|
import LoadingSpinner from "./LoadingSpinner";
|
||||||
import type { Account, Balance } from "../types/api";
|
import type { Account, Balance } from "../types/api";
|
||||||
|
|
||||||
|
// Helper function to get status indicator color and styles
|
||||||
|
const getStatusIndicator = (status: string) => {
|
||||||
|
const statusLower = status.toLowerCase();
|
||||||
|
|
||||||
|
switch (statusLower) {
|
||||||
|
case 'ready':
|
||||||
|
return {
|
||||||
|
color: 'bg-green-500',
|
||||||
|
tooltip: 'Ready',
|
||||||
|
};
|
||||||
|
case 'pending':
|
||||||
|
return {
|
||||||
|
color: 'bg-yellow-500',
|
||||||
|
tooltip: 'Pending',
|
||||||
|
};
|
||||||
|
case 'error':
|
||||||
|
case 'failed':
|
||||||
|
return {
|
||||||
|
color: 'bg-red-500',
|
||||||
|
tooltip: 'Error',
|
||||||
|
};
|
||||||
|
case 'inactive':
|
||||||
|
return {
|
||||||
|
color: 'bg-gray-500',
|
||||||
|
tooltip: 'Inactive',
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
color: 'bg-blue-500',
|
||||||
|
tooltip: status,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default function AccountsOverview() {
|
export default function AccountsOverview() {
|
||||||
const {
|
const {
|
||||||
data: accounts,
|
data: accounts,
|
||||||
@@ -201,14 +235,15 @@ export default function AccountsOverview() {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={account.id}
|
key={account.id}
|
||||||
className="p-6 hover:bg-gray-50 transition-colors"
|
className="p-4 sm:p-6 hover:bg-gray-50 transition-colors"
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
{/* Mobile layout - stack vertically */}
|
||||||
<div className="flex items-center space-x-4">
|
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 sm:gap-4">
|
||||||
<div className="p-3 bg-gray-100 rounded-full">
|
<div className="flex items-start sm:items-center space-x-3 sm:space-x-4 min-w-0 flex-1">
|
||||||
<Building2 className="h-6 w-6 text-gray-600" />
|
<div className="flex-shrink-0 p-2 sm:p-3 bg-gray-100 rounded-full">
|
||||||
|
<Building2 className="h-5 w-5 sm:h-6 sm:w-6 text-gray-600" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1">
|
<div className="flex-1 min-w-0">
|
||||||
{editingAccountId === account.id ? (
|
{editingAccountId === account.id ? (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
@@ -216,7 +251,7 @@ export default function AccountsOverview() {
|
|||||||
type="text"
|
type="text"
|
||||||
value={editingName}
|
value={editingName}
|
||||||
onChange={(e) => setEditingName(e.target.value)}
|
onChange={(e) => setEditingName(e.target.value)}
|
||||||
className="flex-1 px-3 py-1 text-lg font-medium border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
className="flex-1 px-3 py-1 text-base sm:text-lg font-medium border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||||||
placeholder="Account name"
|
placeholder="Account name"
|
||||||
name="search"
|
name="search"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
@@ -245,29 +280,29 @@ export default function AccountsOverview() {
|
|||||||
<X className="h-4 w-4" />
|
<X className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-gray-600">
|
<p className="text-sm text-gray-600 truncate">
|
||||||
{account.institution_id} • {account.status}
|
{account.institution_id}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2 min-w-0">
|
||||||
<h4 className="text-lg font-medium text-gray-900">
|
<h4 className="text-base sm:text-lg font-medium text-gray-900 truncate">
|
||||||
{account.name || "Unnamed Account"}
|
{account.name || "Unnamed Account"}
|
||||||
</h4>
|
</h4>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleEditStart(account)}
|
onClick={() => handleEditStart(account)}
|
||||||
className="p-1 text-gray-400 hover:text-gray-600 transition-colors"
|
className="flex-shrink-0 p-1 text-gray-400 hover:text-gray-600 transition-colors"
|
||||||
title="Edit account name"
|
title="Edit account name"
|
||||||
>
|
>
|
||||||
<Edit2 className="h-4 w-4" />
|
<Edit2 className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-gray-600">
|
<p className="text-sm text-gray-600 truncate">
|
||||||
{account.institution_id} • {account.status}
|
{account.institution_id}
|
||||||
</p>
|
</p>
|
||||||
{account.iban && (
|
{account.iban && (
|
||||||
<p className="text-xs text-gray-500 mt-1">
|
<p className="text-xs text-gray-500 mt-1 font-mono break-all sm:break-normal">
|
||||||
IBAN: {account.iban}
|
IBAN: {account.iban}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
@@ -276,25 +311,45 @@ export default function AccountsOverview() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-right">
|
{/* Balance and date section */}
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center justify-between sm:flex-col sm:items-end sm:text-right flex-shrink-0">
|
||||||
|
{/* Mobile: date/status on left, balance on right */}
|
||||||
|
{/* Desktop: balance on top, date/status on bottom */}
|
||||||
|
|
||||||
|
{/* Date and status indicator - left on mobile, bottom on desktop */}
|
||||||
|
<div className="flex items-center space-x-2 order-1 sm:order-2">
|
||||||
|
<div
|
||||||
|
className={`w-3 h-3 rounded-full ${getStatusIndicator(account.status).color} relative group cursor-help`}
|
||||||
|
role="img"
|
||||||
|
aria-label={`Account status: ${getStatusIndicator(account.status).tooltip}`}
|
||||||
|
>
|
||||||
|
{/* Tooltip */}
|
||||||
|
<div className="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block bg-gray-900 text-white text-xs rounded py-1 px-2 whitespace-nowrap z-10">
|
||||||
|
{getStatusIndicator(account.status).tooltip}
|
||||||
|
<div className="absolute top-full left-1/2 transform -translate-x-1/2 border-2 border-transparent border-t-gray-900"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="text-xs sm:text-sm text-gray-500 whitespace-nowrap">
|
||||||
|
Updated{" "}
|
||||||
|
{formatDate(account.last_accessed || account.created)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Balance - right on mobile, top on desktop */}
|
||||||
|
<div className="flex items-center space-x-2 order-2 sm:order-1">
|
||||||
{isPositive ? (
|
{isPositive ? (
|
||||||
<TrendingUp className="h-4 w-4 text-green-500" />
|
<TrendingUp className="h-4 w-4 text-green-500" />
|
||||||
) : (
|
) : (
|
||||||
<TrendingDown className="h-4 w-4 text-red-500" />
|
<TrendingDown className="h-4 w-4 text-red-500" />
|
||||||
)}
|
)}
|
||||||
<p
|
<p
|
||||||
className={`text-lg font-semibold ${
|
className={`text-base sm:text-lg font-semibold ${
|
||||||
isPositive ? "text-green-600" : "text-red-600"
|
isPositive ? "text-green-600" : "text-red-600"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{formatCurrency(balance, currency)}
|
{formatCurrency(balance, currency)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-gray-500">
|
|
||||||
Updated{" "}
|
|
||||||
{formatDate(account.last_accessed || account.created)}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user