Skip to content

Commit

Permalink
Merge pull request #53 from atlp-rwanda/187354252-ft-profile-page-set…
Browse files Browse the repository at this point in the history
…tings

[Finishes #187354252] implementing profile page settings
  • Loading branch information
niyontwali authored May 9, 2024
2 parents 608d497 + 70ce650 commit d6fbc67
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 0 deletions.
85 changes: 85 additions & 0 deletions src/controllers/profileController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Request, Response } from 'express';
import User from '../database/models/user';
import logger from '../logs/config';
import uploadImage from '../helpers/claudinary';
import Role from '../database/models/role';
import { sendInternalErrorResponse } from '../validations';

export const getUserProfile = async (req: Request, res: Response): Promise<void> => {
const userId: string = req.params.userId;

try {
const user = await User.findByPk(userId, {
attributes: ['id', 'firstName', 'lastName', 'email', 'phoneNumber', 'photoUrl', 'gender'],
include: {
model: Role,
attributes: ['name'],
},
});

if (!user) {
res.status(404).json({ message: 'User not found' });
return;
}

res.status(200).json({ ok: true, message: user });
} catch (error) {
logger.error('Error fetching user profile:: ', error);
sendInternalErrorResponse(res, error);
}
};

//construct updated fields
const constructUpdatedFields = (body: any, user: User, uploadedImage?: string) => {
return {
firstName: body.firstName || user.firstName,
lastName: body.lastName || user.lastName,
gender: body.gender || user.gender,
phoneNumber: body.phoneNumber || user.phoneNumber,
photoUrl: uploadedImage || user.photoUrl,
};
};

// Function to construct user response
const constructUserResponse = (user: User, updatedFields: any) => {
return {
id: user.id,
firstName: updatedFields.firstName,
lastName: updatedFields.lastName,
email: user.email,
phoneNumber: updatedFields.phoneNumber,
gender: updatedFields.gender,
photoUrl: updatedFields.photoUrl,
};
};

export const updateUser = async (req: Request, res: Response) => {
try {
const { firstName, lastName, gender, phoneNumber } = req.body;

const user = await User.findByPk(req.params.id);

if (!user) {
return res.status(404).json({ ok: false, error: 'User not found' });
}

if (!req.file) {
return res.status(400).json({ ok: false, error: 'Profile Image required.' });
}

// Upload image to cloudinary
const uploadedImage = await uploadImage(req.file.buffer);

const updatedFields = constructUpdatedFields(req.body, user, uploadedImage);

await user.update(updatedFields);

const userResponse = constructUserResponse(user, updatedFields);

// Send response
res.status(201).json({ ok: true, message: userResponse });
} catch (error) {
logger.error('Error updating user profile: ', error);
sendInternalErrorResponse(res, error);
}
};
87 changes: 87 additions & 0 deletions src/docs/profile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
openapi: 3.0.0
info:
title: User Profiles API
description: API for managing user profiles
version: 1.0.0

paths:
/api/profiles/users/{userId}:
get:
summary: Get a user profile by ID
description: Retrieve a user profile by its ID
tags:
- Profiles
parameters:
- in: path
name: userId
required: true
description: ID of the user profile to retrieve
schema:
type: string
responses:
'200':
description: The user profile
content:
application/json:
schema:
type: object
properties:
id:
type: string
firstName:
type: string
lastName:
type: string
email:
type: string
phoneNumber:
type: string
photoUrl:
type: string
gender:
type: string
'404':
description: User not found
'500':
description: Internal server error

patch:
summary: Update a user profile
description: Update an existing user profile
tags:
- Profiles
parameters:
- in: path
name: userId
required: true
description: ID of the user profile to update
schema:
type: string
- in: body
name: body
required: true
description: New data for the user profile
schema:
type: object
properties:
firstName:
type: string
lastName:
type: string
email:
type: string
phoneNumber:
type: string
photoUrl:
type: string
gender:
type: string
responses:
'200':
description: User profile updated successfully
'400':
description: Required fields are missing
'404':
description: User not found
'500':
description: Internal server error
3 changes: 3 additions & 0 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-misused-promises */
import { Router } from 'express';
import userRoute from './userRoute';
import profileRoutes from './profileRoutes';
import authRoute from './authRoute';
import roleRoute from './roleRoute';
import { productRouter } from './productRoutes';
Expand All @@ -9,6 +10,8 @@ import { categoryRouter } from './categoryRouter';
const router = Router();

router.use('/users', userRoute);
// Profile routes
router.use('/profiles', profileRoutes);
router.use('/auth', authRoute);
router.use('/roles', roleRoute);
router.use('/products', productRouter);
Expand Down
8 changes: 8 additions & 0 deletions src/routes/profileRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* eslint-disable @typescript-eslint/no-misused-promises */
import { Router } from 'express';
import { updateUser, getUserProfile } from '../controllers/profileController';
import multerUpload from '../helpers/multer';
const router = Router();
router.get('/users/:userId/', getUserProfile);
router.patch('/users/:id', multerUpload.single('profileImage'), updateUser);
export default router;

0 comments on commit d6fbc67

Please sign in to comment.