da50f3b5ea
- Design tokens (ds.ts, theme.ts, scoreTheme.ts): new warm palette (#152642 navy, #f9f8f6 warm white, #e8e7e4 borders, #b8975a gold accent), flat score tier badges replacing CSS gradients, Inter + DM Serif Display typography - Card components: white-background cards, DM Serif score numbers, max-2 badge chips with +N overflow tooltip, editorial score badge positioning - Layout shell: gold left-accent nav active state, 64px top bar, outlined workspace chip, DM Serif page titles - Shared atoms: GenericBadge (outlined/solid variants), ResultFilterBar (simplified chip styles), DecisionContextPanel (dot metrics, no left accent) - Global replacement (118 files): #1e3a5f→#152642, #e2e8f0→#e8e7e4, #f4f6f9→#f9f8f6 — all handled via Node.js for proper UTF-8 safety Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
123 lines
3.8 KiB
TypeScript
123 lines
3.8 KiB
TypeScript
import { WorkspaceType } from '../../domain/enums'
|
|
import type { LucideIcon } from 'lucide-react'
|
|
import {
|
|
LayoutDashboard,
|
|
Building2,
|
|
CheckSquare,
|
|
Search,
|
|
List,
|
|
Columns2,
|
|
ClipboardList,
|
|
Radar,
|
|
MessageSquare,
|
|
Kanban,
|
|
BellRing,
|
|
Settings,
|
|
} from 'lucide-react'
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Types
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export interface NavItem {
|
|
path: string
|
|
label: string
|
|
icon: LucideIcon
|
|
}
|
|
|
|
export interface WorkspaceConfig {
|
|
label: string
|
|
abbreviation: string
|
|
icon: LucideIcon
|
|
firstPath: string
|
|
navItems: NavItem[]
|
|
chipColor: string
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Workspace configuration
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const WORKSPACE_CONFIG: Record<WorkspaceType, WorkspaceConfig> = {
|
|
[WorkspaceType.SUPPLY]: {
|
|
label: 'Verwaltung',
|
|
abbreviation: 'VW',
|
|
icon: Building2,
|
|
firstPath: '/supply/dashboard',
|
|
chipColor: '#152642',
|
|
navItems: [
|
|
{ path: '/supply/dashboard', label: 'Übersicht', icon: LayoutDashboard },
|
|
{ path: '/supply/properties', label: 'Meine Objekte', icon: Building2 },
|
|
{ path: '/supply/reminder-manager', label: 'Reminder Manager', icon: BellRing },
|
|
{ path: '/supply/anfragen', label: 'Anfragencenter', icon: MessageSquare },
|
|
{ path: '/supply/data-quality', label: 'Datenpflege', icon: CheckSquare },
|
|
{ path: '/supply/market-intelligence', label: 'Marktchancen', icon: Radar },
|
|
{ path: '/supply/my-listings', label: 'Inserate', icon: ClipboardList },
|
|
],
|
|
},
|
|
[WorkspaceType.DEMAND]: {
|
|
label: 'Suche',
|
|
abbreviation: 'SU',
|
|
icon: Search,
|
|
firstPath: '/demand/ai-search',
|
|
chipColor: '#1a7a4a',
|
|
navItems: [
|
|
{ path: '/demand/ai-search', label: 'Flächensuche', icon: Search },
|
|
{ path: '/demand/results', label: 'Ergebnisse', icon: List },
|
|
{ path: '/demand/compare', label: 'Vergleich', icon: Columns2 },
|
|
{ path: '/demand/pipeline', label: 'Deal Pipeline', icon: Kanban },
|
|
{ path: '/demand/anfragen', label: 'Anfragen', icon: MessageSquare },
|
|
],
|
|
},
|
|
[WorkspaceType.OPERATIONS]: {
|
|
label: 'Operations',
|
|
abbreviation: 'OP',
|
|
icon: Settings,
|
|
firstPath: '/ops/review-queue',
|
|
chipColor: '#6b21a8',
|
|
navItems: [
|
|
{ path: '/ops/review-queue', label: 'Review Queue', icon: CheckSquare },
|
|
{ path: '/ops/audit', label: 'Audit Log', icon: ClipboardList },
|
|
],
|
|
},
|
|
}
|
|
|
|
// Ordered list for rendering workspace tabs
|
|
export const WORKSPACE_ORDER: WorkspaceType[] = [
|
|
WorkspaceType.SUPPLY,
|
|
WorkspaceType.DEMAND,
|
|
]
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Helpers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function getWorkspaceFromPath(pathname: string): WorkspaceType | null {
|
|
if (pathname.startsWith('/supply')) return WorkspaceType.SUPPLY
|
|
if (pathname.startsWith('/demand')) return WorkspaceType.DEMAND
|
|
return null
|
|
}
|
|
|
|
export function getPageNameFromPath(pathname: string): string {
|
|
for (const ws of Object.values(WORKSPACE_CONFIG)) {
|
|
for (const item of ws.navItems) {
|
|
if (item.path === pathname) return item.label
|
|
}
|
|
}
|
|
if (/^\/demand\/results\/.+/.test(pathname)) return 'Match Detail'
|
|
if (/^\/demand\/property\//.test(pathname)) return 'Objekt Detail'
|
|
if (/^\/supply\/properties\/.+/.test(pathname)) return 'Objekt Detail'
|
|
if (pathname === '/demand/anfragen') return 'Anfragen'
|
|
const segment = pathname.split('/').filter(Boolean).pop() ?? ''
|
|
return segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, ' ')
|
|
}
|
|
|
|
export function getUserInitials(name: string): string {
|
|
return name
|
|
.split(' ')
|
|
.map((n) => n[0])
|
|
.join('')
|
|
.toUpperCase()
|
|
.slice(0, 2)
|
|
}
|