246 lines
6.3 KiB
Go
246 lines
6.3 KiB
Go
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"})
|
|
}
|