Browse Source

commit

main
mac 5 months ago
parent
commit
441efec02e
  1. 9
      package.json
  2. 41
      public/index.html
  3. 42
      public/initialization.js
  4. 38
      src/App.css
  5. 9
      src/App.test.tsx
  6. 24
      src/App.tsx
  7. BIN
      src/assets/b1_bg.png
  8. BIN
      src/assets/login.jpg
  9. 19
      src/components/Button.tsx
  10. 191
      src/components/layout/Header.tsx
  11. 79
      src/components/layout/Slider.tsx
  12. 12
      src/hooks/useRouter.ts
  13. 13
      src/index.css
  14. 15
      src/index.tsx
  15. 1
      src/logo.svg
  16. 31
      src/pages/account/index.tsx
  17. 61
      src/pages/create-proxy/index.tsx
  18. 36
      src/pages/deposit/index.tsx
  19. 40
      src/pages/forget/index.tsx
  20. 30
      src/pages/home/index.tsx
  21. 51
      src/pages/login/index.tsx
  22. 38
      src/pages/security/index.tsx
  23. 46
      src/pages/transfer/index.tsx
  24. 54
      src/pages/withdraw/index.tsx
  25. 46
      src/router/index.tsx
  26. 24
      src/router/renderRouter.tsx
  27. 53
      src/router/routes.tsx
  28. 40
      src/store/index.ts
  29. 88
      src/styles/app.scss
  30. 22
      src/styles/components.scss
  31. 299
      src/styles/global.scss
  32. 66
      src/styles/home.scss
  33. 75
      src/styles/login.scss
  34. 783
      yarn.lock

9
package.json

@ -10,9 +10,15 @@
"@types/node": "^16.7.13",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"antd": "^5.18.1",
"mobx": "^6.12.4",
"mobx-react": "^9.1.1",
"qrcode": "^1.5.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.23.1",
"react-scripts": "5.0.1",
"sass": "^1.77.5",
"typescript": "^4.4.2",
"web-vitals": "^2.1.0"
},
@ -39,5 +45,8 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/qrcode": "^1.5.5"
}
}

41
public/index.html

@ -1,21 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
@ -24,12 +22,13 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
@ -39,5 +38,7 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
<script src="./initialization.js"></script>
</body>
</html>

42
public/initialization.js

@ -0,0 +1,42 @@
(() => {
// 获取屏幕大小
const getScreen = () => {
const width = window.innerWidth;
const height = window.innerHeight;
document.body.style = `
--width:${width}px;
--height:${height}px;
`;
}
getScreen()
// 监听屏幕变化
window.addEventListener('resize', getScreen);
// ios 禁用屏幕缩放
document.documentElement.addEventListener(
"touchstart",
function (event) {
if (event.touches.length > 1) {
event.preventDefault();
}
},
false
);
var lastTouchEnd = 0;
document.documentElement.addEventListener(
"touchend",
function (event) {
var now = Date.now();
if (now - lastTouchEnd <= 300) {
event.preventDefault();
}
lastTouchEnd = now;
},
false
);
document.addEventListener("gesturestart", function (event) {
event.preventDefault();
});
})()

38
src/App.css

@ -1,38 +0,0 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

9
src/App.test.tsx

@ -1,9 +0,0 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

24
src/App.tsx

@ -1,25 +1,11 @@
import React from 'react';
import logo from './logo.svg';
import './App.css';
import RenderRouter from "./router";
import { HashRouter } from 'react-router-dom';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
<HashRouter>
<RenderRouter />
</HashRouter>
);
}

BIN
src/assets/b1_bg.png

After

Width: 1920  |  Height: 1080  |  Size: 572 KiB

BIN
src/assets/login.jpg

After

Width: 200  |  Height: 200  |  Size: 5.8 KiB

19
src/components/Button.tsx

@ -0,0 +1,19 @@
import '../styles/components.scss'
interface ButtonProps {
children?: string | JSX.Element;
className?: string;
style?: React.CSSProperties,
onClick?: Function
}
const Button = (props: ButtonProps) => {
const { children, style, className, onClick } = props
return (
<div onClick={() => onClick && onClick()} className={`default-button ${className}`} style={style}>{children}</div>
)
}
export default Button

191
src/components/layout/Header.tsx

