fix(dashboard): offer bank connection in the all-clear Att gora state (#2049)

* fix(dashboard): offer bank connection in the all-clear Att gora state

When the Att gora worklist is all-clear but the company has no active
bank connection, the plain "Allt klart!" praised silence that was really
a setup gap: nothing flows in automatically. The empty state now says so
and offers "Anslut bank" linking to /settings/banking. Fetch errors
degrade to the ordinary all-clear copy, mirroring the emptyLedger rule.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oUS7VoKWMj3jqQmdnop6R

* fix(dashboard): reword no-bank hint so it holds for automatic non-bank feeds

Skeptic finding: a company on the Stripe transaction feed (nightly cron
into transactions) with no PSD2 connection would read "inga nya
transaktioner kommer in automatiskt" as a false statement. Reworded to
an invitation that is true for every cohort.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oUS7VoKWMj3jqQmdnop6R

* fix(dashboard): scope the no-bank hint to bank transactions

CodeRabbit: "nya transaktioner" could still read as covering non-bank
feeds; say "banktransaktioner" / "bank transactions".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oUS7VoKWMj3jqQmdnop6R

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Mattsson
2026-08-31 00:10:28 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 516e8b62ff
commit dd8c06a8fa
4 changed files with 32 additions and 2 deletions
+7 -1
View File
@@ -190,7 +190,7 @@ export async function HemPanesSection({
// the worklist count is the list's length (it used to scan the same rows
// twice). Everything else runs in the same wave.
const suggestedMatchesPromise = listSuggestedMatches(supabase, companyId, SUGGESTED_MATCH_SCAN_CAP)
const [worklist, suggestedMatches, resumeItems, { data: bankConnections }, postedEntries] =
const [worklist, suggestedMatches, resumeItems, bankConnectionsRes, postedEntries] =
await Promise.all([
// Pending-work counts come from lib/worklist: the same source as the
// sidebar badges, so the numbers can never diverge.
@@ -210,6 +210,11 @@ export async function HemPanesSection({
// bookkeeping that its ledger is blank, so errors degrade to the normal copy.
const emptyLedger = setupOpen && !postedEntries.error && (postedEntries.count || 0) === 0
const bankConnections = bankConnectionsRes.data
// Same degrade-on-error rule as emptyLedger: a failed fetch must NOT tell a
// connected company that no bank is connected, so errors read as connected.
const hasActiveBankConnection = !!bankConnectionsRes.error || (bankConnections ?? []).length > 0
// Same day-math as the bank_connection_expiring notice predicate
// (lib/notices/categories.ts): the Bevaka row and the notice can never
// disagree on the threshold.
@@ -225,6 +230,7 @@ export async function HemPanesSection({
suggestedMatches={suggestedMatches.slice(0, 5)}
expiringBankConnections={expiringBankConnections}
emptyLedger={emptyLedger}
hasActiveBankConnection={hasActiveBankConnection}
/>
<ResumePane items={resumeItems} />
</div>
+19 -1
View File
@@ -60,6 +60,14 @@ interface AttGoraSectionProps {
* state then says "nothing here yet" instead of a false "all caught up".
*/
emptyLedger?: boolean
/**
* False when the company has no active bank connection. The all-clear state
* then explains that nothing flows in automatically and offers "Anslut bank"
* instead of a bare "all caught up": for a disconnected company the silence
* is a setup gap, not an achievement. Defaults to true so a fetch error
* degrades to the ordinary all-clear copy, never to a wrong nag.
*/
hasActiveBankConnection?: boolean
}
interface WorklistRowProps {
@@ -108,6 +116,7 @@ export default function AttGoraSection({
suggestedMatches,
expiringBankConnections = [],
emptyLedger = false,
hasActiveBankConnection = true,
}: AttGoraSectionProps) {
const t = useTranslations('dashboard')
const { toast } = useToast()
@@ -237,13 +246,22 @@ export default function AttGoraSection({
description={t('att_gora_new_body')}
className="py-10"
/>
) : (
) : hasActiveBankConnection ? (
<EmptyState
icon={CheckCircle2}
title={t('att_gora_empty_title')}
description={t('att_gora_empty_body')}
className="py-10"
/>
) : (
<EmptyState
icon={Landmark}
title={t('att_gora_no_bank_title')}
description={t('att_gora_no_bank_body')}
actionLabel={t('att_gora_no_bank_action')}
actionHref="/settings/banking"
className="py-10"
/>
)
) : (
<div className="pb-2">
+3
View File
@@ -6927,6 +6927,9 @@
"att_gora_empty_title": "All caught up!",
"att_gora_empty_body": "No transactions to record and no documents to handle.",
"att_gora_new_status": "Nothing here yet",
"att_gora_no_bank_title": "All clear for now",
"att_gora_no_bank_body": "No bank is connected. Connect your bank to fetch bank transactions automatically.",
"att_gora_no_bank_action": "Connect bank",
"att_gora_new_title": "Your books are empty so far",
"att_gora_new_body": "The get-started steps above will fill them: your history, the bank and the receipts.",
"band_bokfor": "Record",
+3
View File
@@ -6927,6 +6927,9 @@
"att_gora_empty_title": "Allt klart!",
"att_gora_empty_body": "Inga transaktioner att bokföra och inga underlag att hantera.",
"att_gora_new_status": "Inget här än",
"att_gora_no_bank_title": "Allt klart just nu",
"att_gora_no_bank_body": "Ingen bank är ansluten. Anslut din bank så hämtas banktransaktioner automatiskt.",
"att_gora_no_bank_action": "Anslut bank",
"att_gora_new_title": "Bokföringen är tom än så länge",
"att_gora_new_body": "Kom igång-stegen ovan fyller den: historiken, banken och kvittona.",
"band_bokfor": "Bokför",