diff --git a/apps/web/src/pages/DownloadsPage.tsx b/apps/web/src/pages/DownloadsPage.tsx index ad069b2..bbd2e61 100644 --- a/apps/web/src/pages/DownloadsPage.tsx +++ b/apps/web/src/pages/DownloadsPage.tsx @@ -1,9 +1,10 @@ import { useState, useEffect } from 'react'; -import { Upload, Download, BookOpen, ChevronDown, ChevronRight, AlertTriangle, CheckCircle, Package, FileCode2 } from 'lucide-react'; +import { Upload, Download, BookOpen, ChevronDown, ChevronRight, AlertTriangle, CheckCircle, Package, FileCode2, KeyRound, RefreshCw, Check, Copy } from 'lucide-react'; import { Card } from '@/components/ui/Card'; import { Badge } from '@/components/ui/Badge'; import { Button } from '@/components/ui/Button'; import { API_BASE } from '@/lib/constants'; +import { api } from '@/lib/api'; import { useAccountsStore, type Account } from '@/stores/accounts'; import { useAuthStore } from '@/stores/auth'; @@ -14,6 +15,24 @@ const SOURCE_ZIP_NAMES: Record<'master' | 'follower' | 'journal', string> = { journal: 'TradeJournal_Sync_Source.zip', }; +/** Shared "where to find your credentials" callout, reused across the config steps. */ +const credentialsHint = ( +
Where to find these
++ Open the{' '} + Copier{' '} + page. On each account card, your Account ID and API Key are shown with a one-tap Copy button. +
++ Your API Secret is revealed only once — on the credentials screen shown immediately after you create the account. If you did not save it, click Regenerate keys on the account card to issue a fresh API Key + Secret (again shown once). +
+@@ -316,7 +338,7 @@ const troubleshootingItems = [ }, { problem: 'Error 4060 in Experts tab', - solution: 'The URL is not whitelisted. Go to Tools → Options → Expert Advisors and add https://signal.edgerelay.io to the allowed URLs.', + solution: 'The URL is not whitelisted. Go to Tools → Options → Expert Advisors and add https://signal.edgerelay.io to the allowed URLs.', }, { problem: "'Trade context busy' error", @@ -370,6 +392,123 @@ function AccordionItem({ /* EA Download Card */ /* ------------------------------------------------------------------ */ +function CredCopyButton({ text, label }: { text: string; label: string }) { + const [copied, setCopied] = useState(false); + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(text); + setCopied(true); + setTimeout(() => setCopied(false), 1500); + } catch { + /* clipboard unavailable — ignore */ + } + }; + return ( + + ); +} + +function CredRow({ label, value, valueClass }: { label: string; value: string; valueClass: string }) { + return ( +
{value}
+ + No account yet.{' '} + Create one on the Copier page{' '} + to generate your Account ID, API Key and Secret. +
+Copy the secret now — it is shown only this once.
+ > + ) : ( +{regenError}
} +{isJournal - ? 'Install on any MT5 account. Syncs every trade to your journal with zero drops — real-time capture + history catch-up.' + ? 'Install on any MT5 account. Syncs every trade to your journal with zero drops — real-time capture + history catch-up.' : isMaster ? 'Install on your master MT5 account. Captures and sends trade signals to the edge network.' : 'Install on each follower account. Receives signals and executes trades automatically.'} @@ -517,6 +656,8 @@ function EADownloadCard({