Skip to content

Commit 75b6bd9

Browse files
committed
chore: update
1 parent 4eb65e1 commit 75b6bd9

File tree

12 files changed

+189
-72
lines changed

12 files changed

+189
-72
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"axios": "^1.6.7",
2424
"moment": "^2.30.1",
2525
"normalize.css": "^8.0.1",
26+
"prism-react-renderer": "^2.3.1",
2627
"react": "^18.1.0",
2728
"react-dom": "^18.1.0",
2829
"react-redux": "^9.1.0",
@@ -66,4 +67,4 @@
6667
"git add ."
6768
]
6869
}
69-
}
70+
}

src/api/common.ts

-7
This file was deleted.

src/api/interface.ts

+11
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,14 @@ export type GetProductPayments = [
194194
}>,
195195
number,
196196
]
197+
198+
export interface GetStrategyResponse {
199+
id: number
200+
name: string
201+
params: {}
202+
code: string
203+
planId: number
204+
createdAt: string
205+
updatedAt: string
206+
publishedAt: string
207+
}

src/api/request.ts

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export const ApiUrls = {
2222
login: `/api/auth/local`,
2323
forgot: `/api/auth/forgot-password`,
2424
reset: `/api/auth/reset-password`,
25-
config: `/api/config`,
2625
vipGetProduct: '/api/strapi-paypal/getProduct',
2726
vipGetProductCheckout: '/api/strapi-paypal/getPaypalCheckout',
2827
vipCreatePayment: '/api/strapi-paypal/createProductPayment',

src/api/strategy.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import axios from 'axios'
22

33
import { getArray } from '@/utils'
44
import { ApiUrls, request } from './request'
5+
import { GetStrategyResponse } from './interface'
56

67
const createResourceUri = (uri: string) => {
78
return `http://localhost:8080/${uri}`
@@ -38,7 +39,9 @@ export const getStrategyList = async () => {
3839
}))
3940
}
4041