@ -0,0 +1,191 @@
import { ConfigProvider, Drawer, Menu, Popover } from "antd"
import Button from "../Button"
import "../../styles/app.scss"
import { observer } from "mobx-react"
import store from "../../store"
import { useState } from "react"
import Slider from "./Slider"
const Header = () => {
const { screenWidth } = store.state
const [open, setOpen] = useState(false);
const [openMenu, setOpenMenu] = useState(false);
const PopoverData = [
{
title: '资金管理',
content: (
<div style={{ width: 160 }}>
<p className="tp"></p>
<p className="mt-1 tp"></p>
</div>
)
},
{
title: '存款',
content: (
<div style={{ width: 160 }}>
<p className="tp"></p>
<p className="mt-1 tp"></p>
</div>
)
},
{
title: '取款',
content: (
<div style={{ width: 160 }}>
<p className="tp"></p>
<p className="mt-1 tp"></p>
<p className="mt-1 tp"></p>
</div>
)
},
{
title: '我的团队',
content: (
<div style={{ width: 160 }}>
<p className="tp">广</p>
<p className="mt-1 tp"></p>
<p className="mt-1 tp"></p>
</div>
)
},
]
const items = [
{
key: 'sub1',
label: '资金管理',
children: [
{
key: 'g1',
label: 'Item 1',
type: 'group',
children: [
{ key: '1', label: '资金划转' },
{ key: '2', label: '账单记录' },
],
},
],
},
] as any;
const showDrawer = () => {
setOpen(true);
};
const onClose = () => {
setOpen(false);
};
const renderPc = (
<div className="row-between text-white" style={{ height: 70 }}>
<div className="row-items fz-wb-550">
{/* <div className="mr-3"></div>
<div className="mr-3"></div>
<div></div> */}
{
PopoverData.map((item, index) => (
<div className="mr-4" key={index}>
<Popover placement="bottomLeft" content={item.content}>
<div className="tp">{item.title}</div>
</Popover>
</div>
))
}
</div>
<div className="row-items">
<div className="mr-3 tp" style={{ whiteSpace: "nowrap" }}></div>
<Button style={{ height: 40, backgroundColor: 'rgba(0,0,0,.25)', borderRadius: 20, justifyContent: 'flex-start' }}>
<div className="row-items">
<img src="https://cfile.uworkcrm.com/static/images/avtar.jpg" alt="" className="avatar" />
<div style={{ marginLeft: 5, marginRight: 5 }}>CE08</div>
</div>
</Button>
</div>
</div>
)
const renderH5 = (
<div style={{ height: 70 }} className="row-between">
<div className="text-white tp" onClick={() => setOpenMenu(true)}></div>
<div className="row-items">
<img src="https://cfile.uworkcrm.com/static/images/avtar.jpg" alt="" className="avatar" />
<div className="text-white ml-1" onClick={showDrawer}></div>
</div>
</div>
)
return (
<div className="header">
{
screenWidth > 1000 ? renderPc : renderH5
}
<Drawer
open={openMenu}
onClose={() => setOpenMenu(false)}
placement="left"
key="left"
closable={false}
width={screenWidth > 700 ? '50%' : '80%'}
style={{ background: '#009688' }}
>
<div
>
</div>
<div className="row-center p-2" >
<ConfigProvider
theme={{
components: {
Menu: {
itemActiveBg: '#009688',
colorText: '#fff',
groupTitleColor: '#fff',
itemSelectedBg: "#009688",
itemSelectedColor: '#f7b93f'
}
}
}}
>
<Menu
// onClick={onClick}
style={{ background: 'none', color: '#fff' }}
mode="inline"
items={items}
/>
</ConfigProvider>
</div>
</Drawer>
{/* */}
<Drawer
open={open}
onClose={onClose}
placement="right"
key="right"
closable={false}
width={screenWidth > 700 ? '50%' : '80%'}
>
<div
style={{ width: '100%', height: 380, background: '#009688', borderBottomLeftRadius: '2rem', borderBottomRightRadius: '2rem' }}
>
</div>
<div className="row-center" style={{ position: 'relative', top: -370 }}>
<Slider />
</div>
</Drawer>
</div>
)
}
export default observer(Header)

79
src/components/layout/Slider.tsx

