Commit ba5af6c4 authored by Egor Kremnev's avatar Egor Kremnev

add edit user

parent 2584765b
......@@ -3,7 +3,7 @@ const rootPath = __dirname;
module.exports = {
rootPath,
port: 8001,
port: 8010,
uploadPath: path.join(rootPath, 'public', 'uploads'),
db: {
host: 'mongodb://127.0.0.1',
......
......@@ -18,6 +18,32 @@ router.post('/', async (req, res) => {
}
});
router.put('/', auth, async (req, res) => {
const user = req.user;
if (
req.body.oldPassword.trim()
&&
!await user.checkPassword(req.body.oldPassword.toString())
) {
return res
.status(400)
.send({error: 'Old password incorrect'});
}
try {
user.password = req.body.password || user.password;
user.username = req.body.username || user.username;
await user.save();
res.send(user);
} catch (e) {
res
.status(400)
.send({error: e.message});
}
});
router.post('/login', async (req, res) => {
const user = await User.findOne({username: req.body.username});
......@@ -42,10 +68,7 @@ router.post('/login', async (req, res) => {
});
router.get('/profile', auth, async (req, res) => {
res.send({
message: "Большой большой сикрет",
username: req.user.username
});
res.send(req.user);
});
router.delete('/logout', auth, async (req, res) => {
......
import {Navigate, Outlet, Route, Routes as RoutesSwitch} from "react-router-dom";
import {LOGIN, MAIN, PRODUCT_ADD, PRODUCT_LIST, PRODUCT_VIEW, REGISTER} from "./constants/routes";
import {LOGIN, MAIN, PRODUCT_ADD, PRODUCT_LIST, PRODUCT_VIEW, REGISTER, USER_PROFILE} from "./constants/routes";
import AddProduct from "./containers/AddProduct/AddProduct";
import Layout from "./components/Layout/Layout";
import Products from "./containers/Products/Products";
import Register from "./containers/Auth/Register/Register";
import Login from "./containers/Auth/Login/Login";
import User from "./containers/User/User";
const ProtectedRoute = ({isAllowed, redirectPath, children}) => {
if (!isAllowed) {
......@@ -22,6 +23,13 @@ const Routes = ({user}) => {
<AddProduct />
</ProtectedRoute>;
const userProfile = <ProtectedRoute
isAllowed={!!user}
redirectPath={LOGIN}
>
<User />
</ProtectedRoute>;
return <RoutesSwitch>
<Route element={<Layout />}>
<Route index element={<Products />}/>
......@@ -29,6 +37,7 @@ const Routes = ({user}) => {
<Route path={LOGIN} element={<Login />}/>
<Route path={PRODUCT_LIST} element={<Products />}/>
<Route path={PRODUCT_ADD} element={productAdd}/>
<Route path={USER_PROFILE} element={userProfile}/>
<Route path={PRODUCT_VIEW} element={<h1>Show product</h1>}/>
</Route>
</RoutesSwitch>;
......
......@@ -2,8 +2,8 @@ import {useState} from "react";
import {Button, Menu, MenuItem} from '@mui/material';
import {useDispatch} from "react-redux";
import {logoutUser} from "../../../../../store/actions/usersActions";
import {useNavigate} from "react-router-dom";
import {MAIN} from "../../../../../constants/routes";
import {NavLink, useNavigate} from "react-router-dom";
import {MAIN, USER_PROFILE} from "../../../../../constants/routes";
const UserMenu = ({user}) => {
const navigate = useNavigate();
......@@ -33,7 +33,7 @@ const UserMenu = ({user}) => {
onClose={handleClose}
keepMounted
>
<MenuItem>Profile</MenuItem>
<MenuItem component={NavLink} to={USER_PROFILE}>Profile</MenuItem>
<MenuItem>My account</MenuItem>
<MenuItem
onClick={() => dispatch(logoutUser({callback: () => navigate(MAIN)}))}
......
import {useState} from "react";
import {Button, Grid} from "@mui/material";
import FormElement from "../../UI/Form/FormElement/FormElement";
const UserForm = ({onFormSubmit, user}) => {
const [state, setState] = useState({
oldPassword: "",
password: "",
username: user.username
});
const submitFormHandler = e => {
e.preventDefault();
onFormSubmit(state);
};
const inputChangeHandler = e => {
const name = e.target.name;
const value = e.target.value;
setState(prevState => {
return {...prevState, [name]: value};
});
};
return (
<form
autoComplete="off"
onSubmit={submitFormHandler}
>
<Grid container direction="column" spacing={2}>
<FormElement
id="oldPassword"
label="Old Password"
required={!!state.password.trim()}
value={state.oldPassword}
onChange={inputChangeHandler}
name="oldPassword"
/>
<FormElement
id="password"
label="New password"
required={!!state.oldPassword.trim()}
value={state.password}
onChange={inputChangeHandler}
name="password"
/>
<FormElement
id="username"
label="Username"
value={state.username}
onChange={inputChangeHandler}
name="username"
/>
<Grid item xs>
<Button type="submit" color="primary" variant="contained">
Save
</Button>
</Grid>
</Grid>
</form>
);
};
export default UserForm;
export const apiUrl = "http://localhost:8001";
export const apiUrl = "http://localhost:8010";
export const uploadUrl = apiUrl + '/uploads';
......@@ -4,3 +4,4 @@ export const PRODUCT_LIST = '/products/';
export const PRODUCT_VIEW = '/products/:id';
export const REGISTER = '/register';
export const LOGIN = '/login';
export const USER_PROFILE = '/user/profile';
import {useDispatch, useSelector} from "react-redux";
import {Typography} from "@mui/material";
import UserForm from "../../components/User/UserForm/UserForm";
import {useNavigate} from "react-router-dom";
import {updateUser} from "../../store/actions/usersActions";
const User = () => {
const navigate = useNavigate();
const dispatch = useDispatch();
const user = useSelector(({usersState}) => usersState.user);
const onFormSubmit = async data => {
await dispatch(updateUser({data, callback: () => navigate('/')}));
};
return (
<>
<Typography variant='h4'>
Edit {user.username}
</Typography>
<UserForm
onFormSubmit={onFormSubmit}
user={user}
/>
</>
);
};
export default User;
......@@ -44,3 +44,18 @@ export const logoutUser = createAsyncThunk(
throw e;
})
);
export const updateUser = createAsyncThunk(
'users/update',
async ({data, callback}, {dispatch}) => await axiosApi
.put('/users', data)
.then(res => {
dispatch(setUser(res.data));
callback();
})
.catch(e => {
if (e?.response?.data) dispatch(setLoginError(e.response.data));
else dispatch(setLoginError(e));
throw e;
})
);
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