feat: add external URL support for bank accounts, allowing users to link to their bank's portal

This commit is contained in:
Julien Froidefond
2025-11-27 11:50:09 +01:00
parent b2efade4d5
commit 5eb37e631f
6 changed files with 38 additions and 1 deletions

View File

@@ -36,6 +36,7 @@ import {
Wallet, Wallet,
PiggyBank, PiggyBank,
RefreshCw, RefreshCw,
ExternalLink,
} from "lucide-react"; } from "lucide-react";
import type { Account } from "@/lib/types"; import type { Account } from "@/lib/types";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@@ -55,13 +56,14 @@ const accountTypeLabels = {
}; };
export default function AccountsPage() { export default function AccountsPage() {
const { data, isLoading, refresh, update } = useBankingData(); const { data, isLoading, refresh } = useBankingData();
const [editingAccount, setEditingAccount] = useState<Account | null>(null); const [editingAccount, setEditingAccount] = useState<Account | null>(null);
const [isDialogOpen, setIsDialogOpen] = useState(false); const [isDialogOpen, setIsDialogOpen] = useState(false);
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
name: "", name: "",
type: "CHECKING" as Account["type"], type: "CHECKING" as Account["type"],
folderId: "folder-root", folderId: "folder-root",
externalUrl: "",
}); });
if (isLoading || !data) { if (isLoading || !data) {
@@ -88,6 +90,7 @@ export default function AccountsPage() {
name: account.name, name: account.name,
type: account.type, type: account.type,
folderId: account.folderId || "folder-root", folderId: account.folderId || "folder-root",
externalUrl: account.externalUrl || "",
}); });
setIsDialogOpen(true); setIsDialogOpen(true);
}; };
@@ -101,6 +104,7 @@ export default function AccountsPage() {
name: formData.name, name: formData.name,
type: formData.type, type: formData.type,
folderId: formData.folderId, folderId: formData.folderId,
externalUrl: formData.externalUrl || null,
}; };
await updateAccount(updatedAccount); await updateAccount(updatedAccount);
refresh(); refresh();
@@ -244,6 +248,17 @@ export default function AccountsPage() {
)} )}
</p> </p>
)} )}
{account.externalUrl && (
<a
href={account.externalUrl}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-1 text-xs text-primary hover:underline mt-2"
>
<ExternalLink className="w-3 h-3" />
Accéder au portail banque
</a>
)}
</CardContent> </CardContent>
</Card> </Card>
); );
@@ -306,6 +321,19 @@ export default function AccountsPage() {
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
<div className="space-y-2">
<Label>Lien externe (portail banque)</Label>
<Input
value={formData.externalUrl}
onChange={(e) =>
setFormData({ ...formData, externalUrl: e.target.value })
}
placeholder="https://..."
/>
<p className="text-xs text-muted-foreground">
URL personnalisée vers le portail de votre banque
</p>
</div>
<div className="flex justify-end gap-2"> <div className="flex justify-end gap-2">
<Button variant="outline" onClick={() => setIsDialogOpen(false)}> <Button variant="outline" onClick={() => setIsDialogOpen(false)}>
Annuler Annuler

View File

@@ -123,6 +123,7 @@ export function OFXImportDialog({
balance: parsed.balance, balance: parsed.balance,
currency: parsed.currency, currency: parsed.currency,
lastImport: new Date().toISOString(), lastImport: new Date().toISOString(),
externalUrl: null,
}); });
accountId = newAccount.id; accountId = newAccount.id;
} }
@@ -298,6 +299,7 @@ export function OFXImportDialog({
balance: parsedData.balance, balance: parsedData.balance,
currency: parsedData.currency, currency: parsedData.currency,
lastImport: new Date().toISOString(), lastImport: new Date().toISOString(),
externalUrl: null,
}); });
accountId = newAccount.id; accountId = newAccount.id;
} }

View File

@@ -24,6 +24,7 @@ export interface Account {
balance: number; balance: number;
currency: string; currency: string;
lastImport: string | null; lastImport: string | null;
externalUrl: string | null;
} }
export interface Folder { export interface Folder {

View File

@@ -20,6 +20,7 @@ model Account {
balance Float @default(0) balance Float @default(0)
currency String @default("EUR") currency String @default("EUR")
lastImport String? lastImport String?
externalUrl String? // Custom URL for external bank portal
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt

View File

@@ -13,6 +13,7 @@ export const accountService = {
balance: data.balance, balance: data.balance,
currency: data.currency, currency: data.currency,
lastImport: data.lastImport, lastImport: data.lastImport,
externalUrl: data.externalUrl,
}, },
}); });
@@ -26,6 +27,7 @@ export const accountService = {
balance: created.balance, balance: created.balance,
currency: created.currency, currency: created.currency,
lastImport: created.lastImport, lastImport: created.lastImport,
externalUrl: created.externalUrl,
}; };
}, },
@@ -44,6 +46,7 @@ export const accountService = {
balance: data.balance, balance: data.balance,
currency: data.currency, currency: data.currency,
lastImport: data.lastImport, lastImport: data.lastImport,
externalUrl: data.externalUrl,
}, },
}); });
@@ -57,6 +60,7 @@ export const accountService = {
balance: updated.balance, balance: updated.balance,
currency: updated.currency, currency: updated.currency,
lastImport: updated.lastImport, lastImport: updated.lastImport,
externalUrl: updated.externalUrl,
}; };
}, },

View File

@@ -38,6 +38,7 @@ export const bankingService = {
balance: a.balance, balance: a.balance,
currency: a.currency, currency: a.currency,
lastImport: a.lastImport, lastImport: a.lastImport,
externalUrl: a.externalUrl,
}), }),
), ),
transactions: transactions.map( transactions: transactions.map(