@ -0,0 +1,79 @@
import { useRouter } from "../../hooks/useRouter"
import Button from "../Button";
import '../../styles/app.scss'
import { observer } from "mobx-react";
import store from "../../store";
const Slider = () => {
const { push } = useRouter()
const { screenWidth } = store.state
const tabs = [
{ title: 'Android 下载', id: 1 },
{ title: 'IPhone 下载', id: 2 },
{ title: '仪表盘', id: 3 },
{ title: '办理存款', id: 4 },
{ title: '资金划转', id: 5 },
{ title: '办理取款', id: 6 },
{ title: '收款账户', id: 7 },
{ title: '安全设定', id: 8 },
]
const handleLeftMenu = (id: number) => {
switch (id) {
case 1:
window.open("https://m.swissquotecn.com/mt5")
break;
case 2:
window.open("https://m.swissquotecn.com/mt5")
break;
case 3:
push('/')
break;
case 4:
push('/deposit')
break
case 5:
push('/transfer')
break
case 6:
push('/withdraw')
break
case 7:
push('/account')
break
case 8:
push('/security')
}
}
return (
<div className="sidenav-left">
<div className="row-center">
<img src={require('../../assets/login.jpg')} className='img' alt="" />
</div>
<div className="row-center mt-5">
<img src="https://cfile.uworkcrm.com/static/images/avtar.jpg" className="avatar" alt="" />
</div>
<div className="tac text-white mt-2">chainon@12345.com</div>
<div className="row-center mt-1">
<Button className="balance-button">
<div>
<div> $10689</div>
<div className="fz-wb-550">$398.00</div>
</div>
</Button>
</div>
<div className={`mt-10 ${screenWidth > 350 ? 'row-between ' : 'column-center'} flex-wrap`}>
{
tabs.map((item, index) => (
<div key={index} className="tab-box mb-2 text-white row-center tp" onClick={() => handleLeftMenu(item.id)}>{item.title}</div>
))
}
</div>
</div>
)
}
export default observer(Slider)

12
src/hooks/useRouter.ts

@ -0,0 +1,12 @@
import { useLocation, useNavigate } from "react-router-dom";
export const useRouter = () => {
const navigate = useNavigate();
const location = useLocation();
const push = (path: any, state?: any, replace?: boolean) => {
navigate(path, { state, replace: replace || false });
};
return { push, location };
};

13
src/index.css

@ -1,13 +0,0 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

15
src/index.tsx

@ -1,15 +1,26 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import './styles/global.scss'
import { ConfigProvider } from 'antd';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
<ConfigProvider
theme={{
components: {
Button: {
}
}
}}
>
<App />
</ConfigProvider>
</React.StrictMode>
);

1
src/logo.svg

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

31
src/pages/account/index.tsx

@ -0,0 +1,31 @@
import { QRCode } from 'antd'
import '../../styles/home.scss'
const Account = () => {
return (
<div className='account'>
<div className="row-between mb-2">
<div className="row-items">
<div className='text-white fz-22'></div>
<div className="fz-22 ml-1 fz-wb-550 text-blue">3 </div>
<div className="fz-14 text-white"></div>
</div>
<div className="fz-wb-550 text-white"></div>
</div>
<div className='container p-2'>
<div className='text-success'></div>
<div className='border p-2 mt-2 fz-14'>
<div>BSC Main</div>
<div className='text-sub'></div>
<div className='mt-2'>asdakjsdlkajsdasdjk</div>
<div className='text-sub'></div>
<QRCode value='asdakjsdlkajsdasdjk' bordered={false} />
</div>
<div className='fz-14 mt-2'> <span className='fz-wb-550 text-blue'>2024-06-14 10:28:47</span></div>
</div>
</div>
)
}
export default Account

61
src/pages/create-proxy/index.tsx

