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.
48 lines
2.3 KiB
TypeScript
48 lines
2.3 KiB
TypeScript
import React, { useState } from 'react';
|
|
import type { Evidence } from '../types';
|
|
|
|
interface EvidencePopoverProps {
|
|
evidence: Evidence[];
|
|
}
|
|
|
|
const EvidencePopover: React.FC<EvidencePopoverProps> = ({ evidence }) => {
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
if (!evidence || evidence.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div className="relative inline-block ml-2">
|
|
<button
|
|
onClick={(e) => { e.stopPropagation(); setIsOpen(!isOpen); }}
|
|
onBlur={() => setIsOpen(false)}
|
|
className="text-blue-500 dark:text-blue-400 hover:text-blue-600 dark:hover:text-blue-300 focus:outline-none"
|
|
title="Show evidence"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
|
|
<path fillRule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z" clipRule="evenodd" />
|
|
</svg>
|
|
</button>
|
|
{isOpen && (
|
|
<div
|
|
onMouseDown={(e) => e.stopPropagation()} // Prevents onBlur from closing popover when clicking inside
|
|
className="absolute z-20 w-80 -right-2 mt-2 bg-light-secondary dark:bg-brand-secondary border border-light-accent dark:border-brand-accent rounded-lg shadow-xl p-3 text-sm">
|
|
<h5 className="font-bold mb-2 text-light-text dark:text-white">Evidence</h5>
|
|
<div className="space-y-2 max-h-60 overflow-y-auto">
|
|
{evidence.map((e, index) => (
|
|
<div key={index} className="border-t border-light-accent dark:border-brand-accent pt-2">
|
|
<p className="italic text-light-subtle dark:text-brand-light">"{e.snippet}"</p>
|
|
<a href={e.url} target="_blank" rel="noopener noreferrer" className="text-blue-500 dark:text-blue-400 hover:underline break-words">
|
|
{e.url}
|
|
</a>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default EvidencePopover; |