diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx
index 8eb8296..482d286 100644
--- a/src/pages/DashboardPage.tsx
+++ b/src/pages/DashboardPage.tsx
@@ -9,6 +9,7 @@ import { CategoryBreakdownChart, FixedVariableSplit } from "@/components/charts/
import { amountClass, formatAmount, formatDate, pct } from "@/lib/format";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import type { Id } from "../../convex/_generated/dataModel";
+import { AccountBalanceStrip } from "@/components/accounts/AccountBalanceStrip";
function KpiCard({ title, value, className }: { title: string; value: string; className?: string }) {
return (
@@ -43,12 +44,14 @@ export function DashboardPage() {
return (
+
+
-
+
{
@@ -195,6 +204,7 @@ export function SavingsChatPage() {
const [draft, setDraft] = useState("");
const [selectedSessionId, setSelectedSessionId] = useState | undefined>();
const [isSubmitting, setIsSubmitting] = useState(false);
+ const [applyingPlanId, setApplyingPlanId] = useState();
const [legacyImportResult, setLegacyImportResult] = useState<{
key: string;
importedCount: number;
@@ -250,9 +260,15 @@ export function SavingsChatPage() {
basis: monthBasis,
});
const currentUser = useQuery(api.users.currentUser);
+ const pendingActionPlans = useQuery(
+ api.savingsChatActionPlans.listPendingActionPlans,
+ activeSessionId ? { sessionId: activeSessionId } : "skip",
+ );
const createSession = useMutation(api.savingsChatHistory.createSession);
const deleteSession = useMutation(api.savingsChatHistory.deleteSession);
const importLocalSession = useMutation(api.savingsChatHistory.importLocalSession);
+ const applyActionPlan = useMutation(api.savingsChatActionPlans.applyActionPlan);
+ const dismissActionPlan = useMutation(api.savingsChatActionPlans.dismissActionPlan);
const sendMessage = useAction(api.savingsChat.sendMessage);
const importMarkerKey = currentUser ? `${IMPORTED_KEY}:${currentUser._id}` : undefined;
const legacyImportComplete = Boolean(
@@ -373,6 +389,33 @@ export function SavingsChatPage() {
})),
[sessions],
);
+ const actionPlans = (pendingActionPlans ?? []) as AgentActionPlan[];
+
+ const applyPlan = (planId: string) => {
+ setApplyingPlanId(planId);
+ void applyActionPlan({ planId: planId as Id<"agentActionPlans"> })
+ .then((result) => {
+ toast.success(result.summary);
+ })
+ .catch((error) => {
+ console.error(error);
+ toast.error(error instanceof Error ? error.message : "Vorschlag konnte nicht angewendet werden.");
+ })
+ .finally(() => setApplyingPlanId(undefined));
+ };
+
+ const dismissPlan = (planId: string) => {
+ setApplyingPlanId(planId);
+ void dismissActionPlan({ planId: planId as Id<"agentActionPlans"> })
+ .then(() => {
+ toast.message("Vorschlag verworfen");
+ })
+ .catch((error) => {
+ console.error(error);
+ toast.error(error instanceof Error ? error.message : "Vorschlag konnte nicht verworfen werden.");
+ })
+ .finally(() => setApplyingPlanId(undefined));
+ };
const submit = async (event: FormEvent) => {
event.preventDefault();
@@ -390,6 +433,7 @@ export function SavingsChatPage() {
to,
accountId,
basis: monthBasis,
+ today: localDateKey(),
});
} catch (error) {
console.error(error);
@@ -436,6 +480,13 @@ export function SavingsChatPage() {
scrollRef={listRef}
/>
+
+
[balance.accountId, balance]) ?? [],
+ );
return (
@@ -58,33 +66,53 @@ export function SettingsPage() {
Konten
- {accounts?.map((account) => (
-
-
-
{account.name}
-
- {account.type} · {account.iban ?? "keine IBAN"}
- {account.externalId && " · comdirect verbunden"}
+ {accounts?.map((account) => {
+ const liveBalance = balanceByAccountId.get(account._id);
+ return (
+
+
+
{account.name}
+
+ {account.type} · {account.iban ?? "keine IBAN"}
+ {account.externalId && " · Bank verbunden"}
+
+ {liveBalance && (
+
+ Aktueller Kontostand:
+ {liveBalance.balance === null ? (
+ Noch nicht abgerufen
+ ) : (
+
+ {formatAmount(liveBalance.balance)}
+
+ )}
+ {liveBalance.status === "error" && (
+
+ {liveBalance.errorMessage ?? "Fehler"}
+
+ )}
+
+ )}
+
+
-
-
-
- ))}
+ );
+ })}