@ -0,0 +1,61 @@
import { Form, Input } from 'antd'
import '../../styles/login.scss'
import Button from '../../components/Button'
import { useRouter } from '../../hooks/useRouter'
const CreateProxy = () => {
const { push } = useRouter()
return (
<div className='login'>
<div className='container'>
<div className='row-center'>
<img src={require('../../assets/login.jpg')} className='img' alt="" />
</div>
<div className='row-center mt-5'>
<div style={{ maxWidth: 500, width: '100%', padding: '0 20px' }}>
<div className='row-center'>
<div className='tac mb-5 fz-24 tbs'></div>
</div>
<Form>
<Form.Item>
<Input className='input' placeholder='姓名' ></Input>
</Form.Item>
<Form.Item>
<Input className='input' placeholder='邀请码' ></Input>
</Form.Item>
<Form.Item>
<Input className='input' placeholder='电子邮件' ></Input>
</Form.Item>
<Form.Item>
<Input className='input' placeholder='登录密码,(字母+数字)长度8-32' ></Input>
</Form.Item>
<Form.Item>
<div className='row-between'>
<Input className='input' placeholder='验证码' ></Input>
<Button className='verify-button'></Button>
</div>
</Form.Item>
<Form.Item>
<Button style={{ height: 40, fontWeight: 'normal' }}></Button>
</Form.Item>
<Form.Item>
<Button style={{ height: 40, backgroundColor: '#383d49', color: '#f7b93f', fontWeight: 'normal' }} onClick={() => push(-1)}></Button>
</Form.Item>
</Form>
</div>
</div>
</div>
</div>
)
}
export default CreateProxy

36
src/pages/deposit/index.tsx

@ -0,0 +1,36 @@
import { Button, Form, Input, Select } from 'antd'
import '../../styles/home.scss'
const Deposit = () => {
return (
<div className="deposit">
<div className='text-white fz-22 mb-2'></div>
<div className="flex-1 container">
<div className='p-2'>
<div className='fz-wb-550'>-</div>
<div className='text-sub fz-14 mt-1'></div>
</div>
<div className='divider' style={{ backgroundColor: '#8492a6' }}></div>
<div className='p-2'>
<Form
layout="vertical"
>
<Form.Item vertical={true} label={<span className='fz-wb-550'></span>}>
<Select style={{ height: 50 }} value="(CFD)658532 余额:10291.51" className='tac' />
</Form.Item>
<Form.Item vertical={true} label={<span className='fz-wb-550'></span>}>
<Input style={{ height: 50 }} placeholder='请输入存款金额' />
</Form.Item>
<Form.Item>
<div className='row-justify-end'>
<Button type='primary' style={{ borderRadius: 30 }}></Button>
</div>
</Form.Item>
</Form>
</div>
</div>
</div>
)
}
export default Deposit

40
src/pages/forget/index.tsx

@ -0,0 +1,40 @@
import { Form, Input } from 'antd'
import '../../styles/login.scss'
import Button from '../../components/Button'
import { useRouter } from '../../hooks/useRouter'
const ForGet = () => {
const { push } = useRouter()
return (
<div className='login'>
<div className='container'>
<div className='row-center'>
<img src={require('../../assets/login.jpg')} className='img' alt="" />
</div>
<div className='row-center'>
<div style={{ maxWidth: 500, width: '100%', padding: '0 20px' }}>
<Form>
<Form.Item>
<Input className='input' placeholder='邮箱' ></Input>
</Form.Item>
<Form.Item>
<div style={{ position: 'relative' }}>
<Input className='input' placeholder='验证码'></Input>
<img src="https://trader.gmigldgodfx.com/get/captcha?cc=0.24735417863504017" className='verify-img' alt="" />
</div>
</Form.Item>
<Form.Item>
<Button></Button>
</Form.Item>
</Form>
<div onClick={() => push(-1)} className='tac tp'></div>
</div>
</div>
</div>
</div>
)
}
export default ForGet

30
src/pages/home/index.tsx

@ -0,0 +1,30 @@
import '../../styles/home.scss'
const Home = () => {
return (
<div className="home">
<div className="text-white fz-22 fz-wb-500"></div>
<div className="row-between">
<div className="income"></div>
<div className="total-income"></div>
</div>
<div className='CFD-box mt-2'>
</div>
<div className='mt-2'>
<iframe frameBorder="0" width="100%" height="500" scrolling="yes" src="https://www.jin10.com/example/jin10.com.html?fontSize=14px&theme=white">
</iframe>
</div>
<div className='mt-2'>
<iframe id="iframe" frameBorder="0" width="100%" height="500" src="https://rili-test2.jin10.com?quote=1&fontSize=14px&theme=primary"></iframe>
</div>
</div>
)
}
export default Home

51
src/pages/login/index.tsx

