From 39760b20a9eea127a6476de04470702622d4cdc4 Mon Sep 17 00:00:00 2001 From: Timo Uttenweiler Date: Tue, 17 Mar 2026 13:05:14 +0100 Subject: [PATCH] refactor: Entscheider-Kategorie als Einzelauswahl (Radio) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Nur noch eine Kategorie gleichzeitig wählbar (Array → einzelner Wert) - ceo-Label: "CEO / Owner / President / Founder" mit Empfohlen-Badge - API-Aufruf sendet [category] statt categories[] - Überflüssige Validierungen entfernt Co-Authored-By: Claude Sonnet 4.6 --- app/airscale/page.tsx | 40 +++++++++++++++------------------------- app/linkedin/page.tsx | 30 +++++++++++++++--------------- app/maps/page.tsx | 32 ++++++++++++++++---------------- app/serp/page.tsx | 30 +++++++++++++++--------------- 4 files changed, 61 insertions(+), 71 deletions(-) diff --git a/app/airscale/page.tsx b/app/airscale/page.tsx index b4fd15f..3ab900d 100644 --- a/app/airscale/page.tsx +++ b/app/airscale/page.tsx @@ -19,14 +19,12 @@ import { useAppStore } from "@/lib/store"; import type { DecisionMakerCategory } from "@/lib/services/anymailfinder"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; -const DEFAULT_ROLES: DecisionMakerCategory[] = ["ceo"]; - -const CATEGORY_OPTIONS: { value: DecisionMakerCategory; label: string }[] = [ - { value: "ceo", label: "CEO / Inhaber / Gründer" }, - { value: "operations", label: "COO / Geschäftsführung" }, - { value: "engineering", label: "CTO / Technik" }, - { value: "marketing", label: "CMO / Marketing" }, - { value: "finance", label: "CFO / Finanzen" }, +const CATEGORY_OPTIONS: { value: DecisionMakerCategory; label: string; recommended?: boolean }[] = [ + { value: "ceo", label: "CEO / Owner / President / Founder", recommended: true }, + { value: "operations", label: "COO" }, + { value: "engineering", label: "CTO" }, + { value: "marketing", label: "CMO" }, + { value: "finance", label: "CFO" }, { value: "sales", label: "Vertriebsleiter" }, ]; @@ -40,7 +38,7 @@ export default function AirScalePage() { const [headers, setHeaders] = useState([]); const [domainCol, setDomainCol] = useState(""); const [nameCol, setNameCol] = useState(""); - const [categories, setCategories] = useState(DEFAULT_ROLES); + const [category, setCategory] = useState("ceo"); const [jobId, setJobId] = useState(null); const [jobStatus, setJobStatus] = useState("idle"); const [progress, setProgress] = useState({ current: 0, total: 0 }); @@ -70,7 +68,6 @@ export default function AirScalePage() { const startEnrichment = async () => { if (!companies.length) return toast.error("Keine Unternehmen mit Domains gefunden"); - if (!categories.length) return toast.error("Mindestens eine Entscheider-Kategorie auswählen"); setRunning(true); setResults([]); @@ -80,7 +77,7 @@ export default function AirScalePage() { const res = await fetch("/api/jobs/airscale-enrich", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ companies, categories }), + body: JSON.stringify({ companies, categories: [category] }), }); const data = await res.json() as { jobId?: string; error?: string }; if (!res.ok || !data.jobId) throw new Error(data.error || "Failed to start job"); @@ -257,31 +254,24 @@ export default function AirScalePage() {
-
{CATEGORY_OPTIONS.map(opt => ( ))}
-

- Kategorien werden in Prioritätsreihenfolge durchsucht. Die erste Kategorie mit einem gültigen Ergebnis gewinnt. -

@@ -302,7 +292,7 @@ export default function AirScalePage() { ) : ( ))} @@ -382,7 +382,7 @@ export default function LinkedInPage() { {stage === "scraped" && ( ))} @@ -380,7 +380,7 @@ export default function MapsPage() { {stage === "idle" || stage === "failed" ? ( ))} @@ -274,7 +274,7 @@ export default function SerpPage() { {stage === "idle" || stage === "failed" ? (