import { useEffect, useMemo, useState } from 'react' import { Box, Button, CircularProgress, IconButton, Typography, useMediaQuery, useTheme } from '@mui/material' import { ArrowLeft, Plus, Search } from 'lucide-react' import { useNavigate } from 'react-router' import { useNeedProfiles, useArchiveNeed, useUpdateNeed } from '../../hooks/useNeeds' import { useProperties } from '../../hooks/useProperties' import { useMatches } from '../../hooks/useMatches' import { ResultType } from '../../domain/enums' import { ROUTES } from '../../lib/constants' import { EmptyState } from '../ui' import { SavedNeedCard } from './SavedNeedCard' import { SavedNeedDetail } from './SavedNeedDetail' import { needToParsedCriteria } from '../../services/aiSearch/needSearchMapper' interface Props { onNewSearch: (prefillNeedId?: string) => void } export function SavedProfilesTab({ onNewSearch }: Props) { const navigate = useNavigate() const theme = useTheme() const isMobile = useMediaQuery(theme.breakpoints.down('md')) const { data: needs = [], isLoading } = useNeedProfiles() const { data: properties = [] } = useProperties({ resultType: ResultType.VERIFIED_PORTFOLIO }) const { data: allMatches = [] } = useMatches() const archiveMutation = useArchiveNeed() const updateMutation = useUpdateNeed() const [selectedId, setSelectedId] = useState(null) const [mobileView, setMobileView] = useState<'list' | 'detail'>('list') const visible = useMemo( () => needs .filter(n => !n.status || n.status === 'ACTIVE' || n.status === 'DRAFT') .sort((a, b) => { const aActive = !a.status || a.status === 'ACTIVE' const bActive = !b.status || b.status === 'ACTIVE' if (aActive !== bActive) return aActive ? -1 : 1 return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime() }), [needs], ) const { matchCounts, topScores } = useMemo(() => { const counts: Record = {} const tops: Record = {} for (const n of visible) { const needMatches = allMatches.filter(m => m.needId === n.id) const threshold = n.notificationConfig?.minScore ?? 80 counts[n.id] = needMatches.filter(m => m.matchScore >= threshold).length tops[n.id] = needMatches.length > 0 ? Math.round(Math.max(...needMatches.map(m => m.matchScore))) : 0 } return { matchCounts: counts, topScores: tops } }, [visible, allMatches]) useEffect(() => { if (!isMobile && !selectedId && visible.length > 0) setSelectedId(visible[0].id) }, [visible, selectedId, isMobile]) const selectedNeed = visible.find(n => n.id === selectedId) ?? null function handleSelect(id: string) { setSelectedId(id) if (isMobile) setMobileView('detail') } function handleStart(needId: string) { navigate(ROUTES.DEMAND.RESULTS, { state: { fromNeedBuilder: true, activeNeedId: needId } }) } function handleEdit(needId: string) { onNewSearch(needId) } if (isLoading) { return } if (visible.length === 0) { return ( ) } const list = ( Suchprofile {visible.length} {visible.map(n => ( handleSelect(n.id)} /> ))} ) if (isMobile) { if (mobileView === 'detail' && selectedNeed) { return ( setMobileView('list')}> {selectedNeed.companyName} handleStart(selectedNeed.id)} onEdit={() => handleEdit(selectedNeed.id)} onArchive={() => archiveMutation.mutate(selectedNeed.id)} onUpdate={(data) => updateMutation.mutate({ id: selectedNeed.id, ...data })} /> ) } return {list} } return ( {list} {selectedNeed ? ( handleStart(selectedNeed.id)} onEdit={() => handleEdit(selectedNeed.id)} onArchive={() => archiveMutation.mutate(selectedNeed.id)} onUpdate={(data) => updateMutation.mutate({ id: selectedNeed.id, ...data })} /> ) : ( } title="Profil auswählen" description="Wählen Sie ein Suchprofil, um Details zu sehen." /> )} ) }