feat: add feature article

This commit is contained in:
pahmiudahgede 2024-12-10 07:42:51 +07:00
parent c326fcc6fc
commit a05edce16a
8 changed files with 369 additions and 2 deletions

View File

@ -57,6 +57,7 @@ func InitDatabase() {
&domain.MenuAccess{}, &domain.MenuAccess{},
&domain.PlatformHandle{}, &domain.PlatformHandle{},
&domain.Address{}, &domain.Address{},
&domain.Article{},
) )
if err != nil { if err != nil {
log.Fatal("Error: Failed to auto migrate domain:", err) log.Fatal("Error: Failed to auto migrate domain:", err)

14
domain/article.go Normal file
View File

@ -0,0 +1,14 @@
package domain
import "time"
type Article struct {
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4();unique;not null" json:"id"`
Title string `gorm:"not null" json:"title"`
CoverImage string `gorm:"not null" json:"coverImage"`
Author string `gorm:"not null" json:"author"`
Heading string `gorm:"not null" json:"heading"`
Content string `gorm:"not null" json:"content"`
PublishedAt time.Time `gorm:"not null" json:"publishedAt"`
UpdatedAt time.Time `gorm:"not null" json:"updatedAt"`
}

35
dto/article.go Normal file
View File

@ -0,0 +1,35 @@
package dto
import "time"
type ArticleRequest struct {
Title string `json:"title" validate:"required"`
CoverImage string `json:"coverImage" validate:"required"`
Author string `json:"author" validate:"required"`
Heading string `json:"heading" validate:"required"`
Content string `json:"content" validate:"required"`
PublishedAt time.Time `json:"publishedAt" validate:"required"`
}
type ArticleResponse struct {
ID string `json:"id"`
Title string `json:"title"`
CoverImage string `json:"coverImage"`
Author string `json:"author"`
Heading string `json:"heading"`
Content string `json:"content"`
PublishedAt time.Time `json:"publishedAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type ArticleUpdateRequest struct {
Title string `json:"title" validate:"required"`
CoverImage string `json:"coverImage" validate:"required"`
Author string `json:"author" validate:"required"`
Heading string `json:"heading" validate:"required"`
Content string `json:"content" validate:"required"`
}
func (ar *ArticleRequest) Validate() error {
return validate.Struct(ar)
}

View File

@ -31,4 +31,11 @@ func AppRouter(app *fiber.App) {
app.Post("/create-address", middleware.AuthMiddleware, controllers.CreateAddress) app.Post("/create-address", middleware.AuthMiddleware, controllers.CreateAddress)
app.Put("/address/:id", middleware.AuthMiddleware, controllers.UpdateAddress) app.Put("/address/:id", middleware.AuthMiddleware, controllers.UpdateAddress)
app.Delete("/address/:id", middleware.AuthMiddleware, controllers.DeleteAddress) app.Delete("/address/:id", middleware.AuthMiddleware, controllers.DeleteAddress)
// # article
app.Post("/articles", middleware.AuthMiddleware, controllers.CreateArticle)
app.Get("/articles", middleware.AuthMiddleware, controllers.GetArticles)
app.Get("/articles/:id", middleware.AuthMiddleware, controllers.GetArticleByID)
app.Put("/articles/:id", middleware.AuthMiddleware, controllers.UpdateArticle)
app.Delete("/articles/:id", middleware.AuthMiddleware, controllers.DeleteArticle)
} }

View File

@ -0,0 +1,138 @@
package controllers
import (
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
"github.com/pahmiudahgede/senggoldong/dto"
"github.com/pahmiudahgede/senggoldong/internal/services"
"github.com/pahmiudahgede/senggoldong/utils"
)
func CreateArticle(c *fiber.Ctx) error {
var articleRequest dto.ArticleRequest
if err := c.BodyParser(&articleRequest); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Invalid input",
nil,
))
}
validate := validator.New()
err := validate.Struct(articleRequest)
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Validation error",
err.Error(),
))
}
createdArticle, err := services.CreateArticle(&articleRequest)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
fiber.StatusInternalServerError,
"Failed to create article",
nil,
))
}
return c.Status(fiber.StatusCreated).JSON(utils.FormatResponse(
fiber.StatusCreated,
"Article created successfully",
createdArticle,
))
}
func GetArticles(c *fiber.Ctx) error {
articles, err := services.GetArticles()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
fiber.StatusInternalServerError,
"Failed to fetch articles",
nil,
))
}
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
fiber.StatusOK,
"Articles fetched successfully",
articles,
))
}
func GetArticleByID(c *fiber.Ctx) error {
id := c.Params("id")
article, err := services.GetArticleByID(id)
if err != nil {
return c.Status(fiber.StatusNotFound).JSON(utils.FormatResponse(
fiber.StatusNotFound,
"Article not found",
nil,
))
}
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
fiber.StatusOK,
"Article fetched successfully",
article,
))
}
func UpdateArticle(c *fiber.Ctx) error {
id := c.Params("id")
var articleUpdateRequest dto.ArticleUpdateRequest
if err := c.BodyParser(&articleUpdateRequest); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Invalid input",
nil,
))
}
validate := validator.New()
err := validate.Struct(articleUpdateRequest)
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(utils.FormatResponse(
fiber.StatusBadRequest,
"Validation error",
err.Error(),
))
}
updatedArticle, err := services.UpdateArticle(id, &articleUpdateRequest)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
fiber.StatusInternalServerError,
"Failed to update article",
nil,
))
}
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
fiber.StatusOK,
"Article updated successfully",
updatedArticle,
))
}
func DeleteArticle(c *fiber.Ctx) error {
id := c.Params("id")
err := services.DeleteArticle(id)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(utils.FormatResponse(
fiber.StatusInternalServerError,
"Failed to delete article",
nil,
))
}
return c.Status(fiber.StatusOK).JSON(utils.FormatResponse(
fiber.StatusOK,
"Article deleted successfully",
nil,
))
}

View File

@ -0,0 +1,57 @@
package repositories
import (
"github.com/pahmiudahgede/senggoldong/config"
"github.com/pahmiudahgede/senggoldong/domain"
)
func CreateArticle(article *domain.Article) error {
err := config.DB.Create(article).Error
if err != nil {
return err
}
return nil
}
func GetArticles() ([]domain.Article, error) {
var articles []domain.Article
err := config.DB.Find(&articles).Error
if err != nil {
return nil, err
}
return articles, nil
}
func GetArticleByID(id string) (domain.Article, error) {
var article domain.Article
err := config.DB.Where("id = ?", id).First(&article).Error
if err != nil {
return article, err
}
return article, nil
}
func UpdateArticle(article *domain.Article) error {
err := config.DB.Save(article).Error
if err != nil {
return err
}
return nil
}
func DeleteArticle(id string) error {
var article domain.Article
err := config.DB.Where("id = ?", id).First(&article).Error
if err != nil {
return err
}
err = config.DB.Delete(&article).Error
if err != nil {
return err
}
return nil
}

View File

@ -11,7 +11,7 @@ func GetUserRoleByID(id string) (domain.UserRole, error) {
var role domain.UserRole var role domain.UserRole
err := config.DB.Where("id = ?", id).First(&role).Error err := config.DB.Where("id = ?", id).First(&role).Error
if err != nil { if err != nil {
return role, errors.New("UserRole tidak ditemukan") return role, errors.New("userRole tidak ditemukan")
} }
return role, nil return role, nil
} }
@ -20,7 +20,7 @@ func GetAllUserRoles() ([]domain.UserRole, error) {
var roles []domain.UserRole var roles []domain.UserRole
err := config.DB.Find(&roles).Error err := config.DB.Find(&roles).Error
if err != nil { if err != nil {
return nil, errors.New("Gagal mengambil data UserRole") return nil, errors.New("gagal mengambil data UserRole")
} }
return roles, nil return roles, nil
} }

View File

@ -0,0 +1,115 @@
package services
import (
"time"
"github.com/pahmiudahgede/senggoldong/domain"
"github.com/pahmiudahgede/senggoldong/dto"
"github.com/pahmiudahgede/senggoldong/internal/repositories"
)
func CreateArticle(articleRequest *dto.ArticleRequest) (*dto.ArticleResponse, error) {
article := domain.Article{
Title: articleRequest.Title,
CoverImage: articleRequest.CoverImage,
Author: articleRequest.Author,
Heading: articleRequest.Heading,
Content: articleRequest.Content,
PublishedAt: articleRequest.PublishedAt,
UpdatedAt: articleRequest.PublishedAt,
}
err := repositories.CreateArticle(&article)
if err != nil {
return nil, err
}
return &dto.ArticleResponse{
ID: article.ID,
Title: article.Title,
CoverImage: article.CoverImage,
Author: article.Author,
Heading: article.Heading,
Content: article.Content,
PublishedAt: article.PublishedAt,
UpdatedAt: article.UpdatedAt,
}, nil
}
func GetArticles() ([]dto.ArticleResponse, error) {
articles, err := repositories.GetArticles()
if err != nil {
return nil, err
}
var response []dto.ArticleResponse
for _, article := range articles {
response = append(response, dto.ArticleResponse{
ID: article.ID,
Title: article.Title,
CoverImage: article.CoverImage,
Author: article.Author,
Heading: article.Heading,
Content: article.Content,
PublishedAt: article.PublishedAt,
UpdatedAt: article.UpdatedAt,
})
}
return response, nil
}
func GetArticleByID(id string) (dto.ArticleResponse, error) {
article, err := repositories.GetArticleByID(id)
if err != nil {
return dto.ArticleResponse{}, err
}
return dto.ArticleResponse{
ID: article.ID,
Title: article.Title,
CoverImage: article.CoverImage,
Author: article.Author,
Heading: article.Heading,
Content: article.Content,
PublishedAt: article.PublishedAt,
UpdatedAt: article.UpdatedAt,
}, nil
}
func UpdateArticle(id string, articleUpdateRequest *dto.ArticleUpdateRequest) (*dto.ArticleResponse, error) {
article, err := repositories.GetArticleByID(id)
if err != nil {
return nil, err
}
article.Title = articleUpdateRequest.Title
article.CoverImage = articleUpdateRequest.CoverImage
article.Author = articleUpdateRequest.Author
article.Heading = articleUpdateRequest.Heading
article.Content = articleUpdateRequest.Content
article.UpdatedAt = time.Now()
err = repositories.UpdateArticle(&article)
if err != nil {
return nil, err
}
return &dto.ArticleResponse{
ID: article.ID,
Title: article.Title,
CoverImage: article.CoverImage,
Author: article.Author,
Heading: article.Heading,
Content: article.Content,
PublishedAt: article.PublishedAt,
UpdatedAt: article.UpdatedAt,
}, nil
}
func DeleteArticle(id string) error {
err := repositories.DeleteArticle(id)
if err != nil {
return err
}
return nil
}