Resolved multiple issues preventing the 'competitor-analysis' app from running and serving its frontend:
1. **Fixed Python SyntaxError in Prompts:** Corrected unterminated string literals and ensure proper multi-line string formatting (using .format() instead of f-strings for complex prompts) in .
2. **Addressed Python SDK Compatibility (google-generativeai==0.3.0):**
* Removed for and by adapting the orchestrator to pass JSON schemas as direct Python dictionaries, as required by the older SDK version.
* Updated with detailed guidance on handling / imports and dictionary-based schema definitions for older SDKs.
3. **Corrected Frontend Build Dependencies:** Moved critical build dependencies (like , , ) from to in .
* Updated to include this pitfall, ensuring frontend build tools are installed in Docker.
4. **Updated Documentation:**
* : Added comprehensive lessons learned regarding dependencies, Python SDK versioning (specifically and imports for ), and robust multi-line prompt handling.
* : Integrated specific details of the encountered errors and their solutions, making the migration report a more complete historical record and guide.
These changes collectively fix the 404 error by ensuring the Python backend starts correctly and serves the frontend assets after a successful build.
81 lines
4.8 KiB
TypeScript
81 lines
4.8 KiB
TypeScript
import React from 'react';
|
|
import type { ReferenceAnalysis } from '../types';
|
|
|
|
interface Step8ReferencesProps {
|
|
analyses: ReferenceAnalysis[];
|
|
groundingMetadata: any[];
|
|
t: any;
|
|
}
|
|
|
|
const LinkIcon = () => (<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 inline-block ml-1" viewBox="0 0 20 20" fill="currentColor"><path fillRule="evenodd" d="M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z" clipRule="evenodd" /></svg>);
|
|
|
|
|
|
const Step8_References: React.FC<Step8ReferencesProps> = ({ analyses, groundingMetadata, t }) => {
|
|
return (
|
|
<div>
|
|
<h2 className="text-2xl font-bold mb-4">{t.title}</h2>
|
|
<p className="text-light-subtle dark:text-brand-light mb-6">
|
|
{t.subtitle}
|
|
</p>
|
|
|
|
<div className="space-y-6">
|
|
{(analyses || []).map((analysis, index) => {
|
|
// This robust check prevents crashes if `references` is null, undefined, or not an array.
|
|
const hasReferences = Array.isArray(analysis.references) && analysis.references.length > 0;
|
|
|
|
return (
|
|
<div key={index} className="bg-light-secondary dark:bg-brand-secondary p-6 rounded-lg shadow-lg">
|
|
<h3 className="text-xl font-bold text-light-text dark:text-white mb-4">{analysis.competitor_name}</h3>
|
|
|
|
{!hasReferences ? (
|
|
<p className="text-light-subtle dark:text-brand-light">{t.noReferencesFound}</p>
|
|
) : (
|
|
<div className="space-y-4">
|
|
{analysis.references.map((ref, refIndex) => (
|
|
<div key={refIndex} className="bg-light-primary dark:bg-brand-primary p-4 rounded-md border-l-4 border-brand-accent">
|
|
<div className="flex justify-between items-start">
|
|
<div>
|
|
<strong className="text-light-text dark:text-white">{ref.name}</strong>
|
|
{ref.industry && <span className="text-xs ml-2 bg-light-accent dark:bg-brand-accent px-2 py-0.5 rounded-full">{ref.industry}</span>}
|
|
</div>
|
|
{ref.case_study_url && (
|
|
<a href={ref.case_study_url} target="_blank" rel="noopener noreferrer" className="text-sm text-blue-500 dark:text-blue-400 hover:underline flex-shrink-0">
|
|
{t.caseStudyLink} <LinkIcon/>
|
|
</a>
|
|
)}
|
|
</div>
|
|
{ref.testimonial_snippet && (
|
|
<blockquote className="mt-2 text-sm italic text-light-subtle dark:text-brand-light border-l-2 border-gray-400 pl-3">
|
|
"{ref.testimonial_snippet}"
|
|
</blockquote>
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
|
|
{groundingMetadata && groundingMetadata.length > 0 && (
|
|
<div className="mt-8 bg-light-secondary dark:bg-brand-secondary p-6 rounded-lg shadow-lg">
|
|
<h3 className="text-xl font-bold text-light-text dark:text-white mb-4">{t.sourcesTitle}</h3>
|
|
<ul className="list-disc list-inside space-y-2">
|
|
{groundingMetadata
|
|
.filter(chunk => chunk.web && chunk.web.uri)
|
|
.map((chunk, index) => (
|
|
<li key={index} className="text-sm">
|
|
<a href={chunk.web.uri} target="_blank" rel="noopener noreferrer" className="text-blue-500 dark:text-blue-400 hover:underline">
|
|
{chunk.web.title || chunk.web.uri}
|
|
</a>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Step8_References; |