first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:43:40 +03:00
commit f34e54c5a5
100 changed files with 27342 additions and 0 deletions

View 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"})
}