feat: add re-analysis buttons and pass parameters to agent
Browse files
frontend/src/App.tsx
CHANGED
|
@@ -516,7 +516,7 @@ export default function App() {
|
|
| 516 |
};
|
| 517 |
|
| 518 |
// 8. Call QuantIQ AI Analyst Agent
|
| 519 |
-
const triggerAIInsight = async () => {
|
| 520 |
if (!user || (user.credits <= 0 && user.email !== 'karanshelar8775@gmail.com')) {
|
| 521 |
setCurrentView('upgrade');
|
| 522 |
return;
|
|
@@ -528,15 +528,15 @@ export default function App() {
|
|
| 528 |
|
| 529 |
try {
|
| 530 |
const insightData = await graphqlRequest(`
|
| 531 |
-
mutation GetAIInsight($ticker: String!) {
|
| 532 |
-
getAiInsight(ticker: $ticker) {
|
| 533 |
ticker
|
| 534 |
bullishProbability
|
| 535 |
reason
|
| 536 |
creditsRemaining
|
| 537 |
}
|
| 538 |
}
|
| 539 |
-
`, { ticker: activeTicker });
|
| 540 |
|
| 541 |
setInsight(insightData.getAiInsight);
|
| 542 |
setUser({ ...user, credits: insightData.getAiInsight.creditsRemaining });
|
|
@@ -662,6 +662,7 @@ export default function App() {
|
|
| 662 |
onCreateAlert={handleCreateAlert}
|
| 663 |
onDeactivateAlert={handleDeactivateAlert}
|
| 664 |
onTriggerInsight={triggerAIInsight}
|
|
|
|
| 665 |
onOpenRecharge={() => setCurrentView('upgrade')}
|
| 666 |
onLogout={handleLogout}
|
| 667 |
onLogoClick={() => setCurrentView('landing')}
|
|
|
|
| 516 |
};
|
| 517 |
|
| 518 |
// 8. Call QuantIQ AI Analyst Agent
|
| 519 |
+
const triggerAIInsight = async (tradingStyle?: string, riskTolerance?: string) => {
|
| 520 |
if (!user || (user.credits <= 0 && user.email !== 'karanshelar8775@gmail.com')) {
|
| 521 |
setCurrentView('upgrade');
|
| 522 |
return;
|
|
|
|
| 528 |
|
| 529 |
try {
|
| 530 |
const insightData = await graphqlRequest(`
|
| 531 |
+
mutation GetAIInsight($ticker: String!, $tradingStyle: String, $riskTolerance: String) {
|
| 532 |
+
getAiInsight(ticker: $ticker, tradingStyle: $tradingStyle, riskTolerance: $riskTolerance) {
|
| 533 |
ticker
|
| 534 |
bullishProbability
|
| 535 |
reason
|
| 536 |
creditsRemaining
|
| 537 |
}
|
| 538 |
}
|
| 539 |
+
`, { ticker: activeTicker, tradingStyle, riskTolerance });
|
| 540 |
|
| 541 |
setInsight(insightData.getAiInsight);
|
| 542 |
setUser({ ...user, credits: insightData.getAiInsight.creditsRemaining });
|
|
|
|
| 662 |
onCreateAlert={handleCreateAlert}
|
| 663 |
onDeactivateAlert={handleDeactivateAlert}
|
| 664 |
onTriggerInsight={triggerAIInsight}
|
| 665 |
+
onResetInsight={() => { setInsight(null); setInsightError(null); }}
|
| 666 |
onOpenRecharge={() => setCurrentView('upgrade')}
|
| 667 |
onLogout={handleLogout}
|
| 668 |
onLogoClick={() => setCurrentView('landing')}
|
frontend/src/components/AIAnalyst.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { useState } from 'react';
|
| 2 |
import Logo from './Logo';
|
| 3 |
|
| 4 |
interface AIInsight {
|
|
@@ -15,6 +15,7 @@ interface AIAnalystProps {
|
|
| 15 |
loadingInsight: boolean;
|
| 16 |
insightError: string | null;
|
| 17 |
onTriggerInsight: (tradingStyle: string, riskTolerance: string) => void;
|
|
|
|
| 18 |
}
|
| 19 |
|
| 20 |
export default function AIAnalyst({
|
|
@@ -24,6 +25,7 @@ export default function AIAnalyst({
|
|
| 24 |
loadingInsight,
|
| 25 |
insightError,
|
| 26 |
onTriggerInsight,
|
|
|
|
| 27 |
}: AIAnalystProps) {
|
| 28 |
const [activeTab, setActiveTab] = useState<'analysis' | 'history'>('analysis');
|
| 29 |
const [selectedHistoryItem, setSelectedHistoryItem] = useState<any | null>(null);
|
|
@@ -32,6 +34,14 @@ export default function AIAnalyst({
|
|
| 32 |
const [isStyleOpen, setIsStyleOpen] = useState(false);
|
| 33 |
const [isRiskOpen, setIsRiskOpen] = useState(false);
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
// Parse inline markdown: **bold**, *italic*
|
| 36 |
const parseInline = (text: string, keyPrefix: string) => {
|
| 37 |
// Handle **bold** and *italic* (in that order, bold first)
|
|
@@ -466,8 +476,15 @@ export default function AIAnalyst({
|
|
| 466 |
)}
|
| 467 |
|
| 468 |
{insightError && (
|
| 469 |
-
<div style={{ padding: '20px',
|
| 470 |
-
{insightError}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 471 |
</div>
|
| 472 |
)}
|
| 473 |
|
|
@@ -485,6 +502,13 @@ export default function AIAnalyst({
|
|
| 485 |
<span style={{ color: 'var(--neon-cyan)', fontWeight: 600 }}>Disclaimer:</span>
|
| 486 |
<span>QuantIQ AI is an automated strategy assistant and can make mistakes. All analysis is for informational purposes only and should not be considered financial advice. Please verify financial data independently.</span>
|
| 487 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 488 |
</div>
|
| 489 |
</div>
|
| 490 |
)}
|
|
|
|
| 1 |
+
import { useState, useEffect } from 'react';
|
| 2 |
import Logo from './Logo';
|
| 3 |
|
| 4 |
interface AIInsight {
|
|
|
|
| 15 |
loadingInsight: boolean;
|
| 16 |
insightError: string | null;
|
| 17 |
onTriggerInsight: (tradingStyle: string, riskTolerance: string) => void;
|
| 18 |
+
onResetInsight: () => void;
|
| 19 |
}
|
| 20 |
|
| 21 |
export default function AIAnalyst({
|
|
|
|
| 25 |
loadingInsight,
|
| 26 |
insightError,
|
| 27 |
onTriggerInsight,
|
| 28 |
+
onResetInsight,
|
| 29 |
}: AIAnalystProps) {
|
| 30 |
const [activeTab, setActiveTab] = useState<'analysis' | 'history'>('analysis');
|
| 31 |
const [selectedHistoryItem, setSelectedHistoryItem] = useState<any | null>(null);
|
|
|
|
| 34 |
const [isStyleOpen, setIsStyleOpen] = useState(false);
|
| 35 |
const [isRiskOpen, setIsRiskOpen] = useState(false);
|
| 36 |
|
| 37 |
+
// Auto-switch to analysis tab when loading starts
|
| 38 |
+
useEffect(() => {
|
| 39 |
+
if (loadingInsight) {
|
| 40 |
+
setActiveTab('analysis');
|
| 41 |
+
setSelectedHistoryItem(null);
|
| 42 |
+
}
|
| 43 |
+
}, [loadingInsight]);
|
| 44 |
+
|
| 45 |
// Parse inline markdown: **bold**, *italic*
|
| 46 |
const parseInline = (text: string, keyPrefix: string) => {
|
| 47 |
// Handle **bold** and *italic* (in that order, bold first)
|
|
|
|
| 476 |
)}
|
| 477 |
|
| 478 |
{insightError && (
|
| 479 |
+
<div style={{ padding: '20px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '16px' }}>
|
| 480 |
+
<span style={{ color: 'var(--bear-red)', textAlign: 'center' }}>{insightError}</span>
|
| 481 |
+
<button
|
| 482 |
+
className="insight-btn"
|
| 483 |
+
onClick={onResetInsight}
|
| 484 |
+
style={{ maxWidth: '250px' }}
|
| 485 |
+
>
|
| 486 |
+
Try Again / Adjust Parameters
|
| 487 |
+
</button>
|
| 488 |
</div>
|
| 489 |
)}
|
| 490 |
|
|
|
|
| 502 |
<span style={{ color: 'var(--neon-cyan)', fontWeight: 600 }}>Disclaimer:</span>
|
| 503 |
<span>QuantIQ AI is an automated strategy assistant and can make mistakes. All analysis is for informational purposes only and should not be considered financial advice. Please verify financial data independently.</span>
|
| 504 |
</div>
|
| 505 |
+
<button
|
| 506 |
+
className="insight-btn"
|
| 507 |
+
onClick={onResetInsight}
|
| 508 |
+
style={{ marginTop: '20px', width: '100%' }}
|
| 509 |
+
>
|
| 510 |
+
Generate Another Strategy Report
|
| 511 |
+
</button>
|
| 512 |
</div>
|
| 513 |
</div>
|
| 514 |
)}
|
frontend/src/pages/Dashboard.tsx
CHANGED
|
@@ -26,7 +26,8 @@ interface DashboardProps {
|
|
| 26 |
onRemoveTicker: (ticker: string) => Promise<void>;
|
| 27 |
onCreateAlert: (targetPrice: number, condition: string) => Promise<void>;
|
| 28 |
onDeactivateAlert: (alertId: string) => Promise<void>;
|
| 29 |
-
onTriggerInsight: () => void;
|
|
|
|
| 30 |
onOpenRecharge: () => void;
|
| 31 |
onLogout: () => void;
|
| 32 |
onLogoClick?: () => void;
|
|
@@ -54,6 +55,7 @@ export default function Dashboard({
|
|
| 54 |
onCreateAlert,
|
| 55 |
onDeactivateAlert,
|
| 56 |
onTriggerInsight,
|
|
|
|
| 57 |
onOpenRecharge,
|
| 58 |
onLogout,
|
| 59 |
onLogoClick,
|
|
@@ -110,6 +112,7 @@ export default function Dashboard({
|
|
| 110 |
loadingInsight={loadingInsight}
|
| 111 |
insightError={insightError}
|
| 112 |
onTriggerInsight={onTriggerInsight}
|
|
|
|
| 113 |
/>
|
| 114 |
</section>
|
| 115 |
|
|
|
|
| 26 |
onRemoveTicker: (ticker: string) => Promise<void>;
|
| 27 |
onCreateAlert: (targetPrice: number, condition: string) => Promise<void>;
|
| 28 |
onDeactivateAlert: (alertId: string) => Promise<void>;
|
| 29 |
+
onTriggerInsight: (tradingStyle: string, riskTolerance: string) => void;
|
| 30 |
+
onResetInsight: () => void;
|
| 31 |
onOpenRecharge: () => void;
|
| 32 |
onLogout: () => void;
|
| 33 |
onLogoClick?: () => void;
|
|
|
|
| 55 |
onCreateAlert,
|
| 56 |
onDeactivateAlert,
|
| 57 |
onTriggerInsight,
|
| 58 |
+
onResetInsight,
|
| 59 |
onOpenRecharge,
|
| 60 |
onLogout,
|
| 61 |
onLogoClick,
|
|
|
|
| 112 |
loadingInsight={loadingInsight}
|
| 113 |
insightError={insightError}
|
| 114 |
onTriggerInsight={onTriggerInsight}
|
| 115 |
+
onResetInsight={onResetInsight}
|
| 116 |
/>
|
| 117 |
</section>
|
| 118 |
|