@ -0,0 +1,51 @@
import { Form, Input } from 'antd'
import '../../styles/login.scss'
import Button from '../../components/Button'
import { useRouter } from '../../hooks/useRouter'
import store from '../../store'
const Login = () => {
const { push } = useRouter()
return (
<div className='login'>
<div className='container'>
<div className='row-center'>
<img src={require('../../assets/login.jpg')} className='img' alt="" />
</div>
<div className='row-center'>
<div style={{ maxWidth: 500, width: '100%', padding: '0 20px' }}>
<Form>
<Form.Item>
<Input className='input' placeholder='邮箱' ></Input>
</Form.Item>
<Form.Item>
<Input className='input' placeholder='密码'></Input>
</Form.Item>
<Form.Item>
<div style={{ position: 'relative' }}>
<Input className='input' placeholder='验证码'></Input>
<img src="https://trader.gmigldgodfx.com/get/captcha?cc=0.24735417863504017" className='verify-img' alt="" />
</div>
</Form.Item>
<Form.Item>
<Button onClick={() => {
store.setToken('asdakdjajklsdjklas')
push('/')
}}></Button>
</Form.Item>
</Form>
<div className='tac tp' style={{ cursor: 'pointer' }} onClick={() => push('/forget')}>?</div>
<div>
<Button className='create-button' onClick={() => push('/createProxy')}></Button>
</div>
</div>
</div>
</div>
</div>
)
}
export default Login

38
src/pages/security/index.tsx

@ -0,0 +1,38 @@
import { Button, Form, Input } from "antd"
import "../../styles/home.scss"
const Security = () => {
return (
<div className="securify">
<div className='text-white fz-22 mb-2'></div>
<div className="container pb-2">
<div className="p-2">
<div className="fz-wb-550"></div>
<div className="text-sub fz-14 mt-1">
<p>1.使</p>
<p>2.</p>
</div>
</div>
<div className="divider"></div>
<div className="plr-2">
<Form layout="vertical">
<Form.Item label={<span className="fz-wb-550"></span>}>
<Input style={{ height: 50 }} placeholder="密码必须是字母加数字的组合" />
</Form.Item>
<Form.Item label={<span className="fz-wb-550"></span>}>
<div className="row-items">
<Input style={{ height: 50 }} placeholder="密码必须是字母加数字的组合" />
<Button type="primary" style={{ height: 50 }} className="ml-1"></Button>
</div>
</Form.Item>
<Form.Item className="row-center">
<Button type="primary" style={{ borderRadius: 50 }}></Button>
</Form.Item>
</Form>
</div>
</div>
</div>
)
}
export default Security

46
src/pages/transfer/index.tsx

@ -0,0 +1,46 @@
import { Button, Form, Input, Select } from 'antd'
import '../../styles/home.scss'
const Transfer = () => {
return (
<div className="deposit">
<div className='text-white fz-22 mb-2'></div>
<div className="flex-1 container">
<div className='p-2'>
<div className='fz-wb-550'>-</div>
<div className='text-sub fz-14 mt-1'>
<p>1.使</p>
<p>2.</p>
<p>3.10</p>
</div>
</div>
<div className='divider' style={{ backgroundColor: '#8492a6' }}></div>
<div className='p-2'>
<Form
layout="vertical"
>
<Form.Item vertical={true} label={<span className='fz-wb-550'></span>}>
<Select style={{ height: 50 }} placeholder="请选择操作类型..." />
<div>
<span className='fz-12 text-primary'></span>
<span className='fz-12 text-success'>$0.00</span>
</div>
</Form.Item>
<Form.Item vertical={true} label={<span className='fz-wb-550'></span>}>
<Input style={{ height: 50 }} placeholder='请输入转账金额' />
</Form.Item>
<Form.Item>
<div className='row-center'>
<Button type='primary' style={{ borderRadius: 30 }}></Button>
</div>
</Form.Item>
</Form>
</div>
</div>
</div>
)
}
export default Transfer

54
src/pages/withdraw/index.tsx

