feat(ux): company context in settings, Kundfakturor rename, compact verifikat view (#1071)
* feat(ux): company context in settings, Kundfakturor rename, compact verifikat view Support feedback (2026-07-19): active company invisible in settings, menu said Fakturor next to Leverantorsfakturor, no compact verifikat view. - ActiveCompanyBadge chip in the settings modal header and the full-page settings header; the modal covers the sidebar CompanySwitcher - nav + page title Fakturor -> Kundfakturor (sv), Invoices -> Customer invoices (en); command palette gets a Kundfakturor page entry - verifikat list density toggle (comfortable/compact), persisted per company like the existing sort/page-size choices Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: decision log for scoped Kundfakturor rename Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(review): badge hover reveals full company name; pure density state updater Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
ebf69d2933
commit
90e7c7f47f
@@ -0,0 +1,35 @@
|
||||
'use client'
|
||||
|
||||
import { Building2 } from 'lucide-react'
|
||||
import { useTranslations } from 'next-intl'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useCompany } from '@/contexts/CompanyContext'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
|
||||
/**
|
||||
* Quiet chip naming the active company. Settings surfaces (the routed modal
|
||||
* and the full-page fallback) cover or dim the sidebar's CompanySwitcher, so
|
||||
* without this the user edits company-scoped settings with no visible answer
|
||||
* to "which company am I on?" (support feedback 2026-07-19).
|
||||
*/
|
||||
export function ActiveCompanyBadge({ className }: { className?: string }) {
|
||||
const { company } = useCompany()
|
||||
const t = useTranslations('common')
|
||||
|
||||
if (!company) return null
|
||||
|
||||
return (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={cn(
|
||||
'max-w-full min-w-0 gap-1.5 font-normal text-muted-foreground',
|
||||
className,
|
||||
)}
|
||||
title={`${t('active_company')}: ${company.name}`}
|
||||
>
|
||||
<Building2 className="h-3 w-3 shrink-0" aria-hidden="true" />
|
||||
<span className="sr-only">{t('active_company')}: </span>
|
||||
<span className="truncate">{company.name}</span>
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from '@/components/ui/dialog'
|
||||
import { SETTINGS_SECTIONS } from './sections'
|
||||
import { SettingsShell } from './SettingsShell'
|
||||
import { ActiveCompanyBadge } from './ActiveCompanyBadge'
|
||||
|
||||
/**
|
||||
* The settings popup. Rendered only by the intercepting route
|
||||
@@ -52,10 +53,13 @@ export function SettingsModal({ sectionId }: { sectionId?: string }) {
|
||||
<DialogContent
|
||||
className="flex h-[100dvh] max-h-[100dvh] max-w-none flex-col gap-0 overflow-hidden rounded-none p-0 md:h-auto md:max-h-[85dvh] md:max-w-4xl md:rounded-lg"
|
||||
>
|
||||
<div className="flex shrink-0 items-center border-b border-border px-6 py-4">
|
||||
<div className="flex shrink-0 items-center gap-3 border-b border-border px-6 py-4">
|
||||
<DialogTitle className="font-display text-lg tracking-tight">
|
||||
{t('title')}
|
||||
</DialogTitle>
|
||||
{/* The modal covers the sidebar's CompanySwitcher, so the active
|
||||
company must stay visible here (mr-6 clears the close button). */}
|
||||
<ActiveCompanyBadge className="ml-auto mr-6" />
|
||||
</div>
|
||||
<DialogDescription className="sr-only">{t('description')}</DialogDescription>
|
||||
<SettingsShell variant="modal" activeSection={resolved} />
|
||||
|
||||
Reference in New Issue
Block a user