refactor(arch): eliminate direct service calls in components — route all through hooks

New hook files:
- useAuth.ts: useLogin, useSwitchDemoRole, useSwitchOrganization
- useAI.ts: useParseNeed, useGenerateOfferEmail, useGenerateDecisionBrief, useParseListingText
- useAssistant.ts: useAssistantSuggestions (useQuery), useAssistantAnswer (useMutation)
- useOfferReport.ts: useOfferReportByInquiry, useCreateOfferReport, useUpdateOfferReport, useGenerateOfferReportPdf
- useInquiryReport.ts: useInquiryReportByInquiry, useCreateInquiryReport, useUpdateInquiryReport, useFinalizeInquiryReport
- useMarketReport.ts: useMarketReport
- useWeighting.ts: useDefaultWeights (synchronous wrapper)
- useUnitMatches.ts: useUnitMatchesMap, useUnitBundle, useBundleMatches (useMemo wrappers)

Extended hooks: useProperties (add update/create/remove mutations),
useNeeds (add useCreateNeed), useMatches (add useNeedMatchesForProperty,
useAdditionalMatchesForInquiry), useReviewQueue (add useCreateReviewTask)

Updated 21 components/pages: all direct service imports replaced with hooks.
Deliberate exception: getRecommendedActions in DataQuality.tsx (pure sync utility, no provider access).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-24 14:56:32 +02:00
parent f487435a94
commit e36c5bc979
33 changed files with 666 additions and 407 deletions
@@ -1,8 +1,8 @@
import { useEffect, useState } from 'react'
import { useState } from 'react'
import { Alert, Box, Button, Chip, CircularProgress, Typography } from '@mui/material'
import { BarChart2, Building2, FileText, Lightbulb, TrendingUp } from 'lucide-react'
import { marketReportService } from '../../services/marketReportService'
import type { MarketReport, SignalCategory } from '../../domain/marketReport'
import { useMarketReport } from '../../hooks/useMarketReport'
import type { SignalCategory } from '../../domain/marketReport'
import { SignalCard } from './SignalCard'
import { BerichtDialog } from './BerichtDialog'
@@ -18,19 +18,9 @@ const SECTION_CONFIG: { category: SignalCategory; label: string; icon: React.Rea
]
export function PropertyMarketSignalsTab({ propertyId }: Props) {
const [report, setReport] = useState<MarketReport | null>(null)
const [loading, setLoading] = useState(true)
const { data: report = null, isLoading: loading } = useMarketReport(propertyId)
const [dialogOpen, setDialogOpen] = useState(false)
useEffect(() => {
let cancelled = false
setLoading(true)
marketReportService.getByProperty(propertyId).then(r => {
if (!cancelled) { setReport(r); setLoading(false) }
})
return () => { cancelled = true }
}, [propertyId])
if (loading) {
return (
<Box sx={{ p: 3, display: 'flex', justifyContent: 'center' }}>