@ -0,0 +1,54 @@
import { Button, Form, Input, Select } from 'antd'
import '../../styles/home.scss'
const Withdraw = () => {
return (
<div className="deposit">
<div className='text-white fz-22 mb-2'></div>
<div className="flex-1 container">
<div className='p-2'>
<div className='fz-wb-550'></div>
<div className='text-primary fz-14 mt-1'>使</div>
</div>
<div className='divider' style={{ backgroundColor: '#8492a6' }}></div>
<div className='p-2'>
<Form
layout="vertical"
>
<div className='row-between'>
<Form.Item style={{ width: '48%' }} vertical={true} label={<span className='fz-wb-550'></span>}>
<Select style={{ height: 40 }} value="现金钱包 余额:$10291.51" />
</Form.Item>
<Form.Item style={{ width: '48%' }} vertical={true} label={<span className='fz-wb-550'></span>}>
<div className='row-items'>
<Input style={{ height: 40, flex: 1 }} placeholder='请输入取款金额' />
<div className='fz-wb-550 ml-1'>USD</div>
</div>
</Form.Item>
</div>
<div className='row-between'>
<Form.Item style={{ width: '48%' }} vertical={true} label={<span className='fz-wb-550'></span>}>
<Select style={{ height: 40 }} placeholder="选择收款方式..." />
</Form.Item>
<Form.Item style={{ width: '48%' }} vertical={true} label={<span className='fz-wb-550'></span>}>
<div className='row-items'>
<Input style={{ height: 40, flex: 1 }} placeholder='请输入验证码' />
<Button type="primary" className='ml-1' style={{ height: 40 }}></Button>
</div>
</Form.Item>
</div>
<Form.Item>
<div className='row-center'>
<Button type='primary' style={{ borderRadius: 30 }}></Button>
</div>
</Form.Item>
</Form>
</div>
</div>
</div>
)
}
export default Withdraw

46
src/router/index.tsx

@ -0,0 +1,46 @@
import { observer } from "mobx-react";
import RenderRouter from "./renderRouter";
import store from "../store";
import '../styles/app.scss'
import { useRouter } from "../hooks/useRouter";
import Slider from "../components/layout/Slider";
import Header from "../components/layout/Header";
import { useEffect } from "react";
const LayoutRouter = () => {
const { push } = useRouter()
const { token, screenWidth } = store.state
//
useEffect(() => {
window.addEventListener("resize", (e) => {
const _width = window.innerWidth;
store.setScreenWidth(_width)
console.log('react', window.innerWidth);
})
}, [])
return (
token ? (
<RenderRouter />
) : (
<div className="layout">
<div className="container-header"></div>
<div className="container-aplication">
{
screenWidth > 1000 && <Slider />
}
<div style={{ paddingLeft: screenWidth > 1000 ? 40 : 0, flex: 1 }}>
<Header />
<div className="divider"></div>
<RenderRouter />
</div>
</div>
</div>
)
)
}
export default observer(LayoutRouter);

24
src/router/renderRouter.tsx

@ -0,0 +1,24 @@
import { Suspense } from "react";
import { Route, Routes } from "react-router-dom";
import routes from "./routes";
const RenderRouter = () => {
return (
<Suspense fallback={<div className='row-center' style={{ height: '80vh' }}>
<div className='tac'>
{/* <Loading color='#1BEDFF' size={30} /> */}
<div className='fz-16 sub-text mt-1'>...</div>
</div>
</div>}>
<Routes>
{routes.map(item => {
return (
<Route path={item.path} element={item.element} key={item.path} />
)
})}
</Routes>
</Suspense>
)
}
export default RenderRouter;

53
src/router/routes.tsx

@ -0,0 +1,53 @@
import { lazy } from "react";
import { RouteObject } from "react-router-dom";
const Home = lazy(() => import("../pages/home"));
const Login = lazy(() => import("../pages/login"));
const Forget = lazy(() => import("../pages/forget"));
const CreateProxy = lazy(() => import("../pages/create-proxy"));
const Deposit = lazy(() => import("../pages/deposit"));
const Transfer = lazy(() => import("../pages/transfer"));
const Withdraw = lazy(() => import("../pages/withdraw"));
const Account = lazy(() => import("../pages/account"));
const Security = lazy(() => import("../pages/security"));
const routes = [
{
path: "/",
element: <Home />
},
{
path: "/login",
element: <Login />
},
{
path: "/forget",
element: <Forget />
},
{
path: "/createProxy",
element: <CreateProxy />
},
{
path: "/deposit",
element: <Deposit />
},
{
path: "/transfer",
element: <Transfer />
},
{
path: "/withdraw",
element: <Withdraw />
},
{
path: "/account",
element: <Account />
},
{
path: "/security",
element: <Security />
},
] as RouteObject[];
export default routes;

40
src/store/index.ts

