diff --git a/app/(dashboard)/invoices/[id]/page.tsx b/app/(dashboard)/invoices/[id]/page.tsx index 92d814c2..3d63d039 100644 --- a/app/(dashboard)/invoices/[id]/page.tsx +++ b/app/(dashboard)/invoices/[id]/page.tsx @@ -29,6 +29,7 @@ import { Bell, AlertTriangle, MessageSquare, + Trash2, } from 'lucide-react' import type { Invoice, InvoiceItem, Customer, InvoiceStatus, InvoiceReminder, InvoiceDocumentType } from '@/types' @@ -875,12 +876,12 @@ export default function InvoiceDetailPage({ params }: { params: Promise<{ id: st )} )} diff --git a/app/(dashboard)/invoices/new/page.tsx b/app/(dashboard)/invoices/new/page.tsx index 943af255..061f7764 100644 --- a/app/(dashboard)/invoices/new/page.tsx +++ b/app/(dashboard)/invoices/new/page.tsx @@ -49,7 +49,7 @@ const schema = z.object({ type FormData = z.infer const currencies: Currency[] = ['SEK', 'EUR', 'USD', 'GBP', 'NOK', 'DKK'] -const units = ['st', 'tim', 'dag', 'mån', 'km', 'kg'] +const units = ['st', 'tim', 'dag', 'månad', 'km', 'kg'] export default function NewInvoicePage() { const router = useRouter() diff --git a/app/(dashboard)/suppliers/[id]/page.tsx b/app/(dashboard)/suppliers/[id]/page.tsx index d28774d9..030fb7a1 100644 --- a/app/(dashboard)/suppliers/[id]/page.tsx +++ b/app/(dashboard)/suppliers/[id]/page.tsx @@ -68,7 +68,8 @@ export default function SupplierDetailPage() { }) const result = await res.json() if (!res.ok) { - toast({ title: 'Fel', description: result.error, variant: 'destructive' }) + const fieldErrors = result.errors?.map((e: { field: string; message: string }) => `${e.field}: ${e.message}`).join(', ') + toast({ title: 'Fel', description: fieldErrors || result.error || 'Kunde inte uppdatera leverantör', variant: 'destructive' }) } else { toast({ title: 'Sparat', description: 'Leverantören har uppdaterats' }) setSupplier({ ...result.data, stats: supplier?.stats }) diff --git a/app/(dashboard)/suppliers/page.tsx b/app/(dashboard)/suppliers/page.tsx index 93ef9d39..1012c11f 100644 --- a/app/(dashboard)/suppliers/page.tsx +++ b/app/(dashboard)/suppliers/page.tsx @@ -69,9 +69,10 @@ export default function SuppliersPage() { const result = await response.json() if (!response.ok) { + const fieldErrors = result.errors?.map((e: { field: string; message: string }) => `${e.field}: ${e.message}`).join(', ') toast({ title: 'Fel', - description: result.error || 'Kunde inte skapa leverantör', + description: fieldErrors || result.error || 'Kunde inte skapa leverantör', variant: 'destructive', }) } else { diff --git a/components/dashboard/DashboardNav.tsx b/components/dashboard/DashboardNav.tsx index 2b16da18..ca147a84 100644 --- a/components/dashboard/DashboardNav.tsx +++ b/components/dashboard/DashboardNav.tsx @@ -42,6 +42,7 @@ interface NavItem { icon: typeof LayoutDashboard group: string modes?: EntityType[] // If set, only visible for these entity types. If not set, visible to all. + hidden?: boolean // Temporarily hide from sidebar } // All nav items for sidebar and mobile drawer @@ -50,8 +51,9 @@ const navItems: NavItem[] = [ { href: '/deadlines', label: 'Deadlines', icon: Calendar, group: 'main' }, { href: '/invoices', label: 'Fakturor', icon: Receipt, group: 'finans' }, { href: '/customers', label: 'Kunder', icon: Users, group: 'finans' }, - { href: '/suppliers', label: 'Leverantörer', icon: Building2, group: 'finans' }, - { href: '/supplier-invoices', label: 'Leverantörsfakturor', icon: FileInput, group: 'finans' }, + // Temporarily hidden pending module rework (see feedback #49) + { href: '/suppliers', label: 'Leverantörer', icon: Building2, group: 'finans', hidden: true }, + { href: '/supplier-invoices', label: 'Leverantörsfakturor', icon: FileInput, group: 'finans', hidden: true }, { href: '/transactions', label: 'Transaktioner', icon: ArrowLeftRight, group: 'finans' }, { href: '/bookkeeping', label: 'Bokföring', icon: BookOpen, group: 'finans' }, { href: '/reports', label: 'Rapporter', icon: BarChart3, group: 'finans' }, @@ -131,9 +133,9 @@ export default function DashboardNav({ companyName, entityType, enabledExtension const closeMobileMenu = () => setIsMobileMenuOpen(false) - // Filter nav items by entity type + // Filter nav items by entity type and hidden flag const filteredItems = navItems.filter(item => - !item.modes || item.modes.includes(entityType) + !item.hidden && (!item.modes || item.modes.includes(entityType)) ) const mainItems = filteredItems.filter(i => i.group === 'main') diff --git a/extensions.config.json b/extensions.config.json index 0a36cc74..c61a9d8d 100644 --- a/extensions.config.json +++ b/extensions.config.json @@ -1 +1 @@ -{"$schema":"./extensions.schema.json","extensions":["enable-banking","ai-categorization","ai-chat"]} +{"$schema":"./extensions.schema.json","extensions":["enable-banking","ai-categorization","ai-chat","email"]} diff --git a/extensions/general/ai-categorization/categorizer.ts b/extensions/general/ai-categorization/categorizer.ts index 3af9f60f..1253bec7 100644 --- a/extensions/general/ai-categorization/categorizer.ts +++ b/extensions/general/ai-categorization/categorizer.ts @@ -110,6 +110,8 @@ function getCategoryAccountMap(entityType: EntityType): Record 0 diff --git a/extensions/general/ai-categorization/lib/description-analyzer.ts b/extensions/general/ai-categorization/lib/description-analyzer.ts index 2df7c254..ec33878a 100644 --- a/extensions/general/ai-categorization/lib/description-analyzer.ts +++ b/extensions/general/ai-categorization/lib/description-analyzer.ts @@ -106,7 +106,8 @@ VANLIGA BAS-KONTON: Utgifter: 5010 Lokalhyra | 5410 Forbrukningsinventarier | 5420 Programvara | 5460 Forbrukningsvaror | 5611 Bil/drivmedel | 5800 Resekostnader | 5910 Annonsering | 6071 Representation mat | 6200 Telefon/internet | 6530 Redovisning/konsult | 6570 Bankavgifter | 6991 Ovriga kostnader | ${entityType === 'aktiebolag' ? '7610' : '6991'} Utbildning Intakter: 3001 Forsaljning 25% | 3002 Forsaljning 12% | 3003 Forsaljning 6% | 3305 Export | 3308 EU-tjanster | 3900 Ovriga intakter Moms: 2611 Utg moms 25% | 2621 Utg moms 12% | 2631 Utg moms 6% | 2641 Ing moms | 2645 Beraknad ing moms -Ovrigt: 1510 Kundfordringar | 1930 Foretagskonto | 2440 Leverantorsskulder | ${privateAccount} Privat +Skulder: 2350 Skulder till kreditinstitut (banklan, Almi) | 2440 Leverantorsskulder (ENBART for leverantorsfakturor) +Ovrigt: 1510 Kundfordringar | 1930 Foretagskonto | 8410 Rantekostnader | ${privateAccount} Privat MOMSREGLER: - standard_25: Normala varor/tjanster (25%) diff --git a/lib/extensions/_generated/enabled-extensions.ts b/lib/extensions/_generated/enabled-extensions.ts index 00d6eabe..5aa8e317 100644 --- a/lib/extensions/_generated/enabled-extensions.ts +++ b/lib/extensions/_generated/enabled-extensions.ts @@ -4,4 +4,5 @@ export const ENABLED_EXTENSION_IDS: ReadonlySet = new Set([ 'enable-banking', 'ai-categorization', 'ai-chat', + 'email', ]) diff --git a/lib/extensions/_generated/extension-list.ts b/lib/extensions/_generated/extension-list.ts index 8242f2d0..eeb40d7e 100644 --- a/lib/extensions/_generated/extension-list.ts +++ b/lib/extensions/_generated/extension-list.ts @@ -3,9 +3,11 @@ import type { Extension } from '../types' import { enableBankingExtension } from '@/extensions/general/enable-banking' import { aiCategorizationExtension } from '@/extensions/general/ai-categorization' import { aiChatExtension } from '@/extensions/general/ai-chat' +import { emailExtension } from '@/extensions/general/email' export const FIRST_PARTY_EXTENSIONS: Extension[] = [ enableBankingExtension, aiCategorizationExtension, aiChatExtension, + emailExtension, ] diff --git a/lib/extensions/_generated/sector-definitions.ts b/lib/extensions/_generated/sector-definitions.ts index df688fef..bb8affc4 100644 --- a/lib/extensions/_generated/sector-definitions.ts +++ b/lib/extensions/_generated/sector-definitions.ts @@ -57,5 +57,20 @@ export const EXTENSION_DEFINITIONS: Record = { "event": "open-ai-chat" } }, + { + "slug": "email", + "name": "E-post (Resend)", + "sector": "general", + "category": "operations", + "icon": "Mail", + "dataPattern": "core", + "description": "Skicka fakturor och påminnelser via e-post", + "longDescription": "Aktiverar e-postfunktioner: skicka fakturor till kunder, automatiska betalningspåminnelser (15/30/45 dagar), och e-postmeddelanden. Kräver ett Resend-konto med verifierad domän.", + "readsCoreTables": [ + "invoices", + "customers", + "company_settings" + ] + }, ], }