Skip to content

Commit fc6865b

Browse files
Merge pull request #15 from call-0f-code/member/routes
updated member routes
2 parents 3e8061d + 3c16655 commit fc6865b

6 files changed

Lines changed: 595 additions & 0 deletions

File tree

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { Request, Response } from "express";
2+
import * as memberService from "../services/member.service";
3+
import { ApiError } from "../utils/apiError";
4+
import { deleteImage, uploadImage } from "../utils/imageUtils";
5+
import { SupabaseClient } from "@supabase/supabase-js";
6+
7+
// List all approved members
8+
export const listAllApprovedMembers = async (req: Request, res: Response) => {
9+
const user = await memberService.approvedMembers();
10+
res
11+
.status(200)
12+
.json({ user, success: true, message: "Fetched approved users" });
13+
};
14+
15+
// Get details of a single user
16+
export const getUserDetails = async (req: Request, res: Response) => {
17+
const { memberId } = req.params;
18+
19+
if (!memberId) throw new ApiError("No memberId provided", 400);
20+
21+
const user = await memberService.getDetails(memberId);
22+
if (!user) throw new ApiError("No member found", 404);
23+
24+
res.json({ success: true, user, message: "Fetched user details" });
25+
};
26+
27+
// Create a new member
28+
export const createAMember =
29+
(supabase: SupabaseClient) => async (req: Request, res: Response) => {
30+
const { email, name, password, passoutYear } = req.body;
31+
32+
if (!email || !name || !password || !passoutYear) {
33+
throw new ApiError("Required fields absent", 400);
34+
}
35+
36+
let imageUrl: string | undefined;
37+
if (req.file) {
38+
imageUrl = await uploadImage(supabase, req.file, "members");
39+
}
40+
41+
const user = await memberService.createMember(
42+
email,
43+
name,
44+
password,
45+
passoutYear,
46+
imageUrl,
47+
);
48+
49+
if (!user) throw new ApiError("Error creating user", 500);
50+
51+
res.status(201).json({ success: true, user });
52+
};
53+
54+
// Update an existing member
55+
export const updateAMember =
56+
(supabase: SupabaseClient) => async (req: Request, res: Response) => {
57+
const { memberId } = req.params;
58+
59+
if(!memberId) throw new ApiError("No memberId provided", 400);
60+
61+
const body = req.body;
62+
63+
if (req.file) {
64+
const oldData = await memberService.getDetails(memberId);
65+
const oldImage = oldData?.profilePhoto;
66+
67+
if(oldImage) await deleteImage(supabase, oldImage);
68+
69+
const imageUrl = await uploadImage(supabase, req.file, "members");
70+
body.profilePhoto = imageUrl;
71+
}
72+
73+
await memberService.updateMember(memberId, body);
74+
75+
res
76+
.status(200)
77+
.json({ success: true, message: "Updated member details successfully" });
78+
};
79+
80+
// Get all unapproved members
81+
export const getUnapprovedMembers = async (req: Request, res: Response) => {
82+
const unapprovedMembers = await memberService.unapprovedMembers();
83+
res.status(200).json({ success: true, unapprovedMembers });
84+
};
85+
86+
// Approve or reject member request
87+
export const updateRequest = async (req: Request, res: Response) => {
88+
const { memberId } = req.params;
89+
const { isApproved, adminId } = req.body;
90+
91+
if (!memberId || !adminId || isApproved === undefined) {
92+
throw new ApiError("No essential creds provided", 400);
93+
}
94+
95+
if(!isApproved) throw new ApiError("Someone interrupting the backend flow", 400);
96+
97+
const update = await memberService.approveRequest(
98+
isApproved,
99+
adminId,
100+
memberId,
101+
);
102+
103+
res
104+
.status(200)
105+
.json({ success: true, update, message: "Approve Request Checked" });
106+
};
107+
108+
// Get achievements of a member
109+
export const getUserAchievements = async (req: Request, res: Response) => {
110+
const { memberId } = req.params;
111+
112+
if (!memberId) throw new ApiError("No memberId provided", 400);
113+
114+
const achievements = await memberService.getAchievements(memberId);
115+
res.status(200).json({ success: true, achievements });
116+
};
117+
118+
// Get projects of a member
119+
export const getUserProjects = async (req: Request, res: Response) => {
120+
const { memberId } = req.params;
121+
122+
if (!memberId) throw new ApiError("No memberId provided", 400);
123+
124+
const projects = await memberService.getProjects(memberId);
125+
res.status(200).json({ success: true, projects });
126+
};
127+
128+
// Get interviews of a member
129+
export const getUserInterviews = async (req: Request, res: Response) => {
130+
const { memberId } = req.params;
131+
132+
if (!memberId) throw new ApiError("No memberId provided", 400);
133+
134+
const interviews = await memberService.getInterviews(memberId);
135+
res.status(200).json({ success: true, interviews });
136+
};

src/routes/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import interviewRouter from './interviews'
77
import topicRouter from './topics'
88
import quetionsRouter from './questions'
99
import progressRouter from './progress'
10+
import membersRouter from './members'
1011