@ -0,0 +1,40 @@
import { makeAutoObservable } from "mobx";
interface Store {
state: object;
}
class AppStore implements Store {
state = {
token: "",
screenWidth: 0
};
constructor() {
makeAutoObservable(this);
this.initState();
}
/**
* @description
*/
initState() {
// let addr =
// window.sessionStorage.getItem(StoreLocalStorageKey.ADDRESS) || "";
// this.state.walletAddress = addr;
this.state.screenWidth = window.innerWidth
}
setToken(_token: string) {
this.state.token = _token
}
setScreenWidth(_width: number) {
this.state.screenWidth = _width
}
}
const store = new AppStore();
export default store;

88
src/styles/app.scss

@ -0,0 +1,88 @@
.layout {
position: relative;
display: flex;
justify-content: center;
padding: 1rem;
.container-header {
width: 100%;
height: 430px;
position: absolute;
inset: 0;
background-color: #009688;
border-bottom-left-radius: 2rem;
border-bottom-right-radius: 2rem;
z-index: -1;
}
.container-aplication {
max-width: 1420px;
width: 100%;
display: flex;
.divider {
width: 100%;
height: 1px;
background-color: #fff;
transform: scaleY(0.1);
margin-bottom: 20px;
}
}
}
.sidenav-left {
width: 250px;
min-width: 250px;
background-color: 'link';
height: 400px;
.tab-box {
background-color: #009688;
width: 112px;
height: 112px;
border-radius: 10px;
}
.img {
width: 70px;
height: 70px;
}
.avatar {
width: 96px;
height: 96px;
border-radius: 48px;
}
.balance-button {
width: 158px;
height: 58px;
border-radius: 29px;
background-color: #fff;
color: #000;
font-size: 14px;
font-weight: normal;
text-align: center;
}
}
.header {
.avatar {
width: 40px;
height: 40px;
border-radius: 20px;
object-fit: contain;
}
}
:where(.css-dev-only-do-not-override-1q0h2je).ant-drawer .ant-drawer-body {
padding: 0;
&::-webkit-scrollbar {
display: none;
}
}

22
src/styles/components.scss

@ -0,0 +1,22 @@
.default-button {
width: 100%;
height: 52px;
background-color: #f7b93f;
color: #fff;
font-weight: bold;
font-size: 1rem;
border-radius: 6px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
&:hover {
opacity: 0.9;
}
&:active {
opacity: 0.8;
}
}

299
src/styles/global.scss

@ -0,0 +1,299 @@
$iterations: 10;
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-size: 1rem;
color: #000;
user-select: none;
background-color: #f8f8fb;
font-family: Play;
width: 100%;
overflow-x: hidden;
&::-webkit-scrollbar {
display: none;
}
}
.text-white {
color: #fff;
}
.text-black {
color: #000;
}
.text-sub {
color: #8492a6;
}
.text-primary {
color: #f7b93f;
}
.text-blue {
color: #00b8d9;
}
.text-success {
color: #36B37E;
}
@for $i from 1 through $iterations {
// 外边距
.mt-#{$i}px {
margin-top: #{$i}px;
}
.ml-#{$i}px {
margin-left: #{$i}px;
}
.mt-#{$i} {
margin-top: 10px * $i;
}
.mb-#{$i} {
margin-bottom: 10px * $i;
}
.ml-#{$i} {
margin-left: 10px * $i;
}
.mr-#{$i} {
margin-right: 10px * $i;
}
.m-#{$i} {
margin: 10px * $i;
}
.mtb-#{$i} {
margin: 10px*$i 0px;
}
.mlr-#{$i} {
margin: 0px 10px*$i;
}
// 内边距
.pt-#{$i}px {
padding-top: #{$i}px;
}
.pl-#{$i}px {
padding-left: #{$i}px;
}
.pt-#{$i} {
padding-top: 10px * $i;
}
.pb-#{$i} {
padding-bottom: 10px * $i;
}
.pl-#{$i} {
padding-left: 10px * $i;
}
.pr-#{$i} {
padding-right: 10px * $i;
}
.p-#{$i} {
padding: 10px * $i;
}
.ptb-#{$i} {
padding: 10px*$i 0px;
}
.plr-#{$i} {
padding: 0px 10px*$i;
}
}
@for $i from 0 through 30 {
.fz-#{ $i + 8 } {
font-size: 8px + $i
}
}
@for $i from 1 through 10 {
.flex-#{$i} {
flex: $i
}
;
}
.divider {
width: 100%;
height: 0px;
border: 1px solid #D2D4D9;
}
.fz-wb-100 {
font-weight: 100;
}
.fz-wb-550 {
font-weight: 550;
}
.fz-wb-1000 {
font-weight: 1000;
}
.tac {
text-align: center;
}
.tar {
text-align: end;
}
.taj {
text-align: justify;
}
.align-items {
align-items: center;
}
.flex-wrap {
flex-wrap: wrap;
}
.tad {
text-align: end;
}
.row {
display: flex;
}
.row-items {
display: flex;
align-items: center
}
.row-center {
display: flex;
justify-content: center;
align-items: center;
}
.row-between {
display: flex;
justify-content: space-between;
align-items: center;
}
.row-justify-around {
display: flex;
justify-content: space-around
}
.row-justify-evenly {
display: flex;
justify-content: space-evenly
}
.row-justify-end {
display: flex;
justify-content: flex-end
}
.row-justify-start {
display: flex;
justify-content: flex-start
}
.row-center {
display: flex;
justify-content: center;
align-items: center
}
.column {
display: flex;
;
flex-direction: column
}
.column-items-center {
display: flex;
align-items: center;
flex-direction: column
}
.column-justify-center {
display: flex;
justify-content: center;
flex-direction: column
}
.column-justify-between {
display: flex;
justify-content: space-between;
flex-direction: column
}
.column-justify-around {
display: flex;
justify-content: space-around;
flex-direction: column
}
.column-justify-evenly {
display: flex;
justify-content: space-evenly;
flex-direction: column
}
.column-justify-end {
display: flex;
justify-content: flex-end;
flex-direction: column
}
.column-justify-start {
display: flex;
justify-content: flex-start;
flex-direction: column
}
.column-center {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column
}
.tp {
cursor: pointer;
&:hover {
color: #f7b93f;
}
}
.tbs {
border-bottom: 2px solid #f7b93f;
}
.divider {
width: 100%;
height: 1px;
background-color: #fff;
transform: scaleY(0.1);
}

