Skip to content

Commit 1021ad1

Browse files
committed
Fix Comment routes to include the contentId
1 parent d894abc commit 1021ad1

4 files changed

Lines changed: 144 additions & 56 deletions

File tree

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,41 @@
1-
import { Router } from 'express';
1+
import { Router } from "express";
22
import {
3-
updateCommentController,
4-
createCommentController,
5-
deleteCommentController,
6-
getCommentsByPostController,
7-
getCommentByIdController
8-
} from '../controllers/comment.controller';
9-
import { authenticateToken } from '../../../shared/middleware/auth';
3+
updateCommentController,
4+
createCommentController,
5+
deleteCommentController,
6+
getCommentsByPostController,
7+
getCommentByIdController,
8+
} from "../controllers/comment.controller";
9+
import { authenticateToken } from "../../../shared/middleware/auth";
1010
const router = Router();
1111

12-
router.post('/:contentId', authenticateToken, createCommentController, );
12+
// Post routes
13+
router.post("/content/:contentId", authenticateToken, createCommentController);
14+
15+
// Get routes
1316
router.get(
14-
"/:contentId",
17+
"/content/:contentId",
1518
authenticateToken,
1619
getCommentsByPostController
1720
);
18-
router.get("/:commentId", authenticateToken, getCommentByIdController);
19-
router.put("/:commentId", authenticateToken, updateCommentController);
20-
router.delete("/:commentId", authenticateToken, deleteCommentController);
21+
router.get(
22+
"/:commentId/content/:contentId",
23+
authenticateToken,
24+
getCommentByIdController
25+
);
26+
27+
// Put routes
28+
router.put(
29+
"/:commentId/content/:contentId",
30+
authenticateToken,
31+
updateCommentController
32+
);
33+
34+
// Delete routes
35+
router.delete(
36+
"/:commentId/content/:contentId",
37+
authenticateToken,
38+
deleteCommentController
39+
);
2140

2241
export default router;

backend/src/modules/subscription/services/stripe.service.ts

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import Stripe from 'stripe';
2-
import dotenv from 'dotenv';
1+
import Stripe from "stripe";
2+
import dotenv from "dotenv";
33

44
dotenv.config();
5-
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '', {
6-
apiVersion: '2025-04-30.basil',
5+
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", {
6+
apiVersion: "2025-05-28.basil",
77
});
88

99
/**
@@ -24,7 +24,7 @@ export class StripeService {
2424
});
2525
return customer;
2626
} catch (error) {
27-
console.error('Error creating Stripe customer:', error);
27+
console.error("Error creating Stripe customer:", error);
2828
throw error;
2929
}
3030
}
@@ -46,20 +46,20 @@ export class StripeService {
4646
try {
4747
const session = await stripe.checkout.sessions.create({
4848
customer: customerId,
49-
payment_method_types: ['card'],
49+
payment_method_types: ["card"],
5050
line_items: [
5151
{
5252
price: priceId,
5353
quantity: 1,
5454
},
5555
],
56-
mode: 'subscription',
56+
mode: "subscription",
5757
success_url: successUrl,
5858
cancel_url: cancelUrl,
5959
});
6060
return session;
6161
} catch (error) {
62-
console.error('Error creating checkout session:', error);
62+
console.error("Error creating checkout session:", error);
6363
throw error;
6464
}
6565
}
@@ -74,7 +74,7 @@ export class StripeService {
7474
const subscription = await stripe.subscriptions.retrieve(subscriptionId);
7575
return subscription;
7676
} catch (error) {
77-
console.error('Error retrieving subscription:', error);
77+
console.error("Error retrieving subscription:", error);
7878
throw error;
7979
}
8080
}
@@ -95,7 +95,7 @@ export class StripeService {
9595
});
9696
return subscription;
9797
} catch (error) {
98-
console.error('Error canceling subscription:', error);
98+
console.error("Error canceling subscription:", error);
9999
throw error;
100100
}
101101
}
@@ -108,15 +108,15 @@ export class StripeService {
108108
*/
109109
constructWebhookEvent(payload: string, signature: string): Stripe.Event {
110110
try {
111-
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET || '';
111+
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET || "";
112112
const event = stripe.webhooks.constructEvent(
113113
payload,
114114
signature,
115115
webhookSecret
116116
);
117117
return event;
118118
} catch (error) {
119-
console.error('Error constructing webhook event:', error);
119+
console.error("Error constructing webhook event:", error);
120120
throw error;
121121
}
122122
}
@@ -126,12 +126,16 @@ export class StripeService {
126126
* @param paymentIntentId Stripe payment intent ID
127127
* @returns Payment intent object
128128
*/
129-
async getPaymentIntent(paymentIntentId: string): Promise<Stripe.PaymentIntent> {
129+
async getPaymentIntent(
130+
paymentIntentId: string
131+
): Promise<Stripe.PaymentIntent> {
130132
try {
131-
const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId);
133+
const paymentIntent = await stripe.paymentIntents.retrieve(
134+
paymentIntentId
135+
);
132136
return paymentIntent;
133137
} catch (error) {
134-
console.error('Error retrieving payment intent:', error);
138+
console.error("Error retrieving payment intent:", error);
135139
throw error;
136140
}
137141
}
@@ -152,7 +156,7 @@ export class StripeService {
152156
});
153157
return subscription;
154158
} catch (error) {
155-
console.error('Error updating subscription payment method:', error);
159+
console.error("Error updating subscription payment method:", error);
156160
throw error;
157161
}
158162
}

frontend/src/components/content/CommentList.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ export default function CommentList({
9595
// Update comment in the backend
9696
const comment = await CommentService.updateComment(
9797
selectedCommentEdit.comment_id,
98-
selectedCommentEdit.text
98+
selectedCommentEdit.text,
99+
contentId
99100
);
100101

101102
// Check if the comment was updated successfully
@@ -120,7 +121,7 @@ export default function CommentList({
120121
if (!user.uid) navigate(`../authentication/login`);
121122

122123
// Delete comment from the backend
123-
const result = await CommentService.deleteComment(id);
124+
const result = await CommentService.deleteComment(id, contentId);
124125

125126
if (result instanceof Error) {
126127
toast("An error occurred while deleting the comment.", "error");

frontend/src/services/CommentService.ts

Lines changed: 89 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,24 @@ import axios from "axios";
22
import { apiURL } from "../scripts/api";
33
import { Comment } from "../models/Comment";
44

5+
/**
6+
* CommentService class
7+
*
8+
* @description
9+
* This class provides methods for managing comments, including publishing,
10+
* fetching, updating, and deleting comments.
11+
*/
512
export default class CommentService {
13+
/**
14+
* publishComment() -> Promise<{ message: string; comment: Comment } | Error>
15+
*
16+
* Publishes a comment for a specific content ID.
17+
*
18+
* @param contentId - The ID of the content to comment on.
19+
* @param commentText - The text of the comment.
20+
* @param ownerId - The ID of the user who owns the comment.
21+
* @returns A promise that resolves to a success message and the created comment or an error.
22+
*/
623
static async publishComment(
724
contentId: string,
825
commentText: string,
@@ -32,34 +49,51 @@ export default class CommentService {
3249
}
3350
}
3451

35-
static async deleteComment(
36-
commentId: string
37-
): Promise<{ message: string } | Error> {
52+
/**
53+
* getPostComments() -> Promise<Comment[] | Error>
54+
*
55+
* Fetches all comments for a specific content ID.
56+
*
57+
* @param contentId - The ID of the content to fetch comments for.
58+
* @returns A promise that resolves to an array of comments or an error.
59+
*/
60+
static async getPostComments(contentId: string): Promise<Comment[] | Error> {
3861
try {
39-
const response = await axios.delete(`${apiURL}/comment/${commentId}`, {
40-
withCredentials: true,
41-
timeout: 5000,
42-
});
62+
const response = await axios.get(
63+
`${apiURL}/comment/content/${contentId}`,
64+
{
65+
withCredentials: true,
66+
timeout: 5000,
67+
}
68+
);
4369

4470
return response.data;
4571
} catch (error) {
4672
const message =
4773
axios.isAxiosError(error) && error.response?.data?.error
4874
? error.response.data.error
49-
: "Failed to delete comment";
75+
: "Failed to get comments";
5076

5177
return new Error(message);
5278
}
5379
}
5480

55-
static async updateComment(
81+
/**
82+
* getComment() -> Promise<Comment | Error>
83+
*
84+
* Fetches a specific comment by its ID and the content ID it belongs to.
85+
*
86+
* @param commentId - The ID of the comment to fetch.
87+
* @param contentId - The ID of the content the comment belongs to.
88+
* @returns A promise that resolves to the comment or an error.
89+
*/
90+
static async getComment(
5691
commentId: string,
57-
commentText: string
58-
): Promise<{ message: string } | Error> {
92+
contentId: string
93+
): Promise<Comment | Error> {
5994
try {
60-
const response = await axios.put(
61-
`${apiURL}/comment/${commentId}`,
62-
{ text: commentText },
95+
const response = await axios.get(
96+
`${apiURL}/comment/${commentId}/content/${contentId}`,
6397
{
6498
withCredentials: true,
6599
timeout: 5000,
@@ -71,16 +105,31 @@ export default class CommentService {
71105
const message =
72106
axios.isAxiosError(error) && error.response?.data?.error
73107
? error.response.data.error
74-
: "Failed to update comment";
108+
: "Failed to get comment";
75109

76110
return new Error(message);
77111
}
78112
}
79113

80-
static async getPostComments(contentId: string): Promise<Comment[] | Error> {
114+
/**
115+
* updateComment() -> Promise<{ message: string } | Error>
116+
*
117+
* Updates a comment by its ID and the content ID it belongs to.
118+
*
119+
* @param commentId - The ID of the comment to update.
120+
* @param commentText - The new text for the comment.
121+
* @param contentId - The ID of the content the comment belongs to.
122+
* @returns A promise that resolves to a success message or an error.
123+
*/
124+
static async updateComment(
125+
commentId: string,
126+
commentText: string,
127+
contentId: string
128+
): Promise<{ message: string } | Error> {
81129
try {
82-
const response = await axios.get(
83-
`${apiURL}/comment/content/${contentId}`,
130+
const response = await axios.put(
131+
`${apiURL}/comment/${commentId}/content/${contentId}`,
132+
{ text: commentText },
84133
{
85134
withCredentials: true,
86135
timeout: 5000,
@@ -92,25 +141,40 @@ export default class CommentService {
92141
const message =
93142
axios.isAxiosError(error) && error.response?.data?.error
94143
? error.response.data.error
95-
: "Failed to get comments";
144+
: "Failed to update comment";
96145

97146
return new Error(message);
98147
}
99148
}
100149

101-
static async getComment(commentId: string): Promise<Comment | Error> {
150+
/**
151+
* deleteComment() -> Promise<{ message: string } | Error>
152+
*
153+
* Deletes a comment by its ID and the content ID it belongs to.
154+
*
155+
* @param commentId - The ID of the comment to delete.
156+
* @param contentId - The ID of the content the comment belongs to.
157+
* @returns A promise that resolves to a success message or an error.
158+
*/
159+
static async deleteComment(
160+
commentId: string,
161+
contentId: string
162+
): Promise<{ message: string } | Error> {
102163
try {
103-
const response = await axios.get(`${apiURL}/comment/${commentId}`, {
104-
withCredentials: true,
105-
timeout: 5000,
106-
});
164+
const response = await axios.delete(
165+
`${apiURL}/comment/${commentId}/content/${contentId}`,
166+
{
167+
withCredentials: true,
168+
timeout: 5000,
169+
}
170+
);
107171

108172
return response.data;
109173
} catch (error) {
110174
const message =
111175
axios.isAxiosError(error) && error.response?.data?.error
112176
? error.response.data.error
113-
: "Failed to get comment";
177+
: "Failed to delete comment";
114178

115179
return new Error(message);
116180
}

0 commit comments

Comments
 (0)