Skip to content
Snippets Groups Projects
Commit 048eb4e5 authored by Embruch, Gerd's avatar Embruch, Gerd
Browse files

addes signup; cleaned up

parent 1eb8a09a
Branches
No related tags found
No related merge requests found
......@@ -24,8 +24,10 @@ cp ./.env.template.local ./.env.production.local
# Roadmap
- [ ] complete pages
- [ ] sign up
- [ ] resend verification code
- [ ] onboarding / RAGChat
- [ ] admin-login
- [ ] admin-page with LLM options
- [ ] fix errors
- [ ] fix JWT renewal
- [ ] fix axios' JWT auto renewal
- [ ] check width of label & submit on cleanLayout
\ No newline at end of file
......@@ -391,14 +391,16 @@ cp ./.env.template.local ./.env.production.local
<ul>
<li><input type="checkbox" id="checkbox0"><label for="checkbox0">complete pages</label>
<ul>
<li><input type="checkbox" id="checkbox1"><label for="checkbox1">sign up</label></li>
<li><input type="checkbox" id="checkbox1"><label for="checkbox1">resend verification code</label></li>
<li><input type="checkbox" id="checkbox2"><label for="checkbox2">onboarding / RAGChat</label></li>
<li><input type="checkbox" id="checkbox3"><label for="checkbox3">admin-login</label></li>
<li><input type="checkbox" id="checkbox4"><label for="checkbox4">admin-page with LLM options</label></li>
</ul>
</li>
<li><input type="checkbox" id="checkbox3"><label for="checkbox3">fix errors</label>
<li><input type="checkbox" id="checkbox5"><label for="checkbox5">fix errors</label>
<ul>
<li><input type="checkbox" id="checkbox4"><label for="checkbox4">fix JWT renewal</label></li>
<li><input type="checkbox" id="checkbox5"><label for="checkbox5">check width of label &amp; submit on cleanLayout</label></li>
<li><input type="checkbox" id="checkbox6"><label for="checkbox6">fix axios' JWT auto renewal</label></li>
<li><input type="checkbox" id="checkbox7"><label for="checkbox7">check width of label &amp; submit on cleanLayout</label></li>
</ul>
</li>
</ul>
......
......@@ -60,7 +60,6 @@ function FlatListEdit({ methods, initialItems, fieldName, keyName, validator, ta
const isMail = validator(input);
return isMail.success ?? keyName;
});
console.log('validInputs', validInputs);
// handle invalid inputs
// strip off valid entries from input to get remaining invalid inputs
......
......@@ -49,7 +49,6 @@ function FlatListEdit({ initialItems = [], fieldName = '', tooltip = '', columns
});
// exit if no valid items found
if (validInputs.length === 0) return;
console.log('validInputs', validInputs);
// handle invalid inputs
// strip off valid entries from input to get remaining invalid inputs
......@@ -60,7 +59,6 @@ function FlatListEdit({ initialItems = [], fieldName = '', tooltip = '', columns
// set error message on input
methods.setError('addItem', { message: 'invalid entries remaining' });
}
console.log('invalidInputs', invalidInputs);
// handle valid inputs
......
......@@ -31,7 +31,6 @@ function AuthState({ children }) {
credentials,
{ withCredentials: true }
);
console.log;
// set current user to login and merge accessToken into currentUser
dispatchCurrentUser({ type: USER_ACTIONS.SET, payload: { ...result.data.record } });
setAccessToken(result.data.token);
......
......@@ -56,7 +56,6 @@ function ForgotPassword() {
setFlashMsg(result.data?.message);
} catch (error) {
// catch the error
console.error(error);
mergeBackendValidation(error.response.status, error.response.data, methods.setError);
}
}
......
......@@ -82,7 +82,6 @@ function Login() {
setFlashMsg(result.data?.message);
} catch (err) {
console.log(err);
// merge front & backend validation errors
mergeBackendValidation(err.response.status, err.response.data, methods.setError);
}
......@@ -105,8 +104,9 @@ function Login() {
</form>
</FormProvider>
<div className="mt-4">
<Link to="/reset_password">Forgot your Password?</Link>
<div className="mt-4 flex justify-between">
<Link to="/reset_password">Reset Password</Link>
<Link to="/signup">Create an account</Link>
</div>
</>
);
......
......@@ -28,7 +28,6 @@ function Logout() {
// set flash mmessagesg
setFlashMsg(result.data?.message);
} catch (err) {
console.error(err);
mergeBackendValidation(500, err);
}
}
......
......@@ -65,7 +65,6 @@ function ResetPasswordForm() {
setFlashMsg(result.data?.message);
} catch (error) {
// catch the error
console.error(error);
mergeBackendValidation(error.response.status, error.response.data, methods.setError);
}
}
......
import React, { useEffect } from 'react';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import { useAuth } from '../../contexts/Auth/AuthState';
import { FormProvider, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from "zod";
import { toast } from 'react-toastify';
import { mergeBackendValidation, setFlashMsg } from '../../utils/ErrorHandling';
import Input from '../../components/form/Input';
import Submit from '../../components/form/Submit';
import { Helmet } from 'react-helmet-async';
import Heading from '../../components/font/Heading';
import validator from 'validator';
import api from '../../utils/AxiosConfig';
function Signup() {
// #################################
// VALIDATION SCHEMA
// #################################
const schema = z.object({
name: z.string().min(1),
username: z.string().min(1),
email: z.string().email(),
password: z.string().refine((val) => val && validator.isStrongPassword(val), {
message: 'This value must be min 6 characters long and contain uppercase, lowercase, number, specialchar.',
}),
passwordConfirm: z.string(),
}).refine((data) => data.password === data.passwordConfirm, {
message: "Passwords don't match",
path: ["passwordConfirm"],
});
// #################################
// HOOKS
// #################################
// ### CONNECT AUTH CONTEXT
const { signup } = useAuth();
// ### MAKE USE OF NAVIGATION
const redirect = useNavigate();
// ### MAKE USE OF location state to fetch former requested page
const { state } = useLocation();
// ### PREPARE FORM
const methods = useForm({
resolver: zodResolver(schema),
mode: 'onBlur',
defaultValues: {
name: '',
username: '',
email: '',
password: '',
passwordConfirm: ''
}
});
// #################################
// FUNCTIONS
// #################################
// ### HANDLE SUBMITTING LOGIN FORM
async function handleSendForm(record) {
try {
// send data to API
const result = await api.post(`/users/signup`, record);
// if successfull redirect to login page
redirect(`/login`);
// FIX: flash message not dislayed
setFlashMsg(result.data?.message);
} catch (err) {
// merge front & backend validation errors
mergeBackendValidation(err.response.status, err.response.data, methods.setError);
}
}
// #################################
// OUTPUT
// #################################
return (
<>
{/* render page title */}
<Helmet><title>[{import.meta.env.VITE_APP_NAME}]</title></Helmet>
<Heading level="1">ZBH-Portal LogIn</Heading>
<FormProvider {...methods} >
<form onSubmit={methods.handleSubmit(handleSendForm)}>
<Input name='name' type='text' title='Name' className='h-16' autoFocus={true} />
<Input name='username' type='text' title='username' className='h-16' />
<Input name='email' type='mail' title='E-Mail' className='h-16' />
<Input name='password' type='password' title='password' className='h-16' />
<Input name='passwordConfirm' type='password' title='confirm password' className='h-16' />
<Submit value='Signup' />
</form>
</FormProvider>
<div className="mt-4">
<Link to="/login">Back to Login</Link>
</div>
</>
);
}
export default Signup;
\ No newline at end of file
import { zodResolver } from '@hookform/resolvers/zod';
import React, { useRef, useState } from 'react';
import { Helmet } from 'react-helmet-async';
import { FormProvider, useForm, useFormContext } from 'react-hook-form';
import { Link, useNavigate, useParams } from 'react-router-dom';
import { z } from 'zod';
import Input from '../../components/form/Input';
import Submit from '../../components/form/Submit';
import { useAuth } from '../../contexts/Auth/AuthState';
import { mergeBackendValidation, setFlashMsg } from '../../utils/ErrorHandling';
import Heading from '../../components/font/Heading';
import api from '../../utils/AxiosConfig';
function Verify() {
// #################################
// VALIDATION SCHEMA
// #################################
// TODO limit file size via .env
// TODO check for file types
const schema = z.object({
token: z.string().min(1),
});
// #################################
// HOOKS
// #################################
// FETCH TOKEN FROM URL
const { token } = useParams();
// SET FORM
const methods = useForm({
resolver: zodResolver(schema),
mode: 'onSubmit',
defaultValues: {
token: token,
}
});
// ### ENABLE REDIRECTIONS
const redirect = useNavigate();
// #################################
// FUNCTIONS
// #################################
// ### HANDLE SUBMITTING FORM
async function handleSendForm(inputs) {
// TRY UPDATE
try {
// send data
const result = await api.post(`/users/confirmverification`, inputs);
redirect('/login');
// set flash message
setFlashMsg(result.data?.message);
} catch (error) {
// catch the error
mergeBackendValidation(error.response.status, error.response.data, methods.setError);
}
}
// #################################
// OUTPUT
// #################################
return (
<>
{/* render page title */}
<Helmet><title>[{import.meta.env.VITE_APP_NAME}] change E-Mail</title></Helmet>
<Heading level="1">Verify Account</Heading>
<FormProvider {...methods} >
<form onSubmit={methods.handleSubmit(handleSendForm)}>
<Input name='token' type='text' title='confirm token' required={true} />
<Submit value='Verify' />
</form>
</FormProvider>
<div className="my-4 flex justify-between">
<Link to="/login">Back to Login</Link>
</div>
</>
);
}
export default React.memo(Verify);
\ No newline at end of file
......@@ -50,6 +50,13 @@ export const sitemap = [{
}]
}, {
title: 'Others', element: <CleanLayout />, children: [
// SIGNUP
{
path: '/signup', children: [
{ index: true, element: loadComponent('User/Signup') },
{ path: ':token', element: loadComponent('User/Verify') }
]
},
// LOGIN
{ path: '/login', element: loadComponent('User/Login') },
// FORGOT PASSWORD
......
......@@ -33,13 +33,13 @@ api.interceptors.response.use(
return res;
},
async (err) => {
// console.log(err);
// console.log('JWT error: ', err);
// save original request config
const originalConfig = err.config;
// if access denied and not a retry already
// BUG: Infinit loop because _retry isn't set at runtime
// console.log(originalConfig);
// console.log(JSON.stringify(originalConfig));
// console.log('originalConfig: ',originalConfig);
// console.log('originalConfig: ',JSON.stringify(originalConfig));
if (originalConfig && err?.response?.status === 403 && originalConfig._retry !== true) {
// patch config to remember it's a retry
originalConfig._retry = true;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment