Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Create login interface#38 #41

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions webapp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.15.7",
"@mui/material": "^5.15.3",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^14.1.2",
Expand Down
20 changes: 0 additions & 20 deletions webapp/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,6 @@ import { RouterProvider } from 'react-router-dom';
function App() {
return (
<RouterProvider router={ router } />
/*<Container className='min-h-screen'>
<Container className='bg-white p-5' component="main" maxWidth="xs">
<CssBaseline />
<Typography component="h1" variant="h5" align="center" sx={{ marginTop: 2 }}>
Welcome to wiq_es1c
</Typography>
{showLogin ? <Login /> : <AddUser />}
<Typography component="div" align="center" sx={{ marginTop: 2 }}>
{showLogin ? (
<Link name="gotoregister" component="button" variant="body2" onClick={handleToggleView}>
Don't have an account? Register here.
</Link>
) : (
<Link component="button" variant="body2" onClick={handleToggleView}>
Already have an account? Login here.
</Link>
)}
</Typography>
</Container>
</Container>*/
);
}

Expand Down
161 changes: 93 additions & 68 deletions webapp/src/components/login/Login.js
Original file line number Diff line number Diff line change
@@ -1,78 +1,103 @@
// src/components/Login.js
import React, { useState } from 'react';
import axios from 'axios';
import { Container, Typography, TextField, Button, Snackbar } from '@mui/material';
import React from "react";
import {
Container,
Typography,
TextField,
Button,
CssBaseline,
Box,
FormControlLabel,
Checkbox,
Grid,
Avatar,
} from "@mui/material";
import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
import { Link } from "react-router-dom";

const Login = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loginSuccess, setLoginSuccess] = useState(false);
const [createdAt, setCreatedAt] = useState('');
const [openSnackbar, setOpenSnackbar] = useState(false);

const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000';

const loginUser = async () => {
try {
const response = await axios.post(`${apiEndpoint}/login`, { username, password });

// Extract data from the response
const { createdAt: userCreatedAt } = response.data;

setCreatedAt(userCreatedAt);
setLoginSuccess(true);

setOpenSnackbar(true);
} catch (error) {
setError(error.response.data.error);
}
};

const handleCloseSnackbar = () => {
setOpenSnackbar(false);
};
const handleSubmit = () => {};

return (
<Container className='text-white' component="main" maxWidth="xs" sx={{ marginTop: 0 }}>
{loginSuccess ? (
<div>
<Typography component="h1" variant="h5" sx={{ textAlign: 'center' }}>
Hello {username}!
</Typography>
<Typography component="p" variant="body1" sx={{ textAlign: 'center', marginTop: 2 }}>
Your account was created on {new Date(createdAt).toLocaleDateString()}.
</Typography>
</div>
) : (
<div>
<Container
component="main"
maxWidth="sm"
sx={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", minHeight: "100vh" }}
className="min-h-screen flex justify-center align-middle"
>
<Container
className="bg-white rounded-lg"
component="main"
maxWidth="sm"
>
<CssBaseline />
<Box
sx={{
padding: 3,
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Login
Iniciar Sesión
</Typography>
<TextField
margin="normal"
fullWidth
label="Username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<TextField
margin="normal"
fullWidth
label="Password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<Button variant="contained" color="primary" onClick={loginUser}>
Login
</Button>
<Snackbar open={openSnackbar} autoHideDuration={6000} onClose={handleCloseSnackbar} message="Login successful" />
{error && (
<Snackbar open={!!error} autoHideDuration={6000} onClose={() => setError('')} message={`Error: ${error}`} />
)}
</div>
)}
<Box
component="div"
onSubmit={handleSubmit}
noValidate
sx={{ mt: 1 }}
>
<TextField
margin="normal"
required
fullWidth
id="username"
label="Nombre de usuario"
name="username"
autoComplete="username"
autoFocus
/>
<TextField
margin="normal"
required
fullWidth
name="password"
label="Contraseña"
type="password"
id="password"
autoComplete="current-password"
/>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Recordarme"
/>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
>
Iniciar sesión
</Button>
<Grid container>
<Grid item xs>
<Link href="#" variant="body2">
<span></span>
</Link>
</Grid>
<Grid item>
<Link to={ '/register' } className="underline text-blue-600 hover:text-blue-900">
{"¿No tienes una cuenta? Regístrate"}
</Link>
</Grid>
</Grid>
</Box>
</Box>
</Container>
</Container>
);
};
Expand Down
57 changes: 8 additions & 49 deletions webapp/src/components/register/AddUser.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,17 @@
// src/components/AddUser.js
import React, { useState } from 'react';
import axios from 'axios';
import { Container, Typography, TextField, Button, Snackbar } from '@mui/material';

const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000';

const AddUser = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [openSnackbar, setOpenSnackbar] = useState(false);

const addUser = async () => {
try {
await axios.post(`${apiEndpoint}/adduser`, { username, password });
setOpenSnackbar(true);
} catch (error) {
setError(error.response.data.error);
}
};

const handleCloseSnackbar = () => {
setOpenSnackbar(false);
};


return (
<Container component="main" maxWidth="xs" sx={{ marginTop: 4 }}>
<Typography component="h1" variant="h5">
Add User
</Typography>
<TextField
name="username"
margin="normal"
fullWidth
label="Username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<TextField
name="password"
margin="normal"
fullWidth
label="Password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<Button variant="contained" color="primary" onClick={addUser}>
Add User
</Button>
<Snackbar open={openSnackbar} autoHideDuration={6000} onClose={handleCloseSnackbar} message="User added successfully" />
{error && (
<Snackbar open={!!error} autoHideDuration={6000} onClose={() => setError('')} message={`Error: ${error}`} />
)}
<Container
component="main"
maxWidth="xs"
sx={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", minHeight: "100vh" }}
className="min-h-screen flex justify-center align-middle"
>

</Container>
);
};
Expand Down
Loading