Skip to content

Commit

Permalink
Merge pull request #591 from idurar/feat/profile-update-module
Browse files Browse the repository at this point in the history
profile controller api
  • Loading branch information
salahlalami authored Oct 23, 2023
2 parents f912887 + 0f7a726 commit 016c9a3
Show file tree
Hide file tree
Showing 28 changed files with 293 additions and 188 deletions.
2 changes: 2 additions & 0 deletions backend/controllers/coreControllers/adminController/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const create = require('./create');
const read = require('./read');
const update = require('./update');
const updateProfile = require('./updateProfile');
const remove = require('./remove');
const updatePassword = require('./updatePassword');
const profile = require('./profile');
Expand All @@ -15,6 +16,7 @@ const adminController = {
create,
read,
update,
updateProfile,
photo,
delete: remove,
updatePassword,
Expand Down
14 changes: 7 additions & 7 deletions backend/controllers/coreControllers/adminController/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ const Admin = mongoose.model('Admin');

const update = async (req, res) => {
try {
let { email } = req.body;
// let { email } = req.body;

if (email) {
const existingAdmin = await Admin.findOne({ email: email });
// if (email) {
// const existingAdmin = await Admin.findOne({ email: email });

if (existingAdmin._id != req.params.id)
return res.status(400).json({ message: 'An account with this email already exists.' });
}
// if (existingAdmin._id != req.params.id)
// return res.status(400).json({ message: 'An account with this email already exists.' });
// }
let updates = {
role: req.body.role,
email: req.body.email,
employee: req.body.employee,
name: req.body.name,
surname: req.body.surname,
photo: req.body.photo,
};

// Find document by id and updates with the required fields
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
const mongoose = require('mongoose');
const Admin = mongoose.model('Admin');

const updateProfile = async (req, res) => {
try {
console.log('🚀 ~ file: updateProfile.js:7 ~ updateProfile ~ req.admin:', req.admin._id);
console.log('🚀 ~ file: updateProfile.js:10 ~ updateProfile ~ req.params.id:', req.params.id);
if (req.admin._id == req.params.id) {
console.log(
'🚀 ~ file: updateProfile.js:10 ~ updateProfile ~ req.admin._id === req.params.id'
);
}
if (req.admin._id != req.params.id)
return res.status(403).json({
success: false,
result: null,
message: "you don't have permission to edit this profile",
});

let updates = {
role: req.body.role,
email: req.body.email,
name: req.body.name,
surname: req.body.surname,
photo: req.body.photo,
};
console.log('🚀 ~ file: updateProfile.js:41 ~ updateProfile ~ updates:', updates);

// Find document by id and updates with the required fields
const result = await Admin.findOneAndUpdate(
{ _id: req.params.id, removed: false },
{ $set: updates },
{
new: true, // return the new result instead of the old one
}
).exec();
console.log('🚀 ~ file: updateProfile.js:50 ~ updateProfile ~ result:', result);

if (!result) {
return res.status(404).json({
success: false,
result: null,
message: 'No document found by this id: ' + req.params.id,
});
}
return res.status(200).json({
success: true,
result: {
_id: result?._id,
enabled: result?.enabled,
email: result?.email,
name: result?.name,
surname: result?.surname,
photo: result?.photo,
role: result?.role,
},
message: 'we update this document by this id: ' + req.params.id,
});
} catch (error) {
// Server Error
return res.status(500).json({
success: false,
result: null,
message: 'Oops there is an Error',
error: error.message,
});
}
};

module.exports = updateProfile;
2 changes: 2 additions & 0 deletions backend/middlewares/permission.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ exports.roles = roles;
exports.hasPermission = (permissionName = 'all') => {
return function (req, res, next) {
const currentUserRole = req.admin.role;

if (roles[currentUserRole].includes(permissionName) || req.admin.role === 'admin') {
console.log('🚀 ~ file: permission.js:14 ~ req.admin.role:', req.admin.role);
console.log('🚀 ~ file: permission.js:25 ~ return ~ permissionName:', permissionName);
next();
} else {
Expand Down
22 changes: 11 additions & 11 deletions backend/middlewares/setFilePathToBody.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//this middleware will check if the admin is logged in, if not he will be redirected to the login page :)
module.exports = (req, res, next) => {
console.log('🚀 ~ file: setFilePathToBody.js:4 ~ req.file:', req.file);
if (req.file) {
console.log('🚀 ~ file: setFilePathToBody.js:5 ~ req.file:', req.file);
req.body.filePath = req.file.path;
console.log('🚀 ~ file: setFilePathToBody.js:6 ~ req.file.path:', req.file.path);
}
// if (req.files) {
// req.body[req.files.fieldname] = req.files.path
// }
next();
module.exports = (fieldName = 'filePath') => {
return (req, res, next) => {
if (req.file) {
req.body[fieldName] = req.file.path;
console.log('🚀 ~ file: setFilePathToBody.js:6 ~ return ~ fieldName:', fieldName);
}
// if (req.files) {
// req.body[req.files.fieldname] = req.files.path
// }
next();
};
};
Binary file added backend/public/uploads/admin/1698074521167.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added backend/public/uploads/admin/1698075821139.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added backend/public/uploads/admin/1698078684580.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added backend/public/uploads/admin/1698078729260.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added backend/public/uploads/admin/1698078978212.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions backend/routes/appRoutes/appApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,15 +334,15 @@ router
.post(
hasPermission('create'),
kycFileUpload.single('file'),
setFilePathToBody,
setFilePathToBody('filePath'),
catchErrors(kycController.create)
);
router
.route('/kyc/update/:id')
.patch(
hasPermission('update'),
kycFileUpload.single('file'),
setFilePathToBody,
setFilePathToBody('filePath'),
catchErrors(kycController.update)
);

Expand Down
64 changes: 43 additions & 21 deletions backend/routes/coreRoutes/coreApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var adminPhotoStorage = multer.diskStorage({
cb(null, 'public/uploads/admin');
},
filename: function (req, file, cb) {
console.log('🚀 ~ file: coreApi.js:28 ~ file:', file.originalname);
cb(null, Date.now() + path.extname(file.originalname));
},
});
Expand All @@ -34,11 +35,17 @@ router
.route('/admin/create')
.post(
hasPermission(),
[adminPhotoUpload.single('photo'), setFilePathToBody],
[adminPhotoUpload.single('photo'), setFilePathToBody('photo')],
catchErrors(adminController.create)
);
router.route('/admin/read/:id').get(hasPermission(), catchErrors(adminController.read));
router.route('/admin/update/:id').patch(hasPermission(), catchErrors(adminController.update));
router
.route('/admin/update/:id')
.patch(
hasPermission(),
[adminPhotoUpload.single('photo'), setFilePathToBody('photo')],
catchErrors(adminController.update)
);
router.route('/admin/delete/:id').delete(hasPermission(), catchErrors(adminController.delete));
router.route('/admin/search').get(hasPermission(), catchErrors(adminController.search));
router.route('/admin/list').get(hasPermission(), catchErrors(adminController.list));
Expand All @@ -48,44 +55,59 @@ router
.route('/admin/photo')
.post(
hasPermission(),
[adminPhotoUpload.single('photo'), setFilePathToBody],
[adminPhotoUpload.single('photo'), setFilePathToBody('photo')],
catchErrors(adminController.photo)
);
router
.route('/admin/password-update/:id')
.patch(hasPermission(), catchErrors(adminController.updatePassword));

router
.route('/profile/update/:id')
.patch(
hasPermission('read'),
adminPhotoUpload.single('file'),
setFilePathToBody('photo'),
catchErrors(adminController.updateProfile)
);

// //____________________________________________ API for Global Setting _________________

router.route('/setting/create').post(hasPermission(), catchErrors(settingController.create));
router.route('/setting/read/:id').get(hasPermission(), catchErrors(settingController.read));
router.route('/setting/update/:id').patch(hasPermission(), catchErrors(settingController.update));
router
.route('/setting/create')
.post(hasPermission('create'), catchErrors(settingController.create));
router.route('/setting/read/:id').get(hasPermission('read'), catchErrors(settingController.read));
router
.route('/setting/update/:id')
.patch(hasPermission('update'), catchErrors(settingController.update));
//router.route('/setting/delete/:id).delete(hasPermission(),catchErrors(settingController.delete));
router.route('/setting/search').get(hasPermission(), catchErrors(settingController.search));
router.route('/setting/list').get(hasPermission(), catchErrors(settingController.list));
router.route('/setting/listAll').get(hasPermission(), catchErrors(settingController.listAll));
router.route('/setting/filter').get(hasPermission(), catchErrors(settingController.filter));
router.route('/setting/search').get(hasPermission('read'), catchErrors(settingController.search));
router.route('/setting/list').get(hasPermission('read'), catchErrors(settingController.list));
router.route('/setting/listAll').get(hasPermission('read'), catchErrors(settingController.listAll));
router.route('/setting/filter').get(hasPermission('read'), catchErrors(settingController.filter));
router
.route('/setting/readBySettingKey/:settingKey')
.get(hasPermission(), catchErrors(settingController.readBySettingKey));
.get(hasPermission('read'), catchErrors(settingController.readBySettingKey));
router
.route('/setting/listBySettingKey')
.get(hasPermission(), catchErrors(settingController.listBySettingKey));
.get(hasPermission('read'), catchErrors(settingController.listBySettingKey));
router
.route('/setting/updateBySettingKey/:settingKey?')
.patch(hasPermission(), catchErrors(settingController.updateBySettingKey));
.patch(hasPermission('update'), catchErrors(settingController.updateBySettingKey));
router
.route('/setting/updateManySetting')
.patch(hasPermission(), catchErrors(settingController.updateManySetting));
.patch(hasPermission('read'), catchErrors(settingController.updateManySetting));

// //____________________________________________ API for Email Templates _________________
router.route('/email/create').post(hasPermission(), catchErrors(emailController.create));
router.route('/email/read/:id').get(hasPermission(), catchErrors(emailController.read));
router.route('/email/update/:id').patch(hasPermission(), catchErrors(emailController.update));
router.route('/email/search').get(hasPermission(), catchErrors(emailController.search));
router.route('/email/list').get(hasPermission(), catchErrors(emailController.list));
router.route('/email/listAll').get(hasPermission(), catchErrors(emailController.listAll));
router.route('/email/filter').get(hasPermission(), catchErrors(emailController.filter));
router.route('/email/create').post(hasPermission('create'), catchErrors(emailController.create));
router.route('/email/read/:id').get(hasPermission('read'), catchErrors(emailController.read));
router
.route('/email/update/:id')
.patch(hasPermission('update'), catchErrors(emailController.update));
router.route('/email/search').get(hasPermission('read'), catchErrors(emailController.search));
router.route('/email/list').get(hasPermission('read'), catchErrors(emailController.list));
router.route('/email/listAll').get(hasPermission('read'), catchErrors(emailController.listAll));
router.route('/email/filter').get(hasPermission('read'), catchErrors(emailController.filter));

// //____________________________________________ API for Upload controller _________________

Expand Down
18 changes: 12 additions & 6 deletions frontend/src/app/HeaderContent/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,39 @@ import Notifications from '@/components/Notification';
import {
AppstoreOutlined,
SettingOutlined,
MailOutlined,
UserOutlined,
LogoutOutlined,
BellOutlined,
DeleteOutlined,
} from '@ant-design/icons';
import photo from '@/style/images/photo.png';

import { selectAuth } from '@/redux/auth/selectors';
import { selectCurrentAdmin } from '@/redux/auth/selectors';
import history from '@/utils/history';
import uniqueId from '@/utils/uinqueId';

import { BASE_URL } from '@/config/serverApiConfig';

export default function HeaderContent() {
const currentAdmin = useSelector(selectAuth);
const currentAdmin = useSelector(selectCurrentAdmin);
console.log('🚀 ~ file: index.jsx:23 ~ HeaderContent ~ currentAdmin:', currentAdmin);

const { SubMenu } = Menu;

const srcImgProfile = currentAdmin?.photo ? (
BASE_URL + currentAdmin?.photo
) : (
<UserOutlined style={{ color: '#333', fontSize: 'inherit' }} />
);

const profileDropdown = (
<div className="profileDropdown whiteBox shadow" style={{ minWidth: '200px' }}>
<div className="pad15" onClick={() => history.push('/profile')} style={{ cursor: 'pointer' }}>
<Avatar
size="large"
className="last"
src={`${BASE_URL}${currentAdmin?.photo}`}
style={{ float: 'left' }}
src={srcImgProfile}
style={{ float: 'left', fontSize: '32px' }}
/>
<div className="info">
<p className="strong">
Expand Down Expand Up @@ -80,7 +86,7 @@ export default function HeaderContent() {
<div className="headerIcon" style={{ position: 'absolute', right: 0, zIndex: '99' }}>
<Dropdown overlay={profileDropdown} trigger={['click']} placement="bottomRight">
{/* <Badge dot> */}
<Avatar className="last" src={`${BASE_URL}${currentAdmin?.photo}`} />
<Avatar className="last" src={srcImgProfile} />
{/* </Badge> */}
</Dropdown>

Expand Down
25 changes: 24 additions & 1 deletion frontend/src/forms/AdminForm.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
import SelectAsync from '@/components/SelectAsync';
import { Form, Input, Select } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import { message, Upload, Button } from 'antd';

const beforeUpload = (file) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('You can only upload JPG/PNG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
};

export default function AdminForm({ isUpdateForm = false }) {
return (
Expand Down Expand Up @@ -77,6 +90,16 @@ export default function AdminForm({ isUpdateForm = false }) {
<Select.Option value="readOnly">Read Only</Select.Option>
</Select>
</Form.Item>
<Form.Item
name="file"
label="File"
valuePropName="fileList"
getValueFromEvent={(e) => e.fileList}
>
<Upload beforeUpload={beforeUpload}>
<Button icon={<UploadOutlined />}>Click to Upload</Button>
</Upload>
</Form.Item>
</>
);
}
1 change: 0 additions & 1 deletion frontend/src/forms/KycForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ export default function KycForm({ isUpdateForm = false }) {
>
<Input />
</Form.Item>

<Form.Item
name="file"
label="File"
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/modules/AdminCrudModule/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function SidePanelTopContent({ config, formElements }) {
<div className="space10"></div>
</Row>
<ReadItem config={config} />
<UpdateForm config={config} formElements={formElements} />
<UpdateForm config={config} formElements={formElements} withUpload={true} />
<UpdatePassword config={config} />
</>
);
Expand Down Expand Up @@ -160,7 +160,9 @@ function AdminCrudModule({ config, createForm, updateForm }) {
<CrudLayout
config={config}
fixHeaderPanel={<FixHeaderPanel config={config} />}
sidePanelBottomContent={<CreateForm config={config} formElements={createForm} />}
sidePanelBottomContent={
<CreateForm config={config} formElements={createForm} withUpload={true} />
}
sidePanelTopContent={<SidePanelTopContent config={config} formElements={updateForm} />}
>
<AdminDataTable config={config} />
Expand Down
Loading

0 comments on commit 016c9a3

Please sign in to comment.