Files
Brancheneinstufung2/general-market-intelligence/App.tsx

189 lines
6.5 KiB
TypeScript

import React, { useState, useCallback } from 'react';
import { Header } from './components/Header';
import { StepInput } from './components/StepInput';
import { StepStrategy } from './components/StepStrategy';
import { StepReview } from './components/StepReview';
import { StepProcessing } from './components/StepProcessing';
import { StepReport } from './components/StepReport';
import { StepOutreach } from './components/StepOutreach';
import { AppStep, Competitor, AnalysisResult, AnalysisState, Language, SearchStrategy } from './types';
import { identifyCompetitors, analyzeCompanyWithStrategy, generateSearchStrategy } from './services/geminiService';
const generateId = () => Math.random().toString(36).substr(2, 9);
const App: React.FC = () => {
const [step, setStep] = useState<AppStep>(AppStep.INPUT);
const [isLoading, setIsLoading] = useState(false);
const [language, setLanguage] = useState<Language>('de');
const [referenceUrl, setReferenceUrl] = useState<string>('');
const [targetMarket, setTargetMarket] = useState<string>('');
// Data States
const [strategy, setStrategy] = useState<SearchStrategy | null>(null);
const [competitors, setCompetitors] = useState<Competitor[]>([]);
const [analysisResults, setAnalysisResults] = useState<AnalysisResult[]>([]);
const [processingState, setProcessingState] = useState<AnalysisState>({
currentCompany: '', progress: 0, total: 0, completed: 0
});
const [selectedCompanyForOutreach, setSelectedCompanyForOutreach] = useState<AnalysisResult | null>(null);
const handleBack = () => {
if (step === AppStep.STRATEGY) setStep(AppStep.INPUT);
else if (step === AppStep.REVIEW_LIST) setStep(AppStep.STRATEGY);
else if (step === AppStep.REPORT) setStep(AppStep.REVIEW_LIST);
else if (step === AppStep.OUTREACH) {
setStep(AppStep.REPORT);
setSelectedCompanyForOutreach(null);
}
};
const handleInitialInput = async (url: string, productContext: string, market: string, selectedLang: Language) => {
setIsLoading(true);
setLanguage(selectedLang);
setReferenceUrl(url);
setTargetMarket(market);
try {
// 1. Generate Strategy first
const generatedStrategy = await generateSearchStrategy(url, productContext, selectedLang);
setStrategy(generatedStrategy);
setStep(AppStep.STRATEGY);
} catch (error) {
alert("Failed to generate strategy. Please try again.");
console.error(error);
} finally {
setIsLoading(false);
}
};
const handleLoadReport = (loadedStrategy: SearchStrategy, loadedResults: AnalysisResult[]) => {
setStrategy(loadedStrategy);
setAnalysisResults(loadedResults);
// Reconstruct competitors list from results for consistency if user goes back
const reconstructedCompetitors = loadedResults.map(r => ({
id: generateId(),
name: r.companyName,
dataSource: r.dataSource
}));
setCompetitors(reconstructedCompetitors);
setStep(AppStep.REPORT);
};
const handleStrategyConfirm = async (finalStrategy: SearchStrategy) => {
setStrategy(finalStrategy);
setIsLoading(true);
try {
// 2. Identify Competitors based on Reference
const results = await identifyCompetitors(referenceUrl, targetMarket, language);
const mappedCompetitors: Competitor[] = results.map(c => ({
id: generateId(),
name: c.name || "Unknown",
url: c.url,
description: c.description
}));
setCompetitors(mappedCompetitors);
setStep(AppStep.REVIEW_LIST);
} catch (e) {
alert("Failed to find companies.");
} finally {
setIsLoading(false);
}
};
const handleRemoveCompetitor = (id: string) => {
setCompetitors(prev => prev.filter(c => c.id !== id));
};
const handleAddCompetitor = (name: string) => {
setCompetitors(prev => [...prev, { id: generateId(), name }]);
};
const runAnalysis = useCallback(async () => {
if (!strategy) return;
setStep(AppStep.ANALYSIS);
setAnalysisResults([]);
setProcessingState({ currentCompany: '', progress: 0, total: competitors.length, completed: 0 });
const results: AnalysisResult[] = [];
for (let i = 0; i < competitors.length; i++) {
const comp = competitors[i];
setProcessingState(prev => ({ ...prev, currentCompany: comp.name }));
try {
// 3. Analyze using the specific strategy
const result = await analyzeCompanyWithStrategy(comp.name, strategy, language);
results.push(result);
} catch (e) {
console.error(`Failed to analyze ${comp.name}`);
}
setProcessingState(prev => ({ ...prev, completed: i + 1 }));
}
setAnalysisResults(results);
setStep(AppStep.REPORT);
}, [competitors, language, strategy]);
const handleRestart = () => {
setCompetitors([]);
setAnalysisResults([]);
setStrategy(null);
setStep(AppStep.INPUT);
};
return (
<div className="min-h-screen bg-slate-50 text-slate-900 font-sans">
<Header showBack={step !== AppStep.INPUT && step !== AppStep.ANALYSIS} onBack={handleBack} />
<main>
{step === AppStep.INPUT && (
<StepInput onSearch={handleInitialInput} onLoadReport={handleLoadReport} isLoading={isLoading} />
)}
{step === AppStep.STRATEGY && strategy && (
<StepStrategy strategy={strategy} onConfirm={handleStrategyConfirm} />
)}
{step === AppStep.REVIEW_LIST && (
<StepReview
competitors={competitors}
onAdd={handleAddCompetitor}
onRemove={handleRemoveCompetitor}
onConfirm={runAnalysis}
hasResults={analysisResults.length > 0}
onShowReport={() => setStep(AppStep.REPORT)}
/>
)}
{step === AppStep.ANALYSIS && (
<StepProcessing state={processingState} />
)}
{step === AppStep.REPORT && strategy && (
<StepReport
results={analysisResults}
strategy={strategy}
onRestart={handleRestart}
language={language}
onStartOutreach={(company) => {
setSelectedCompanyForOutreach(company);
setStep(AppStep.OUTREACH);
}}
/>
)}
{step === AppStep.OUTREACH && selectedCompanyForOutreach && (
<StepOutreach
company={selectedCompanyForOutreach}
language={language}
referenceUrl={referenceUrl}
onBack={handleBack}
/>
)}
</main>
</div>
);
};
export default App;