first commit
This commit is contained in:
245
app/blog/handlers/comment_handler.go
Normal file
245
app/blog/handlers/comment_handler.go
Normal file
@@ -0,0 +1,245 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"gobeyhan/app/blog/services"
|
||||
"gobeyhan/database/models"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type CommentHandler struct {
|
||||
service *services.CommentService
|
||||
}
|
||||
|
||||
func NewCommentHandler(service *services.CommentService) *CommentHandler {
|
||||
return &CommentHandler{service: service}
|
||||
}
|
||||
|
||||
// GetPostComments godoc
|
||||
// @Summary Get comments for a post
|
||||
// @Description Get all active comments for a specific post (public endpoint)
|
||||
// @Tags comments
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path int true "Post ID"
|
||||
// @Success 200 {array} models.Comment
|
||||
// @Router /api/v1/posts/{id}/comments [get]
|
||||
func (h *CommentHandler) GetPostComments(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
postID, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid post ID"})
|
||||
return
|
||||
}
|
||||
|
||||
comments, err := h.service.GetCommentsByPost(postID, true)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"data": comments})
|
||||
}
|
||||
|
||||
// CreatePostComment godoc
|
||||
// @Summary Create a comment on a post
|
||||
// @Description Create a new comment (requires authentication)
|
||||
// @Tags comments
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "Post ID"
|
||||
// @Param comment body models.Comment true "Comment object"
|
||||
// @Success 201 {object} models.Comment
|
||||
// @Router /api/v1/posts/{id}/comments [post]
|
||||
func (h *CommentHandler) CreatePostComment(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
postID, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid post ID"})
|
||||
return
|
||||
}
|
||||
|
||||
// Get user ID from context (set by auth middleware)
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "User not authenticated"})
|
||||
return
|
||||
}
|
||||
|
||||
var input struct {
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body" binding:"required"`
|
||||
ParentID *uint64 `json:"parent_id"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Convert user_id to uint64
|
||||
var uid uint64
|
||||
switch v := userID.(type) {
|
||||
case string:
|
||||
uid, _ = strconv.ParseUint(v, 10, 64)
|
||||
case uint64:
|
||||
uid = v
|
||||
case int:
|
||||
uid = uint64(v)
|
||||
case float64:
|
||||
uid = uint64(v)
|
||||
}
|
||||
|
||||
comment := &models.Comment{
|
||||
UserID: uid,
|
||||
ProductID: postID,
|
||||
Title: input.Title,
|
||||
Body: input.Body,
|
||||
ParentID: input.ParentID,
|
||||
IsActive: true,
|
||||
}
|
||||
|
||||
if err := h.service.CreateComment(comment); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{"data": comment})
|
||||
}
|
||||
|
||||
// AdminGetAllComments godoc
|
||||
// @Summary Get all comments (Admin)
|
||||
// @Description Get paginated list of all comments
|
||||
// @Tags admin,comments
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param page query int false "Page number" default(1)
|
||||
// @Param limit query int false "Items per page" default(10)
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/admin/comments [get]
|
||||
func (h *CommentHandler) AdminGetAllComments(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
||||
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if limit < 1 || limit > 100 {
|
||||
limit = 10
|
||||
}
|
||||
|
||||
comments, total, err := h.service.GetAllComments(page, limit, false)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"data": comments,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"limit": limit,
|
||||
})
|
||||
}
|
||||
|
||||
// AdminGetCommentByID godoc
|
||||
// @Summary Get comment by ID (Admin)
|
||||
// @Description Get a single comment by ID
|
||||
// @Tags admin,comments
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "Comment ID"
|
||||
// @Success 200 {object} models.Comment
|
||||
// @Router /api/v1/admin/comments/{id} [get]
|
||||
func (h *CommentHandler) AdminGetCommentByID(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid comment ID"})
|
||||
return
|
||||
}
|
||||
|
||||
comment, err := h.service.GetCommentByID(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if comment == nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Comment not found"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"data": comment})
|
||||
}
|
||||
|
||||
// AdminUpdateComment godoc
|
||||
// @Summary Update a comment (Admin)
|
||||
// @Description Update an existing comment
|
||||
// @Tags admin,comments
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "Comment ID"
|
||||
// @Param comment body models.Comment true "Comment object"
|
||||
// @Success 200 {object} models.Comment
|
||||
// @Router /api/v1/admin/comments/{id} [put]
|
||||
func (h *CommentHandler) AdminUpdateComment(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid comment ID"})
|
||||
return
|
||||
}
|
||||
|
||||
var input map[string]interface{}
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.service.UpdateComment(id, input); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Fetch updated comment
|
||||
comment, err := h.service.GetCommentByID(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"data": comment})
|
||||
}
|
||||
|
||||
// AdminDeleteComment godoc
|
||||
// @Summary Delete a comment (Admin)
|
||||
// @Description Delete a comment by ID
|
||||
// @Tags admin,comments
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security BearerAuth
|
||||
// @Param id path int true "Comment ID"
|
||||
// @Success 200 {object} map[string]string
|
||||
// @Router /api/v1/admin/comments/{id} [delete]
|
||||
func (h *CommentHandler) AdminDeleteComment(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid comment ID"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.service.DeleteComment(id); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Comment deleted successfully"})
|
||||
}
|
||||
Reference in New Issue
Block a user