Files
property-match/src/components/layout/appShellConfig.ts
T
Benjamin Sutter 36570c5bdc fix: resolve all TypeScript errors and refactor oversized components
- Fix MUI v9 API: PaperProps/InputLabelProps/inputProps → slotProps in 6 components
- Add ExternalMarketResult alias, PropertyUnit import, OPERATIONS workspace config
- Fix TradeOff.description → .concern, ScoreFactor.label → .criterion
- Make schattenmarktRelease.leadTimeMonths optional, fix mock-data enum values
- Fix useMatchDetailData query typing, weightingService missing WeightProfile keys
- Split Pipeline/Compare/MatchDetail/IntelligenceMatchCard into sub-components
- Fix all test fixtures (CreateNeedInput, CreatePropertyInput, TradeOffInput, etc.)
- Add vercel.json for deployment, zero tsc errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 00:08:35 +02:00

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: '#1e3a5f',
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)
}