v1.1
This commit is contained in:
parent
1446ff9ff6
commit
d01befdf60
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,8 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
*/node_modules/
|
*/node_modules/
|
||||||
*/build/
|
*/build/
|
||||||
|
|
||||||
|
**/node_modules/
|
||||||
|
**/build/
|
||||||
|
.DS_Store
|
||||||
|
.env
|
||||||
File diff suppressed because one or more lines are too long
1
frontend/json/runtimeError.json
Normal file
1
frontend/json/runtimeError.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@ -92,6 +92,58 @@ const menuAside: MenuAsideItem[] = [
|
|||||||
icon: icon.mdiFileCode,
|
icon: icon.mdiFileCode,
|
||||||
permissions: 'READ_API_DOCS',
|
permissions: 'READ_API_DOCS',
|
||||||
},
|
},
|
||||||
|
// Web Terminal Overview and Guides
|
||||||
|
{
|
||||||
|
href: '/overview/web-terminal',
|
||||||
|
label: 'Web Terminal Overview',
|
||||||
|
icon: icon.mdiMonitorClassic,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
href: '/strategy-builder',
|
||||||
|
label: 'Strategy Builder',
|
||||||
|
icon: icon.mdiPuzzleOutline,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
href: '/trading-demo',
|
||||||
|
label: 'Trading Demo Account',
|
||||||
|
icon: icon.mdiBank,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
href: '/copy-trading',
|
||||||
|
label: 'Copy Trading',
|
||||||
|
icon: icon.mdiAccountSwitch,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
href: '/api-integration',
|
||||||
|
label: 'API Integration',
|
||||||
|
icon: icon.mdiApi,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
href: '/corporate-events',
|
||||||
|
label: 'Corporate Events',
|
||||||
|
icon: icon.mdiCalendar,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
href: '/financial-instruments',
|
||||||
|
label: 'Financial Instruments',
|
||||||
|
icon: icon.mdiChartBox,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
href: '/stocks-trader-app',
|
||||||
|
label: 'StocksTrader App',
|
||||||
|
icon: icon.mdiCellphoneLink,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
href: '/faq',
|
||||||
|
label: 'FAQ',
|
||||||
|
icon: icon.mdiHelpCircle,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
href: '/latest-updates',
|
||||||
|
label: 'Latest Updates',
|
||||||
|
icon: icon.mdiUpdate,
|
||||||
|
},
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default menuAside;
|
export default menuAside;
|
||||||
|
|||||||
42
frontend/src/pages/[...slug].tsx
Normal file
42
frontend/src/pages/[...slug].tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import SectionMain from '../components/SectionMain';
|
||||||
|
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton';
|
||||||
|
import * as icon from '@mdi/js';
|
||||||
|
import LayoutAuthenticated from '../layouts/Authenticated';
|
||||||
|
|
||||||
|
const stubTitles: Record<string, { title: string; icon: string }> = {
|
||||||
|
'overview/web-terminal': { title: 'Web Terminal Overview', icon: icon.mdiMonitorClassic },
|
||||||
|
'strategy-builder': { title: 'Strategy Builder', icon: icon.mdiPuzzleOutline },
|
||||||
|
'trading-demo': { title: 'Trading Demo Account', icon: icon.mdiBank },
|
||||||
|
'copy-trading': { title: 'Copy Trading', icon: icon.mdiAccountSwitch },
|
||||||
|
'api-integration': { title: 'API Integration', icon: icon.mdiApi },
|
||||||
|
'corporate-events': { title: 'Corporate Events', icon: icon.mdiCalendar },
|
||||||
|
'financial-instruments': { title: 'Financial Instruments', icon: icon.mdiChartBox },
|
||||||
|
'stocks-trader-app': { title: 'StocksTrader App', icon: icon.mdiCellphoneLink },
|
||||||
|
'faq': { title: 'FAQ', icon: icon.mdiHelpCircle },
|
||||||
|
'latest-updates': { title: 'Latest Updates', icon: icon.mdiUpdate }
|
||||||
|
};
|
||||||
|
|
||||||
|
const StubPage: React.FC = () => {
|
||||||
|
const router = useRouter();
|
||||||
|
const { slug } = router.query;
|
||||||
|
const slugArray = Array.isArray(slug) ? slug : slug ? [slug] : [];
|
||||||
|
const path = slugArray.join('/');
|
||||||
|
const stub = stubTitles[path];
|
||||||
|
|
||||||
|
if (!stub) {
|
||||||
|
return <p>404 - Page Not Found</p>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SectionMain>
|
||||||
|
<SectionTitleLineWithButton icon={stub.icon} title={stub.title} main />
|
||||||
|
<p>Coming soon: {stub.title} section.</p>
|
||||||
|
</SectionMain>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
StubPage.getLayout = (page: React.ReactElement) => <LayoutAuthenticated>{page}</LayoutAuthenticated>;
|
||||||
|
|
||||||
|
export default StubPage;
|
||||||
109
frontend/src/pages/strategy-builder.tsx
Normal file
109
frontend/src/pages/strategy-builder.tsx
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import SectionMain from '../components/SectionMain';
|
||||||
|
import LayoutAuthenticated from '../layouts/Authenticated';
|
||||||
|
import { Button } from '../components/BaseButton';
|
||||||
|
import * as icon from '@mdi/js';
|
||||||
|
|
||||||
|
const StrategyBuilderPage: React.FC = () => {
|
||||||
|
const [maxOpenDeals, setMaxOpenDeals] = useState(false);
|
||||||
|
const [multiplier, setMultiplier] = useState(1);
|
||||||
|
const [orderVolumeEnabled, setOrderVolumeEnabled] = useState(false);
|
||||||
|
const [orderVolume, setOrderVolume] = useState(1);
|
||||||
|
const [backtestEnabled, setBacktestEnabled] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SectionMain>
|
||||||
|
{/* Top toolbar */}
|
||||||
|
<div className="flex items-center justify-between mb-6">
|
||||||
|
<Button variant="ghost" icon={icon.mdiArrowLeft}>Back</Button>
|
||||||
|
<div className="flex space-x-4">
|
||||||
|
<Button variant="outline">Overview</Button>
|
||||||
|
<Button variant="outline">Editor</Button>
|
||||||
|
<Button variant="outline">Trades</Button>
|
||||||
|
<Button variant="outline">Export CSV</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Buy/Sell panels */}
|
||||||
|
<div className="grid grid-cols-2 gap-6 mb-6">
|
||||||
|
{/* Buy Panel */}
|
||||||
|
<div className="p-4 border rounded-lg">
|
||||||
|
<h3 className="text-lg font-semibold mb-4">Buy</h3>
|
||||||
|
<div className="flex items-center mb-3">
|
||||||
|
<span className="mr-2">Max. open deals</span>
|
||||||
|
<input type="checkbox" checked={maxOpenDeals} onChange={() => setMaxOpenDeals(!maxOpenDeals)} />
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center mb-3">
|
||||||
|
<label className="mr-2">Multiplier</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="border p-1 w-16"
|
||||||
|
value={multiplier}
|
||||||
|
onChange={e => setMultiplier(Number(e.target.value))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center mb-3">
|
||||||
|
<span className="mr-2">Order volume</span>
|
||||||
|
<input type="checkbox" checked={orderVolumeEnabled} onChange={() => setOrderVolumeEnabled(!orderVolumeEnabled)} />
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className="border p-1 w-16 ml-2"
|
||||||
|
value={orderVolume}
|
||||||
|
onChange={e => setOrderVolume(Number(e.target.value))}
|
||||||
|
disabled={!orderVolumeEnabled}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center mb-3">
|
||||||
|
<span className="mr-2">Backtest</span>
|
||||||
|
<input type="checkbox" checked={backtestEnabled} onChange={() => setBacktestEnabled(!backtestEnabled)} />
|
||||||
|
</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<h4 className="font-medium">Entry when <Button size="sm">+ Add rule</Button></h4>
|
||||||
|
<p className="text-sm text-gray-500 ml-4">Enter every 10 ticks below last entry</p>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<h4 className="font-medium">Exit when <Button size="sm">+ Add rule</Button></h4>
|
||||||
|
<ul className="list-disc ml-6 text-sm">
|
||||||
|
<li>close at SL</li>
|
||||||
|
<li>close at TP</li>
|
||||||
|
<li>close if lifetime</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Sell Panel */}
|
||||||
|
<div className="p-4 border rounded-lg">
|
||||||
|
<h3 className="text-lg font-semibold mb-4">Sell</h3>
|
||||||
|
<div className="mt-4">
|
||||||
|
<h4 className="font-medium">Entry when <Button size="sm">+ Add rule</Button></h4>
|
||||||
|
<p className="text-sm text-gray-500 ml-4">Enter every 0 ticks above last entry</p>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4">
|
||||||
|
<h4 className="font-medium">Exit when <Button size="sm">+ Add rule</Button></h4>
|
||||||
|
<ul className="list-disc ml-6 text-sm">
|
||||||
|
<li>close at SL</li>
|
||||||
|
<li>close at TP</li>
|
||||||
|
<li>close if lifetime</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Footer actions */}
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<Button variant="link">Help</Button>
|
||||||
|
<div className="flex space-x-2">
|
||||||
|
<Button variant="outline">Discard</Button>
|
||||||
|
<Button>Save changes</Button>
|
||||||
|
<Button variant="ghost" icon={icon.mdiCogOutline} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</SectionMain>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
StrategyBuilderPage.getLayout = (page: React.ReactElement) => (
|
||||||
|
<LayoutAuthenticated>{page}</LayoutAuthenticated>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default StrategyBuilderPage;
|
||||||
Loading…
x
Reference in New Issue
Block a user