import { useState } from 'react' import { useNavigate } from 'react-router-dom' import { usePortfolioPositions, usePortfolioSummary, usePnlHistory, useAddPosition, useClosePosition } from '../hooks/useApi' import { useQueryClient, useMutation } from '@tanstack/react-query' import axios from 'axios' import clsx from 'clsx' import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, ReferenceLine, BarChart, Bar } from 'recharts' import { TrendingUp, TrendingDown, Plus, X, DollarSign, BarChart2, RefreshCw, Trash2, ExternalLink, ChevronDown, ChevronUp } from 'lucide-react' import type { TradeIdea } from '../types' const useDeletePosition = () => { const qc = useQueryClient() return useMutation({ mutationFn: (id: string) => axios.delete(`/api/portfolio/${id}`).then(r => r.data), onSuccess: () => { qc.invalidateQueries({ queryKey: ['portfolio'] }) qc.invalidateQueries({ queryKey: ['portfolio-summary'] }) }, }) } const STRATEGIES = ['Long Call', 'Long Put', 'Bull Call Spread', 'Bear Put Spread', 'Long Straddle', 'Long Strangle', 'Covered Call'] const ASSET_CLASSES = ['energy', 'metals', 'agriculture', 'equities', 'indices', 'forex'] interface AddModalProps { prefill?: Partial onClose: () => void } const STRADDLE_STRATEGIES = ['Long Straddle', 'Short Straddle', 'Long Strangle', 'Short Strangle'] function AddPositionModal({ prefill, onClose }: AddModalProps) { const { mutate: addPos, isPending } = useAddPosition() const [addError, setAddError] = useState(null) const [form, setForm] = useState({ title: prefill?.title || '', underlying: prefill?.underlying || '', strategy: prefill?.strategy || 'Long Call', asset_class: prefill?.asset_class || 'indices', expiry_days: prefill?.horizon_days || 90, capital_invested: prefill?.capital_required || 1000, geo_trigger: prefill?.geo_trigger || '', rationale: prefill?.rationale || '', strike: '', option_type: 'call', quantity: 1, premium: '', }) const set = (k: string, v: unknown) => setForm(f => ({ ...f, [k]: v })) const isStraddle = STRADDLE_STRATEGIES.includes(form.strategy) const isShort = form.strategy.startsWith('Short') const submit = () => { setAddError(null) const strikeVal = parseFloat(form.strike) || undefined const premiumVal = parseFloat(form.premium) || undefined const legs = isStraddle ? [ { strike: strikeVal, option_type: 'call', quantity: form.quantity, position: isShort ? 'short' : 'long', premium_paid: premiumVal }, { strike: strikeVal, option_type: 'put', quantity: form.quantity, position: isShort ? 'short' : 'long', premium_paid: premiumVal }, ] : [{ strike: strikeVal, option_type: form.option_type, quantity: form.quantity, position: form.strategy.startsWith('Short') ? 'short' : 'long', premium_paid: premiumVal, }] addPos({ title: form.title || `${form.strategy} ${form.underlying}`, underlying: form.underlying, strategy: form.strategy, asset_class: form.asset_class, expiry_days: form.expiry_days, capital_invested: form.capital_invested, geo_trigger: form.geo_trigger, rationale: form.rationale, legs, }, { onSuccess: onClose, onError: (err: unknown) => { const detail = (err as { response?: { data?: { detail?: string } } })?.response?.data?.detail setAddError(detail || 'Erreur lors de l\'ajout de la position') } }) } return (

Ajouter au portefeuille

set('title', e.target.value)} placeholder="Ex: Long Call GLD Q3 2026" className="w-full bg-dark-700 border border-slate-700 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:border-blue-500" />
{ set('underlying', e.target.value.toUpperCase()); setAddError(null) }} placeholder="^GSPC, GLD, CL=F..." className="w-full bg-dark-700 border border-slate-700 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:border-blue-500" />
S&P 500: ^GSPC · Or: GC=F · WTI: CL=F · GLD · USO
set('strike', e.target.value)} placeholder="Prix d'exercice" className="w-full bg-dark-700 border border-slate-700 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:border-blue-500" />
set('premium', e.target.value)} placeholder="Prix option" className="w-full bg-dark-700 border border-slate-700 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:border-blue-500" />
set('capital_invested', Number(e.target.value))} className="w-full bg-dark-700 border border-slate-700 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:border-blue-500" />
set('expiry_days', Number(e.target.value))} className="w-full bg-dark-700 border border-slate-700 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:border-blue-500" />
set('geo_trigger', e.target.value)} placeholder="Ex: Middle East escalation → oil spike" className="w-full bg-dark-700 border border-slate-700 rounded px-2 py-1.5 text-sm text-white focus:outline-none focus:border-blue-500" />