41-
export const getStrategy = async (id: string) => {
42-
const res = await request.get(`${ApiUrls.getStrategy}/${id}`)
43-
return res.data
42+
export const getStrategy = async (id: number) => {
43+
const res = await request.get<GetStrategyResponse>(
44+
`${ApiUrls.getStrategy}/${id}`,
45+
)
46+
return res?.data
4447
}

src/api/vip.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const getProductCheckout = async (orderId: string) => {
3434
return res.data
3535
}
3636

37-
export const createProductPayment = async (planId: string) => {
37+
export const createProductPayment = async (planId: any) => {
3838
if (!planId) {
3939
message.error('PlanId Not Found')
4040
return

src/app.tsx

+5-7
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import ReactDOM from 'react-dom'
66
import { Provider } from 'react-redux'
77
import { HashRouter, Route, Routes, useNavigate } from 'react-router-dom'
88

9-
import { getUserInfo, setCode } from './api'
10-
import { getConfig } from './api/common'
9+
import { getToken, getUserInfo, setCode } from './api'
1110
import { Container, Content, GlobalStyle } from './app.style'
1211
import { Footer } from './components/footer'
1312
import { Header } from './components/header'
@@ -34,18 +33,17 @@ export const App = () => {
3433
const navigate = useNavigate()
3534

3635
const { loading } = useAsync(async () => {
37-
// const config = await getConfig()
38-
// dispatch(commonSlice.actions.setConfig(config))
39-
4036
const query = parseUrlParam(location.search)
4137
if (query?.code) {
4238
setCode(query?.code)
4339
navigate('/confirmReset')
4440
return
4541
}
4642

47-
// const userInfo = await getUserInfo()
48-
// dispatch(commonSlice.actions.setUserInfo(userInfo))
43+
if (getToken()) {
44+
const userInfo = await getUserInfo()
45+
dispatch(commonSlice.actions.setUserInfo(userInfo))
46+
}
4947
}, [])
5048

5149
useEffect(() => {

src/components/card/index.tsx

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Card as AntdCard, Image } from 'antd'
1+
import { Card as AntdCard, Badge, Image } from 'antd'
22
import React from 'react'
33

44
import { StrategyExtItem } from '@/api/strategy'
@@ -11,15 +11,17 @@ export interface CardProps {
1111
export const Card: React.FC<CardProps> = ({ item }) => {
1212
const navigate = useNavigate()
1313
return (
14-
<AntdCard
15-
hoverable
16-
cover={<Image height={200} preview={false} src={item.cover_uri} />}
17-
onClick={() => navigate(`/strategy/${item.id}`)}
18-
>
19-
<AntdCard.Meta
20-
title={item.name}
21-
description={`Profit factor: ${item.factor}`}
22-
/>
23-
</AntdCard>
14+
<Badge.Ribbon text="Futures" placement="start" color="purple">
15+
<AntdCard
16+
hoverable
17+
cover={<Image height={200} preview={false} src={item.cover_uri} />}
18+
onClick={() => navigate(`/strategy/${item.id}`)}
19+
>
20+
<AntdCard.Meta
21+
title={item.name}
22+
description={`Profit factor: ${item.factor}`}
23+
/>
24+
</AntdCard>
25+
</Badge.Ribbon>
2426
)
2527
}

src/components/code/index.tsx

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Highlight, themes } from 'prism-react-renderer'
2+
3+
import React from 'react'
4+
5+
export interface CodeProps {
6+
children: string
7+
}
8+
9+
export const Code: React.FC<CodeProps> = ({ children }) => {
10+
return (
11+
<Highlight theme={themes.github} code={children} language="python">
12+
{({ className, style, tokens, getLineProps, getTokenProps }) => (
13+
<pre style={style}>
14+
{tokens.map((line, i) => (
15+
<div key={i} {...getLineProps({ line })}>
16+
{line.map((token, key) => (
17+
<span key={key} {...getTokenProps({ token })} />
18+
))}
19+
</div>
20+
))}
21+
</pre>
22+
)}
23+
</Highlight>
24+
)
25+
}

src/pages/StrategyInfo/index.style.ts

+10
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,13 @@ export const Iframe = styled.iframe`
77
height: 75vh;
88
border: none;
99
`
10+
11+
export const CodeWrap = styled.div`
12+
position: relative;
13+
`
14+
15+
export const CopyBtn = styled.div`
16+
position: absolute;
17+
right: 16px;
18+
top: 16px;
19+
`

src/pages/StrategyInfo/index.tsx

+95-41
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
1-
import { getStrategyList } from '@/api/strategy'
2-
import { useAsync } from '@/hooks/useAsync'
3-
import { useBacktestInfo } from '@/hooks/useBacktestInfo'
4-
import { getArray } from '@/utils'
51
import {
62
Button,
7-
Col,
83
Descriptions,
94
Divider,
5+
message,
6+
Modal,
107
Result,
11-
Row,
12-
Space,
138
Spin,
149
Typography,
1510
} from 'antd'
1611
import React, { useMemo, useState } from 'react'
17-
import { useParams } from 'react-router'
18-
import { Contain, Iframe } from './index.style'
12+
import { useNavigate, useParams } from 'react-router'
13+
14+
import { getStrategy, getStrategyList } from '@/api/strategy'
15+
import { Code } from '@/components/code'
16+
import { useAsync } from '@/hooks/useAsync'
17+
import { useBacktestInfo } from '@/hooks/useBacktestInfo'
18+
import { useIsLogined } from '@/hooks/useIsLogined'
19+
import { getArray } from '@/utils'
20+
21+
import { CodeWrap, Contain, CopyBtn, Iframe } from './index.style'
22+
import { createProductPayment } from '@/api/vip'
1923

2024
export interface StrategyInfoProps {}
2125

@@ -26,6 +30,8 @@ const highStyle = {
2630
export const StrategyInfo: React.FC<StrategyInfoProps> = ({}) => {
2731
const { data: list, loading } = useAsync(() => getStrategyList(), [])
2832

33+
const navigate = useNavigate()
34+
2935
const params = useParams()
3036
const [frameLoading, setFrameLoading] = useState(true)
3137

@@ -40,6 +46,50 @@ export const StrategyInfo: React.FC<StrategyInfoProps> = ({}) => {
4046
currentItem?.backtest_uri,
4147
)
4248

49+
const isLogined = useIsLogined()
50+
51+
const {
52+
run: buy,
53+
loading: buyLoading,
54+
data: strategy,
55+
} = useAsync(
56+
async () => {
57+
if (!isLogined) {
58+
navigate('/login')
59+
message.info('Please login first')
60+
return
61+
}
62+
if (currentItem) {
63+
const strategy = await getStrategy(currentItem?.id)
64+
if (strategy?.code) {
65+
message.success('Get success')
66+
return strategy
67+
} else {
68+
Modal.confirm({
69+
title: 'Requirements',
70+
content: `The current strategy needs to be purchased before it can be viewed`,
71+
async onOk() {
72+
const payment = await createProductPayment(strategy?.planId)
73+
if (payment) {
74+
const item = getArray(payment?.paymentLinks).find(
75+
(item) => item.rel === 'approve',
76+
)
77+
location.href = item.href
78+
} else {
79+
message.error('Product not found')
80+
}
81+
},
82+
okText: 'Go to buy',
83+
})
84+
}
85+
}
86+
},
87+
[currentItem, isLogined],
88+
{
89+
manual: true,
90+
},
91+
)
92+
4393
if (!currentItem && !loading) {
4494
return (
4595
<Contain>
@@ -61,40 +111,44 @@ export const StrategyInfo: React.FC<StrategyInfoProps> = ({}) => {
61111
}}
62112
></Iframe>
63113
</Spin>
64-
<Row>
65-
<Col span={12}>
66-
<Spin spinning={backtestInfoLoading}>
67-
<Descriptions size="small" bordered column={1}>
68-
{getArray(backtestInfo).map((item) => {
69-
let style = {}
70-
if (
71-
item.key.includes('CAGR') ||
72-
item.key.includes('Profit factor') ||
73-
item.key.includes('Absolute Drawdown (Account)')
74-
) {
75-
style = highStyle
76-
}
77-
return (
78-
<Descriptions.Item
79-
labelStyle={style}
80-
contentStyle={style}
81-
label={item.key}
82-
key={item.key}
83-
>
84-
{item.value}
85-
</Descriptions.Item>
86-
)
87-
})}
88-
</Descriptions>
89-
</Spin>
90-
</Col>
91-
<Col span={12}></Col>
92-
</Row>
114+
<Spin spinning={backtestInfoLoading}>
115+
<Descriptions size="small" bordered column={2}>
116+
{getArray(backtestInfo).map((item) => {
117+
let style = {}
118+
if (
119+
item.key.includes('CAGR') ||
120+
item.key.includes('Profit factor') ||
121+
item.key.includes('Absolute Drawdown (Account)')
122+
) {
123+
style = highStyle
124+
}
125+
return (
126+
<Descriptions.Item
127+
labelStyle={style}
128+
contentStyle={style}
129+
label={item.key}
130+
key={item.key}
131+
>
132+
{item.value}
133+
</Descriptions.Item>
134+
)
135+
})}
136+
</Descriptions>
137+
</Spin>
93138
{/* code */}
94139
<Divider />
95-
<Space>
96-
<Button type="primary">Download StrategyCode</Button>
97-
</Space>
140+
{strategy?.code ? (
141+
<CodeWrap>
142+
<CopyBtn>
143+
<Typography.Text copyable={{ text: strategy?.code }} />
144+
</CopyBtn>
145+
<Code>{strategy?.code}</Code>
146+
</CodeWrap>
147+
) : (
148+
<Button loading={buyLoading} type="primary" onClick={buy}>
149+
Download StrategyCode
150+
</Button>
151+
)}
98152
</Contain>
99153
)
100154
}

0 commit comments

Comments
 (0)