Commit cf746962 authored by Ermolaev Timur's avatar Ermolaev Timur

Merge branch 'task-31-feature/connect_registration_login_with_back' into 'development'

Task 31 feature/connect registration login with back

See merge request !19
parents ba39a466 17659ca3
This diff is collapsed.
......@@ -15,6 +15,7 @@
"license": "ISC",
"devDependencies": {
"@faker-js/faker": "^7.6.0",
"@types/multer": "^1.4.7",
"@types/node": "^18.11.8",
"@typescript-eslint/eslint-plugin": "^5.41.0",
"@typescript-eslint/parser": "^5.41.0",
......@@ -34,7 +35,9 @@
"cors": "^2.8.5",
"express": "^4.18.2",
"mongoose": "^6.7.0",
"multer": "^1.4.5-lts.1",
"nanoid": "^3.3.4",
"path": "^0.12.7",
"pg": "^8.8.0",
"reflect-metadata": "^0.1.13",
"typeorm": "^0.3.10"
......
*
!.gitignore
!_ACzV5N3r69BCMdpyqmGC.png
!lDmNHjGy5I2g1mWMR-n_c.png
!ExATi9O98uKnHxJ_wqUS2.png
!Aqvv8P8AgL_1xfC93CLKp.png
!NqUZ1Tq8pxbVptmhZPKcd.png
!46AlFQI4qKG2GpuJGdKbG.png
!ip5KgNCs30o3djHb8V_GR.png
!1tlFOumiL3MmH89O8OO6H.png
!nTVRV1ZePPe7tTIdGKKfX.png
\ No newline at end of file
import path = require('path');
const rootPath = __dirname;
export const config = {
rootPath,
uploadPath: path.join(rootPath, "public", "uploads"),
db: {
url: "mongodb://localhost/",
name: "planner"
}
};
......@@ -2,10 +2,25 @@ import express,{Router, Request, Response} from 'express';
import {User} from '../models/User';
import {myDataSource} from '../app-data-source';
import { nanoid } from 'nanoid';
import multer = require('multer');
import path = require("path");
import {config} from "../config"
const router:Router = express.Router();
const dataSource = myDataSource;
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, config.uploadPath);
},
filename: (req, file, cb) => {
cb(null, nanoid() + path.extname(file.originalname));
}
})
const upload = multer({ storage })
router.get('/', async (req : Request, res : Response):Promise<object> => {
const users = await dataSource
.getRepository(User)
......@@ -15,9 +30,10 @@ return res.send({users})
})
router.post('/', async (req : Request, res : Response):Promise<object> => {
router.post('/', upload.single("avatar"), async (req : Request, res : Response):Promise<object> => {
console.log(req.body)
const {name,surname,password,email, role} = req.body;
console.log(req.body)
const displayName = surname+' '+name[0]+'.'
const user = new User();
user.name = name;
......@@ -27,16 +43,20 @@ router.post('/', async (req : Request, res : Response):Promise<object> => {
user.email = email;
user.role = role;
user.generateToken()
console.log("user " + user)
await user.save();
console.log("saved")
const userToFront:User|null = await dataSource.manager.findOneBy(User, {
email: user.email
})
console.log("userToFront " + userToFront)
return res.send({userToFront})
})
router.post('/sessions/', async (req : Request, res : Response):Promise<object> => {
const {email, password} = req.body;
console.log("email" + email, "password" + password )
const user = await dataSource
.createQueryBuilder()
.select("user")
......@@ -46,6 +66,7 @@ router.post('/sessions/', async (req : Request, res : Response):Promise<object>
.getOne()
if(!user) return res.status(404).send({Message:'user not found'})
const isMatch:boolean = await user.checkPassword(password);
console.log("123")
if (!isMatch) return res.status(400).send({
error: "Wrong Password"
})
......
......@@ -6,6 +6,7 @@ import MyTasks from './containers/MyTasks/MyTasks';
import Login from './containers/Login/Login';
import Register from './containers/Register/Register';
import MonthCalendar from './containers/MonthCalendar/MonthCalendar';
import ForgottenPassword from "./containers/ForgottenPassword/ForgottenPassword";
const ProtectedRoute = ({isAllowed, roles, redirectUrl, children}) => {
const user = useSelector(state => state.users?.user);
......@@ -95,6 +96,7 @@ const App = () => {
}/>
<Route path={"/sign-in"} element={<Login/>}/>
<Route path={"/forgottenpassword"} element={<ForgottenPassword/>}/>
<Route path='*' element={<h1>404</h1>}/>
</Route>
</Routes>
......
import { Button, Grid} from "@mui/material";
import { NavLink } from "react-router-dom";
import FormElement from "../UI/Form/FormElement/FormElement";
const ResetPasswordForm = ({ state, onChange, onSubmit, getFieldError, buttonText }) => {
return <form onSubmit={onSubmit}>
<Grid container spacing={2}>
<FormElement
onChange={onChange}
name="email"
label="Enter your email address"
state={state}
error={getFieldError?.("email")}
/>
</Grid>
<Button
sx={{ mt: "15px" }}
type="submit"
fullWidth
variant="contained"
color="primary"
>
{buttonText}
</Button>
</form>
}
export default ResetPasswordForm;
\ No newline at end of file
import { Button, Grid} from "@mui/material";
// import { NavLink } from "react-router-dom";
import { NavLink } from "react-router-dom";
import FormElement from "../UI/Form/FormElement/FormElement";
const UserForm = ({ state, onChange, onSubmit, getFieldError, buttonText, resetPassword }) => {
......@@ -30,17 +30,17 @@ const UserForm = ({ state, onChange, onSubmit, getFieldError, buttonText, resetP
>
{buttonText}
</Button>
{/* <Button
<Button
component={NavLink}
to={"/forgottenpassword"}
sx={{ mt: "15px" }}
sx={{ mt: "15px", color: "red" }}
type="submit"
fullWidth
variant="contained"
color="primary"
color="inherit"
>
{resetPassword}
</Button> */}
</Button>
</form>
}
......
......@@ -25,13 +25,13 @@ const UserRegistrationForm = ({ state, onChange, onSubmit, getFieldError, button
state={state}
error={getFieldError?.("email")}
/>
<FormElement
{/* <FormElement
onChange={onChange}
name="number"
label="Number"
state={state}
error={getFieldError?.("number")}
/>
/> */}
<FormElement
onChange={onChange}
name="password"
......
// import { useState } from "react";
// import { useDispatch, useSelector } from "react-redux";
// import { useNavigate } from "react-router-dom";
// import Loader from "../../components/UI/Loader/Loader";
// import UserForm from "../../components/UserForm/UserForm";
// import { loginUser } from "../../store/actions/usersActions";
// import PersonIcon from '@mui/icons-material/Person';
// import styled from "@emotion/styled";
// import { Alert, Avatar, Container, Typography } from "@mui/material";
import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import Loader from "../../components/UI/Loader/Loader";
import { loginUser } from "../../store/actions/usersActions";
import PersonIcon from '@mui/icons-material/Person';
import styled from "@emotion/styled";
import { Alert, Avatar, Container, Typography } from "@mui/material";
import ResetPasswordForm from "../../components/UserForm/ResetPasswordForm";
// const StyledContainer = styled(Container)`
// padding-top: 30px;
// padding-bottom: 30px;
// box-shadow: 0 18px 30px 0 rgba(0, 0, 0, 0.6);
// border-radius: 6px;
// `;
const StyledContainer = styled(Container)`
padding-top: 30px;
padding-bottom: 30px;
box-shadow: 0 18px 30px 0 rgba(0, 0, 0, 0.6);
border-radius: 6px;
`;
// const StyledTitle = styled(Typography)`
// text-align: center;
// font-size: 30px;
// margin-bottom: 30px;
// `;
const StyledTitle = styled(Typography)`
text-align: center;
font-size: 30px;
margin-bottom: 30px;
`;
// const ForgottenPassword = () => {
// const [state, setState] = useState({
// email: '',
// redirectUrl: 'http://localhost:3000/passwordreset'
// });
const ForgottenPassword = () => {
const [state, setState] = useState({
email: '',
redirectUrl: 'http://localhost:3000/passwordreset'
});
// const dispatch = useDispatch();
// const { loginError, loading } = useSelector(state => state.users);
// console.log(loginError)
// const navigate = useNavigate("/")
const dispatch = useDispatch();
const { loginError, loading } = useSelector(state => state.users);
console.log(loginError)
const navigate = useNavigate("/")
// const inputChangeHandler = (e) => {
// const { name, value } = e.target;
// setState((prevState) => {
// return {
// ...prevState,
// [name]: value
// }
// });
// };
const inputChangeHandler = (e) => {
const { name, value } = e.target;
setState((prevState) => {
return {
...prevState,
[name]: value
}
});
};
// const submitHandler = async (e) => {
// e.preventDefault();
// await dispatch(loginUser(state, navigate));
// };
const submitHandler = async (e) => {
e.preventDefault();
await dispatch(loginUser(state, navigate));
};
// return <>
// <StyledContainer component={"section"} maxWidth={"xs"}>
// {!!loginError && <Alert color="error">{loginError}</Alert>}
// <Avatar sx={{ m: "0 auto 30px" }}>
// <PersonIcon />
// </Avatar>
// <StyledTitle variant={"h1"}>
// Password Reset
// </StyledTitle>
// <UserForm
// onSubmit={submitHandler}
// state={state}
// onChange={inputChangeHandler}
// buttonText={"Sign In"}
// resetPassword={"Forgot your password?"}
// />
// </StyledContainer>
// <Loader loading={loading} />
// </>
// };
return <>
<StyledContainer component={"section"} maxWidth={"xs"}>
{!!loginError && <Alert color="error">{loginError}</Alert>}
<Avatar sx={{ m: "0 auto 30px" }}>
<PersonIcon />
</Avatar>
<StyledTitle variant={"h1"}>
Password Reset
</StyledTitle>
<ResetPasswordForm
onSubmit={submitHandler}
state={state}
onChange={inputChangeHandler}
buttonText={"Submit"}
resetPassword={"Forgot your password?"}
/>
</StyledContainer>
<Loader loading={loading} />
</>
};
// export default ForgottenPassword;
\ No newline at end of file
export default ForgottenPassword;
\ No newline at end of file
......@@ -62,7 +62,7 @@ const Login = () => {
state={state}
onChange={inputChangeHandler}
buttonText={"Sign In"}
// resetPassword={"Forgot your password?"}
resetPassword={"Forgot your password?"}
/>
</StyledContainer>
<Loader loading={loading} />
......
......@@ -26,7 +26,7 @@ const Register = () => {
name: '',
surname: "",
email: "",
number: "",
// number: "",
password: '',
// avatar: "",
});
......@@ -62,9 +62,10 @@ const Register = () => {
const formData = new FormData();
Object.keys(state).forEach(key => {
formData.append(key, state[key]);
console.log("key " + key + "state " + state[key])
})
await dispatch(registerUser(formData, navigate));
await dispatch(loginUser(state, navigate))
// dispatch(loginUser(state, navigate))
};
const getFieldError = (fieldname) => {
......
......@@ -18,6 +18,7 @@ export const registerUser = (userData, navigate) => {
return async (dispatch) => {
dispatch(registerUserRequest());
try {
console.log("register " + userData)
const response = await axios.post("/users", userData);
dispatch(registerUserSuccess())
navigate("/")
......@@ -49,7 +50,25 @@ const logoutUserFailure = (error) => {
export const loginUser = (userData, navigate) => {
return async (dispatch) => {
try {
console.log(userData)
const response = await axios.post("users/sessions", userData);
console.log(response)
dispatch(loginUserSuccess(response.data.user));
navigate("/")
} catch (e) {
dispatch(loginUserFailure(e?.response?.data?.err))
}
}
}
export const forgottenPassword = (userData, navigate) => {
return async (dispatch) => {
try {
console.log(userData)
const response = await axios.post("users/requestPasswordReset", userData);
// if (userData.email === response.data.email) {
// }
dispatch(loginUserSuccess(response.data));
navigate("/")
} catch (e) {
......
import { REGISTER_USER_REQUEST, REGISTER_USER_SUCCESS, REGISTER_USER_FAILURE, LOGIN_USER_SUCCESS, LOGIN_USER_FAILURE, LOGOUT_USER_SUCCESS } from "../actionTypes/actionTypes";
const initialState = {
user: {
name: 'Ivan',
surname: 'Petrov',
email: 'test@gmail.com',
role: 'superuser'
},
user: null,
registerError: null,
loginError: null,
loading: false
......@@ -17,12 +12,15 @@ const usersReducer = (state = initialState, action) => {
case REGISTER_USER_REQUEST:
return {...state, loading: true};
case REGISTER_USER_SUCCESS:
console.log("register.user " + action)
return {...state, loading: false};
case REGISTER_USER_FAILURE:
return {...state, loading: false, registerError: action.error};
case LOGIN_USER_SUCCESS:
console.log("action.user " + action)
return {...state, user: action.user};
case LOGIN_USER_FAILURE:
console.log("action.error" + action.error)
return {...state, loginError: action.error};
case LOGOUT_USER_SUCCESS:
return {...state, user: null};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment