nice
This commit is contained in:
85
src/App.tsx
85
src/App.tsx
@ -1,4 +1,4 @@
|
|||||||
import { BrowserRouter as Router, Routes, Route, Navigate, Outlet, useLocation } from 'react-router-dom';
|
import { BrowserRouter as Router, Routes, Route, Outlet, useLocation, useNavigate } from 'react-router-dom';
|
||||||
import {useEffect, useState } from "react";
|
import {useEffect, useState } from "react";
|
||||||
|
|
||||||
import { ToastContainer } from "react-toastify";
|
import { ToastContainer } from "react-toastify";
|
||||||
@ -20,49 +20,14 @@ import Settings from "./pages/settings/settings"
|
|||||||
import useAuth from './auth/auth';
|
import useAuth from './auth/auth';
|
||||||
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
const theme = themeFromSourceColor(argbFromHex("ffddaf"));
|
|
||||||
const systemDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
||||||
applyTheme(theme, { target: document.body, dark: systemDark });
|
|
||||||
return (
|
|
||||||
<AuthProvider>
|
|
||||||
<>
|
|
||||||
<ToastContainer
|
|
||||||
position="top-right"
|
|
||||||
autoClose={2000}
|
|
||||||
hideProgressBar={false}
|
|
||||||
newestOnTop={false}
|
|
||||||
closeOnClick={false}
|
|
||||||
rtl={false}
|
|
||||||
theme={"light"}
|
|
||||||
// transition={Bounce}
|
|
||||||
/>
|
|
||||||
<Router>
|
|
||||||
<Routes>
|
|
||||||
<Route path="/login" element={<Login />} />
|
|
||||||
<Route path="/register" element={<Register />} />
|
|
||||||
|
|
||||||
<Route element={<PrivateRoute />}>
|
|
||||||
<Route path='/' element={<Home />} />
|
|
||||||
<Route path='/dashboard' element={<Dashboard />} />
|
|
||||||
<Route path='/settings' element={<Settings />} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route path="*" element={<div>404</div>} />
|
|
||||||
</Routes>
|
|
||||||
</Router>
|
|
||||||
</>
|
|
||||||
</AuthProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const PrivateRoute = () => {
|
const PrivateRoute = () => {
|
||||||
const { token, loading } = useAuth();
|
const { token, loading } = useAuth();
|
||||||
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [checked, setChecked] = useState(false);
|
const [checked, setChecked] = useState(false);
|
||||||
const [isValid, setIsValid] = useState(false);
|
const [isValid, setIsValid] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkAuth = async () => {
|
const checkAuth = async () => {
|
||||||
if (!token) {
|
if (!token) {
|
||||||
@ -83,10 +48,48 @@ const PrivateRoute = () => {
|
|||||||
return <div>Checking server availability...</div>;
|
return <div>Checking server availability...</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isValid) {
|
||||||
|
navigate(`/login?to=${location.pathname}`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return <Outlet />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
const theme = themeFromSourceColor(argbFromHex("ffddaf"));
|
||||||
|
const systemDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||||
|
applyTheme(theme, { target: document.body, dark: systemDark });
|
||||||
return (
|
return (
|
||||||
isValid
|
<AuthProvider>
|
||||||
? <Outlet />
|
<>
|
||||||
: <Navigate to="/login" state={{ from: location }} replace />
|
<ToastContainer
|
||||||
|
position="top-right"
|
||||||
|
autoClose={2000}
|
||||||
|
hideProgressBar={false}
|
||||||
|
newestOnTop={false}
|
||||||
|
closeOnClick={false}
|
||||||
|
rtl={false}
|
||||||
|
theme={systemDark ? "light" : "dark"}
|
||||||
|
// transition={Bounce}
|
||||||
|
/>
|
||||||
|
<Router>
|
||||||
|
<Routes>
|
||||||
|
<Route path="/login" element={<Login />} />
|
||||||
|
<Route path="/register" element={<Register />} />
|
||||||
|
|
||||||
|
<Route element={<PrivateRoute />}>
|
||||||
|
<Route path='/' element={<Home />} />
|
||||||
|
<Route path='/dashboard' element={<Dashboard />} />
|
||||||
|
<Route path='/settings' element={<Settings />} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path="*" element={<div>404</div>} />
|
||||||
|
</Routes>
|
||||||
|
</Router>
|
||||||
|
</>
|
||||||
|
</AuthProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form-field input {
|
.form-field input {
|
||||||
width: 100%;
|
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
border: 2px solid #ddd;
|
border: 2px solid #ddd;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|||||||
@ -20,5 +20,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
display: flex;
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100vw;
|
||||||
|
max-width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,34 @@
|
|||||||
.login-div {
|
.login {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
width: 100vw;
|
||||||
justify-content: flex-end;
|
height: 100vh;
|
||||||
align-items: center;
|
max-width:100%;
|
||||||
border: 1px solid green;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-right-div {
|
.login-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border: 1px solid blue;
|
justify-content: center;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 5vw;
|
||||||
|
margin-left: 5vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-left {
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
background-color: black;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.login-block {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,52 +41,55 @@ const Login = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="login-right-div">
|
<div className="login">
|
||||||
<h2
|
<div className="login-left">
|
||||||
style={{
|
<video className='videoTag' autoPlay loop muted>
|
||||||
display: "flex"
|
<source src={"./test.mp4"} type='video/mp4' />
|
||||||
}}
|
</video>
|
||||||
>
|
</div>
|
||||||
Login
|
<div className="login-right">
|
||||||
</h2>
|
<div className="login-block">
|
||||||
<form onSubmit={handleSubmit}
|
<h2>
|
||||||
style={{
|
Login
|
||||||
flexDirection: "column",
|
</h2>
|
||||||
display: "flex",
|
<form onSubmit={handleSubmit}
|
||||||
gap: "10px",
|
style={{
|
||||||
alignItems: "center",
|
flexDirection: "column",
|
||||||
}}
|
display: "flex",
|
||||||
noValidate
|
gap: "10px",
|
||||||
>
|
alignItems: "center",
|
||||||
<FormField
|
}}
|
||||||
type="text"
|
noValidate
|
||||||
placeholder="Username"
|
>
|
||||||
value={username}
|
<FormField
|
||||||
onChange={(e) => setUsername(e.target.value)}
|
type="text"
|
||||||
required
|
placeholder="Username"
|
||||||
showError={usernameEmpty}
|
value={username}
|
||||||
errorMessage="Please enter your username"
|
onChange={(e) => setUsername(e.target.value)}
|
||||||
className="test1"
|
required
|
||||||
/>
|
showError={usernameEmpty}
|
||||||
<FormField
|
errorMessage="Please enter your username"
|
||||||
type="password"
|
/>
|
||||||
placeholder="Password"
|
<FormField
|
||||||
value={password}
|
type="password"
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
placeholder="Password"
|
||||||
required
|
value={password}
|
||||||
showError={passwordEmpty}
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
errorMessage="Please enter your password"
|
required
|
||||||
className="test2"
|
showError={passwordEmpty}
|
||||||
/>
|
errorMessage="Please enter your password"
|
||||||
<button type="submit"
|
/>
|
||||||
style={{
|
<button type="submit"
|
||||||
display: "flex",
|
style={{
|
||||||
marginTop: "10px"
|
display: "flex",
|
||||||
}}
|
marginTop: "10px"
|
||||||
>
|
}}
|
||||||
Login
|
>
|
||||||
</button>
|
Login
|
||||||
</form>
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,66 +0,0 @@
|
|||||||
div {
|
|
||||||
margin: auto;
|
|
||||||
text-align:center;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
input {
|
|
||||||
margin: auto;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
button {
|
|
||||||
/* margin: auto; */
|
|
||||||
background-color: var(--background_dark);
|
|
||||||
color: var(--text_dark);
|
|
||||||
border: 2px solid black;
|
|
||||||
border-color: var(--buttons-main-color);
|
|
||||||
padding: 16px 32px;
|
|
||||||
text-align: center;
|
|
||||||
text-decoration: none;
|
|
||||||
font-size: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 12px;
|
|
||||||
transition-duration: 0.4s;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:hover {
|
|
||||||
background-color: var(--buttons-main-color);
|
|
||||||
color: var(--text_dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
button:active {
|
|
||||||
background-color: var(--buttons-press-color);
|
|
||||||
color: var(--text_dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
button span {
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
transition: 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
button span:after {
|
|
||||||
/* content: '\00bb'; */
|
|
||||||
content: '\2317';
|
|
||||||
position: absolute;
|
|
||||||
opacity: 0;
|
|
||||||
top: 0;
|
|
||||||
right: -20px;
|
|
||||||
transition: 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:hover span {
|
|
||||||
padding-right: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:hover span:after {
|
|
||||||
opacity: 1;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bold-text {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
@ -1,89 +0,0 @@
|
|||||||
import React from "react"
|
|
||||||
import './login.css'
|
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
|
||||||
|
|
||||||
const Login = () => {
|
|
||||||
state = {
|
|
||||||
username: "",
|
|
||||||
password: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
const { setAuth } = useContext(AuthContext); // используем контекст для получения значений isAuthenticated и setAuth
|
|
||||||
|
|
||||||
const navigate = useNavigate(); // используем хук useNavigate для навигации по маршрутам
|
|
||||||
const location = useLocation(); // используем хук useLocation для получения текущего маршрута
|
|
||||||
|
|
||||||
// получаем маршрут, на который нужно перенаправить пользователя после авторизации
|
|
||||||
const from = location.state?.from?.pathname || '/';
|
|
||||||
|
|
||||||
validateString = (text:string) => {
|
|
||||||
return text ? text : false
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
name="username"
|
|
||||||
placeholder="Username"
|
|
||||||
onChange={(e) => this.setState({username: e.target.value})}
|
|
||||||
onBlur={(e) => this.setState({username: e.target.value})}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
name="password"
|
|
||||||
placeholder="Password"
|
|
||||||
onChange={(e) => this.setState({password: e.target.value})}
|
|
||||||
onBlur={(e) => this.setState({password: e.target.value})}
|
|
||||||
color="#FF0000"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="bold-text">
|
|
||||||
Your username is: {this.state.username}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{
|
|
||||||
(() => {
|
|
||||||
const r: string | boolean = this.validateString(this.state.username);
|
|
||||||
if (r) {
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
return "invalid";
|
|
||||||
})()
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div className="bold-text">
|
|
||||||
Your password is: {this.state.password}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{
|
|
||||||
(() => {
|
|
||||||
const r: string | boolean = this.validateString(this.state.password);
|
|
||||||
if (r) {
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
return "invalid";
|
|
||||||
})()
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
onClick={() =>
|
|
||||||
this.validateString(this.state.username)
|
|
||||||
&&
|
|
||||||
this.validateString(this.state.password)
|
|
||||||
? false
|
|
||||||
: alert("Please enter not blank username and password")
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
Login
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Login;
|
|
||||||
Reference in New Issue
Block a user