// desktop-screen-dashboard.jsx — Dashboard screen for desktop function DashboardDesktop({ active = 'kauf', onNav = () => {}, onOpenResults = () => {}, onOpenDetail = () => {}, onNewSearch = () => {}, onOpenAdmin = () => {}, ctx = {}, searchQuery = '', topBarProps = {}, } = {}) { const listings = desktopListings(ctx); const searches = desktopSearches(ctx).filter(s => s.category === 'kauf'); const [activeOnly, setActiveOnly] = React.useState(false); const [bestSort, setBestSort] = React.useState('score'); const user = ctx.user || {}; const scoredListings = listings.filter(l => l.aiScore); const avgScore = scoredListings.length ? Math.round(scoredListings.reduce((sum, l) => sum + Number(l.aiScore || 0), 0) / scoredListings.length) : '—'; const recentActivity = desktopNotifications(ctx).slice(0, 4); const today = new Date().toLocaleDateString('de-DE', { day: '2-digit', month: 'long', year: 'numeric' }); const visibleSearches = desktopFilterByQuery(searches, searchQuery).filter(s => !activeOnly || s.active); const firstVisibleSearch = visibleSearches[0] || searches[0]; const bestDeals = desktopFilterByQuery(listings, searchQuery) .filter(l => l.type === 'kauf' && l.aiScore) .sort((a, b) => { if (bestSort === 'price') return Number(a.price || 0) - Number(b.price || 0); if (bestSort === 'newest') return new Date(b.posted || 0) - new Date(a.posted || 0); return Number(b.aiScore || 0) - Number(a.aiScore || 0); }) .slice(0, 5); return (
{user?.isAdmin && } onClick={onOpenAdmin}>Jobs} } onClick={onNewSearch}>Neue Suche } {...topBarProps} />
{/* Stats row */}
s.active).length} icon={} delta={`${searches.length} insgesamt`} /> s+x.matches, 0)} icon={} delta="alle Plattformen" /> s+x.newToday, 0)}`} icon={} delta="seit Mitternacht" trend="up" accent /> } delta={scoredListings.length ? `${scoredListings.length} bewertet` : 'noch keine KI-Werte'} trend={scoredListings.length ? 'up' : null} />
{/* Two-column main grid */}
{/* Active searches table */}

Ihre Kauf-Suchen

{searches.filter(s => s.active).length} aktiv · {searches.length - searches.filter(s => s.active).length} pausiert
} size="sm" onClick={() => setActiveOnly(v => !v)}> {activeOnly ? 'Aktive' : 'Filter'}
Suche Lage & Budget Treffer Neu heute Letzter Lauf
{visibleSearches.map((s, i) => (
onOpenResults(s.id)} style={{ display: 'grid', gridTemplateColumns: '1.6fr 1fr 0.8fr 0.7fr 0.7fr 32px', padding: '14px 20px', alignItems: 'center', gap: 8, borderBottom: i < visibleSearches.length - 1 ? '1px solid var(--border)' : 'none', fontSize: 13, cursor: 'pointer', }}>
{s.name}
{desktopSearchPlatforms(s).map(p => {p === 'immoscout24' ? 'Scout24' : 'Kleinanz.'})} {s.aiEnabled && }>KI}
{s.city} +{s.radius}km
{fmtPriceShort(s.priceMin)}–{fmtPriceShort(s.priceMax)}
{s.matches}
{s.newToday > 0 ? +{s.newToday} : }
{fmtRelative(s.lastRun)}
))} {visibleSearches.length === 0 && (
Keine Kauf-Suchen passen zur aktuellen Suche.
)}
{/* Right column */}
{/* Daily-quota / system */}

System

Tageskontingent · zurückgesetzt 00:00 UTC
}>aktiv
s.active).length} total={ctx.taskLimit?.max_tasks || Math.max(1, searches.length)} color="var(--info)" /> !n.read).length || 0} total={Math.max(1, ctx.notifications?.length || 1)} color="var(--success)" />
{/* Recent activity */}

Letzte Aktivität

{recentActivity.length === 0 ? (
Noch keine Aktivitäten.
) : recentActivity.map((a, i) => (
{a.kind === 'ai-high' ? : a.kind === 'new-match' ? : }
{a.title}
{fmtRelative(a.at)}
))}
{/* Best deals row */}
Kauf } onClick={() => setBestSort(bestSort === 'score' ? 'price' : bestSort === 'price' ? 'newest' : 'score')}> {bestSort === 'score' ? 'Score' : bestSort === 'price' ? 'Preis' : 'Neueste'} firstVisibleSearch && onOpenResults(firstVisibleSearch.id)}>Alle Inserate →
} />
{bestDeals.map(l => ( ))}
); } function Quota({ label, used, total, color }) { const pct = (used / total) * 100; return (
{label} {used.toLocaleString('de-DE')} / {total.toLocaleString('de-DE')}
); } function BestDealCard({ listing, onTap }) { const photos = desktopPhotos(listing); return (
onTap && onTap(listing.id)} style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 12, overflow: 'hidden', cursor: 'pointer', }}>
{fmtPriceShort(listing.price)}
{listing.title}
{listing.district}, {listing.city}
{fmtArea(listing.area)} · {listing.rooms} Zi. · {listing.baujahr}
); } Object.assign(window, { DashboardDesktop });