added some stuff to help get ready for after logging in
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
presets: [['@babel/preset-env', { targets: { node: 'current' } }]],
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.m?js/,
|
||||
resolve: {
|
||||
fullySpecified: false, // Disables strict extension requirements
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// eslint.config.js (Advanced alternative)
|
||||
import prettierPlugin from 'eslint-plugin-prettier'
|
||||
import prettierConfig from 'eslint-config-prettier'
|
||||
import prettierOptions from './prettier.config.js' // Import your config directly
|
||||
import importPlugin from 'eslint-plugin-import'
|
||||
|
||||
export default [
|
||||
{
|
||||
plugins: {
|
||||
prettier: prettierPlugin,
|
||||
import: importPlugin,
|
||||
},
|
||||
rules: {
|
||||
...prettierConfig.rules,
|
||||
'prettier/prettier': ['error', prettierOptions],
|
||||
'no-sequences': 'off',
|
||||
'no-console': 'warn',
|
||||
'import/first': 'error',
|
||||
'import/newline-after-import': 'error',
|
||||
'import/no-duplicates': 'error',
|
||||
'import/no-unresolved': 'error',
|
||||
'import/no-unused-modules': ['warn', { missingExports: true }],
|
||||
quotes: ['error', 'single'],
|
||||
semi: 'off',
|
||||
},
|
||||
},
|
||||
]
|
||||
Generated
+13213
-1710
File diff suppressed because it is too large
Load Diff
+23
-4
@@ -3,6 +3,11 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
"@fontsource/roboto": "^5.2.10",
|
||||
"@mui/icons-material": "^9.1.1",
|
||||
"@mui/material": "^9.1.1",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^16.3.2",
|
||||
@@ -10,13 +15,15 @@
|
||||
"react": "^19.2.7",
|
||||
"react-dom": "^19.2.7",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-transition-group": "4.4.2",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
"start": "craco start",
|
||||
"build": "craco build",
|
||||
"test": "craco test",
|
||||
"eject": "react-scripts eject",
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
@@ -35,5 +42,17 @@
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^8.0.1",
|
||||
"@babel/preset-env": "^8.0.2",
|
||||
"@craco/craco": "^7.1.0",
|
||||
"babel-jest": "^30.4.1",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-prettier": "^5.5.6",
|
||||
"jest": "^27.5.1",
|
||||
"prettier": "^3.8.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// prettier.config.js
|
||||
export default {
|
||||
trailingComma: 'es5',
|
||||
tabWidth: 2,
|
||||
semi: false, // Crucial: Sets semicolon removal.
|
||||
useTabs: true,
|
||||
singleQuote: true,
|
||||
}
|
||||
-38
@@ -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);
|
||||
}
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
import logo from './logo.svg';
|
||||
import './App.css';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<img src={logo} className="App-logo" alt="logo" />
|
||||
<p>
|
||||
Edit <code>src/App.js</code> and save to reload.
|
||||
</p>
|
||||
<a
|
||||
className="App-link"
|
||||
href="https://reactjs.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Learn React
|
||||
</a>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -1,8 +0,0 @@
|
||||
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();
|
||||
});
|
||||
@@ -1,3 +1,5 @@
|
||||
export default {
|
||||
baseUrl: "http://192.168.68.150:8469"
|
||||
}
|
||||
const constants = {
|
||||
baseUrl: 'http://192.168.68.150:8469',
|
||||
}
|
||||
|
||||
export default constants
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import Login from './pages/login';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
<Login />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
|
||||
+101
-50
@@ -1,22 +1,30 @@
|
||||
import React from 'react';
|
||||
import './style.css';
|
||||
import React, { useState } from 'react'
|
||||
import {
|
||||
Container,
|
||||
Box,
|
||||
Avatar,
|
||||
Typography,
|
||||
TextField,
|
||||
FormControlLabel,
|
||||
Checkbox,
|
||||
Button,
|
||||
Grid,
|
||||
Link,
|
||||
Paper
|
||||
} from '@mui/material'
|
||||
import LockOutlinedIcon from '@mui/icons-material/LockOutlined'
|
||||
import './style.css'
|
||||
|
||||
import { baseUrl } from "../../constants";
|
||||
import constants from "../../constants/index";
|
||||
|
||||
class Login extends React.Component {
|
||||
state = {
|
||||
username: '',
|
||||
password: ''
|
||||
};
|
||||
function Login() {
|
||||
const [formData, setFormData] = useState({ username: '', password: '' })
|
||||
const [error, setError] = useState(false)
|
||||
|
||||
handleChange = (event) => {
|
||||
this.setState({ [event.target.name]: event.target.value });
|
||||
};
|
||||
|
||||
handleSubmit = (event) => {
|
||||
const handleSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
const { username, password } = this.state;
|
||||
fetch(`${baseUrl}/auth/login`, {
|
||||
const { username, password } = formData;
|
||||
fetch(`${constants.baseUrl}/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@@ -34,41 +42,84 @@ class Login extends React.Component {
|
||||
alert('Invalid username or password');
|
||||
}
|
||||
})
|
||||
.catch(error => console.error(error));
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="login-page">
|
||||
<div className="login-container">
|
||||
<h2>Login</h2>
|
||||
<form onSubmit={this.handleSubmit} className="login-form">
|
||||
<div>
|
||||
<label htmlFor="username">Username:</label>
|
||||
<input
|
||||
type="text"
|
||||
name="username"
|
||||
value={this.state.username}
|
||||
onChange={this.handleChange}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="password">Password:</label>
|
||||
<input
|
||||
type="password"
|
||||
name="password"
|
||||
value={this.state.password}
|
||||
onChange={this.handleChange}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
.catch(error => console.error(error))
|
||||
}
|
||||
|
||||
return (
|
||||
<Container component="main" maxWidth="xs">
|
||||
<Paper
|
||||
elevation={6}
|
||||
sx={{
|
||||
marginTop: 8,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
padding: 4,
|
||||
borderRadius: 2
|
||||
}}
|
||||
>
|
||||
<Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}>
|
||||
<LockOutlinedIcon />
|
||||
</Avatar>
|
||||
<Typography component="h1" variant="h5">
|
||||
Sign in
|
||||
</Typography>
|
||||
<Box component="form" onSubmit={handleSubmit} noValidate sx={{ mt: 1 }}>
|
||||
<TextField
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
id="username"
|
||||
label="Username or Email"
|
||||
name="username"
|
||||
autoComplete="username"
|
||||
autoFocus
|
||||
value={formData.username}
|
||||
onChange={(e) => setFormData({ ...formData, username: e.target.value })}
|
||||
error={error}
|
||||
/>
|
||||
<TextField
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
name="password"
|
||||
label="Password"
|
||||
type="password"
|
||||
id="password"
|
||||
autoComplete="current-password"
|
||||
value={formData.password}
|
||||
onChange={(e) => setFormData({ ...formData, password: e.target.value })}
|
||||
error={error}
|
||||
helperText={error ? "Incorrect username or password" : ""}
|
||||
/>
|
||||
<FormControlLabel
|
||||
control={<Checkbox value="remember" color="primary" />}
|
||||
label="Remember me"
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
sx={{ mt: 3, mb: 2 }}
|
||||
>
|
||||
Sign In
|
||||
</Button>
|
||||
<Grid container>
|
||||
<Grid item xs>
|
||||
<Link href="#" variant="body2">
|
||||
Forgot password?
|
||||
</Link>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Link href="#" variant="body2">
|
||||
{"Don't have an account? Sign Up"}
|
||||
</Link>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Paper>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export default Login;
|
||||
export default Login
|
||||
|
||||
+12
-12
@@ -1,13 +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);
|
||||
});
|
||||
}
|
||||
};
|
||||
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;
|
||||
export default reportWebVitals
|
||||
|
||||
+1
-1
@@ -2,4 +2,4 @@
|
||||
// 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';
|
||||
import '@testing-library/jest-dom'
|
||||
|
||||
Reference in New Issue
Block a user