update
parent
b0ae509531
commit
78c3c92905
|
@ -8,12 +8,12 @@
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-spring/web": "^9.4.4",
|
|
||||||
"@reduxjs/toolkit": "^1.8.0",
|
"@reduxjs/toolkit": "^1.8.0",
|
||||||
"autoprefixer": "^10.4.2",
|
"autoprefixer": "^10.4.2",
|
||||||
"axios": "^0.26.1",
|
"axios": "^0.26.1",
|
||||||
"daisyui": "^2.6.4",
|
"daisyui": "^2.6.4",
|
||||||
"filesize": "^8.0.7",
|
"filesize": "^8.0.7",
|
||||||
|
"framer-motion": "^6.2.8",
|
||||||
"mtproton": "^6.0.0",
|
"mtproton": "^6.0.0",
|
||||||
"postcss": "^8.4.8",
|
"postcss": "^8.4.8",
|
||||||
"prettier-plugin-tailwindcss": "^0.1.8",
|
"prettier-plugin-tailwindcss": "^0.1.8",
|
||||||
|
|
118
pnpm-lock.yaml
118
pnpm-lock.yaml
|
@ -1,7 +1,6 @@
|
||||||
lockfileVersion: 5.3
|
lockfileVersion: 5.3
|
||||||
|
|
||||||
specifiers:
|
specifiers:
|
||||||
'@react-spring/web': ^9.4.4
|
|
||||||
'@redux-devtools/core': ^3.11.0
|
'@redux-devtools/core': ^3.11.0
|
||||||
'@reduxjs/toolkit': ^1.8.0
|
'@reduxjs/toolkit': ^1.8.0
|
||||||
'@tailwindcss/forms': ^0.5.0
|
'@tailwindcss/forms': ^0.5.0
|
||||||
|
@ -12,6 +11,7 @@ specifiers:
|
||||||
axios: ^0.26.1
|
axios: ^0.26.1
|
||||||
daisyui: ^2.6.4
|
daisyui: ^2.6.4
|
||||||
filesize: ^8.0.7
|
filesize: ^8.0.7
|
||||||
|
framer-motion: ^6.2.8
|
||||||
mtproton: ^6.0.0
|
mtproton: ^6.0.0
|
||||||
postcss: ^8.4.8
|
postcss: ^8.4.8
|
||||||
prettier: ^2.5.1
|
prettier: ^2.5.1
|
||||||
|
@ -26,12 +26,12 @@ specifiers:
|
||||||
vite: ^2.8.6
|
vite: ^2.8.6
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@react-spring/web': 9.4.4_react-dom@17.0.2+react@17.0.2
|
|
||||||
'@reduxjs/toolkit': 1.8.0_react-redux@7.2.6+react@17.0.2
|
'@reduxjs/toolkit': 1.8.0_react-redux@7.2.6+react@17.0.2
|
||||||
autoprefixer: 10.4.2_postcss@8.4.8
|
autoprefixer: 10.4.2_postcss@8.4.8
|
||||||
axios: 0.26.1
|
axios: 0.26.1
|
||||||
daisyui: 2.6.4_554c024960c0d85659bdf1e5e950b7f7
|
daisyui: 2.6.4_554c024960c0d85659bdf1e5e950b7f7
|
||||||
filesize: 8.0.7
|
filesize: 8.0.7
|
||||||
|
framer-motion: 6.2.8_react-dom@17.0.2+react@17.0.2
|
||||||
mtproton: 6.0.0
|
mtproton: 6.0.0
|
||||||
postcss: 8.4.8
|
postcss: 8.4.8
|
||||||
prettier-plugin-tailwindcss: 0.1.8_prettier@2.5.1
|
prettier-plugin-tailwindcss: 0.1.8_prettier@2.5.1
|
||||||
|
@ -325,6 +325,19 @@ packages:
|
||||||
to-fast-properties: 2.0.0
|
to-fast-properties: 2.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@emotion/is-prop-valid/0.8.8:
|
||||||
|
resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==}
|
||||||
|
requiresBuild: true
|
||||||
|
dependencies:
|
||||||
|
'@emotion/memoize': 0.7.4
|
||||||
|
dev: false
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@emotion/memoize/0.7.4:
|
||||||
|
resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==}
|
||||||
|
dev: false
|
||||||
|
optional: true
|
||||||
|
|
||||||
/@jridgewell/resolve-uri/3.0.5:
|
/@jridgewell/resolve-uri/3.0.5:
|
||||||
resolution: {integrity: sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==}
|
resolution: {integrity: sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
|
@ -362,60 +375,6 @@ packages:
|
||||||
fastq: 1.13.0
|
fastq: 1.13.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@react-spring/animated/9.4.4_react@17.0.2:
|
|
||||||
resolution: {integrity: sha512-e9xnuBaUTD+NolKikUmrGWjX8AVCPyj1GcEgjgq9E+0sXKv46UY7cm2EmB6mUDTxWIDVKebARY++xT4nGDraBQ==}
|
|
||||||
peerDependencies:
|
|
||||||
react: ^16.8.0 || ^17.0.0
|
|
||||||
dependencies:
|
|
||||||
'@react-spring/shared': 9.4.4_react@17.0.2
|
|
||||||
'@react-spring/types': 9.4.4
|
|
||||||
react: 17.0.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@react-spring/core/9.4.4_react@17.0.2:
|
|
||||||
resolution: {integrity: sha512-llgb0ljFyjMB0JhWsaFHOi9XFT8n1jBMVs1IFY2ipIBerWIRWrgUmIpakLPHTa4c4jwqTaDSwX90s2a0iN7dxQ==}
|
|
||||||
peerDependencies:
|
|
||||||
react: ^16.8.0 || ^17.0.0
|
|
||||||
dependencies:
|
|
||||||
'@react-spring/animated': 9.4.4_react@17.0.2
|
|
||||||
'@react-spring/rafz': 9.4.4
|
|
||||||
'@react-spring/shared': 9.4.4_react@17.0.2
|
|
||||||
'@react-spring/types': 9.4.4
|
|
||||||
react: 17.0.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@react-spring/rafz/9.4.4:
|
|
||||||
resolution: {integrity: sha512-5ki/sQ06Mdf8AuFstSt5zbNNicRT4LZogiJttDAww1ozhuvemafNWEHxhzcULgCPCDu2s7HsroaISV7+GQWrhw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@react-spring/shared/9.4.4_react@17.0.2:
|
|
||||||
resolution: {integrity: sha512-ySVgScDZlhm/+Iy2smY9i/DDrShArY0j6zjTS/Re1lasKnhq8qigoGiAxe8xMPJNlCaj3uczCqHy3TY9bKRtfQ==}
|
|
||||||
peerDependencies:
|
|
||||||
react: ^16.8.0 || ^17.0.0
|
|
||||||
dependencies:
|
|
||||||
'@react-spring/rafz': 9.4.4
|
|
||||||
'@react-spring/types': 9.4.4
|
|
||||||
react: 17.0.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@react-spring/types/9.4.4:
|
|
||||||
resolution: {integrity: sha512-KpxKt/D//q/t/6FBcde/RE36LKp8PpWu7kFEMLwpzMGl9RpcexunmYOQJWwmJWtkQjgE1YRr7DzBMryz6La1cQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@react-spring/web/9.4.4_react-dom@17.0.2+react@17.0.2:
|
|
||||||
resolution: {integrity: sha512-iJmOLdhcuizriUlu/xqBc5y8KaFts+UI+iC+GxyTwBtzxA9czKiSAZW2ESuhG8stafa3jncwjfTQQp84KN36cw==}
|
|
||||||
peerDependencies:
|
|
||||||
react: ^16.8.0 || ^17.0.0
|
|
||||||
react-dom: ^16.8.0 || ^17.0.0
|
|
||||||
dependencies:
|
|
||||||
'@react-spring/animated': 9.4.4_react@17.0.2
|
|
||||||
'@react-spring/core': 9.4.4_react@17.0.2
|
|
||||||
'@react-spring/shared': 9.4.4_react@17.0.2
|
|
||||||
'@react-spring/types': 9.4.4
|
|
||||||
react: 17.0.2
|
|
||||||
react-dom: 17.0.2_react@17.0.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@redux-devtools/core/3.11.0_34362ad81a919891909cf289bf01b934:
|
/@redux-devtools/core/3.11.0_34362ad81a919891909cf289bf01b934:
|
||||||
resolution: {integrity: sha512-LE8GF/9pttlIOYJWqOfwbAvYAokRNHCEtCu0DfA11tksYVwIX79CpB2jIJH/KH7n1LzwXPCCl4MOFnyZH4przg==}
|
resolution: {integrity: sha512-LE8GF/9pttlIOYJWqOfwbAvYAokRNHCEtCu0DfA11tksYVwIX79CpB2jIJH/KH7n1LzwXPCCl4MOFnyZH4przg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -1099,6 +1058,29 @@ packages:
|
||||||
resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
|
resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/framer-motion/6.2.8_react-dom@17.0.2+react@17.0.2:
|
||||||
|
resolution: {integrity: sha512-4PtBWFJ6NqR350zYVt9AsFDtISTqsdqna79FvSYPfYDXuuqFmiKtZdkTnYPslnsOMedTW0pEvaQ7eqjD+sA+HA==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.8 || ^17.0.0 || ^18.0.0'
|
||||||
|
react-dom: '>=16.8 || ^17.0.0 || ^18.0.0'
|
||||||
|
dependencies:
|
||||||
|
framesync: 6.0.1
|
||||||
|
hey-listen: 1.0.8
|
||||||
|
popmotion: 11.0.3
|
||||||
|
react: 17.0.2
|
||||||
|
react-dom: 17.0.2_react@17.0.2
|
||||||
|
style-value-types: 5.0.0
|
||||||
|
tslib: 2.3.1
|
||||||
|
optionalDependencies:
|
||||||
|
'@emotion/is-prop-valid': 0.8.8
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/framesync/6.0.1:
|
||||||
|
resolution: {integrity: sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==}
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.3.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fsevents/2.3.2:
|
/fsevents/2.3.2:
|
||||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||||
|
@ -1152,6 +1134,10 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
function-bind: 1.1.1
|
function-bind: 1.1.1
|
||||||
|
|
||||||
|
/hey-listen/1.0.8:
|
||||||
|
resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/history/5.3.0:
|
/history/5.3.0:
|
||||||
resolution: {integrity: sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==}
|
resolution: {integrity: sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -1385,6 +1371,15 @@ packages:
|
||||||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||||
engines: {node: '>=8.6'}
|
engines: {node: '>=8.6'}
|
||||||
|
|
||||||
|
/popmotion/11.0.3:
|
||||||
|
resolution: {integrity: sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==}
|
||||||
|
dependencies:
|
||||||
|
framesync: 6.0.1
|
||||||
|
hey-listen: 1.0.8
|
||||||
|
style-value-types: 5.0.0
|
||||||
|
tslib: 2.3.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/postcss-js/4.0.0_postcss@8.4.8:
|
/postcss-js/4.0.0_postcss@8.4.8:
|
||||||
resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==}
|
resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==}
|
||||||
engines: {node: ^12 || ^14 || >= 16}
|
engines: {node: ^12 || ^14 || >= 16}
|
||||||
|
@ -1637,6 +1632,13 @@ packages:
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/style-value-types/5.0.0:
|
||||||
|
resolution: {integrity: sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==}
|
||||||
|
dependencies:
|
||||||
|
hey-listen: 1.0.8
|
||||||
|
tslib: 2.3.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/supports-color/5.5.0:
|
/supports-color/5.5.0:
|
||||||
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
|
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
@ -1699,6 +1701,10 @@ packages:
|
||||||
is-number: 7.0.0
|
is-number: 7.0.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/tslib/2.3.1:
|
||||||
|
resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/typedarray-to-buffer/3.1.5:
|
/typedarray-to-buffer/3.1.5:
|
||||||
resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==}
|
resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
import { BrowserRouter, Route, Routes } from "react-router-dom";
|
import { BrowserRouter, Route, Routes } from "react-router-dom";
|
||||||
import Home from "./pages/home";
|
import Home from "./pages/home";
|
||||||
import Dashboard from "./pages/dashboard";
|
import Dashboard from "./pages/dashboard";
|
||||||
|
import { Provider } from "react-redux";
|
||||||
|
import store from "./store";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
|
<Provider store={store}>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Home />} />
|
<Route path="/" element={<Home />} />
|
||||||
<Route path="/dashboard" element={<Dashboard />} />
|
<Route path="/dashboard" element={<Dashboard />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
</Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,49 @@
|
||||||
import { useState } from "react";
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
import { animated, useSpring } from "@react-spring/web";
|
import { useEffect, useState } from "react";
|
||||||
|
import { sendSignInCode, signIn } from "../../telegram/telegram";
|
||||||
|
import user, {
|
||||||
|
login,
|
||||||
|
setCodeHash,
|
||||||
|
useSelectCodeHash,
|
||||||
|
useSelectorIsLoggedIn,
|
||||||
|
} from "../../store/user";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { getMe } from "../../telegram/user";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
let [hiddenDrawer, setHiddenDrawer] = useState(true);
|
let [hiddenDrawer, setHiddenDrawer] = useState(true);
|
||||||
|
let dispatch = useDispatch();
|
||||||
|
let handleHiddenDrawer = (e: MouseEvent) => {
|
||||||
|
if (!hiddenDrawer) {
|
||||||
|
console.log(e.target);
|
||||||
|
setHiddenDrawer(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener("click", handleHiddenDrawer);
|
||||||
|
return () => document.removeEventListener("click", handleHiddenDrawer);
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let dcID = localStorage.getItem("defaultDcId");
|
||||||
|
console.log(dcID);
|
||||||
|
let authKey = localStorage.getItem(dcID + "authKey");
|
||||||
|
let serverSalt = localStorage.getItem(dcID + "serverSalt");
|
||||||
|
console.log("authKey = %s", authKey);
|
||||||
|
console.log("serverSalt = %s", serverSalt);
|
||||||
|
getMe()
|
||||||
|
.then((user) => {
|
||||||
|
dispatch(login(user));
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.log(e);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={""}>
|
<div className={"h-screen w-screen bg-amber-400"}>
|
||||||
<Logo />
|
<Logo />
|
||||||
|
|
||||||
<Menu
|
<Menu
|
||||||
|
@ -38,32 +77,58 @@ function Logo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function Menu(props: { onClickLogin: () => void }) {
|
function Menu(props: { onClickLogin: () => void }) {
|
||||||
|
let loggedIn = useSelectorIsLoggedIn();
|
||||||
return (
|
return (
|
||||||
<ul
|
<motion.ul
|
||||||
|
initial={{
|
||||||
|
y: 20,
|
||||||
|
opacity: 0,
|
||||||
|
}}
|
||||||
|
animate={{
|
||||||
|
y: 0,
|
||||||
|
opacity: 1,
|
||||||
|
transition: { type: "tween", duration: 1, ease: "easeInOut" },
|
||||||
|
}}
|
||||||
className={
|
className={
|
||||||
"absolute right-8 top-0 m-4 flex justify-end gap-4 rounded-xl bg-base-200 px-12 py-4 shadow"
|
"absolute right-8 top-0 m-4 flex justify-end gap-4 rounded-l bg-base-200 px-8 py-2 shadow"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
className={"cursor-pointer select-none text-base hover:text-base-300"}
|
className={
|
||||||
|
"cursor-pointer select-none p-2 text-base hover:bg-amber-400 hover:bg-opacity-50"
|
||||||
|
}
|
||||||
>
|
>
|
||||||
定价
|
定价
|
||||||
</li>
|
</li>
|
||||||
|
{!loggedIn ? (
|
||||||
<li
|
<li
|
||||||
className={"cursor-pointer select-none text-base hover:text-base-300"}
|
className={
|
||||||
|
"cursor-pointer select-none p-2 text-base hover:text-gray-500"
|
||||||
|
}
|
||||||
onClick={props.onClickLogin}
|
onClick={props.onClickLogin}
|
||||||
>
|
>
|
||||||
注册/登录
|
注册/登录
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
) : (
|
||||||
|
<Link to={"dashboard"}>
|
||||||
|
<li
|
||||||
|
className={
|
||||||
|
"cursor-pointer select-none p-2 text-base hover:text-gray-500"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
文件列表
|
||||||
|
</li>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</motion.ul>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function FileButton(props: { openLogin: () => void }) {
|
function FileButton(props: { openLogin: () => void }) {
|
||||||
return (
|
return (
|
||||||
<div className={"btn-group absolute top-1/2 left-1/4"}>
|
<div className={"btn-group absolute top-1/2 left-1/4"}>
|
||||||
<button className={"btn"}>上传文件</button>
|
<button className={"btn rounded-l-full"}>上传文件</button>
|
||||||
<button className={"btn"} onClick={props.openLogin}>
|
<button className={"btn rounded-r-full"} onClick={props.openLogin}>
|
||||||
口令下载
|
口令下载
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -71,39 +136,100 @@ function FileButton(props: { openLogin: () => void }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function Drawer(props: { hidden: boolean; setHidden: () => void }) {
|
function Drawer(props: { hidden: boolean; setHidden: () => void }) {
|
||||||
const styles = useSpring({
|
let width = window.innerWidth;
|
||||||
opacity: !props.hidden ? 1 : 0,
|
|
||||||
visibility: !props.hidden ? "visible" : "hidden",
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<animated.div style={styles}>
|
<AnimatePresence>
|
||||||
<div className={"absolute right-0 z-0 h-screen w-screen"}>
|
{props.hidden ? (
|
||||||
<div
|
""
|
||||||
className={"absolute z-40 h-screen w-screen bg-gray-400 opacity-60"}
|
) : (
|
||||||
onClick={() => {
|
<div className={"h-screen w-screen overflow-hidden"}>
|
||||||
props.setHidden();
|
<motion.div
|
||||||
}}
|
initial={{ translateX: width / 2 }}
|
||||||
></div>
|
animate={{ translateX: 0 }}
|
||||||
|
exit={{ translateX: width / 2 }}
|
||||||
|
transition={{ type: "spring", bounce: 0.25 }}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
"absolute right-0 z-50 h-screen w-1/3 origin-right bg-base-100"
|
"absolute right-0 z-50 flex h-screen w-1/2 origin-right justify-center bg-base-100"
|
||||||
|
}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.nativeEvent.stopImmediatePropagation();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
"z-50 flex h-full w-3/4 flex-col items-center justify-center gap-8"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className={"container mt-20 flex items-center justify-center"}>
|
<LoginContent setHidden={props.setHidden} />
|
||||||
<LoginContent />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</animated.div>
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function LoginContent() {
|
function LoginContent(props: { setHidden: () => void }) {
|
||||||
|
let [phone, setPhone] = useState("");
|
||||||
|
let [phoneCode, setPhoneCode] = useState("");
|
||||||
|
let codeHash = useSelectCodeHash();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
let handleSendCode = () => {
|
||||||
|
sendSignInCode(phone)
|
||||||
|
.then((hash) => {
|
||||||
|
dispatch(setCodeHash(hash));
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
alert(e.error_message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let handleLogin = () => {
|
||||||
|
signIn(phone, phoneCode, codeHash)
|
||||||
|
.then((e) => {
|
||||||
|
dispatch(login(e.user));
|
||||||
|
props.setHidden();
|
||||||
|
alert("登录成功");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
alert(e.error_message);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div className={"flex flex-col gap-8 rounded-2xl border-2 p-16"}>
|
||||||
|
{codeHash === "" ? (
|
||||||
|
<>
|
||||||
<div className={"flex bg-base-100"}>
|
<div className={"flex bg-base-100"}>
|
||||||
<label className={"label mr-5 text-base-content"}>手机号</label>
|
<label className={"label mr-5 text-base-content"}>手机号</label>
|
||||||
<input className={"input input-primary"} />
|
<input
|
||||||
|
className={"input input-primary"}
|
||||||
|
value={phone}
|
||||||
|
onChange={(e) => setPhone(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button className={"btn self-end"} onClick={handleSendCode}>
|
||||||
|
发送验证码
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className={"flex flex-col gap-8"}>
|
||||||
|
<label className={"label mr-5 text-base-content"}>验证码</label>
|
||||||
|
<input
|
||||||
|
className={"input input-primary"}
|
||||||
|
value={phoneCode}
|
||||||
|
onChange={(e) => setPhoneCode(e.target.value)}
|
||||||
|
/>
|
||||||
|
<button className={"btn self-end"} onClick={handleLogin}>
|
||||||
|
登录
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit";
|
||||||
|
import userReducer from "./store/user";
|
||||||
|
|
||||||
|
export default configureStore({
|
||||||
|
reducer: {
|
||||||
|
user: userReducer,
|
||||||
|
},
|
||||||
|
middleware: getDefaultMiddleware({
|
||||||
|
serializableCheck: false,
|
||||||
|
}),
|
||||||
|
});
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
const User = createSlice({
|
||||||
|
name: "user",
|
||||||
|
initialState: {
|
||||||
|
codeHash: "",
|
||||||
|
isLoggedIn: false,
|
||||||
|
user: {},
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
login: (state, action) => {
|
||||||
|
state.isLoggedIn = true;
|
||||||
|
state.user = action.payload;
|
||||||
|
},
|
||||||
|
logout: (state) => {
|
||||||
|
state.isLoggedIn = false;
|
||||||
|
state.user = {};
|
||||||
|
},
|
||||||
|
setCodeHash: (state, action) => {
|
||||||
|
state.codeHash = action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function useSelectorUser() {
|
||||||
|
return useSelector((state: any) => state.user.user);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSelectorIsLoggedIn() {
|
||||||
|
return useSelector((state: any) => state.user.isLoggedIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSelectCodeHash() {
|
||||||
|
return useSelector((state: any) => state.user.codeHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const { login, logout, setCodeHash } = User.actions;
|
||||||
|
|
||||||
|
export default User.reducer;
|
|
@ -15,7 +15,7 @@ class TelegramHelper {
|
||||||
this.client = new Client({
|
this.client = new Client({
|
||||||
api_id: appID,
|
api_id: appID,
|
||||||
api_hash: appHash,
|
api_hash: appHash,
|
||||||
test: false,
|
test: true,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let createTransport = function (dc: any, crypto: any) {
|
let createTransport = function (dc: any, crypto: any) {
|
||||||
|
@ -47,15 +47,15 @@ class TelegramHelper {
|
||||||
hideLog: boolean = false
|
hideLog: boolean = false
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
try {
|
try {
|
||||||
!hideLog && console.log(`${method} req\n${params}`);
|
!hideLog && console.debug(`${method} req\n%o`, params);
|
||||||
options = {
|
options = {
|
||||||
...options,
|
...options,
|
||||||
};
|
};
|
||||||
let resp = await this.client.call(method, params, options);
|
let resp = await this.client.call(method, params, options);
|
||||||
!hideLog && console.log(`${method} resp\n${resp}`);
|
!hideLog && console.debug(`${method} resp\n%o`, resp);
|
||||||
return resp;
|
return resp;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
!hideLog && console.log(`${method} error:`, error);
|
!hideLog && console.debug(`${method} error\n%o`, error);
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const { error_code, error_message } = error;
|
const { error_code, error_message } = error;
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from "vite";
|
||||||
import react from '@vitejs/plugin-react'
|
import react from "@vitejs/plugin-react";
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()]
|
server: {
|
||||||
})
|
port: 3000,
|
||||||
|
host: true,
|
||||||
|
},
|
||||||
|
plugins: [react()],
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue