Skip to content

Commit

Permalink
add page for user info
Browse files Browse the repository at this point in the history
  • Loading branch information
jmrodriguezc committed Aug 19, 2024
1 parent e006944 commit c91682e
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 47 deletions.
7 changes: 7 additions & 0 deletions app/src/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@
font-size: var(--nl-font-size);
}

.login-content .p-inputtext, .login-content .p-password-input {
width: 300px;
}
.register-content .p-inputtext, .register-content .p-password-input {
width: 300px;
}


/*
* DATATABLE: PIPELINES, WORKFLOWS,...
Expand Down
4 changes: 3 additions & 1 deletion app/src/components/AppContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import {
import {
AppToaster,
} from '../services/toastServices';
import RoleBasedRoute from './RoleBasedRoute';
import NavigationTabs from './NavigationTabs';
import MainPage from './MainPage';
import Login from './Login';
import Register from './Register';
import RoleBasedRoute from './RoleBasedRoute';
import User from './User';
import Pipelines from './Pipelines';
import Parameters from './Parameters';
import Workflows from './Workflows';
Expand Down Expand Up @@ -47,6 +48,7 @@ const AppContent = () => {
<Switch>
<Route path="/login" component={Login} />
<Route path="/register" component={Register} />
<RoleBasedRoute path="/user" component={User} allowedRoles={['guest','admin']} />
<RoleBasedRoute path="/workflows/:workflowId/:attemptId/datasets/:datasetId" component={Parameters} allowedRoles={['guest','admin']} />
<RoleBasedRoute path="/workflows/:workflowId/:attemptId" component={Workflow} allowedRoles={['guest','admin']} />
<RoleBasedRoute path="/workflows" component={Workflows} allowedRoles={['guest','admin']} />
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/AppHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const AppHeader = () => {
items: [{
label: 'Profile',
icon: 'pi pi-fw pi-user',
command: () => history.push('/user-info')
command: () => history.push('/user')
},{
label: 'Logout',
icon: 'pi pi-fw pi-sign-out',
Expand Down
31 changes: 20 additions & 11 deletions app/src/components/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import {
GUEST_USER,
GUEST_PWD
} from '../constants';
import {
showError,
} from '../services/toastServices';
import { userServices } from '../services/userServices';


Expand All @@ -29,11 +32,11 @@ import { userServices } from '../services/userServices';
const Login = () => {

// Declare variables
const { login } = useContext(userServices);
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [empty, setEmpty] = useState({});
const history = useHistory();
const { login, error, success } = useContext(userServices);

// Check if fields are empty
const emptyValidation = () => {
Expand All @@ -50,24 +53,32 @@ const Login = () => {
if (Object.keys(validationEmpties).length > 0) {
setEmpty(validationEmpties);
} else {
setEmpty({});
await login(username, password);
history.push('/pipelines');
try {
setEmpty({});
await login(username, password);
history.push('/pipelines');
} catch (err) {
showError('', `${err}`);
}
}
};

// Login guest user
const handleGuestLogin = async (e) => {
await login(GUEST_USER, GUEST_PWD);
history.push('/pipelines');
e.preventDefault();
try {
await login(GUEST_USER, GUEST_PWD);
history.push('/pipelines');
} catch (err) {
showError('', `${err}`);
}
};

// Go to register page
const goToRegister = () => {
history.push('/register');
};



return (
<div className='login-content'>
<div className='flex flex-column md:flex-row'>
Expand All @@ -80,8 +91,6 @@ const Login = () => {
className='w-10rem'
onClick={handleGuestLogin}
/>
{error && <div style={{ color: 'red' }}>{error}</div>}
{success && <div style={{ color: 'green' }}>{success}</div>}
</div>

<div className='w-full md:w-2'>
Expand All @@ -92,7 +101,7 @@ const Login = () => {
<div className='w-full md:w-7 flex flex-column align-items-center gap-3 py-5'>
<div className='flex flex-wrap align-items-center gap-2'>
{/* <label htmlFor='username'>Username</label> */}
<InputText id='username' placeholder='Username' type='text' className='w-14rem' value={username} onChange={(e) => setUsername(e.target.value)} />
<InputText id='username' placeholder='Username' type='text'value={username} onChange={(e) => setUsername(e.target.value)} />
{empty.username && <Message severity='error' text='Username is required' />}
</div>
<div className='flex flex-wrap align-items-center gap-2'>
Expand Down
66 changes: 57 additions & 9 deletions app/src/components/Register.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,75 @@
/*
* Import libraries
*/

import React, {
useState,
useContext
} from 'react';
import {
useHistory
} from 'react-router-dom';
import { Divider } from 'primereact/divider';
import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button';
import { Message } from 'primereact/message';
import { Password } from 'primereact/password';

import {
showError,
} from '../services/toastServices';
import { userServices } from '../services/userServices';


/*
* Components
*/

const Register = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [empty, setEmpty] = useState({});
// const [isLoggingIn, setIsLoggingIn] = useState(false); // state to prevent multiple logins
const history = useHistory();

const emptyValidation = () => {
const newErrors = {};
if (!username) newErrors.username = 'Username is required';
if (!password) newErrors.password = 'Password is required';
return newErrors;
const newErrors = {};
if (!username) newErrors.username = 'Username is required';
if (!password) newErrors.password = 'Password is required';
if (!confirmPassword) newErrors.confirmPassword = 'Confirmation password is required';
if (password && confirmPassword && password !== confirmPassword) {
newErrors.confirmPassword = 'Passwords do not match';
}
return newErrors;
};

const { register } = useContext(userServices);

const { register, login } = useContext(userServices);

// Register user
const handleRegister = async (e) => {
e.preventDefault();
const validationEmpties = emptyValidation();
if (Object.keys(validationEmpties).length > 0) {
setEmpty(validationEmpties);
} else {
setEmpty({});
await register(username, password);
// first register
try {
await register(username, password);
// if everything was right, then login and redirect to "user" page
try {
await login(username, password);
history.push('/user');
} catch (err) {
showError('', `Error during login: ${err}`);
console.error('Error during login: ', err);
}
} catch (err) {
showError('', `Error during registration: ${err}`);
console.error('Error during registration: ', err);
}
}
};

Expand All @@ -52,21 +90,31 @@ const Register = () => {
return (
<div className='register-content'>

<div className='w-full md:w-7 flex flex-column align-items-center gap-3 py-5'>
<div className='text-left mb-4'>
<h2>Register a New User</h2>
<p>Please fill in the details below to create a new account.</p>
</div>

<div className='w-full md:w-7 flex flex-column align-items-left gap-3 py-5 ml-3'>
<div className='flex flex-wrap align-items-center gap-2'>
{/* <label htmlFor='username'>Username</label> */}
<InputText id='username' placeholder='Username' type='text' className='w-14rem' value={username} onChange={(e) => setUsername(e.target.value)} />
<InputText id='username' placeholder='Username' type='text' value={username} onChange={(e) => setUsername(e.target.value)} />
{empty.username && <Message severity='error' text='Username is required' />}
</div>
<div className='flex flex-wrap align-items-center gap-2'>
{/* <label htmlFor='password'>Password</label> */}
<Password id='password' type='password' placeholder='Password' className='w-14rem' value={password} header={header} footer={footer} onChange={(e) => setPassword(e.target.value)} toggleMask />
<Password id='password' type='password' placeholder='Password' value={password} header={header} footer={footer} onChange={(e) => setPassword(e.target.value)} toggleMask />
{empty.password && <Message severity='error' text='Password is required' />}
</div>
<div className='flex flex-wrap align-items-center gap-2'>
<Password id='confirmPassword' type='password' placeholder='Confirm Password' value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} toggleMask />
{empty.confirmPassword && <Message severity='error' text={empty.confirmPassword} />}
</div>
<Button label='Sign In' icon='pi pi-user-plus' severity='success' className='w-10rem' onClick={handleRegister}></Button>
</div>

</div>

);
};

Expand Down
65 changes: 65 additions & 0 deletions app/src/components/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Import libraries
*/

import React, {
useState,
useEffect,
useContext
} from 'react';
import { Card } from 'primereact/card';
import { ProgressSpinner } from 'primereact/progressspinner';

import {
showError,
} from '../services/toastServices';
import { userServices } from '../services/userServices';


/*
* Components
*/

const User = () => {
const [userData, setUserData] = useState(null);
const { auth, info } = useContext(userServices);
const [loading, setLoading] = useState(true);

useEffect(() => {
const fetchUserInfo = async () => {
if (auth && auth.username) {
try {
const data = await info(auth.username);
setLoading(false);
setUserData(data);
} catch (err) {
showError('', `Error during login: ${err}`);
}
} else {
showError('', 'User is not authenticated');
}
};

fetchUserInfo();

}, [auth, info]);

return (
<div className='user-info'>
{loading ? (
<div className="flex justify-content-center flex-wrap">
<ProgressSpinner />
</div>
) : (
<Card title="User Information" style={{ width: '25rem', marginBottom: '2em' }}>
<p><strong>ID:</strong> {userData._id}</p>
<p><strong>Username:</strong> {userData.username}</p>
<p><strong>Role:</strong> {userData.role}</p>
<p><strong>Date Created:</strong> {new Date(userData.date_created).toLocaleString()}</p>
</Card>
)}
</div>
);
};

export default User;
Loading

0 comments on commit c91682e

Please sign in to comment.