начало подвязки к беку
This commit is contained in:
parent
b92e54683b
commit
d9e7ba2c19
@ -2,36 +2,7 @@
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="3a23e62a-21bd-4f51-a89e-05a6cca5b71f" name="Changes" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/craco.config.js" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/assets/Icons/ZeroIcons.svg" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/assets/Icons/tariffs-time/Infinity.svg" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/assets/Icons/tariffs-time/NineIcons.svg" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/assets/Icons/tariffs-time/OneIcons.svg" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/assets/Icons/tariffs-time/SixIcons.svg" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/assets/Icons/tariffs-time/ThreeIcons.svg" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/assets/Icons/tariffs-volume/FiveIcons.svg" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/assets/Icons/tariffs-volume/FourIcons.svg" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/assets/Icons/tariffs-volume/OneIcons.svg" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/assets/Icons/tariffs-volume/ThreeIcons.svg" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/assets/Icons/tariffs-volume/TwoIcons.svg" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/components/icons/CalendarIcon.tsx" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/lib/IconsCreate.tsx" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/pages/Tariffs/FreeTariffCard.tsx" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/pages/Tariffs/TariffCardTimeAndVolume.tsx" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/pages/Tariffs/TariffsTime.tsx" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/pages/Tariffs/TariffsVolume.tsx" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/tsconfig.extend.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/package-lock.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/App.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/App.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/components/icons/CustomIcon.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/icons/CustomIcon.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/pages/CustomTariff/TariffConstructorCard.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/CustomTariff/TariffConstructorCard.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/pages/Tariffs/CalendarIcon.tsx" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/pages/Tariffs/TariffCard.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/Tariffs/TariffCard.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/pages/Tariffs/Tariffs.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/Tariffs/Tariffs.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/utils/decorators.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/decorators.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/tsconfig.json" beforeDir="false" afterPath="$PROJECT_DIR$/tsconfig.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@ -53,7 +24,7 @@
|
||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/../amo" />
|
||||
<property name="node.js.detected.package.eslint" value="true" />
|
||||
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
||||
<property name="nodejs_package_manager_path" value="yarn" />
|
||||
@ -71,7 +42,7 @@
|
||||
<workItem from="1678978983245" duration="601000" />
|
||||
<workItem from="1679058561119" duration="973000" />
|
||||
<workItem from="1679059624759" duration="2016000" />
|
||||
<workItem from="1679061985124" duration="718000" />
|
||||
<workItem from="1679061985124" duration="1330000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
787
package-lock.json
generated
787
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,7 @@
|
||||
"@types/node": "^16.7.13",
|
||||
"@types/react": "^18.0.0",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"axios": "^1.3.4",
|
||||
"formik": "^2.2.9",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"notistack": "^2.0.8",
|
||||
@ -23,7 +24,8 @@
|
||||
"react-scripts": "5.0.1",
|
||||
"reconnecting-eventsource": "^1.6.2",
|
||||
"typescript": "^4.9.3",
|
||||
"web-vitals": "^2.1.0"
|
||||
"web-vitals": "^2.1.0",
|
||||
"zustand": "^4.3.6"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "craco start",
|
||||
|
@ -2,6 +2,7 @@ import { Box, IconButton, Link, Typography, useMediaQuery, useTheme } from "@mui
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useFormik } from "formik";
|
||||
import { authStore } from "@stores/makeRequest"
|
||||
|
||||
import CustomButton from "@components/CustomButton";
|
||||
import InputTextfield from "@components/InputTextfield";
|
||||
@ -37,6 +38,7 @@ export default function Signin() {
|
||||
const theme = useTheme();
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
const navigate = useNavigate();
|
||||
const { makeRequest } = authStore()
|
||||
const formik = useFormik<Values>({
|
||||
initialValues: {
|
||||
email: "",
|
||||
@ -44,18 +46,17 @@ export default function Signin() {
|
||||
},
|
||||
validate,
|
||||
onSubmit: async (values: Values) => {
|
||||
const result = await apiRequestHandler.login({
|
||||
email: values.email,
|
||||
password: values.password,
|
||||
});
|
||||
if (result instanceof ApiError) {
|
||||
enqueueSnackbar(`Error: ${result.message}`);
|
||||
} else if (result instanceof Error) {
|
||||
console.log(result);
|
||||
enqueueSnackbar(`Unknown error`);
|
||||
} else {
|
||||
// navigate("/"); // TODO
|
||||
}
|
||||
makeRequest({
|
||||
url: "https://hub.pena.digital/auth/login",
|
||||
body: {
|
||||
"email": values.email,
|
||||
"password": values.password
|
||||
},
|
||||
useToken: false
|
||||
})
|
||||
.catch((e:any) => {
|
||||
enqueueSnackbar(e.message ? e.message : `Unknown error`)
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -10,6 +10,7 @@ import PenaLogo from "@components/PenaLogo";
|
||||
import { ApiError } from "@utils/api/types";
|
||||
|
||||
import { useSnackbar } from "notistack";
|
||||
import {authStore} from "@stores/makeRequest";
|
||||
|
||||
interface Values {
|
||||
login: string;
|
||||
@ -43,6 +44,7 @@ export default function Signup() {
|
||||
const theme = useTheme();
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
const navigate = useNavigate();
|
||||
const { makeRequest } = authStore()
|
||||
const formik = useFormik<Values>({
|
||||
initialValues: {
|
||||
login: "",
|
||||
@ -53,22 +55,20 @@ export default function Signup() {
|
||||
},
|
||||
validate,
|
||||
onSubmit: async (values: Values) => {
|
||||
const result = await apiRequestHandler.register({
|
||||
email: values.email,
|
||||
login: values.login,
|
||||
password: values.password,
|
||||
phoneNumber: values.phoneNumber,
|
||||
});
|
||||
if (result instanceof ApiError) {
|
||||
enqueueSnackbar(`Error: ${result.message}`);
|
||||
return;
|
||||
} else if (result instanceof Error) {
|
||||
console.log(result);
|
||||
enqueueSnackbar(`Unknown error`);
|
||||
return;
|
||||
} else {
|
||||
// navigate("/signin"); // TODO
|
||||
}
|
||||
makeRequest({
|
||||
url: "https://hub.pena.digital/auth/register",
|
||||
body: {
|
||||
"login": values.email,
|
||||
"email": values.email,
|
||||
"password": values.repeatPassword,
|
||||
"phoneNumber": "--"
|
||||
},
|
||||
useToken: false
|
||||
})
|
||||
.catch((e:any) => {
|
||||
console.log(e)
|
||||
enqueueSnackbar(e.response && e.response.data && e.response.data.message ? e.response.data.message : `Unknown error`)
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
|
90
src/stores/makeRequest.ts
Normal file
90
src/stores/makeRequest.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import axios from 'axios'
|
||||
import { create } from "zustand";
|
||||
import { persist } from "zustand/middleware";
|
||||
|
||||
type Token = string
|
||||
interface AuthStore {
|
||||
token: Token
|
||||
// setToken: () => Promise;
|
||||
}
|
||||
interface FirstRequest {
|
||||
method?: string
|
||||
url: string
|
||||
body?: unknown
|
||||
useToken?: boolean
|
||||
contentType?: boolean
|
||||
}
|
||||
|
||||
export const authStore = create<any>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
token: "",
|
||||
makeRequest: (props:FirstRequest) => {
|
||||
const newProps = {...props, HC: (newToken:Token) => set({ token: newToken }),token: get().token}
|
||||
return (
|
||||
new Promise(async (resolve, reject) => {
|
||||
await makeRequest(newProps)
|
||||
.then(r => resolve(r))
|
||||
.catch(r => reject(r))
|
||||
})
|
||||
)
|
||||
},
|
||||
clearToken: () => set({token: ""})
|
||||
}),
|
||||
{
|
||||
name: "token"
|
||||
}
|
||||
)
|
||||
);
|
||||
interface MakeRequest extends FirstRequest {
|
||||
HC: (newToken:Token) => void
|
||||
token:Token
|
||||
}
|
||||
|
||||
function makeRequest({
|
||||
method = "post",
|
||||
url,
|
||||
body,
|
||||
useToken = true,
|
||||
contentType = false,
|
||||
HC,
|
||||
token
|
||||
}: MakeRequest) {
|
||||
//В случае 401 рефреш должен попробовать вызваться 1 раз
|
||||
let counterRefresh = true
|
||||
let headers: any = {}
|
||||
if (useToken) headers["Authorization"] = token
|
||||
if (contentType) headers["Content-Type"] = "application/json"
|
||||
return axios({
|
||||
url: url,
|
||||
method: method,
|
||||
headers: headers,
|
||||
data: body
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data && response.data.accessToken) {
|
||||
HC(response.data.accessToken)
|
||||
}
|
||||
return response
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.response.status == 401 && counterRefresh) {
|
||||
refresh().then(response => {
|
||||
if (response.data && response.data.accessToken) HC(response.data.accessToken)
|
||||
counterRefresh = false
|
||||
})
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
throw error
|
||||
})
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
return axios("https://admin.pena.digital/auth/refresh", {
|
||||
headers: {
|
||||
"Authorization": localStorage.getItem('AT'),
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
}
|
15
src/utils/privateRoute.tsx
Normal file
15
src/utils/privateRoute.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import * as React from "react";
|
||||
import { useLocation, Navigate } from 'react-router-dom'
|
||||
import {authStore} from "@stores/makeRequest";
|
||||
|
||||
export default ({ children }: any) => {
|
||||
const location = useLocation()
|
||||
const { token } = authStore()
|
||||
console.log(token)
|
||||
//Если пользователь авторизован, перенаправляем его на нужный путь. Иначе выкидываем в регистрацию
|
||||
if (token) {
|
||||
return children
|
||||
}
|
||||
return <Navigate to="/" state={{from: location}} />
|
||||
|
||||
}
|
@ -1,11 +1,15 @@
|
||||
import * as React from "react";
|
||||
import { useLocation, Navigate } from "react-router-dom";
|
||||
import { useLocation, Navigate } from 'react-router-dom'
|
||||
import {authStore} from "@stores/makeRequest";
|
||||
|
||||
export default ({ children }: any) => {
|
||||
const location = useLocation();
|
||||
//Если пользователь авторизован, перенаправляем его в приложение. Иначе пускаем куда хотел
|
||||
if (localStorage.getItem("AT")) {
|
||||
return <Navigate to="/users" state={{ from: location }} />;
|
||||
}
|
||||
return children;
|
||||
};
|
||||
const location = useLocation()
|
||||
const { token } = authStore()
|
||||
console.log(token)
|
||||
//Если пользователь авторизован, перенаправляем его в приложение. Иначе пускаем куда хотел
|
||||
if (token) {
|
||||
return <Navigate to="/users" state={{from: location}} />
|
||||
}
|
||||
return children
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,8 @@
|
||||
"paths": {
|
||||
"@root/*": ["./*"],
|
||||
"@utils/*": ["./utils/*"],
|
||||
"@components/*": ["./components/*"]
|
||||
"@components/*": ["./components/*"],
|
||||
"@stores/*": ["./stores/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user