Files
property-match/src/App.tsx
T
Benjamin Sutter d902feb6c0 feat: Objekt→Einheit architecture — unit-level pre-market, property detail page, click-through from cards
- Domain: PropertyUnit extended with propertyId + schattenmarktRelease per unit
- Domain: FutureAvailabilityResult carries resolved property + unit
- useSchattenmarktSignals: generates unit-level signals (schattenmarkt-{propId}-{unitId})
- useUnifiedResults: resolves backing property + unit on FUTURE_AVAILABILITY fast path
- IUnitProvider + MockupUnitProvider: first-class unit access and mutation
- matchCardAdapter: maps preMarketUnit, preMarketAllUnits, propertyId, unitId to ViewModel
- IntelligenceMatchCard: PRE-MARKET VERIFIED shows unit info strip + "Zur Einheit →" button
- PropertyDetailView: unit-level toggles + date pickers inside PreMarketPanel
- New page: /demand/property/:propertyId with unit table, status chips, inquiry form
- App.tsx: demand route /demand/property/:propertyId registered
- Mock data: prop-001/007/037 units updated with correct lease dates + unit-level schattenmarktRelease

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 19:47:59 +02:00

90 lines
4.0 KiB
TypeScript

import { lazy, Suspense } from 'react'
import { Routes, Route, Navigate } from 'react-router'
import { LoadingPage, AppErrorBoundary } from './components/ui'
import { AppShell } from './components/layout'
import { ProtectedRoute } from './components/auth'
import { WorkspaceType } from './domain/enums'
import { useSessionStore } from './stores/sessionStore'
const WORKSPACE_HOME: Record<string, string> = {
[WorkspaceType.SUPPLY]: '/supply/dashboard',
[WorkspaceType.DEMAND]: '/demand/ai-search',
}
function RoleRedirect() {
const { currentUser } = useSessionStore()
const first = currentUser?.allowedWorkspaces[0] ?? WorkspaceType.SUPPLY
return <Navigate to={WORKSPACE_HOME[first] ?? '/supply/dashboard'} replace />
}
const LoginScreen = lazy(() => import('./pages/auth/LoginScreen'))
const SupplyDashboard = lazy(() => import('./pages/supply/SupplyDashboard'))
const Properties = lazy(() => import('./pages/supply/Properties'))
const MatchCenter = lazy(() => import('./pages/supply/MatchCenter'))
const Anfragencenter = lazy(() => import('./pages/supply/Anfragencenter'))
const FutureAvailability = lazy(() => import('./pages/supply/FutureAvailability'))
const DataQuality = lazy(() => import('./pages/supply/DataQuality'))
const ReminderManager = lazy(() => import('./pages/supply/ReminderManager'))
const MarketLeads = lazy(() => import('./pages/supply/MarketLeads'))
const AISearch = lazy(() => import('./pages/demand/AISearch'))
const Results = lazy(() => import('./pages/demand/Results'))
const MatchDetail = lazy(() => import('./pages/demand/MatchDetail'))
const Compare = lazy(() => import('./pages/demand/Compare'))
const Shortlists = lazy(() => import('./pages/demand/Shortlists'))
const Pipeline = lazy(() => import('./pages/demand/Pipeline'))
const PropertyDetail = lazy(() => import('./pages/demand/PropertyDetail'))
const MarketIntelligence = lazy(() => import('./pages/ops/MarketIntelligence'))
function App() {
return (
<AppErrorBoundary>
<Suspense fallback={<LoadingPage />}>
<Routes>
{/* Public */}
<Route path="/auth/login" element={<LoginScreen />} />
{/* Protected: auth check only */}
<Route element={<ProtectedRoute />}>
<Route element={<AppShell />}>
<Route path="/" element={<RoleRedirect />} />
{/* Supply Workspace */}
<Route element={<ProtectedRoute workspace={WorkspaceType.SUPPLY} />}>
<Route path="/supply/dashboard" element={<SupplyDashboard />} />
<Route path="/supply/properties" element={<Properties />} />
<Route path="/supply/match-center" element={<MatchCenter />} />
<Route path="/supply/anfragen" element={<Anfragencenter />} />
<Route path="/supply/future-availability" element={<FutureAvailability />} />
<Route path="/supply/data-quality" element={<DataQuality />} />
<Route path="/supply/reminder-manager" element={<ReminderManager />} />
<Route path="/supply/market-leads" element={<MarketLeads />} />
<Route path="/supply/market-intelligence" element={<MarketIntelligence />} />
</Route>
{/* Demand Workspace */}
<Route element={<ProtectedRoute workspace={WorkspaceType.DEMAND} />}>
<Route path="/demand/ai-search" element={<AISearch />} />
<Route path="/demand/results" element={<Results />} />
<Route path="/demand/results/:matchId" element={<MatchDetail />} />
<Route path="/demand/compare" element={<Compare />} />
<Route path="/demand/shortlists" element={<Shortlists />} />
<Route path="/demand/pipeline" element={<Pipeline />} />
<Route path="/demand/property/:propertyId" element={<PropertyDetail />} />
</Route>
</Route>
</Route>
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Suspense>
</AppErrorBoundary>
)
}
export default App