1112
export default function routes(upload: Multer, supabase: SupabaseClient) {
1213
const router = Router();
1314

15+
router.use('/members', membersRouter(upload, supabase))
1416

1517
router.use('/projects', projectsRouter(upload, supabase))
1618

src/routes/members.ts

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import express from "express";
2+
import * as memberCtrl from "../controllers/member.controller";
3+
import { Multer } from "multer";
4+
import { supabase } from "../app";
5+
import { SupabaseClient } from "@supabase/supabase-js";
6+
7+
export default function membersRouter(
8+
upload: Multer,
9+
supabase: SupabaseClient,
10+
) {
11+
const router = express.Router();
12+
13+
/**
14+
* @api {get} /members/details/:memberId Get a member's details
15+
* @apiName GetUserDetails
16+
* @apiGroup Member
17+
*
18+
* @apiParam (URL Params) {String} memberId Member's unique ID.
19+
*
20+
* @apiSuccess {Object} user Member object.
21+
* @apiError (Error 400) BadRequest No memberId provided.
22+
*/
23+
router.get("/:memberId", memberCtrl.getUserDetails);
24+
25+
/**
26+
* @api {get} /members List all approved members
27+
* @apiName ListAllApprovedMembers
28+
* @apiGroup Member
29+
*
30+
* @apiSuccess {Object[]} user List of approved members.
31+
*/
32+
router.get("/", memberCtrl.listAllApprovedMembers);
33+
34+
/**
35+
* @api {post} /members Create a new member
36+
* @apiName CreateAMember
37+
* @apiGroup Member
38+
*
39+
* @apiBody {String} email Email of the member.
40+
* @apiBody {String} name Full name of the member.
41+
* @apiBody {String} password Member's password.
42+
* @apiBody {String} passoutYear Graduation year.
43+
* @apiBody {String} imageUrl profile photo of the member.
44+
*
45+
* @apiSuccess {Object} user Created member object.
46+
* @apiError (Error 402) ValidationError Required fields missing.
47+
*/
48+
router.post("/", upload.single("file"), memberCtrl.createAMember(supabase));
49+
50+
/**
51+
* @api {patch} /members/:memberId Update a member
52+
* @apiName UpdateAMember
53+
* @apiGroup Member
54+
*
55+
* @apiParam {String} memberId Member's unique ID.
56+
*
57+
* @apiBody {File} [file] Profile photo file (field name: "file").
58+
* @apiBody {String} [name] Full name of the member.
59+
* @apiBody {String} [email] Email address.
60+
* @apiBody {String} [phone] Phone number.
61+
* @apiBody {String} [bio] Short bio.
62+
* @apiBody {String} [github] GitHub handle.
63+
* @apiBody {String} [linkedin] LinkedIn handle.
64+
* @apiBody {String} [twitter] Twitter handle.
65+
* @apiBody {String} [geeksforgeeks] GeeksforGeeks username.
66+
* @apiBody {String} [leetcode] LeetCode username.
67+
* @apiBody {String} [codechef] CodeChef username.
68+
* @apiBody {String} [codeforces] Codeforces username.
69+
* @apiBody {Date} [passoutYear] Graduation year (ISO string format).
70+
*
71+
* @apiSuccess {Object} member Updated member object.
72+
* @apiError (Error 404) NotFound Member not found.
73+
* @apiError (Error 400) ValidationError Invalid or missing fields.
74+
* @apiError (Error 500) ServerError Unexpected error occurred during update.
75+
*/
76+
router.patch(
77+
"/:memberId",
78+
upload.single("file"),
79+
memberCtrl.updateAMember(supabase),
80+
);
81+
82+
/**
83+
* @api {get} /members/unapproved Get unapproved members
84+
* @apiName GetUnapprovedMembers
85+
* @apiGroup Member
86+
*
87+
* @apiSuccess {Object[]} unapprovedMembers List of unapproved members.
88+
*/
89+
router.get("/unapproved", memberCtrl.getUnapprovedMembers);
90+
91+
/**
92+
* @api {patch} /members/approve/:memberId Approve/reject a member
93+
* @apiName UpdateApprovalRequest
94+
* @apiGroup Member
95+
*
96+
* @apiParam (URL Params) {String} memberId Member ID.
97+
* @apiBody {Boolean} isApproved Approval status.
98+
* @apiBody {String} adminId Admin who approved.
99+
*
100+
* @apiSuccess {Object} update Approval status updated.
101+
* @apiError (Error 400) BadRequest Missing required fields.
102+
*/
103+
router.patch("/approve/:memberId", memberCtrl.updateRequest);
104+
105+
/**
106+
* @api {get} /members/achievements/:memberId Get member's achievements
107+
* @apiName GetUserAchievements
108+
* @apiGroup Member
109+
*
110+
* @apiParam (URL Params) {String} memberId Member ID.
111+
*
112+
* @apiSuccess {Object[]} achievements List of achievements.
113+
*/
114+
router.get("/achievements/:memberId", memberCtrl.getUserAchievements);
115+
116+
/**
117+
* @api {get} /api/members/projects/:memberId Get member's projects
118+
* @apiName GetUserProjects
119+
* @apiGroup Member
120+
*
121+
* @apiParam (URL Params) {String} memberId Member ID.
122+
*
123+
* @apiSuccess {Object[]} projects List of projects.
124+
*/
125+
router.get("/projects/:memberId", memberCtrl.getUserProjects);
126+
127+
/**
128+
* @api {get} /members/interviews/:memberId Get member's interviews
129+
* @apiName GetUserInterviews
130+
* @apiGroup Member
131+
*
132+
* @apiParam (URL Params) {String} memberId Member ID.
133+
*
134+
* @apiSuccess {Object[]} interviews List of interviews.
135+
*/
136+
router.get("/interviews/:memberId", memberCtrl.getUserInterviews);
137+
138+
return router;
139+
}

0 commit comments

Comments
 (0)