e36c5bc979
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>
45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
import { Alert, Box, CircularProgress, Typography } from '@mui/material'
|
|
import { useNavigate } from 'react-router'
|
|
import { useNeedMatchesForProperty } from '../../hooks/useMatches'
|
|
import { useOfferWizardStore } from '../../stores/offerWizardStore'
|
|
import { NeedMatchCard } from './NeedMatchCard'
|
|
|
|
export function MatchabilityTabPanel({ propertyId }: { propertyId: string }) {
|
|
const navigate = useNavigate()
|
|
const setSelectedProperties = useOfferWizardStore(s => s.setSelectedProperties)
|
|
const { data: matches = [], isLoading: loading } = useNeedMatchesForProperty(propertyId, { minScore: 80 })
|
|
|
|
function handleNeedCardClick() {
|
|
setSelectedProperties([propertyId])
|
|
navigate('/supply/anfragen', { state: { tab: 1 } })
|
|
}
|
|
|
|
if (loading) {
|
|
return (
|
|
<Box sx={{ p: 3, display: 'flex', justifyContent: 'center' }}>
|
|
<CircularProgress size={24} />
|
|
</Box>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Box sx={{ p: 2.5 }}>
|
|
<Box sx={{ mb: 2 }}>
|
|
<Typography variant="subtitle2" sx={{ fontWeight: 700, color: '#0f172a' }}>
|
|
Matchability
|
|
</Typography>
|
|
<Typography variant="caption" color="text.secondary">
|
|
Bedarfsprofile mit ≥ 80% Match-Score — Karte klicken um Angebot zu erstellen
|
|
</Typography>
|
|
</Box>
|
|
{matches.length === 0 ? (
|
|
<Alert severity="info" sx={{ fontSize: '0.8125rem' }}>
|
|
Keine Bedarfsprofile mit ≥ 80% Match-Score für dieses Objekt gefunden.
|
|
</Alert>
|
|
) : (
|
|
matches.map(m => <NeedMatchCard key={m.matchId} match={m} onClick={handleNeedCardClick} />)
|
|
)}
|
|
</Box>
|
|
)
|
|
}
|