feat: UI polish, lint fixes, onboarding redesign, help page expansion, and test improvements

Broad update across dashboard pages, components, extensions, and lib code. Includes ESLint config additions, onboarding flow redesign, settings page refactor, help page content expansion, dead code removal, and test mock fixes. Adds dev docs and public assets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-03-05 23:05:49 +01:00
co-authored by Claude Opus 4.6
parent 02ebe50f52
commit 091d043c85
106 changed files with 1177 additions and 326 deletions
@@ -10,7 +10,6 @@ import {
type CategorizationSuggestion,
type AccountUsageEntry,
type MerchantHistoryEntry,
type TrackingContext,
} from './categorizer'
import type { BookingTemplate } from '@/lib/bookkeeping/booking-templates'
@@ -198,9 +197,9 @@ async function handleTransactionSynced(
// Helpers
// ============================================================
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function buildEnrichedContext(
userId: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
supabase: any,
transactions: TransactionForCategorization[]
): Promise<EnrichedCategorizationContext> {
+1 -1
View File
@@ -1,6 +1,6 @@
import { NextResponse } from 'next/server'
import type { ApiRouteDefinition, ExtensionContext } from '@/lib/extensions/types'
import { generateChatResponse, streamChatResponse, streamRoutedResponse } from '@/extensions/general/ai-chat/chatbot/chain'
import { generateChatResponse, streamRoutedResponse } from '@/extensions/general/ai-chat/chatbot/chain'
import { CHATBOT_CONFIG } from '@/extensions/general/ai-chat/chatbot/config'
import type { ChatMessage, ChatRequest, SourceReference, ArtifactSpec } from '@/types/chat'
+1 -2
View File
@@ -9,7 +9,6 @@ import {
import {
retrieveRelevantDocuments,
documentsToSources,
type RetrievedDocument,
} from './retriever'
import { routeMessage, type RouteType } from './router'
import { createAccountingTools } from './tools'
@@ -171,7 +170,7 @@ export async function* streamRoutedResponse(
conversationHistory: ChatMessage[],
supabase: SupabaseClient,
userId: string,
sessionId?: string
_sessionId?: string
): AsyncGenerator<RoutedStreamEvent> {
// 1. Route the message
const { route, rewrittenQuery } = await routeMessage(userMessage, conversationHistory)
+1 -1
View File
@@ -65,7 +65,7 @@ export function createAccountingTools(supabase: SupabaseClient, userId: string)
if (date_from) query = query.gte('invoice_date', date_from)
if (date_to) query = query.lte('invoice_date', date_to)
const { data, error, count } = await supabase
const { data: _data, error: _countError, count } = await supabase
.from('invoices')
.select('id', { count: 'exact', head: true })
.eq('user_id', userId)
@@ -144,7 +144,7 @@ function chunkText(text: string, maxSize: number, overlap: number): string[] {
*/
function extractMetadata(
content: string,
sectionTitle: string
_sectionTitle: string
): Record<string, unknown> {
const metadata: Record<string, unknown> = {}
@@ -1,7 +1,7 @@
'use client'
import { cn } from '@/lib/utils'
import { Invoice, Deadline, DeadlineStatus } from '@/types'
import { Invoice, Deadline } from '@/types'
import { isInvoiceOverdue, isSameDay, formatDateISO, STATUS_COLORS } from '@/lib/calendar/utils'
interface CalendarDayCellProps {
@@ -131,7 +131,7 @@ export function CalendarWeekView({
{/* Time grid */}
<div className="max-h-[500px] overflow-y-auto">
{timeSlots.map((time, timeIndex) => (
{timeSlots.map((time, _timeIndex) => (
<div key={time} className="grid grid-cols-[60px_repeat(7,1fr)] border-b last:border-b-0">
<div className="p-2 border-r text-xs text-muted-foreground text-right pr-2">
{time}
@@ -10,7 +10,7 @@ import {
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Invoice, Deadline } from '@/types'
import { formatCurrency, formatDate } from '@/lib/utils'
import { formatCurrency } from '@/lib/utils'
import {
isInvoiceOverdue,
isDeadlineOverdue,
@@ -1,6 +1,6 @@
'use client'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Card, CardContent } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Flame, Receipt, CreditCard, Camera, ArrowRight } from 'lucide-react'
@@ -1,13 +1,13 @@
'use client'
import { useState, useEffect } from 'react'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Card, CardContent } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Skeleton } from '@/components/ui/skeleton'
import { formatCurrency, formatDate } from '@/lib/utils'
import { X, Check, Link2, AlertCircle, Search, Loader2 } from 'lucide-react'
import type { Receipt, ReceiptMatchCandidate, Transaction } from '@/types'
import type { Receipt, ReceiptMatchCandidate } from '@/types'
interface TransactionMatcherProps {
receipt: Receipt
@@ -5,7 +5,7 @@
* using pattern matching and AI-suggested categories.
*/
import type { TransactionCategory, ReceiptLineItem, ExtractedLineItem } from '@/types'
import type { TransactionCategory, ExtractedLineItem } from '@/types'
import { getTemplateById } from '@/lib/bookkeeping/booking-templates'
// Category mappings from suggested category to TransactionCategory
@@ -9,7 +9,7 @@
import 'server-only'
import type { SupabaseClient } from '@supabase/supabase-js'
import type { Receipt, ReceiptMatchCandidate, ReceiptExtractionResult } from '@/types'
import type { Receipt, ReceiptExtractionResult } from '@/types'
import { analyzeReceipt } from './receipt-analyzer'
import { processLineItems, getDefaultClassification } from './receipt-categorizer'
import { autoMatchReceipts } from './receipt-matcher'
@@ -1,7 +1,7 @@
'use client'
import { useState, useEffect, useCallback } from 'react'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Card, CardContent } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Skeleton } from '@/components/ui/skeleton'