added main login code

This commit is contained in:
SnippetsX 2024-10-14 00:19:06 +03:00
parent f2aac31a5f
commit e9df2f7a2f
20 changed files with 20561 additions and 0 deletions

23
.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

7
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": []
}

20134
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

43
package.json Normal file
View File

@ -0,0 +1,43 @@
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@mui/material": "^6.1.3",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"eslint-plugin-react": "^7.37.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.27.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

15
public/index.html Normal file
View File

@ -0,0 +1,15 @@
<!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" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

BIN
public/logo192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
public/logo512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

25
public/manifest.json Normal file
View File

@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

3
public/robots.txt Normal file
View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

45
src/App.css Normal file
View File

@ -0,0 +1,45 @@
.board-row {
align-items: center;
display: flex;
justify-content: center;
min-width: 210px;
}
.board-row:after {
clear: both;
content: "";
display: table;
}
.square {
background-color: #6b3b3b;
border: 1px solid #999;
float: left;
font-size: 23px;
font-weight: bold;
line-height: 10px;
height: 64px;
margin-right: -1px;
margin-top: -1px;
padding: 0;
text-align: center;
width: 34px;
}
.square:focus {
outline: none;
}
.square:hover {
background-color: #00a2ff;
}
.game {
display: flex;
flex-direction: row;
}
.game-info {
margin-left: 20px;
min-width: 180px;
}

40
src/App.js Normal file
View File

@ -0,0 +1,40 @@
import LoginPage from './Login/LoginPage';
import React, { useState, useEffect } from 'react';
import {
Typography,
Box,
} from '@mui/material';
import Login from './Login/LoginPage';
import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom';
import { checkAuthCookie } from './Login/CookieCreating';
function App() {
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
const token = checkAuthCookie();
setIsAuthenticated(!!token);
}, []);
return (
<Router>
<Routes>
<Route
path="/login"
element={isAuthenticated ? <Navigate to="/dashboard" /> : <Login />}
/>
<Route
path="/dashboard"
element={isAuthenticated ? <Login /> : <Navigate to="/login" />}
/>
<Route
path="/"
element={<Navigate to={isAuthenticated ? "/dashboard" : "/login"} />}
/>
</Routes>
</Router>
);
}
export default App;

View File

@ -0,0 +1,29 @@
export const createAuthCookie = (token) => {
const expirationDate = new Date();
expirationDate.setDate(expirationDate.getDate() + 7); // Set expiration to 7 days from now
const cookieValue = encodeURIComponent(token);
const cookieString = `authToken=${cookieValue}; expires=${expirationDate.toUTCString()}; path=/; SameSite=Strict; Secure; domain=admin.lcsa.ru`;
document.cookie = cookieString;
};
export const checkAuthCookie = () => {
const cookies = document.cookie.split(';');
const authCookie = cookies.find(cookie => cookie.trim().startsWith('authToken='));
if (!authCookie) {
return null; // Cookie not found
}
const [, token] = authCookie.split('=');
const decodedToken = decodeURIComponent(token);
// Check if the cookie has expired
const expirationDate = new Date(document.cookie.match(/expires=([^;]+)/)[1]);
if (expirationDate < new Date()) {
return null; // Cookie has expired
}
return decodedToken;
};

120
src/Login/LoginPage.js Normal file
View File

@ -0,0 +1,120 @@
import React, { useState } from 'react';
import {
Container,
TextField,
Button,
Typography,
Box,
} from '@mui/material';
import { ThemeProvider } from '@mui/material/styles';
import theme from '../theme';
const LoginPageWithTheme = () => (
<ThemeProvider theme={theme}>
<LoginPage />
</ThemeProvider>
);
let isPasswordIncorrect = null;
const LoginPage = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (event) => {
event.preventDefault();
// Here you would typically handle the login logic
console.log('Login attempt with:', email, password);
isPasswordIncorrect = true;
};
return (
<>
<Box
sx={{
width: '100%',
backgroundColor: '#4e00ba',
color: 'white',
padding: 2,
textAlign: 'bottom',
}}
>
<Typography variant="h6">
Admin Dashboard
</Typography>
</Box>
<Container maxWidth="xs">
<Box
sx={{
marginTop: 5,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Typography component="h1" variant="h5">
Sign in to Admin Panel
</Typography>
<Box component="form" onSubmit={handleSubmit} noValidate sx={{ mt: 1 }}>
<TextField
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<TextField
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
value={password}
onChange={(e) => setPassword(e.target.value)}
error={isPasswordIncorrect}
helperText={isPasswordIncorrect ? "Incorrect password" : ""}
InputProps={{
className: isPasswordIncorrect ? 'shake-animation' : '',
}}
/>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
>
Sign In
</Button>
</Box>
</Box>
</Container>
<Box sx={{
position: 'fixed',
bottom: 0,
left: 0,
right: 0,
textAlign: 'center',
padding: '10px',
backgroundColor: 'background.paper'
}}>
<Typography variant="body2" color="text.secondary">
© {new Date().getFullYear()} LCSA and SnippetsX. Все права защищены.
</Typography>
</Box>
</>
);
};
export default LoginPageWithTheme;

View File

@ -0,0 +1,17 @@
import axios from 'axios';
const API_BASE_URL = 'https://api.admin.lcsa.ru'; // Replace with your actual API base URL
export const sendLoginCredentials = async (username, password) => {
/*try {
const response = await axios.post(`${API_BASE_URL}/login`, {
username,
password
});
return response.data;
} catch (error) {
console.error('Login error:', error);
throw error;
}*/
return false
};

13
src/index.css Normal file
View File

@ -0,0 +1,13 @@
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;
}

17
src/index.js Normal file
View File

@ -0,0 +1,17 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

13
src/reportWebVitals.js Normal file
View File

@ -0,0 +1,13 @@
const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

5
src/setupTests.js Normal file
View File

@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

12
src/theme.js Normal file
View File

@ -0,0 +1,12 @@
import { createTheme } from '@mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: '#4e00ba',
},
},
});
export default theme;