66
src/styles/home.scss

@ -0,0 +1,66 @@
.home {
.income {
width: 60%;
height: 400px;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 .05rem 0.04rem rgba(8, 5, 3, .03);
}
.total-income {
width: 38%;
height: 400px;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 .05rem 0.04rem rgba(8, 5, 3, .03);
}
.CFD-box {
width: 360px;
height: 430px;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 .05rem 0.04rem rgba(8, 5, 3, .03);
}
}
.deposit {
.container {
width: 100%;
background-color: #fff;
box-shadow: 0 .05rem 0.04rem rgba(8, 5, 3, .03);
border-radius: 5px;
}
}
.account {
.container {
width: 100%;
background-color: #fff;
box-shadow: 0 .05rem 0.04rem rgba(8, 5, 3, .03);
border-radius: 5px;
.border {
border: 1px dashed #eff2f7;
}
}
}
.securify {
.container {
width: 100%;
background-color: #fff;
box-shadow: 0 .05rem 0.04rem rgba(8, 5, 3, .03);
border-radius: 5px;
}
}

75
src/styles/login.scss

@ -0,0 +1,75 @@
.login {
min-width: 100%;
min-height: 100vh;
background-image: url('../assets/b1_bg.png');
background-size: cover;
background-position: center;
padding: 10px;
.container {
width: 100%;
min-height: 100vh;
background-color: rgba(0, 0, 0, .5);
color: #fff;
.img {
max-width: 100%;
margin-top: 20px;
margin-bottom: 30px;
}
.verify-button {
height: 50px;
max-width: 160px;
margin-left: 10px;
font-size: 16px;
font-weight: normal;
}
.input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: hsla(0, 0%, 100%, .2);
border-radius: .25rem;
padding: 1rem 2rem;
width: 100%;
height: 50px;
border-width: 1px;
border-color: hsla(0, 0%, 100%, .1);
color: #fff;
&::placeholder {
color: #999;
}
}
.button {
width: 100%;
height: 52px;
background-color: #f7b93f;
color: #fff;
font-weight: bold;
font-size: 18px;
}
.verify-img {
position: absolute;
right: 0;
width: 100px;
height: 45px;
right: 2px;
top: 2px;
border-radius: 5px;
}
.create-button {
background-color: #383d49;
margin-top: 30px;
color: #f7b93f;
}
}
}

783
yarn.lock
File diff suppressed because it is too large
View File

Loading…
Cancel
Save