add api tabs
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Anang Yusman 2026-04-10 02:08:56 +08:00
parent a2f9c3423b
commit c1c6689209
99 changed files with 5391 additions and 890 deletions

View File

@ -0,0 +1,20 @@
package entity
import "time"
type AboutUsContentImage struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
AboutUsContentID uint `json:"about_us_content_id" gorm:"type:int4;not null"`
MediaPath string `json:"media_path" gorm:"type:varchar(255)"`
MediaType string `json:"media_type" gorm:"type:varchar(100)"`
MediaURL string `json:"media_url" gorm:"type:text"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
// relation (optional tapi bagus)
AboutUsContent AboutUsContent `json:"about_us_content" gorm:"foreignKey:AboutUsContentID"`
}
func (AboutUsContentImage) TableName() string {
return "about_us_content_images"
}

View File

@ -0,0 +1,19 @@
package entity
import "time"
type AboutUsContent struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
PrimaryTitle string `json:"primary_title" gorm:"type:varchar(255)"`
SecondaryTitle string `json:"secondary_title" gorm:"type:varchar(255)"`
Description string `json:"description" gorm:"type:text"`
PrimaryCta string `json:"primary_cta" gorm:"type:varchar(255)"`
SecondaryCtaText string `json:"secondary_cta_text" gorm:"type:varchar(255)"`
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
}
func (AboutUsContent) TableName() string {
return "about_us_contents"
}

View File

@ -0,0 +1,25 @@
package entity
import (
"time"
"github.com/google/uuid"
)
type HeroContents struct {
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid;default:uuid_generate_v4()"`
PrimaryTitle string `json:"primary_title" gorm:"type:varchar(255)"`
SecondaryTitle string `json:"secondary_title" gorm:"type:varchar(255)"`
Description string `json:"description" gorm:"type:text"`
PrimaryCta string `json:"primary_cta" gorm:"type:varchar(255)"`
SecondaryCtaText string `json:"secondary_cta_text" gorm:"type:varchar(255)"`
IsActive *bool `json:"is_active" gorm:"default:true"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
HeroContentImage []HeroContentImages `json:"images" gorm:"foreignKey:HeroContentID"`
}
func (HeroContents) TableName() string {
return "hero_contents"
}

View File

@ -0,0 +1,20 @@
package entity
import (
"time"
"github.com/google/uuid"
)
type HeroContentImages struct {
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid;default:uuid_generate_v4()"`
HeroContentID uuid.UUID `json:"hero_content_id" gorm:"type:uuid;not null"`
ImagePath string `json:"image_path" gorm:"type:text"`
ImageURL string `json:"image_url" gorm:"type:text"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func (HeroContentImages) TableName() string {
return "hero_content_images"
}

View File

@ -0,0 +1,17 @@
package entity
import (
"github.com/google/uuid"
)
type OurProductContentImage struct {
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid;default:uuid_generate_v4()"`
OurProductContentID uuid.UUID `json:"our_product_content_id" gorm:"type:uuid"`
ImagePath string `json:"image_path" gorm:"type:varchar(255)"`
ImageURL string `json:"image_url" gorm:"type:text"`
IsThumbnail *bool `json:"is_thumbnail" gorm:"default:false"`
}
func (OurProductContentImage) TableName() string {
return "our_product_content_images"
}

View File

@ -0,0 +1,23 @@
package entity
import (
"time"
"github.com/google/uuid"
)
type OurProductContent struct {
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid;default:uuid_generate_v4()"`
PrimaryTitle string `json:"primary_title" gorm:"type:varchar(255)"`
SecondaryTitle string `json:"secondary_title" gorm:"type:varchar(255)"`
Description string `json:"description" gorm:"type:text"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
IsActive *bool `json:"is_active" gorm:"default:true"`
Images []OurProductContentImage `json:"images" gorm:"foreignKey:OurProductContentID"`
}
func (OurProductContent) TableName() string {
return "our_product_contents"
}

View File

@ -0,0 +1,13 @@
package entity
type OurServiceContentImage struct {
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
OurServiceContentID uint `json:"our_service_content_id"`
ImagePath string `json:"image_path" gorm:"type:varchar(255)"`
ImageURL string `json:"image_url" gorm:"type:text"`
IsThumbnail *bool `json:"is_thumbnail" gorm:"default:false"`
}
func (OurServiceContentImage) TableName() string {
return "our_service_content_images"
}

View File

@ -0,0 +1,20 @@
package entity
import (
"time"
)
type OurServiceContent struct {
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
PrimaryTitle string `json:"primary_title" gorm:"type:varchar(255)"`
SecondaryTitle string `json:"secondary_title" gorm:"type:varchar(255)"`
Description string `json:"description" gorm:"type:text"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
IsActive *bool `json:"is_active" gorm:"default:true"`
Images []OurServiceContentImage `json:"images" gorm:"foreignKey:OurServiceContentID"`
}
func (OurServiceContent) TableName() string {
return "our_service_contents"
}

View File

@ -0,0 +1,21 @@
package entity
import (
"time"
"github.com/google/uuid"
)
type PartnerContent struct {
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid;default:uuid_generate_v4()"`
PrimaryTitle string `json:"primary_title" gorm:"type:varchar(255)"`
ImagePath string `json:"image_path" gorm:"type:varchar(255)"`
ImageURL string `json:"image_url" gorm:"type:text"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func (PartnerContent) TableName() string {
return "partner_contents"
}

View File

@ -0,0 +1,16 @@
package entity
type PopupNewsContentImages struct {
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
PopupNewsContentID uint `json:"popup_news_content_id"`
MediaPath string `json:"media_path" gorm:"type:varchar(255)"`
MediaURL string `json:"media_url" gorm:"type:text"`
IsThumbnail *bool `json:"is_thumbnail" gorm:"default:false"`
// 🔥 RELATION BACK (optional)
PopupNewsContents PopupNewsContents `json:"popup_news_contents" gorm:"foreignKey:PopupNewsContentID"`
}
func (PopupNewsContentImages) TableName() string {
return "popup_news_content_image"
}

View File

@ -0,0 +1,17 @@
package entity
type PopupNewsContents struct {
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
PrimaryTitle string `json:"primary_title" gorm:"type:varchar(255)"`
SecondaryTitle string `json:"secondary_title" gorm:"type:varchar(255)"`
Description string `json:"description" gorm:"type:text"`
PrimaryCTA string `json:"primary_cta" gorm:"type:varchar(255)"`
SecondaryCTAText string `json:"secondary_cta_text" gorm:"type:varchar(255)"`
// 🔥 RELATION
Images []PopupNewsContentImages `json:"images" gorm:"foreignKey:PopupNewsContentID"`
}
func (PopupNewsContents) TableName() string {
return "popup_news_content"
}

View File

@ -85,6 +85,8 @@ func Models() []interface{} {
return []interface{}{
entity.ActivityLogs{},
entity.ActivityLogTypes{},
entity.AboutUsContent{},
entity.AboutUsContentImage{},
entity.Advertisement{},
entity.ApprovalWorkflows{},
entity.ApprovalWorkflowSteps{},
@ -106,6 +108,8 @@ func Models() []interface{} {
entity.CustomStaticPages{},
entity.Districts{},
entity.Feedbacks{},
entity.HeroContents{},
entity.HeroContentImages{},
entity.ForgotPasswords{},
entity.Magazines{},
entity.MagazineFiles{},
@ -115,6 +119,9 @@ func Models() []interface{} {
entity.MasterApprovalStatuses{},
entity.Provinces{},
entity.OneTimePasswords{},
entity.OurProductContent{},
entity.OurProductContentImage{},
entity.PartnerContent{},
entity.Subscription{},
entity.Schedules{},
entity.UserLevels{},

View File

@ -0,0 +1,56 @@
package about_us_content_images
import (
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
"web-qudo-be/app/module/about_us_content_images/controller"
"web-qudo-be/app/module/about_us_content_images/repository"
"web-qudo-be/app/module/about_us_content_images/service"
)
// struct router
type AboutUsContentImageRouter struct {
App fiber.Router
Controller *controller.Controller
}
// register module
var NewAboutUsContentImageModule = fx.Options(
// repository
fx.Provide(repository.NewAboutUsContentImageRepository),
// service
fx.Provide(service.NewAboutUsContentImageService),
// controller
fx.Provide(controller.NewController),
// router
fx.Provide(NewAboutUsContentImageRouter),
)
// init router
func NewAboutUsContentImageRouter(fiber *fiber.App, controller *controller.Controller) *AboutUsContentImageRouter {
return &AboutUsContentImageRouter{
App: fiber,
Controller: controller,
}
}
// register routes
func (_i *AboutUsContentImageRouter) RegisterAboutUsContentImageRoutes() {
aboutUsContentImageController := _i.Controller.AboutUsContentImage
_i.App.Route("/about-us-content-images", func(router fiber.Router) {
router.Get("/", aboutUsContentImageController.All)
router.Get("/:id", aboutUsContentImageController.Show)
// upload image (pakai form-data)
router.Post("/", aboutUsContentImageController.Save)
router.Delete("/:id", aboutUsContentImageController.Delete)
})
}

View File

@ -0,0 +1,115 @@
package controller
import (
"strconv"
"web-qudo-be/app/module/about_us_content_images/service"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog"
utilRes "web-qudo-be/utils/response"
)
type aboutUsContentImageController struct {
service service.AboutUsContentImageService
Log zerolog.Logger
}
type AboutUsContentImageController interface {
All(c *fiber.Ctx) error
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewAboutUsContentImageController(service service.AboutUsContentImageService, log zerolog.Logger) AboutUsContentImageController {
return &aboutUsContentImageController{
service: service,
Log: log,
}
}
// GET ALL
func (_i *aboutUsContentImageController) All(c *fiber.Ctx) error {
_i.Log.Info().Msg("GET /about-us-content-images")
data, err := _i.service.All()
if err != nil {
_i.Log.Error().Err(err).Msg("failed get about us content images")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"About us content images retrieved"},
Data: data,
})
}
// GET BY ID
func (_i *aboutUsContentImageController) Show(c *fiber.Ctx) error {
id, err := strconv.Atoi(c.Params("id"))
if err != nil {
return err
}
data, err := _i.service.Show(uint(id))
if err != nil {
_i.Log.Error().Err(err).Msg("failed get about us content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"About us content image retrieved"},
Data: data,
})
}
// CREATE
func (_i *aboutUsContentImageController) Save(c *fiber.Ctx) error {
// Ambil about_us_content_id dari form
aboutUsContentId, err := strconv.Atoi(c.FormValue("about_us_content_id"))
if err != nil {
return err
}
// Ambil file
file, err := c.FormFile("file")
if err != nil {
return err
}
// Kirim ke service
result, err := _i.service.Save(uint(aboutUsContentId), file)
if err != nil {
_i.Log.Error().Err(err).Msg("failed create about us content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"About us content image created"},
Data: result,
})
}
// DELETE
func (_i *aboutUsContentImageController) Delete(c *fiber.Ctx) error {
id, err := strconv.Atoi(c.Params("id"))
if err != nil {
return err
}
err = _i.service.Delete(uint(id))
if err != nil {
_i.Log.Error().Err(err).Msg("failed delete about us content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"About us content image deleted"},
})
}

View File

@ -0,0 +1,17 @@
package controller
import (
"web-qudo-be/app/module/about_us_content_images/service"
"github.com/rs/zerolog"
)
type Controller struct {
AboutUsContentImage AboutUsContentImageController
}
func NewController(aboutUsContentImageService service.AboutUsContentImageService, log zerolog.Logger) *Controller {
return &Controller{
AboutUsContentImage: NewAboutUsContentImageController(aboutUsContentImageService, log),
}
}

View File

@ -0,0 +1,69 @@
package repository
import (
"web-qudo-be/app/database"
"web-qudo-be/app/database/entity"
"github.com/rs/zerolog"
)
type aboutUsContentImageRepository struct {
DB *database.Database
Log zerolog.Logger
}
// interface
type AboutUsContentImageRepository interface {
GetAll() (images []*entity.AboutUsContentImage, err error)
FindOne(id uint) (image *entity.AboutUsContentImage, err error)
FindByContentID(contentID uint) (images []*entity.AboutUsContentImage, err error)
Create(image *entity.AboutUsContentImage) (imageReturn *entity.AboutUsContentImage, err error)
Delete(id uint) (err error)
}
// constructor
func NewAboutUsContentImageRepository(db *database.Database, log zerolog.Logger) AboutUsContentImageRepository {
return &aboutUsContentImageRepository{
DB: db,
Log: log,
}
}
// ==============================
// IMPLEMENTATION
// ==============================
// GET ALL
func (_i *aboutUsContentImageRepository) GetAll() (images []*entity.AboutUsContentImage, err error) {
err = _i.DB.DB.
Where("is_active = ?", true).
Find(&images).Error
return
}
// GET BY ID
func (_i *aboutUsContentImageRepository) FindOne(id uint) (image *entity.AboutUsContentImage, err error) {
if err := _i.DB.DB.First(&image, id).Error; err != nil {
return nil, err
}
return image, nil
}
// GET BY ABOUT US CONTENT ID
func (_i *aboutUsContentImageRepository) FindByContentID(contentID uint) (images []*entity.AboutUsContentImage, err error) {
err = _i.DB.DB.
Where("about_us_content_id = ? AND is_active = ?", contentID, true).
Find(&images).Error
return
}
// CREATE
func (_i *aboutUsContentImageRepository) Create(image *entity.AboutUsContentImage) (imageReturn *entity.AboutUsContentImage, err error) {
result := _i.DB.DB.Create(image)
return image, result.Error
}
// DELETE (hard delete, bisa ubah ke soft delete kalau mau)
func (_i *aboutUsContentImageRepository) Delete(id uint) (err error) {
return _i.DB.DB.Delete(&entity.AboutUsContentImage{}, id).Error
}

View File

@ -0,0 +1,92 @@
package service
import (
"fmt"
"mime/multipart"
"path/filepath"
"time"
"web-qudo-be/app/database/entity"
"web-qudo-be/app/module/about_us_content_images/repository"
"github.com/rs/zerolog"
fileUtil "web-qudo-be/utils/file"
)
type aboutUsContentImageService struct {
Repo repository.AboutUsContentImageRepository
Log zerolog.Logger
}
type AboutUsContentImageService interface {
All() (images []*entity.AboutUsContentImage, err error)
Show(id uint) (image *entity.AboutUsContentImage, err error)
Save(aboutUsContentId uint, file *multipart.FileHeader) (image *entity.AboutUsContentImage, err error)
Delete(id uint) error
}
func NewAboutUsContentImageService(
repo repository.AboutUsContentImageRepository,
log zerolog.Logger,
) AboutUsContentImageService {
return &aboutUsContentImageService{
Repo: repo,
Log: log,
}
}
func (_i *aboutUsContentImageService) All() (images []*entity.AboutUsContentImage, err error) {
return _i.Repo.GetAll()
}
func (_i *aboutUsContentImageService) Show(id uint) (image *entity.AboutUsContentImage, err error) {
return _i.Repo.FindOne(id)
}
func (_i *aboutUsContentImageService) Save(aboutUsContentId uint, file *multipart.FileHeader) (image *entity.AboutUsContentImage, err error) {
_i.Log.Info().
Uint("aboutUsContentId", aboutUsContentId).
Str("filename", file.Filename).
Msg("upload image")
// validasi file
ext := filepath.Ext(file.Filename)
if ext != ".jpg" && ext != ".jpeg" && ext != ".png" {
return nil, fmt.Errorf("invalid file type")
}
// generate filename
filename := fmt.Sprintf("about_us_%d_%d%s", aboutUsContentId, time.Now().Unix(), ext)
filePath := fmt.Sprintf("./uploads/%s", filename)
// save file
if err := fileUtil.SaveFile(file, filePath); err != nil {
_i.Log.Error().Err(err).Msg("failed save file")
return nil, err
}
// save ke DB
data := &entity.AboutUsContentImage{
AboutUsContentID: aboutUsContentId,
MediaPath: filePath,
MediaType: ext,
MediaURL: "/uploads/" + filename,
}
result, err := _i.Repo.Create(data)
if err != nil {
_i.Log.Error().Err(err).Msg("failed save to DB")
return nil, err
}
return result, nil
}
func (_i *aboutUsContentImageService) Delete(id uint) error {
return _i.Repo.Delete(id)
}

View File

@ -0,0 +1,57 @@
package about_us_contents
import (
"web-qudo-be/app/module/about_us_contents/controller"
"web-qudo-be/app/module/about_us_contents/repository"
"web-qudo-be/app/module/about_us_contents/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
// AboutUsContentsRouter struct
type AboutUsContentsRouter struct {
App fiber.Router
Controller *controller.Controller
}
// register module
var NewAboutUsContentsModule = fx.Options(
// repository
fx.Provide(repository.NewAboutUsContentRepository),
// service
fx.Provide(service.NewAboutUsContentService),
// controller
fx.Provide(controller.NewController),
// router
fx.Provide(NewAboutUsContentsRouter),
)
// init router
func NewAboutUsContentsRouter(
fiber *fiber.App,
controller *controller.Controller,
) *AboutUsContentsRouter {
return &AboutUsContentsRouter{
App: fiber,
Controller: controller,
}
}
// register routes
func (_i *AboutUsContentsRouter) RegisterAboutUsContentsRoutes() {
aboutController := _i.Controller.AboutUsContent
_i.App.Route("/about-us-contents", func(router fiber.Router) {
// BASIC CRUD (mirip articles tapi tanpa middleware & fitur tambahan)
router.Get("/", aboutController.All) // get all
router.Get("/:id", aboutController.Show) // get by id
router.Post("/", aboutController.Save) // create
router.Put("/:id", aboutController.Update) // update
router.Delete("/:id", aboutController.Delete) // delete
})
}

View File

@ -0,0 +1,135 @@
package controller
import (
"strconv"
"web-qudo-be/app/module/about_us_contents/service"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog"
utilRes "web-qudo-be/utils/response"
utilVal "web-qudo-be/utils/validator"
)
type aboutUsContentController struct {
service service.AboutUsContentService
Log zerolog.Logger
}
type AboutUsContentController interface {
All(c *fiber.Ctx) error
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewAboutUsContentController(service service.AboutUsContentService, log zerolog.Logger) AboutUsContentController {
return &aboutUsContentController{
service: service,
Log: log,
}
}
// GET ALL
func (_i *aboutUsContentController) All(c *fiber.Ctx) error {
_i.Log.Info().Msg("GET /about-us-contents")
data, err := _i.service.All()
if err != nil {
_i.Log.Error().Err(err).Msg("failed get about us contents")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"About us contents retrieved"},
Data: data,
})
}
// GET BY ID
func (_i *aboutUsContentController) Show(c *fiber.Ctx) error {
id, err := strconv.Atoi(c.Params("id"))
if err != nil {
return err
}
data, err := _i.service.Show(uint(id))
if err != nil {
_i.Log.Error().Err(err).Msg("failed get about us content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"About us content retrieved"},
Data: data,
})
}
// CREATE
func (_i *aboutUsContentController) Save(c *fiber.Ctx) error {
req := new(map[string]interface{})
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
result, err := _i.service.Save(*req)
if err != nil {
_i.Log.Error().Err(err).Msg("failed create about us content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"About us content created"},
Data: result,
})
}
// UPDATE
func (_i *aboutUsContentController) Update(c *fiber.Ctx) error {
id, err := strconv.Atoi(c.Params("id"))
if err != nil {
return err
}
req := new(map[string]interface{})
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err = _i.service.Update(uint(id), *req)
if err != nil {
_i.Log.Error().Err(err).Msg("failed update about us content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"About us content updated"},
})
}
// DELETE (soft delete)
func (_i *aboutUsContentController) Delete(c *fiber.Ctx) error {
id, err := strconv.Atoi(c.Params("id"))
if err != nil {
return err
}
err = _i.service.Delete(uint(id))
if err != nil {
_i.Log.Error().Err(err).Msg("failed delete about us content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"About us content deleted"},
})
}

View File

@ -0,0 +1,17 @@
package controller
import (
"web-qudo-be/app/module/about_us_contents/service"
"github.com/rs/zerolog"
)
type Controller struct {
AboutUsContent AboutUsContentController
}
func NewController(aboutUsContentService service.AboutUsContentService, log zerolog.Logger) *Controller {
return &Controller{
AboutUsContent: NewAboutUsContentController(aboutUsContentService, log),
}
}

View File

@ -0,0 +1,96 @@
package repository
import (
"github.com/rs/zerolog"
"web-qudo-be/app/database"
"web-qudo-be/app/database/entity"
)
type aboutUsContentRepository struct {
DB *database.Database
Log zerolog.Logger
}
// interface
type AboutUsContentRepository interface {
GetAll() ([]*entity.AboutUsContent, error)
FindOne(id uint) (*entity.AboutUsContent, error)
Create(data *entity.AboutUsContent) (*entity.AboutUsContent, error)
Update(id uint, data *entity.AboutUsContent) error
Delete(id uint) error
}
// constructor
func NewAboutUsContentRepository(db *database.Database, logger zerolog.Logger) AboutUsContentRepository {
return &aboutUsContentRepository{
DB: db,
Log: logger,
}
}
// GET ALL
func (r *aboutUsContentRepository) GetAll() ([]*entity.AboutUsContent, error) {
var results []*entity.AboutUsContent
err := r.DB.DB.
Where("is_active = ?", true).
Find(&results).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed get about us contents")
return nil, err
}
return results, nil
}
// GET ONE
func (r *aboutUsContentRepository) FindOne(id uint) (*entity.AboutUsContent, error) {
var data entity.AboutUsContent
err := r.DB.DB.First(&data, id).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed find about us content")
return nil, err
}
return &data, nil
}
// CREATE
func (r *aboutUsContentRepository) Create(data *entity.AboutUsContent) (*entity.AboutUsContent, error) {
err := r.DB.DB.Create(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed create about us content")
return nil, err
}
return data, nil
}
// UPDATE
func (r *aboutUsContentRepository) Update(id uint, data *entity.AboutUsContent) error {
err := r.DB.DB.
Model(&entity.AboutUsContent{}).
Where("id = ?", id).
Updates(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed update about us content")
return err
}
return nil
}
// DELETE (hard delete, optional)
func (r *aboutUsContentRepository) Delete(id uint) error {
err := r.DB.DB.Delete(&entity.AboutUsContent{}, id).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed delete about us content")
return err
}
return nil
}

View File

@ -0,0 +1,64 @@
package request
import (
"time"
"web-qudo-be/app/database/entity"
"web-qudo-be/utils/paginator"
)
type AboutUsContentQueryRequest struct {
PrimaryTitle *string `json:"primary_title"`
Pagination *paginator.Pagination `json:"pagination"`
}
type AboutUsContentCreateRequest struct {
PrimaryTitle string `json:"primary_title" validate:"required"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
PrimaryCTA string `json:"primary_cta"`
SecondaryCTAText string `json:"secondary_cta_text"`
}
func (req AboutUsContentCreateRequest) ToEntity() *entity.AboutUsContent {
return &entity.AboutUsContent{
PrimaryTitle: req.PrimaryTitle,
SecondaryTitle: req.SecondaryTitle,
Description: req.Description,
PrimaryCta: req.PrimaryCTA,
SecondaryCtaText: req.SecondaryCTAText,
CreatedAt: time.Now(),
}
}
type AboutUsContentUpdateRequest struct {
PrimaryTitle string `json:"primary_title"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
PrimaryCTA string `json:"primary_cta"`
SecondaryCTAText string `json:"secondary_cta_text"`
}
func (req AboutUsContentUpdateRequest) ToEntity() *entity.AboutUsContent {
return &entity.AboutUsContent{
PrimaryTitle: req.PrimaryTitle,
SecondaryTitle: req.SecondaryTitle,
Description: req.Description,
PrimaryCta: req.PrimaryCTA,
SecondaryCtaText: req.SecondaryCTAText,
UpdatedAt: time.Now(),
}
}
type AboutUsContentQueryRequestContext struct {
PrimaryTitle string `json:"primary_title"`
}
func (req AboutUsContentQueryRequestContext) ToParamRequest() AboutUsContentQueryRequest {
var request AboutUsContentQueryRequest
if req.PrimaryTitle != "" {
request.PrimaryTitle = &req.PrimaryTitle
}
return request
}

View File

@ -0,0 +1,15 @@
package response
import "time"
type AboutUsContentResponse struct {
ID uint `json:"id"`
PrimaryTitle string `json:"primary_title"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
PrimaryCTA string `json:"primary_cta"`
SecondaryCTAText string `json:"secondary_cta_text"`
IsActive bool `json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

View File

@ -0,0 +1,124 @@
package service
import (
"github.com/rs/zerolog"
"web-qudo-be/app/database/entity"
"web-qudo-be/app/module/about_us_contents/repository"
)
type aboutUsContentService struct {
Repo repository.AboutUsContentRepository
Log zerolog.Logger
}
type AboutUsContentService interface {
All() ([]*entity.AboutUsContent, error)
Show(id uint) (*entity.AboutUsContent, error)
Save(data map[string]interface{}) (*entity.AboutUsContent, error)
Update(id uint, data map[string]interface{}) error
Delete(id uint) error
}
func NewAboutUsContentService(
repo repository.AboutUsContentRepository,
log zerolog.Logger,
) AboutUsContentService {
return &aboutUsContentService{
Repo: repo,
Log: log,
}
}
// GET ALL
func (s *aboutUsContentService) All() ([]*entity.AboutUsContent, error) {
results, err := s.Repo.GetAll()
if err != nil {
s.Log.Error().Err(err).Msg("failed get about us contents")
return nil, err
}
return results, nil
}
// GET BY ID
func (s *aboutUsContentService) Show(id uint) (*entity.AboutUsContent, error) {
result, err := s.Repo.FindOne(id)
if err != nil {
s.Log.Error().Err(err).Msg("failed get about us content")
return nil, err
}
return result, nil
}
// CREATE
func (s *aboutUsContentService) Save(data map[string]interface{}) (*entity.AboutUsContent, error) {
entityData := &entity.AboutUsContent{}
if v, ok := data["primary_title"].(string); ok {
entityData.PrimaryTitle = v
}
if v, ok := data["secondary_title"].(string); ok {
entityData.SecondaryTitle = v
}
if v, ok := data["description"].(string); ok {
entityData.Description = v
}
if v, ok := data["primary_cta"].(string); ok {
entityData.PrimaryCta = v
}
if v, ok := data["secondary_cta_text"].(string); ok {
entityData.SecondaryCtaText = v
}
result, err := s.Repo.Create(entityData)
if err != nil {
s.Log.Error().Err(err).Msg("failed create about us content")
return nil, err
}
return result, nil
}
// UPDATE
func (s *aboutUsContentService) Update(id uint, data map[string]interface{}) error {
entityData := &entity.AboutUsContent{}
if v, ok := data["primary_title"].(string); ok {
entityData.PrimaryTitle = v
}
if v, ok := data["secondary_title"].(string); ok {
entityData.SecondaryTitle = v
}
if v, ok := data["description"].(string); ok {
entityData.Description = v
}
if v, ok := data["primary_cta"].(string); ok {
entityData.PrimaryCta = v
}
if v, ok := data["secondary_cta_text"].(string); ok {
entityData.SecondaryCtaText = v
}
err := s.Repo.Update(id, entityData)
if err != nil {
s.Log.Error().Err(err).Msg("failed update about us content")
return err
}
return nil
}
// DELETE (soft delete)
func (s *aboutUsContentService) Delete(id uint) error {
result, err := s.Repo.FindOne(id)
if err != nil {
return err
}
isActive := false
result.IsActive = &isActive
return s.Repo.Update(id, result)
}

View File

@ -0,0 +1,17 @@
package controller
import (
"web-qudo-be/app/module/hero_content_images/service"
"github.com/rs/zerolog"
)
type Controller struct {
HeroContentImages HeroContentImagesController
}
func NewController(heroService service.HeroContentImagesService, log zerolog.Logger) *Controller {
return &Controller{
HeroContentImages: NewHeroContentImagesController(heroService, log),
}
}

View File

@ -0,0 +1,120 @@
package controller
import (
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"github.com/rs/zerolog"
"web-qudo-be/app/module/hero_content_images/request"
"web-qudo-be/app/module/hero_content_images/service"
utilRes "web-qudo-be/utils/response"
utilVal "web-qudo-be/utils/validator"
)
type heroContentImagesController struct {
service service.HeroContentImagesService
Log zerolog.Logger
}
type HeroContentImagesController interface {
FindByHeroID(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewHeroContentImagesController(service service.HeroContentImagesService, log zerolog.Logger) HeroContentImagesController {
return &heroContentImagesController{
service: service,
Log: log,
}
}
func (_i *heroContentImagesController) FindByHeroID(c *fiber.Ctx) error {
heroIDStr := c.Params("hero_id")
heroID, err := uuid.Parse(heroIDStr)
if err != nil {
return err
}
data, err := _i.service.FindByHeroID(heroID)
if err != nil {
_i.Log.Error().Err(err).Msg("failed get hero content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Hero content image retrieved"},
Data: data,
})
}
func (_i *heroContentImagesController) Save(c *fiber.Ctx) error {
req := new(request.HeroContentImageCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
data := req.ToEntity()
result, err := _i.service.Save(data)
if err != nil {
_i.Log.Error().Err(err).Msg("failed create hero content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Hero content image created"},
Data: result,
})
}
func (_i *heroContentImagesController) Update(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := uuid.Parse(idStr)
if err != nil {
return err
}
req := new(request.HeroContentImageUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err = _i.service.Update(id, req.ToEntity())
if err != nil {
_i.Log.Error().Err(err).Msg("failed update hero content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Hero content image updated"},
})
}
func (_i *heroContentImagesController) Delete(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := uuid.Parse(idStr)
if err != nil {
return err
}
err = _i.service.Delete(id)
if err != nil {
_i.Log.Error().Err(err).Msg("failed delete hero content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Hero content image deleted"},
})
}

View File

@ -0,0 +1,47 @@
package hero_content_image
import (
"web-qudo-be/app/module/hero_content_images/controller"
"web-qudo-be/app/module/hero_content_images/repository"
"web-qudo-be/app/module/hero_content_images/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
type HeroContentImagesRouter struct {
App fiber.Router
Controller *controller.Controller
}
var NewHeroContentImagesModule = fx.Options(
// repository
fx.Provide(repository.NewHeroContentImagesRepository),
// service
fx.Provide(service.NewHeroContentImagesService),
// controller
fx.Provide(controller.NewController),
// router
fx.Provide(NewHeroContentImagesRouter),
)
func NewHeroContentImagesRouter(fiber *fiber.App, controller *controller.Controller) *HeroContentImagesRouter {
return &HeroContentImagesRouter{
App: fiber,
Controller: controller,
}
}
func (_i *HeroContentImagesRouter) RegisterHeroContentImagesRoutes() {
imageController := _i.Controller.HeroContentImages
_i.App.Route("/hero-content-images", func(router fiber.Router) {
router.Get("/:hero_id", imageController.FindByHeroID)
router.Post("/", imageController.Save)
router.Put("/:id", imageController.Update)
router.Delete("/:id", imageController.Delete)
})
}

View File

@ -0,0 +1,79 @@
package repository
import (
"web-qudo-be/app/database"
"web-qudo-be/app/database/entity"
"github.com/google/uuid"
"github.com/rs/zerolog"
)
type heroContentImagesRepository struct {
DB *database.Database
Log zerolog.Logger
}
type HeroContentImagesRepository interface {
FindByHeroID(heroID uuid.UUID) (*entity.HeroContentImages, error)
Create(data *entity.HeroContentImages) (*entity.HeroContentImages, error)
Update(id uuid.UUID, data *entity.HeroContentImages) error
Delete(id uuid.UUID) error
}
func NewHeroContentImagesRepository(db *database.Database, log zerolog.Logger) HeroContentImagesRepository {
return &heroContentImagesRepository{
DB: db,
Log: log,
}
}
func (r *heroContentImagesRepository) FindByHeroID(heroID uuid.UUID) (*entity.HeroContentImages, error) {
var data entity.HeroContentImages
err := r.DB.DB.
Where("hero_content_id = ?", heroID).
First(&data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed get hero content image")
return nil, err
}
return &data, nil
}
func (r *heroContentImagesRepository) Create(data *entity.HeroContentImages) (*entity.HeroContentImages, error) {
data.ID = uuid.New()
err := r.DB.DB.Create(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed create hero content image")
return nil, err
}
return data, nil
}
func (r *heroContentImagesRepository) Update(id uuid.UUID, data *entity.HeroContentImages) error {
err := r.DB.DB.
Model(&entity.HeroContentImages{}).
Where("id = ?", id).
Updates(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed update hero content image")
return err
}
return nil
}
func (r *heroContentImagesRepository) Delete(id uuid.UUID) error {
err := r.DB.DB.Delete(&entity.HeroContentImages{}, id).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed delete hero content image")
return err
}
return nil
}

View File

@ -0,0 +1,33 @@
package request
import (
"web-qudo-be/app/database/entity"
"github.com/google/uuid"
)
type HeroContentImageCreateRequest struct {
HeroContentID uuid.UUID `json:"hero_content_id" validate:"required"`
ImagePath string `json:"image_path"`
ImageURL string `json:"image_url"`
}
func (r *HeroContentImageCreateRequest) ToEntity() *entity.HeroContentImages {
return &entity.HeroContentImages{
HeroContentID: r.HeroContentID,
ImagePath: r.ImagePath,
ImageURL: r.ImageURL,
}
}
type HeroContentImageUpdateRequest struct {
ImagePath string `json:"image_path"`
ImageURL string `json:"image_url"`
}
func (r *HeroContentImageUpdateRequest) ToEntity() *entity.HeroContentImages {
return &entity.HeroContentImages{
ImagePath: r.ImagePath,
ImageURL: r.ImageURL,
}
}

View File

@ -0,0 +1,73 @@
package service
import (
"github.com/google/uuid"
"github.com/rs/zerolog"
"web-qudo-be/app/database/entity"
"web-qudo-be/app/module/hero_content_images/repository"
)
type heroContentImagesService struct {
Repo repository.HeroContentImagesRepository
Log zerolog.Logger
}
type HeroContentImagesService interface {
FindByHeroID(heroID uuid.UUID) (*entity.HeroContentImages, error)
Save(data *entity.HeroContentImages) (*entity.HeroContentImages, error)
Update(id uuid.UUID, data *entity.HeroContentImages) error
Delete(id uuid.UUID) error
}
func NewHeroContentImagesService(
repo repository.HeroContentImagesRepository,
log zerolog.Logger,
) HeroContentImagesService {
return &heroContentImagesService{
Repo: repo,
Log: log,
}
}
func (s *heroContentImagesService) FindByHeroID(heroID uuid.UUID) (*entity.HeroContentImages, error) {
data, err := s.Repo.FindByHeroID(heroID)
if err != nil {
s.Log.Error().Err(err).Msg("failed get hero content image")
return nil, err
}
return data, nil
}
func (s *heroContentImagesService) Save(data *entity.HeroContentImages) (*entity.HeroContentImages, error) {
data.ID = uuid.New()
result, err := s.Repo.Create(data)
if err != nil {
s.Log.Error().Err(err).Msg("failed create hero content image")
return nil, err
}
return result, nil
}
func (s *heroContentImagesService) Update(id uuid.UUID, data *entity.HeroContentImages) error {
err := s.Repo.Update(id, data)
if err != nil {
s.Log.Error().Err(err).Msg("failed update hero content image")
return err
}
return nil
}
func (s *heroContentImagesService) Delete(id uuid.UUID) error {
err := s.Repo.Delete(id)
if err != nil {
s.Log.Error().Err(err).Msg("failed delete hero content image")
return err
}
return nil
}

View File

@ -0,0 +1,17 @@
package controller
import (
"web-qudo-be/app/module/hero_contents/service"
"github.com/rs/zerolog"
)
type Controller struct {
HeroContent HeroContentsController
}
func NewController(heroService service.HeroContentsService, log zerolog.Logger) *Controller {
return &Controller{
HeroContent: NewHeroContentController(heroService, log),
}
}

View File

@ -0,0 +1,114 @@
package controller
import (
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"github.com/rs/zerolog"
"web-qudo-be/app/module/hero_contents/request"
"web-qudo-be/app/module/hero_contents/service"
utilRes "web-qudo-be/utils/response"
utilVal "web-qudo-be/utils/validator"
)
type heroContentsController struct {
service service.HeroContentsService
Log zerolog.Logger
}
type HeroContentsController interface {
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewHeroContentController(service service.HeroContentsService, log zerolog.Logger) HeroContentsController {
return &heroContentsController{
service: service,
Log: log,
}
}
func (_i *heroContentsController) Show(c *fiber.Ctx) error {
_i.Log.Info().Msg("GET /hero-content")
data, err := _i.service.Show()
if err != nil {
_i.Log.Error().Err(err).Msg("failed get hero content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Hero content retrieved"},
Data: data,
})
}
func (_i *heroContentsController) Save(c *fiber.Ctx) error {
req := new(request.HeroContentsCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
data := req.ToEntity()
result, err := _i.service.Save(data)
if err != nil {
_i.Log.Error().Err(err).Msg("failed create hero content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Hero content created"},
Data: result,
})
}
func (_i *heroContentsController) Update(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := uuid.Parse(idStr)
if err != nil {
return err
}
req := new(request.HeroContentsUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err = _i.service.Update(id, req.ToEntity())
if err != nil {
_i.Log.Error().Err(err).Msg("failed update hero content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Hero content updated"},
})
}
func (_i *heroContentsController) Delete(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := uuid.Parse(idStr)
if err != nil {
return err
}
err = _i.service.Delete(id)
if err != nil {
_i.Log.Error().Err(err).Msg("failed delete hero content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Hero content deleted"},
})
}

View File

@ -0,0 +1,48 @@
package hero_content
import (
"web-qudo-be/app/module/hero_contents/controller"
"web-qudo-be/app/module/hero_contents/repository"
"web-qudo-be/app/module/hero_contents/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
type HeroContentsRouter struct {
App fiber.Router
Controller *controller.Controller
}
var NewHeroContentsModule = fx.Options(
// repository
fx.Provide(repository.NewHeroContentsRepository),
// service
fx.Provide(service.NewHeroContentsService),
// controller
fx.Provide(controller.NewController),
// router
fx.Provide(NewHeroContentsRouter),
)
// init router
func NewHeroContentsRouter(fiber *fiber.App, controller *controller.Controller) *HeroContentsRouter {
return &HeroContentsRouter{
App: fiber,
Controller: controller,
}
}
func (_i *HeroContentsRouter) RegisterHeroContentsRoutes() {
heroController := _i.Controller.HeroContent
_i.App.Route("/hero-contents", func(router fiber.Router) {
router.Get("/", heroController.Show)
router.Post("/", heroController.Save)
router.Put("/:id", heroController.Update)
router.Delete("/:id", heroController.Delete)
})
}

View File

@ -1,9 +1,9 @@
package mapper
import "web-qudo-be/app/module/hero_section/response"
import "web-qudo-be/app/module/hero_contents/response"
func ToHeroSectionResponse(data map[string]interface{}) response.HeroSectionResponse {
return response.HeroSectionResponse{
func ToHeroContentResponse(data map[string]interface{}) response.HeroContentsResponse {
return response.HeroContentsResponse{
ID: data["id"].(int),
PrimaryTitle: data["primary_title"].(string),
SecondaryTitle: data["secondary_title"].(string),

View File

@ -0,0 +1,79 @@
package repository
import (
"web-qudo-be/app/database"
"web-qudo-be/app/database/entity"
"github.com/google/uuid"
"github.com/rs/zerolog"
)
type heroContentsRepository struct {
DB *database.Database
Log zerolog.Logger
}
type HeroContentsRepository interface {
Get() (*entity.HeroContents, error)
Create(data *entity.HeroContents) (*entity.HeroContents, error)
Update(id uuid.UUID, data *entity.HeroContents) error
Delete(id uuid.UUID) error
}
func NewHeroContentsRepository(db *database.Database, logger zerolog.Logger) HeroContentsRepository {
return &heroContentsRepository{
DB: db,
Log: logger,
}
}
func (r *heroContentsRepository) Get() (*entity.HeroContents, error) {
var data entity.HeroContents
err := r.DB.DB.
Preload("HeroContentImage").
First(&data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed get hero content")
return nil, err
}
return &data, nil
}
func (r *heroContentsRepository) Create(data *entity.HeroContents) (*entity.HeroContents, error) {
data.ID = uuid.New()
err := r.DB.DB.Create(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed create hero contents")
return nil, err
}
return data, nil
}
func (r *heroContentsRepository) Update(id uuid.UUID, data *entity.HeroContents) error {
err := r.DB.DB.
Model(&entity.HeroContents{}).
Where("id = ?", id).
Updates(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed update hero content")
return err
}
return nil
}
func (r *heroContentsRepository) Delete(id uuid.UUID) error {
err := r.DB.DB.Delete(&entity.HeroContents{}, id).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed delete hero content")
return err
}
return nil
}

View File

@ -0,0 +1,39 @@
package request
import "web-qudo-be/app/database/entity"
type HeroContentsCreateRequest struct {
PrimaryTitle string `json:"primary_title" form:"primary_title" validate:"required"`
SecondaryTitle string `json:"secondary_title" form:"secondary_title"`
Description string `json:"description" form:"description"`
PrimaryCTA string `json:"primary_cta" form:"primary_cta"`
SecondaryCTAText string `json:"secondary_cta_text" form:"secondary_cta_text"`
}
func (r *HeroContentsCreateRequest) ToEntity() *entity.HeroContents {
return &entity.HeroContents{
PrimaryTitle: r.PrimaryTitle,
SecondaryTitle: r.SecondaryTitle,
Description: r.Description,
PrimaryCta: r.PrimaryCTA,
SecondaryCtaText: r.SecondaryCTAText,
}
}
type HeroContentsUpdateRequest struct {
PrimaryTitle string `json:"primary_title"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
PrimaryCTA string `json:"primary_cta"`
SecondaryCTAText string `json:"secondary_cta_text"`
}
func (r *HeroContentsUpdateRequest) ToEntity() *entity.HeroContents {
return &entity.HeroContents{
PrimaryTitle: r.PrimaryTitle,
SecondaryTitle: r.SecondaryTitle,
Description: r.Description,
PrimaryCta: r.PrimaryCTA,
SecondaryCtaText: r.SecondaryCTAText,
}
}

View File

@ -1,6 +1,6 @@
package response
type HeroSectionResponse struct {
type HeroContentsResponse struct {
ID int `json:"id"`
PrimaryTitle string `json:"primary_title"`
SecondaryTitle string `json:"secondary_title"`

View File

@ -0,0 +1,79 @@
package service
import (
"github.com/google/uuid"
"github.com/rs/zerolog"
"web-qudo-be/app/database/entity"
heroContentImagesService "web-qudo-be/app/module/hero_content_images/service"
"web-qudo-be/app/module/hero_contents/repository"
)
type heroContentsService struct {
Repo repository.HeroContentsRepository
ImageService heroContentImagesService.HeroContentImagesService
Log zerolog.Logger
}
type HeroContentsService interface {
Show() (*entity.HeroContents, error)
Save(data *entity.HeroContents) (*entity.HeroContents, error)
Update(id uuid.UUID, data *entity.HeroContents) error
Delete(id uuid.UUID) error
}
func NewHeroContentsService(
repo repository.HeroContentsRepository,
imageService heroContentImagesService.HeroContentImagesService,
log zerolog.Logger,
) HeroContentsService {
return &heroContentsService{
Repo: repo,
ImageService: imageService,
Log: log,
}
}
func (s *heroContentsService) Show() (*entity.HeroContents, error) {
data, err := s.Repo.Get()
if err != nil {
s.Log.Error().Err(err).Msg("failed get hero content")
return nil, err
}
return data, nil
}
func (s *heroContentsService) Save(data *entity.HeroContents) (*entity.HeroContents, error) {
data.ID = uuid.New()
result, err := s.Repo.Create(data)
if err != nil {
s.Log.Error().Err(err).Msg("failed create hero content")
return nil, err
}
return result, nil
}
func (s *heroContentsService) Update(id uuid.UUID, data *entity.HeroContents) error {
err := s.Repo.Update(id, data)
if err != nil {
s.Log.Error().Err(err).Msg("failed update hero content")
return err
}
return nil
}
func (s *heroContentsService) Delete(id uuid.UUID) error {
result, err := s.Repo.Get()
if err != nil {
return err
}
isActive := false
result.IsActive = &isActive
return s.Repo.Update(id, result)
}

View File

@ -1,94 +0,0 @@
package controller
import (
"strconv"
"web-qudo-be/app/module/hero_section/service"
"github.com/gofiber/fiber/v2"
)
type HeroSectionController struct {
Service *service.HeroSectionService
}
type Controller struct {
HeroSection *HeroSectionController
}
func NewController(service *service.HeroSectionService) *Controller {
return &Controller{
HeroSection: &HeroSectionController{
Service: service,
},
}
}
// GET
func (c *HeroSectionController) Get(ctx *fiber.Ctx) error {
data, err := c.Service.Get(ctx.Context())
if err != nil {
return ctx.Status(500).JSON(fiber.Map{
"message": err.Error(),
})
}
return ctx.JSON(fiber.Map{
"data": data,
})
}
// CREATE
func (c *HeroSectionController) Create(ctx *fiber.Ctx) error {
err := c.Service.Create(ctx.Context(), ctx)
if err != nil {
return ctx.Status(500).JSON(fiber.Map{
"message": err.Error(),
})
}
return ctx.JSON(fiber.Map{
"message": "Hero section created successfully",
})
}
// UPDATE
func (c *HeroSectionController) Update(ctx *fiber.Ctx) error {
id, err := strconv.Atoi(ctx.Params("id"))
if err != nil {
return ctx.Status(400).JSON(fiber.Map{
"message": "Invalid ID",
})
}
err = c.Service.Update(ctx.Context(), id, ctx)
if err != nil {
return ctx.Status(500).JSON(fiber.Map{
"message": err.Error(),
})
}
return ctx.JSON(fiber.Map{
"message": "Hero section updated successfully",
})
}
// DELETE
func (c *HeroSectionController) Delete(ctx *fiber.Ctx) error {
id, err := strconv.Atoi(ctx.Params("id"))
if err != nil {
return ctx.Status(400).JSON(fiber.Map{
"message": "Invalid ID",
})
}
err = c.Service.Delete(ctx.Context(), id)
if err != nil {
return ctx.Status(500).JSON(fiber.Map{
"message": err.Error(),
})
}
return ctx.JSON(fiber.Map{
"message": "Hero section deleted successfully",
})
}

View File

@ -1,43 +0,0 @@
package hero_section
import (
"web-qudo-be/app/module/hero_section/controller"
"web-qudo-be/app/module/hero_section/repository"
"web-qudo-be/app/module/hero_section/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
type HeroSectionRouter struct {
App fiber.Router
Controller *controller.Controller
}
var NewHeroSectionModule = fx.Options(
fx.Provide(repository.NewHeroSectionRepository),
fx.Provide(service.NewHeroSectionService),
fx.Provide(controller.NewController),
fx.Provide(NewHeroSectionRouter),
)
func NewHeroSectionRouter(fiber *fiber.App, controller *controller.Controller) *HeroSectionRouter {
return &HeroSectionRouter{
App: fiber,
Controller: controller,
}
}
func (_i *HeroSectionRouter) RegisterHeroSectionRoutes() {
heroController := _i.Controller.HeroSection
_i.App.Route("/hero-section", func(router fiber.Router) {
router.Get("/", heroController.Get)
router.Post("/", heroController.Create)
router.Put("/:id", heroController.Update)
router.Delete("/:id", heroController.Delete)
})
}

View File

@ -1,110 +0,0 @@
package repository
import (
"context"
"database/sql"
)
type HeroSectionRepository struct {
DB *sql.DB
}
func NewHeroSectionRepository(db *sql.DB) *HeroSectionRepository {
return &HeroSectionRepository{DB: db}
}
func (r *HeroSectionRepository) Get(ctx context.Context) (map[string]interface{}, error) {
query := `
SELECT hc.id, hc.primary_title, hc.secondary_title, hc.description,
hc.primary_cta, hc.secondary_cta_text,
hci.image_path, hci.image_url
FROM hero_content hc
LEFT JOIN hero_content_image hci ON hc.id = hci.hero_content_id
LIMIT 1
`
row := r.DB.QueryRowContext(ctx, query)
var result map[string]interface{} = make(map[string]interface{})
var id int
var primaryTitle, secondaryTitle, description, primaryCTA, secondaryCTA string
var imagePath, imageUrl sql.NullString
err := row.Scan(&id, &primaryTitle, &secondaryTitle, &description,
&primaryCTA, &secondaryCTA, &imagePath, &imageUrl)
if err != nil {
return nil, err
}
result["id"] = id
result["primary_title"] = primaryTitle
result["secondary_title"] = secondaryTitle
result["description"] = description
result["primary_cta"] = primaryCTA
result["secondary_cta_text"] = secondaryCTA
result["image_path"] = imagePath.String
result["image_url"] = imageUrl.String
return result, nil
}
func (r *HeroSectionRepository) Create(ctx context.Context, data map[string]interface{}) (int, error) {
query := `
INSERT INTO hero_content
(primary_title, secondary_title, description, primary_cta, secondary_cta_text)
VALUES (?, ?, ?, ?, ?)
`
result, err := r.DB.ExecContext(
ctx,
query,
data["primary_title"],
data["secondary_title"],
data["description"],
data["primary_cta"],
data["secondary_cta_text"],
)
if err != nil {
return 0, err
}
id, err := result.LastInsertId()
if err != nil {
return 0, err
}
return int(id), nil
}
func (r *HeroSectionRepository) Update(ctx context.Context, id int, data map[string]interface{}) error {
query := `
UPDATE hero_content SET
primary_title = ?,
secondary_title = ?,
description = ?,
primary_cta = ?,
secondary_cta_text = ?
WHERE id = ?
`
_, err := r.DB.ExecContext(
ctx,
query,
data["primary_title"],
data["secondary_title"],
data["description"],
data["primary_cta"],
data["secondary_cta_text"],
id,
)
return err
}
func (r *HeroSectionRepository) Delete(ctx context.Context, id int) error {
query := `DELETE FROM hero_content WHERE id = ?`
_, err := r.DB.ExecContext(ctx, query, id)
return err
}

View File

@ -1,11 +0,0 @@
package request
type HeroSectionRequest struct {
PrimaryTitle string `json:"primary_title"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
PrimaryCTA string `json:"primary_cta"`
SecondaryCTA string `json:"secondary_cta_text"`
ImagePath string `json:"image_path"`
ImageURL string `json:"image_url"`
}

View File

@ -1,129 +0,0 @@
package service
import (
"context"
"github.com/gofiber/fiber/v2"
"web-qudo-be/app/module/hero_section/repository"
hero_section_image_service "web-qudo-be/app/module/hero_section_image/service"
)
type HeroSectionService struct {
Repo *repository.HeroSectionRepository
ImageService *hero_section_image_service.HeroSectionImageService
}
func NewHeroSectionService(
repo *repository.HeroSectionRepository,
imageService *hero_section_image_service.HeroSectionImageService,
) *HeroSectionService {
return &HeroSectionService{
Repo: repo,
ImageService: imageService,
}
}
// GET
func (s *HeroSectionService) Get(ctx context.Context) (interface{}, error) {
data, err := s.Repo.Get(ctx)
if err != nil {
return nil, err
}
// ambil image (optional)
if id, ok := data["id"].(int); ok {
image, _ := s.ImageService.GetByHeroID(ctx, id)
data["image"] = image
}
return data, nil
}
// CREATE
func (s *HeroSectionService) Create(ctx context.Context, c *fiber.Ctx) error {
type request struct {
PrimaryTitle string `json:"primary_title"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
PrimaryCTA string `json:"primary_cta"`
SecondaryCTAText string `json:"secondary_cta_text"`
}
req := new(request)
if err := c.BodyParser(req); err != nil {
return err
}
// insert hero_content
heroID, err := s.Repo.Create(ctx, map[string]interface{}{
"primary_title": req.PrimaryTitle,
"secondary_title": req.SecondaryTitle,
"description": req.Description,
"primary_cta": req.PrimaryCTA,
"secondary_cta_text": req.SecondaryCTAText,
})
if err != nil {
return err
}
// OPTIONAL: upload image kalau ada
file, err := c.FormFile("image")
if err == nil {
path := "./uploads/" + file.Filename
c.SaveFile(file, path)
url := "/uploads/" + file.Filename
_ = s.ImageService.Upload(ctx, heroID, path, url)
}
return nil
}
// UPDATE
func (s *HeroSectionService) Update(ctx context.Context, id int, c *fiber.Ctx) error {
type request struct {
PrimaryTitle string `json:"primary_title"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
PrimaryCTA string `json:"primary_cta"`
SecondaryCTAText string `json:"secondary_cta_text"`
}
req := new(request)
if err := c.BodyParser(req); err != nil {
return err
}
err := s.Repo.Update(ctx, id, map[string]interface{}{
"primary_title": req.PrimaryTitle,
"secondary_title": req.SecondaryTitle,
"description": req.Description,
"primary_cta": req.PrimaryCTA,
"secondary_cta_text": req.SecondaryCTAText,
})
if err != nil {
return err
}
// update image kalau ada upload baru
file, err := c.FormFile("image")
if err == nil {
path := "./uploads/" + file.Filename
c.SaveFile(file, path)
url := "/uploads/" + file.Filename
_ = s.ImageService.Upload(ctx, id, path, url)
}
return nil
}
// DELETE
func (s *HeroSectionService) Delete(ctx context.Context, id int) error {
return s.Repo.Delete(ctx, id)
}

View File

@ -1,113 +0,0 @@
package controller
import (
"strconv"
"web-qudo-be/app/module/hero_section_image/service"
"github.com/gofiber/fiber/v2"
)
type HeroSectionImageController struct {
Service *service.HeroSectionImageService
}
type Controller struct {
HeroSectionImage *HeroSectionImageController
}
func NewController(service *service.HeroSectionImageService) *Controller {
return &Controller{
HeroSectionImage: &HeroSectionImageController{
Service: service,
},
}
}
// GET by hero_id
func (c *HeroSectionImageController) GetByHeroID(ctx *fiber.Ctx) error {
heroId, err := strconv.Atoi(ctx.Params("heroId"))
if err != nil {
return err
}
data, err := c.Service.GetByHeroID(ctx.Context(), heroId)
if err != nil {
return err
}
return ctx.JSON(fiber.Map{
"data": data,
})
}
// CREATE (UPLOAD)
func (c *HeroSectionImageController) Upload(ctx *fiber.Ctx) error {
heroId, err := strconv.Atoi(ctx.Params("heroId"))
if err != nil {
return err
}
file, err := ctx.FormFile("image")
if err != nil {
return err
}
path := "./uploads/" + file.Filename
ctx.SaveFile(file, path)
url := "/uploads/" + file.Filename
err = c.Service.Upload(ctx.Context(), heroId, path, url)
if err != nil {
return err
}
return ctx.JSON(fiber.Map{
"message": "uploaded",
})
}
// UPDATE
func (c *HeroSectionImageController) Update(ctx *fiber.Ctx) error {
id, err := strconv.Atoi(ctx.Params("id"))
if err != nil {
return err
}
file, err := ctx.FormFile("image")
if err != nil {
return err
}
path := "./uploads/" + file.Filename
ctx.SaveFile(file, path)
url := "/uploads/" + file.Filename
err = c.Service.Update(ctx.Context(), id, path, url)
if err != nil {
return err
}
return ctx.JSON(fiber.Map{
"message": "updated",
})
}
// DELETE
func (c *HeroSectionImageController) Delete(ctx *fiber.Ctx) error {
id, err := strconv.Atoi(ctx.Params("id"))
if err != nil {
return err
}
err = c.Service.Delete(ctx.Context(), id)
if err != nil {
return err
}
return ctx.JSON(fiber.Map{
"message": "deleted",
})
}

View File

@ -1,39 +0,0 @@
package hero_section_image
import (
"web-qudo-be/app/module/hero_section_image/controller"
"web-qudo-be/app/module/hero_section_image/repository"
"web-qudo-be/app/module/hero_section_image/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
type HeroSectionImageRouter struct {
App fiber.Router
Controller *controller.Controller
}
var NewHeroSectionImageModule = fx.Options(
fx.Provide(repository.NewHeroSectionImageRepository),
fx.Provide(service.NewHeroSectionImageService),
fx.Provide(controller.NewController),
fx.Provide(NewHeroSectionImageRouter),
)
func NewHeroSectionImageRouter(fiber *fiber.App, controller *controller.Controller) *HeroSectionImageRouter {
return &HeroSectionImageRouter{
App: fiber,
Controller: controller,
}
}
func (_i *HeroSectionImageRouter) RegisterHeroSectionImageRoutes() {
ctrl := _i.Controller.HeroSectionImage
_i.App.Route("/hero-section-image", func(r fiber.Router) {
r.Post("/:heroId", ctrl.Upload)
r.Put("/:id", ctrl.Update)
r.Delete("/:id", ctrl.Delete)
})
}

View File

@ -1,59 +0,0 @@
package repository
import (
"context"
"database/sql"
)
type HeroSectionImageRepository struct {
DB *sql.DB
}
func NewHeroSectionImageRepository(db *sql.DB) *HeroSectionImageRepository {
return &HeroSectionImageRepository{DB: db}
}
func (r *HeroSectionImageRepository) Create(ctx context.Context, heroId int, path, url string) error {
query := `
INSERT INTO hero_content_image (hero_content_id, image_path, image_url)
VALUES (?, ?, ?)
`
_, err := r.DB.ExecContext(ctx, query, heroId, path, url)
return err
}
func (r *HeroSectionImageRepository) FindByHeroID(ctx context.Context, heroId int) (map[string]string, error) {
query := `
SELECT image_path, image_url
FROM hero_content_image
WHERE hero_content_id = ?
LIMIT 1
`
row := r.DB.QueryRowContext(ctx, query, heroId)
var path, url string
err := row.Scan(&path, &url)
if err != nil {
return nil, err
}
return map[string]string{
"image_path": path,
"image_url": url,
}, nil
}
// UPDATE
func (r *HeroSectionImageRepository) Update(ctx context.Context, id int, path, url string) error {
query := `UPDATE hero_content_image SET image_path = ?, image_url = ? WHERE id = ?`
_, err := r.DB.ExecContext(ctx, query, path, url, id)
return err
}
// DELETE
func (r *HeroSectionImageRepository) Delete(ctx context.Context, id int) error {
query := `DELETE FROM hero_content_image WHERE id = ?`
_, err := r.DB.ExecContext(ctx, query, id)
return err
}

View File

@ -1,35 +0,0 @@
package service
import (
"context"
"web-qudo-be/app/module/hero_section_image/repository"
)
type HeroSectionImageService struct {
Repo *repository.HeroSectionImageRepository
}
func NewHeroSectionImageService(repo *repository.HeroSectionImageRepository) *HeroSectionImageService {
return &HeroSectionImageService{Repo: repo}
}
// GET by hero_id
func (s *HeroSectionImageService) GetByHeroID(ctx context.Context, heroId int) (interface{}, error) {
return s.Repo.FindByHeroID(ctx, heroId)
}
// CREATE (UPLOAD)
func (s *HeroSectionImageService) Upload(ctx context.Context, heroId int, path, url string) error {
return s.Repo.Create(ctx, heroId, path, url)
}
// UPDATE
func (s *HeroSectionImageService) Update(ctx context.Context, id int, path, url string) error {
return s.Repo.Update(ctx, id, path, url)
}
// DELETE
func (s *HeroSectionImageService) Delete(ctx context.Context, id int) error {
return s.Repo.Delete(ctx, id)
}

View File

@ -0,0 +1,17 @@
package controller
import (
"web-qudo-be/app/module/our_product_content_images/service"
"github.com/rs/zerolog"
)
type Controller struct {
OurProductContentImages OurProductContentImagesController
}
func NewController(ourProductService service.OurProductContentImagesService, log zerolog.Logger) *Controller {
return &Controller{
OurProductContentImages: NewOurProductContentImagesController(ourProductService, log),
}
}

View File

@ -0,0 +1,120 @@
package controller
import (
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"github.com/rs/zerolog"
"web-qudo-be/app/module/our_product_content_images/request"
"web-qudo-be/app/module/our_product_content_images/service"
utilRes "web-qudo-be/utils/response"
utilVal "web-qudo-be/utils/validator"
)
type ourProductContentImagesController struct {
service service.OurProductContentImagesService
Log zerolog.Logger
}
type OurProductContentImagesController interface {
FindByOurProductContentID(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewOurProductContentImagesController(service service.OurProductContentImagesService, log zerolog.Logger) OurProductContentImagesController {
return &ourProductContentImagesController{
service: service,
Log: log,
}
}
func (_i *ourProductContentImagesController) FindByOurProductContentID(c *fiber.Ctx) error {
contentIDStr := c.Params("our_product_content_id")
contentID, err := uuid.Parse(contentIDStr)
if err != nil {
return err
}
data, err := _i.service.FindByContentID(contentID)
if err != nil {
_i.Log.Error().Err(err).Msg("failed get our product content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our product content image retrieved"},
Data: data,
})
}
func (_i *ourProductContentImagesController) Save(c *fiber.Ctx) error {
req := new(request.OurProductContentImageCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
data := req.ToEntity()
result, err := _i.service.Save(data)
if err != nil {
_i.Log.Error().Err(err).Msg("failed create our product content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our product content image created"},
Data: result,
})
}
func (_i *ourProductContentImagesController) Update(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := uuid.Parse(idStr)
if err != nil {
return err
}
req := new(request.OurProductContentImageUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err = _i.service.Update(id, req.ToEntity())
if err != nil {
_i.Log.Error().Err(err).Msg("failed update our product content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our product content image updated"},
})
}
func (_i *ourProductContentImagesController) Delete(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := uuid.Parse(idStr)
if err != nil {
return err
}
err = _i.service.Delete(id)
if err != nil {
_i.Log.Error().Err(err).Msg("failed delete our product content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our product content image deleted"},
})
}

View File

@ -0,0 +1,47 @@
package our_product_content_images
import (
"web-qudo-be/app/module/our_product_content_images/controller"
"web-qudo-be/app/module/our_product_content_images/repository"
"web-qudo-be/app/module/our_product_content_images/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
type OurProductContentImagesRouter struct {
App fiber.Router
Controller *controller.Controller
}
var NewOurProductContentImagesModule = fx.Options(
// repository
fx.Provide(repository.NewOurProductContentImagesRepository),
// service
fx.Provide(service.NewOurProductContentImagesService),
// controller
fx.Provide(controller.NewController),
// router
fx.Provide(NewOurProductContentImagesRouter),
)
func NewOurProductContentImagesRouter(fiber *fiber.App, controller *controller.Controller) *OurProductContentImagesRouter {
return &OurProductContentImagesRouter{
App: fiber,
Controller: controller,
}
}
func (_i *OurProductContentImagesRouter) RegisterOurProductContentImagesRoutes() {
imageController := _i.Controller.OurProductContentImages
_i.App.Route("/our-product-content-images", func(router fiber.Router) {
router.Get("/:content_id", imageController.FindByOurProductContentID)
router.Post("/", imageController.Save)
router.Put("/:id", imageController.Update)
router.Delete("/:id", imageController.Delete)
})
}

View File

@ -0,0 +1,79 @@
package repository
import (
"web-qudo-be/app/database"
"web-qudo-be/app/database/entity"
"github.com/google/uuid"
"github.com/rs/zerolog"
)
type ourProductContentImagesRepository struct {
DB *database.Database
Log zerolog.Logger
}
type OurProductContentImagesRepository interface {
FindByContentID(contentID uuid.UUID) ([]entity.OurProductContentImage, error)
Create(data *entity.OurProductContentImage) (*entity.OurProductContentImage, error)
Update(id uuid.UUID, data *entity.OurProductContentImage) error
Delete(id uuid.UUID) error
}
func NewOurProductContentImagesRepository(db *database.Database, log zerolog.Logger) OurProductContentImagesRepository {
return &ourProductContentImagesRepository{
DB: db,
Log: log,
}
}
func (r *ourProductContentImagesRepository) FindByContentID(contentID uuid.UUID) ([]entity.OurProductContentImage, error) {
var data []entity.OurProductContentImage
err := r.DB.DB.
Where("our_product_content_id = ?", contentID).
Find(&data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed get our product content images")
return nil, err
}
return data, nil
}
func (r *ourProductContentImagesRepository) Create(data *entity.OurProductContentImage) (*entity.OurProductContentImage, error) {
data.ID = uuid.New()
err := r.DB.DB.Create(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed create our product content image")
return nil, err
}
return data, nil
}
func (r *ourProductContentImagesRepository) Update(id uuid.UUID, data *entity.OurProductContentImage) error {
err := r.DB.DB.
Model(&entity.OurProductContentImage{}).
Where("id = ?", id).
Updates(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed update our product content image")
return err
}
return nil
}
func (r *ourProductContentImagesRepository) Delete(id uuid.UUID) error {
err := r.DB.DB.Delete(&entity.OurProductContentImage{}, id).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed delete our product content image")
return err
}
return nil
}

View File

@ -0,0 +1,37 @@
package request
import (
"web-qudo-be/app/database/entity"
"github.com/google/uuid"
)
type OurProductContentImageCreateRequest struct {
OurProductContentID uuid.UUID `json:"our_product_content_id" validate:"required"`
ImagePath string `json:"image_path"`
ImageURL string `json:"image_url"`
IsThumbnail *bool `json:"is_thumbnail"`
}
func (r *OurProductContentImageCreateRequest) ToEntity() *entity.OurProductContentImage {
return &entity.OurProductContentImage{
OurProductContentID: r.OurProductContentID,
ImagePath: r.ImagePath,
ImageURL: r.ImageURL,
IsThumbnail: r.IsThumbnail,
}
}
type OurProductContentImageUpdateRequest struct {
ImagePath string `json:"image_path"`
ImageURL string `json:"image_url"`
IsThumbnail *bool `json:"is_thumbnail"`
}
func (r *OurProductContentImageUpdateRequest) ToEntity() *entity.OurProductContentImage {
return &entity.OurProductContentImage{
ImagePath: r.ImagePath,
ImageURL: r.ImageURL,
IsThumbnail: r.IsThumbnail,
}
}

View File

@ -0,0 +1,73 @@
package service
import (
"github.com/google/uuid"
"github.com/rs/zerolog"
"web-qudo-be/app/database/entity"
"web-qudo-be/app/module/our_product_content_images/repository"
)
type ourProductContentImagesService struct {
Repo repository.OurProductContentImagesRepository
Log zerolog.Logger
}
type OurProductContentImagesService interface {
FindByContentID(contentID uuid.UUID) ([]entity.OurProductContentImage, error)
Save(data *entity.OurProductContentImage) (*entity.OurProductContentImage, error)
Update(id uuid.UUID, data *entity.OurProductContentImage) error
Delete(id uuid.UUID) error
}
func NewOurProductContentImagesService(
repo repository.OurProductContentImagesRepository,
log zerolog.Logger,
) OurProductContentImagesService {
return &ourProductContentImagesService{
Repo: repo,
Log: log,
}
}
func (s *ourProductContentImagesService) FindByContentID(contentID uuid.UUID) ([]entity.OurProductContentImage, error) {
data, err := s.Repo.FindByContentID(contentID)
if err != nil {
s.Log.Error().Err(err).Msg("failed get our product content images")
return nil, err
}
return data, nil
}
func (s *ourProductContentImagesService) Save(data *entity.OurProductContentImage) (*entity.OurProductContentImage, error) {
data.ID = uuid.New()
result, err := s.Repo.Create(data)
if err != nil {
s.Log.Error().Err(err).Msg("failed create our product content image")
return nil, err
}
return result, nil
}
func (s *ourProductContentImagesService) Update(id uuid.UUID, data *entity.OurProductContentImage) error {
err := s.Repo.Update(id, data)
if err != nil {
s.Log.Error().Err(err).Msg("failed update our product content image")
return err
}
return nil
}
func (s *ourProductContentImagesService) Delete(id uuid.UUID) error {
err := s.Repo.Delete(id)
if err != nil {
s.Log.Error().Err(err).Msg("failed delete our product content image")
return err
}
return nil
}

View File

@ -0,0 +1,17 @@
package controller
import (
"web-qudo-be/app/module/our_product_contents/service"
"github.com/rs/zerolog"
)
type Controller struct {
OurProductContent OurProductContentController
}
func NewController(ourProductService service.OurProductContentService, log zerolog.Logger) *Controller {
return &Controller{
OurProductContent: NewOurProductContentController(ourProductService, log),
}
}

View File

@ -0,0 +1,115 @@
package controller
import (
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"github.com/rs/zerolog"
"web-qudo-be/app/module/our_product_contents/request"
"web-qudo-be/app/module/our_product_contents/service"
utilRes "web-qudo-be/utils/response"
utilVal "web-qudo-be/utils/validator"
)
type ourProductContentController struct {
service service.OurProductContentService
Log zerolog.Logger
}
type OurProductContentController interface {
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewOurProductContentController(service service.OurProductContentService, log zerolog.Logger) OurProductContentController {
return &ourProductContentController{
service: service,
Log: log,
}
}
func (_i *ourProductContentController) Show(c *fiber.Ctx) error {
_i.Log.Info().Msg("GET /our-product-content")
data, err := _i.service.Show()
if err != nil {
_i.Log.Error().Err(err).Msg("failed get our product content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our product content retrieved"},
Data: data,
})
}
func (_i *ourProductContentController) Save(c *fiber.Ctx) error {
req := new(request.OurProductContentCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
data := req.ToEntity()
result, err := _i.service.Save(data)
if err != nil {
_i.Log.Error().Err(err).Msg("failed create our product content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our product content created"},
Data: result,
})
}
func (_i *ourProductContentController) Update(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := uuid.Parse(idStr)
if err != nil {
return err
}
req := new(request.OurProductContentUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err = _i.service.Update(id, req.ToEntity())
if err != nil {
_i.Log.Error().Err(err).Msg("failed update our product content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our product content updated"},
})
}
func (_i *ourProductContentController) Delete(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := uuid.Parse(idStr)
if err != nil {
return err
}
err = _i.service.Delete(id)
if err != nil {
_i.Log.Error().Err(err).Msg("failed delete our product content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our product content deleted"},
})
}

View File

@ -0,0 +1,48 @@
package our_product_contents
import (
"web-qudo-be/app/module/our_product_contents/controller"
"web-qudo-be/app/module/our_product_contents/repository"
"web-qudo-be/app/module/our_product_contents/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
type OurProductContentsRouter struct {
App fiber.Router
Controller *controller.Controller
}
var NewOurProductContentsModule = fx.Options(
// repository
fx.Provide(repository.NewOurProductContentRepository),
// service
fx.Provide(service.NewOurProductContentService),
// controller
fx.Provide(controller.NewController),
// router
fx.Provide(NewOurProductContentsRouter),
)
// init router
func NewOurProductContentsRouter(fiber *fiber.App, controller *controller.Controller) *OurProductContentsRouter {
return &OurProductContentsRouter{
App: fiber,
Controller: controller,
}
}
func (_i *OurProductContentsRouter) RegisterOurProductContentsRoutes() {
contentController := _i.Controller.OurProductContent
_i.App.Route("/our-product-contents", func(router fiber.Router) {
router.Get("/", contentController.Show)
router.Post("/", contentController.Save)
router.Put("/:id", contentController.Update)
router.Delete("/:id", contentController.Delete)
})
}

View File

@ -0,0 +1,79 @@
package repository
import (
"web-qudo-be/app/database"
"web-qudo-be/app/database/entity"
"github.com/google/uuid"
"github.com/rs/zerolog"
)
type ourProductContentRepository struct {
DB *database.Database
Log zerolog.Logger
}
type OurProductContentRepository interface {
Get() (*entity.OurProductContent, error)
Create(data *entity.OurProductContent) (*entity.OurProductContent, error)
Update(id uuid.UUID, data *entity.OurProductContent) error
Delete(id uuid.UUID) error
}
func NewOurProductContentRepository(db *database.Database, logger zerolog.Logger) OurProductContentRepository {
return &ourProductContentRepository{
DB: db,
Log: logger,
}
}
func (r *ourProductContentRepository) Get() (*entity.OurProductContent, error) {
var data entity.OurProductContent
err := r.DB.DB.
Preload("Images").
First(&data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed get our product content")
return nil, err
}
return &data, nil
}
func (r *ourProductContentRepository) Create(data *entity.OurProductContent) (*entity.OurProductContent, error) {
data.ID = uuid.New()
err := r.DB.DB.Create(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed create our product content")
return nil, err
}
return data, nil
}
func (r *ourProductContentRepository) Update(id uuid.UUID, data *entity.OurProductContent) error {
err := r.DB.DB.
Model(&entity.OurProductContent{}).
Where("id = ?", id).
Updates(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed update our product content")
return err
}
return nil
}
func (r *ourProductContentRepository) Delete(id uuid.UUID) error {
err := r.DB.DB.Delete(&entity.OurProductContent{}, id).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed delete our product content")
return err
}
return nil
}

View File

@ -0,0 +1,31 @@
package request
import "web-qudo-be/app/database/entity"
type OurProductContentCreateRequest struct {
PrimaryTitle string `json:"primary_title" form:"primary_title" validate:"required"`
SecondaryTitle string `json:"secondary_title" form:"secondary_title"`
Description string `json:"description" form:"description"`
}
func (r *OurProductContentCreateRequest) ToEntity() *entity.OurProductContent {
return &entity.OurProductContent{
PrimaryTitle: r.PrimaryTitle,
SecondaryTitle: r.SecondaryTitle,
Description: r.Description,
}
}
type OurProductContentUpdateRequest struct {
PrimaryTitle string `json:"primary_title"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
}
func (r *OurProductContentUpdateRequest) ToEntity() *entity.OurProductContent {
return &entity.OurProductContent{
PrimaryTitle: r.PrimaryTitle,
SecondaryTitle: r.SecondaryTitle,
Description: r.Description,
}
}

View File

@ -0,0 +1,79 @@
package service
import (
"github.com/google/uuid"
"github.com/rs/zerolog"
"web-qudo-be/app/database/entity"
ourProductContentImagesService "web-qudo-be/app/module/our_product_content_images/service"
"web-qudo-be/app/module/our_product_contents/repository"
)
type ourProductContentService struct {
Repo repository.OurProductContentRepository
ImageService ourProductContentImagesService.OurProductContentImagesService
Log zerolog.Logger
}
type OurProductContentService interface {
Show() (*entity.OurProductContent, error)
Save(data *entity.OurProductContent) (*entity.OurProductContent, error)
Update(id uuid.UUID, data *entity.OurProductContent) error
Delete(id uuid.UUID) error
}
func NewOurProductContentService(
repo repository.OurProductContentRepository,
imageService ourProductContentImagesService.OurProductContentImagesService,
log zerolog.Logger,
) OurProductContentService {
return &ourProductContentService{
Repo: repo,
ImageService: imageService,
Log: log,
}
}
func (s *ourProductContentService) Show() (*entity.OurProductContent, error) {
data, err := s.Repo.Get()
if err != nil {
s.Log.Error().Err(err).Msg("failed get our product content")
return nil, err
}
return data, nil
}
func (s *ourProductContentService) Save(data *entity.OurProductContent) (*entity.OurProductContent, error) {
data.ID = uuid.New()
result, err := s.Repo.Create(data)
if err != nil {
s.Log.Error().Err(err).Msg("failed create our product content")
return nil, err
}
return result, nil
}
func (s *ourProductContentService) Update(id uuid.UUID, data *entity.OurProductContent) error {
err := s.Repo.Update(id, data)
if err != nil {
s.Log.Error().Err(err).Msg("failed update our product content")
return err
}
return nil
}
func (s *ourProductContentService) Delete(id uuid.UUID) error {
result, err := s.Repo.Get()
if err != nil {
return err
}
isActive := false
result.IsActive = &isActive
return s.Repo.Update(id, result)
}

View File

@ -0,0 +1,17 @@
package controller
import (
"web-qudo-be/app/module/our_service_content_images/service"
"github.com/rs/zerolog"
)
type Controller struct {
OurServiceContentImages OurServiceContentImagesController
}
func NewController(ourServiceContentImagesService service.OurServiceContentImagesService, log zerolog.Logger) *Controller {
return &Controller{
OurServiceContentImages: NewOurServiceContentImagesController(ourServiceContentImagesService, log),
}
}

View File

@ -0,0 +1,127 @@
package controller
import (
"strconv"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog"
"web-qudo-be/app/module/our_service_content_images/request"
"web-qudo-be/app/module/our_service_content_images/service"
utilRes "web-qudo-be/utils/response"
utilVal "web-qudo-be/utils/validator"
)
type ourServiceContentImagesController struct {
service service.OurServiceContentImagesService
Log zerolog.Logger
}
type OurServiceContentImagesController interface {
FindByOurServiceContentID(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewOurServiceContentImagesController(service service.OurServiceContentImagesService, log zerolog.Logger) OurServiceContentImagesController {
return &ourServiceContentImagesController{
service: service,
Log: log,
}
}
func (_i *ourServiceContentImagesController) FindByOurServiceContentID(c *fiber.Ctx) error {
contentIDStr := c.Params("our_service_content_id")
contentIDInt, err := strconv.Atoi(contentIDStr)
if err != nil {
return err
}
contentID := uint(contentIDInt)
data, err := _i.service.FindByContentID(contentID)
if err != nil {
_i.Log.Error().Err(err).Msg("failed get our service content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our service content image retrieved"},
Data: data,
})
}
func (_i *ourServiceContentImagesController) Save(c *fiber.Ctx) error {
req := new(request.OurServiceContentImageCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
data := req.ToEntity()
result, err := _i.service.Save(data)
if err != nil {
_i.Log.Error().Err(err).Msg("failed create our service content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our service content image created"},
Data: result,
})
}
func (_i *ourServiceContentImagesController) Update(c *fiber.Ctx) error {
idStr := c.Params("id")
idInt, err := strconv.Atoi(idStr)
if err != nil {
return err
}
id := uint(idInt)
req := new(request.OurServiceContentImageUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err = _i.service.Update(id, req.ToEntity())
if err != nil {
_i.Log.Error().Err(err).Msg("failed update our service content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our service content image updated"},
})
}
func (_i *ourServiceContentImagesController) Delete(c *fiber.Ctx) error {
idStr := c.Params("id")
idInt, err := strconv.Atoi(idStr)
if err != nil {
return err
}
id := uint(idInt)
err = _i.service.Delete(id)
if err != nil {
_i.Log.Error().Err(err).Msg("failed delete our service content image")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our service content image deleted"},
})
}

View File

@ -0,0 +1,48 @@
package our_service_content_images
import (
"web-qudo-be/app/module/our_service_content_images/controller"
"web-qudo-be/app/module/our_service_content_images/repository"
"web-qudo-be/app/module/our_service_content_images/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
type OurServiceContentImagesRouter struct {
App fiber.Router
Controller *controller.Controller
}
var NewOurServiceContentImagesModule = fx.Options(
// repository
fx.Provide(repository.NewOurServiceContentImagesRepository),
// service
fx.Provide(service.NewOurServiceContentImagesService),
// controller
fx.Provide(controller.NewController),
// router
fx.Provide(NewOurServiceContentImagesRouter),
)
// init router
func NewOurServiceContentImagesRouter(fiber *fiber.App, controller *controller.Controller) *OurServiceContentImagesRouter {
return &OurServiceContentImagesRouter{
App: fiber,
Controller: controller,
}
}
func (_i *OurServiceContentImagesRouter) RegisterOurServiceContentImagesRoutes() {
imageController := _i.Controller.OurServiceContentImages
_i.App.Route("/our-service-content-images", func(router fiber.Router) {
router.Get("/:our_service_content_id", imageController.FindByOurServiceContentID)
router.Post("/", imageController.Save)
router.Put("/:id", imageController.Update)
router.Delete("/:id", imageController.Delete)
})
}

View File

@ -0,0 +1,76 @@
package repository
import (
"web-qudo-be/app/database"
"web-qudo-be/app/database/entity"
"github.com/rs/zerolog"
)
type ourServiceContentImagesRepository struct {
DB *database.Database
Log zerolog.Logger
}
type OurServiceContentImagesRepository interface {
FindByContentID(contentID uint) ([]entity.OurServiceContentImage, error)
Create(data *entity.OurServiceContentImage) (*entity.OurServiceContentImage, error)
Update(id uint, data *entity.OurServiceContentImage) error
Delete(id uint) error
}
func NewOurServiceContentImagesRepository(db *database.Database, log zerolog.Logger) OurServiceContentImagesRepository {
return &ourServiceContentImagesRepository{
DB: db,
Log: log,
}
}
func (r *ourServiceContentImagesRepository) FindByContentID(contentID uint) ([]entity.OurServiceContentImage, error) {
var data []entity.OurServiceContentImage
err := r.DB.DB.
Where("our_service_content_id = ?", contentID).
Find(&data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed get our service content images")
return nil, err
}
return data, nil
}
func (r *ourServiceContentImagesRepository) Create(data *entity.OurServiceContentImage) (*entity.OurServiceContentImage, error) {
err := r.DB.DB.Create(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed create our service content images")
return nil, err
}
return data, nil
}
func (r *ourServiceContentImagesRepository) Update(id uint, data *entity.OurServiceContentImage) error {
err := r.DB.DB.
Model(&entity.OurServiceContentImage{}).
Where("id = ?", id).
Updates(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed update our service content images")
return err
}
return nil
}
func (r *ourServiceContentImagesRepository) Delete(id uint) error {
err := r.DB.DB.Delete(&entity.OurServiceContentImage{}, id).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed delete our service content images")
return err
}
return nil
}

View File

@ -0,0 +1,35 @@
package request
import (
"web-qudo-be/app/database/entity"
)
type OurServiceContentImageCreateRequest struct {
OurServiceContentID uint `json:"our_service_content_id" validate:"required"`
ImagePath string `json:"image_path"`
ImageURL string `json:"image_url"`
IsThumbnail *bool `json:"is_thumbnail"`
}
func (r *OurServiceContentImageCreateRequest) ToEntity() *entity.OurServiceContentImage {
return &entity.OurServiceContentImage{
OurServiceContentID: r.OurServiceContentID,
ImagePath: r.ImagePath,
ImageURL: r.ImageURL,
IsThumbnail: r.IsThumbnail,
}
}
type OurServiceContentImageUpdateRequest struct {
ImagePath string `json:"image_path"`
ImageURL string `json:"image_url"`
IsThumbnail *bool `json:"is_thumbnail"`
}
func (r *OurServiceContentImageUpdateRequest) ToEntity() *entity.OurServiceContentImage {
return &entity.OurServiceContentImage{
ImagePath: r.ImagePath,
ImageURL: r.ImageURL,
IsThumbnail: r.IsThumbnail,
}
}

View File

@ -0,0 +1,70 @@
package service
import (
"github.com/rs/zerolog"
"web-qudo-be/app/database/entity"
"web-qudo-be/app/module/our_service_content_images/repository"
)
type ourServiceContentImagesService struct {
Repo repository.OurServiceContentImagesRepository
Log zerolog.Logger
}
type OurServiceContentImagesService interface {
FindByContentID(contentID uint) ([]entity.OurServiceContentImage, error)
Save(data *entity.OurServiceContentImage) (*entity.OurServiceContentImage, error)
Update(id uint, data *entity.OurServiceContentImage) error
Delete(id uint) error
}
func NewOurServiceContentImagesService(
repo repository.OurServiceContentImagesRepository,
log zerolog.Logger,
) OurServiceContentImagesService {
return &ourServiceContentImagesService{
Repo: repo,
Log: log,
}
}
func (s *ourServiceContentImagesService) FindByContentID(contentID uint) ([]entity.OurServiceContentImage, error) {
data, err := s.Repo.FindByContentID(contentID)
if err != nil {
s.Log.Error().Err(err).Msg("failed get our service content images")
return nil, err
}
return data, nil
}
func (s *ourServiceContentImagesService) Save(data *entity.OurServiceContentImage) (*entity.OurServiceContentImage, error) {
result, err := s.Repo.Create(data)
if err != nil {
s.Log.Error().Err(err).Msg("failed create our service content image")
return nil, err
}
return result, nil
}
func (s *ourServiceContentImagesService) Update(id uint, data *entity.OurServiceContentImage) error {
err := s.Repo.Update(id, data)
if err != nil {
s.Log.Error().Err(err).Msg("failed update our service content image")
return err
}
return nil
}
func (s *ourServiceContentImagesService) Delete(id uint) error {
err := s.Repo.Delete(id)
if err != nil {
s.Log.Error().Err(err).Msg("failed delete our service content image")
return err
}
return nil
}

View File

@ -0,0 +1,20 @@
package controller
import (
"web-qudo-be/app/module/our_service_contents/service"
"github.com/rs/zerolog"
)
type Controller struct {
OurServiceContent OurServiceContentController
}
func NewController(
ourServiceService service.OurServiceContentService,
log zerolog.Logger,
) *Controller {
return &Controller{
OurServiceContent: NewOurServiceContentController(ourServiceService, log),
}
}

View File

@ -0,0 +1,116 @@
package controller
import (
"strconv"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog"
"web-qudo-be/app/module/our_service_contents/request"
"web-qudo-be/app/module/our_service_contents/service"
utilRes "web-qudo-be/utils/response"
utilVal "web-qudo-be/utils/validator"
)
type ourServiceContentController struct {
service service.OurServiceContentService
Log zerolog.Logger
}
type OurServiceContentController interface {
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewOurServiceContentController(service service.OurServiceContentService, log zerolog.Logger) OurServiceContentController {
return &ourServiceContentController{
service: service,
Log: log,
}
}
func (_i *ourServiceContentController) Show(c *fiber.Ctx) error {
_i.Log.Info().Msg("GET /our-service-contents")
data, err := _i.service.Show()
if err != nil {
_i.Log.Error().Err(err).Msg("failed get our service content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our service content retrieved"},
Data: data,
})
}
func (_i *ourServiceContentController) Save(c *fiber.Ctx) error {
req := new(request.OurServiceContentCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
data := req.ToEntity()
result, err := _i.service.Save(data)
if err != nil {
_i.Log.Error().Err(err).Msg("failed create our service content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our service content created"},
Data: result,
})
}
func (_i *ourServiceContentController) Update(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := strconv.Atoi(idStr)
if err != nil {
return err
}
req := new(request.OurServiceContentUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err = _i.service.Update(uint(id), req.ToEntity())
if err != nil {
_i.Log.Error().Err(err).Msg("failed update our service content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our service content updated"},
})
}
func (_i *ourServiceContentController) Delete(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := strconv.Atoi(idStr)
if err != nil {
return err
}
err = _i.service.Delete(uint(id))
if err != nil {
_i.Log.Error().Err(err).Msg("failed delete our service content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Our service content deleted"},
})
}

View File

@ -0,0 +1,48 @@
package our_service_contents
import (
"web-qudo-be/app/module/our_service_contents/controller"
"web-qudo-be/app/module/our_service_contents/repository"
"web-qudo-be/app/module/our_service_contents/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
type OurServiceContentsRouter struct {
App fiber.Router
Controller *controller.Controller
}
var NewOurServiceContentsModule = fx.Options(
// repository
fx.Provide(repository.NewOurServiceContentRepository),
// service
fx.Provide(service.NewOurServiceContentService),
// controller
fx.Provide(controller.NewController),
// router
fx.Provide(NewOurServiceContentsRouter),
)
// init router
func NewOurServiceContentsRouter(fiber *fiber.App, controller *controller.Controller) *OurServiceContentsRouter {
return &OurServiceContentsRouter{
App: fiber,
Controller: controller,
}
}
func (_i *OurServiceContentsRouter) RegisterOurServiceContentsRoutes() {
contentController := _i.Controller.OurServiceContent
_i.App.Route("/our-service-contents", func(router fiber.Router) {
router.Get("/", contentController.Show)
router.Post("/", contentController.Save)
router.Put("/:id", contentController.Update)
router.Delete("/:id", contentController.Delete)
})
}

View File

@ -0,0 +1,76 @@
package repository
import (
"web-qudo-be/app/database"
"web-qudo-be/app/database/entity"
"github.com/rs/zerolog"
)
type ourServiceContentRepository struct {
DB *database.Database
Log zerolog.Logger
}
type OurServiceContentRepository interface {
Get() (*entity.OurServiceContent, error)
Create(data *entity.OurServiceContent) (*entity.OurServiceContent, error)
Update(id uint, data *entity.OurServiceContent) error
Delete(id uint) error
}
func NewOurServiceContentRepository(db *database.Database, logger zerolog.Logger) OurServiceContentRepository {
return &ourServiceContentRepository{
DB: db,
Log: logger,
}
}
func (r *ourServiceContentRepository) Get() (*entity.OurServiceContent, error) {
var data entity.OurServiceContent
err := r.DB.DB.
Preload("Images").
First(&data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed get our service content")
return nil, err
}
return &data, nil
}
func (r *ourServiceContentRepository) Create(data *entity.OurServiceContent) (*entity.OurServiceContent, error) {
err := r.DB.DB.Create(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed create our service content")
return nil, err
}
return data, nil
}
func (r *ourServiceContentRepository) Update(id uint, data *entity.OurServiceContent) error {
err := r.DB.DB.
Model(&entity.OurServiceContent{}).
Where("id = ?", id).
Updates(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed update our service content")
return err
}
return nil
}
func (r *ourServiceContentRepository) Delete(id uint) error {
err := r.DB.DB.Delete(&entity.OurServiceContent{}, id).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed delete our service content")
return err
}
return nil
}

View File

@ -0,0 +1,31 @@
package request
import "web-qudo-be/app/database/entity"
type OurServiceContentCreateRequest struct {
PrimaryTitle string `json:"primary_title" form:"primary_title" validate:"required"`
SecondaryTitle string `json:"secondary_title" form:"secondary_title"`
Description string `json:"description" form:"description"`
}
func (r *OurServiceContentCreateRequest) ToEntity() *entity.OurServiceContent {
return &entity.OurServiceContent{
PrimaryTitle: r.PrimaryTitle,
SecondaryTitle: r.SecondaryTitle,
Description: r.Description,
}
}
type OurServiceContentUpdateRequest struct {
PrimaryTitle string `json:"primary_title"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
}
func (r *OurServiceContentUpdateRequest) ToEntity() *entity.OurServiceContent {
return &entity.OurServiceContent{
PrimaryTitle: r.PrimaryTitle,
SecondaryTitle: r.SecondaryTitle,
Description: r.Description,
}
}

View File

@ -0,0 +1,87 @@
package service
import (
"github.com/rs/zerolog"
"web-qudo-be/app/database/entity"
ourServiceContentImagesService "web-qudo-be/app/module/our_service_content_images/service"
"web-qudo-be/app/module/our_service_contents/repository"
)
type ourServiceContentService struct {
Repo repository.OurServiceContentRepository
ImageService ourServiceContentImagesService.OurServiceContentImagesService
Log zerolog.Logger
}
type OurServiceContentService interface {
Show() (*entity.OurServiceContent, error)
Save(data *entity.OurServiceContent) (*entity.OurServiceContent, error)
Update(id uint, data *entity.OurServiceContent) error
Delete(id uint) error
}
func NewOurServiceContentService(
repo repository.OurServiceContentRepository,
imageService ourServiceContentImagesService.OurServiceContentImagesService,
log zerolog.Logger,
) OurServiceContentService {
return &ourServiceContentService{
Repo: repo,
ImageService: imageService,
Log: log,
}
}
func (s *ourServiceContentService) Show() (*entity.OurServiceContent, error) {
data, err := s.Repo.Get()
if err != nil {
s.Log.Error().Err(err).Msg("failed get our service content")
return nil, err
}
return data, nil
}
func (s *ourServiceContentService) Save(data *entity.OurServiceContent) (*entity.OurServiceContent, error) {
result, err := s.Repo.Create(data)
if err != nil {
s.Log.Error().Err(err).Msg("failed create our service content")
return nil, err
}
// 🔥 kalau nanti mau save images sekalian
// contoh:
// for _, img := range data.Images {
// img.OurServiceContentID = result.ID
// s.ImageService.Save(&img)
// }
return result, nil
}
func (s *ourServiceContentService) Update(id uint, data *entity.OurServiceContent) error {
err := s.Repo.Update(id, data)
if err != nil {
s.Log.Error().Err(err).Msg("failed update our service content")
return err
}
// 🔥 handle update images (opsional)
// bisa delete lama → insert baru
// atau update satu-satu
return nil
}
func (s *ourServiceContentService) Delete(id uint) error {
result, err := s.Repo.Get()
if err != nil {
return err
}
isActive := false
result.IsActive = &isActive
return s.Repo.Update(id, result)
}

View File

@ -0,0 +1,22 @@
package controller
import (
"web-qudo-be/app/module/partner_contents/service"
"github.com/rs/zerolog"
)
type Controller struct {
PartnerContent PartnerContentController
}
func NewController(
partnerService service.PartnerContentService,
log zerolog.Logger,
) *Controller {
return &Controller{
PartnerContent: NewPartnerContentController(partnerService, log),
}
}

View File

@ -0,0 +1,115 @@
package controller
import (
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"github.com/rs/zerolog"
"web-qudo-be/app/module/partner_contents/request"
"web-qudo-be/app/module/partner_contents/service"
utilRes "web-qudo-be/utils/response"
utilVal "web-qudo-be/utils/validator"
)
type partnerContentController struct {
service service.PartnerContentService
Log zerolog.Logger
}
type PartnerContentController interface {
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewPartnerContentController(service service.PartnerContentService, log zerolog.Logger) PartnerContentController {
return &partnerContentController{
service: service,
Log: log,
}
}
func (_i *partnerContentController) Show(c *fiber.Ctx) error {
_i.Log.Info().Msg("GET /partner-contents")
data, err := _i.service.Show()
if err != nil {
_i.Log.Error().Err(err).Msg("failed get partner content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Partner content retrieved"},
Data: data,
})
}
func (_i *partnerContentController) Save(c *fiber.Ctx) error {
req := new(request.PartnerContentCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
data := req.ToEntity()
result, err := _i.service.Save(data)
if err != nil {
_i.Log.Error().Err(err).Msg("failed create partner content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Partner content created"},
Data: result,
})
}
func (_i *partnerContentController) Update(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := uuid.Parse(idStr)
if err != nil {
return err
}
req := new(request.PartnerContentUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err = _i.service.Update(id, req.ToEntity())
if err != nil {
_i.Log.Error().Err(err).Msg("failed update partner content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Partner content updated"},
})
}
func (_i *partnerContentController) Delete(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := uuid.Parse(idStr)
if err != nil {
return err
}
err = _i.service.Delete(id)
if err != nil {
_i.Log.Error().Err(err).Msg("failed delete partner content")
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Partner content deleted"},
})
}

View File

@ -0,0 +1,48 @@
package partner_contents
import (
"web-qudo-be/app/module/partner_contents/controller"
"web-qudo-be/app/module/partner_contents/repository"
"web-qudo-be/app/module/partner_contents/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
type PartnerContentsRouter struct {
App fiber.Router
Controller *controller.Controller
}
var NewPartnerContentsModule = fx.Options(
// repository
fx.Provide(repository.NewPartnerContentRepository),
// service
fx.Provide(service.NewPartnerContentService),
// controller
fx.Provide(controller.NewController),
// router
fx.Provide(NewPartnerContentsRouter),
)
// init router
func NewPartnerContentsRouter(fiber *fiber.App, controller *controller.Controller) *PartnerContentsRouter {
return &PartnerContentsRouter{
App: fiber,
Controller: controller,
}
}
func (_i *PartnerContentsRouter) RegisterPartnerContentsRoutes() {
partnerController := _i.Controller.PartnerContent
_i.App.Route("/partner-contents", func(router fiber.Router) {
router.Get("/", partnerController.Show)
router.Post("/", partnerController.Save)
router.Put("/:id", partnerController.Update)
router.Delete("/:id", partnerController.Delete)
})
}

View File

@ -0,0 +1,93 @@
package repository
import (
"web-qudo-be/app/database"
"web-qudo-be/app/database/entity"
"github.com/google/uuid"
"github.com/rs/zerolog"
)
type partnerContentRepository struct {
DB *database.Database
Log zerolog.Logger
}
type PartnerContentRepository interface {
Get() ([]entity.PartnerContent, error)
Create(data *entity.PartnerContent) (*entity.PartnerContent, error)
Update(id uuid.UUID, data *entity.PartnerContent) error
Delete(id uuid.UUID) error
FindByID(id uuid.UUID) (*entity.PartnerContent, error) // opsional (buat soft delete)
}
func NewPartnerContentRepository(db *database.Database, logger zerolog.Logger) PartnerContentRepository {
return &partnerContentRepository{
DB: db,
Log: logger,
}
}
func (r *partnerContentRepository) Get() ([]entity.PartnerContent, error) {
var data []entity.PartnerContent
err := r.DB.DB.
Find(&data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed get partner contents")
return nil, err
}
return data, nil
}
func (r *partnerContentRepository) Create(data *entity.PartnerContent) (*entity.PartnerContent, error) {
data.ID = uuid.New()
err := r.DB.DB.Create(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed create partner content")
return nil, err
}
return data, nil
}
func (r *partnerContentRepository) Update(id uuid.UUID, data *entity.PartnerContent) error {
err := r.DB.DB.
Model(&entity.PartnerContent{}).
Where("id = ?", id).
Updates(data).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed update partner content")
return err
}
return nil
}
func (r *partnerContentRepository) Delete(id uuid.UUID) error {
err := r.DB.DB.Delete(&entity.PartnerContent{}, id).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed delete partner content")
return err
}
return nil
}
func (r *partnerContentRepository) FindByID(id uuid.UUID) (*entity.PartnerContent, error) {
var data entity.PartnerContent
err := r.DB.DB.
First(&data, "id = ?", id).Error
if err != nil {
r.Log.Error().Err(err).Msg("failed find partner content by id")
return nil, err
}
return &data, nil
}

View File

@ -0,0 +1,31 @@
package request
import "web-qudo-be/app/database/entity"
type PartnerContentCreateRequest struct {
PrimaryTitle string `json:"primary_title" form:"primary_title" validate:"required"`
ImagePath string `json:"image_path" form:"image_path"`
ImageURL string `json:"image_url" form:"image_url"`
}
func (r *PartnerContentCreateRequest) ToEntity() *entity.PartnerContent {
return &entity.PartnerContent{
PrimaryTitle: r.PrimaryTitle,
ImagePath: r.ImagePath,
ImageURL: r.ImageURL,
}
}
type PartnerContentUpdateRequest struct {
PrimaryTitle string `json:"primary_title"`
ImagePath string `json:"image_path"`
ImageURL string `json:"image_url"`
}
func (r *PartnerContentUpdateRequest) ToEntity() *entity.PartnerContent {
return &entity.PartnerContent{
PrimaryTitle: r.PrimaryTitle,
ImagePath: r.ImagePath,
ImageURL: r.ImageURL,
}
}

View File

@ -0,0 +1,73 @@
package service
import (
"github.com/google/uuid"
"github.com/rs/zerolog"
"web-qudo-be/app/database/entity"
"web-qudo-be/app/module/partner_contents/repository"
)
type partnerContentService struct {
Repo repository.PartnerContentRepository
Log zerolog.Logger
}
type PartnerContentService interface {
Show() ([]entity.PartnerContent, error)
Save(data *entity.PartnerContent) (*entity.PartnerContent, error)
Update(id uuid.UUID, data *entity.PartnerContent) error
Delete(id uuid.UUID) error
}
func NewPartnerContentService(
repo repository.PartnerContentRepository,
log zerolog.Logger,
) PartnerContentService {
return &partnerContentService{
Repo: repo,
Log: log,
}
}
func (s *partnerContentService) Show() ([]entity.PartnerContent, error) {
data, err := s.Repo.Get()
if err != nil {
s.Log.Error().Err(err).Msg("failed get partner content")
return nil, err
}
return data, nil
}
func (s *partnerContentService) Save(data *entity.PartnerContent) (*entity.PartnerContent, error) {
data.ID = uuid.New()
result, err := s.Repo.Create(data)
if err != nil {
s.Log.Error().Err(err).Msg("failed create partner content")
return nil, err
}
return result, nil
}
func (s *partnerContentService) Update(id uuid.UUID, data *entity.PartnerContent) error {
err := s.Repo.Update(id, data)
if err != nil {
s.Log.Error().Err(err).Msg("failed update partner content")
return err
}
return nil
}
func (s *partnerContentService) Delete(id uuid.UUID) error {
err := s.Repo.Delete(id)
if err != nil {
s.Log.Error().Err(err).Msg("failed delete partner content")
return err
}
return nil
}

View File

@ -0,0 +1,13 @@
package controller
import "web-qudo-be/app/module/popup_news_content_images/service"
type Controller struct {
PopupNewsContent PopupNewsContentImagesController
}
func NewController(popupNewsContentImagesService service.PopupNewsContentImagesService) *Controller {
return &Controller{
PopupNewsContent: NewPopupNewsContentImagesController(popupNewsContentImagesService),
}
}

View File

@ -0,0 +1,82 @@
package controller
import (
"strconv"
"github.com/gofiber/fiber/v2"
"web-qudo-be/app/module/popup_news_content_images/request"
"web-qudo-be/app/module/popup_news_content_images/service"
utilRes "web-qudo-be/utils/response"
utilVal "web-qudo-be/utils/validator"
)
type popupNewsContentImagesController struct {
service service.PopupNewsContentImagesService
}
type PopupNewsContentImagesController interface {
Save(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewPopupNewsContentImagesController(s service.PopupNewsContentImagesService) PopupNewsContentImagesController {
return &popupNewsContentImagesController{
service: s,
}
}
// Save Popup News Content Image
// @Summary Upload Popup News Content Image
// @Description API for uploading image for Popup News Content
// @Tags Popup News Content Images
// @Security Bearer
// @Body request.PopupNewsContentImagesCreateRequest
// @Success 200 {object} response.Response
// @Failure 401 {object} response.Response
// @Failure 422 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /popup-news-content-images [post]
func (_i *popupNewsContentImagesController) Save(c *fiber.Ctx) error {
req := new(request.PopupNewsContentImagesCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err := _i.service.Save(*req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Messages: utilRes.Messages{"Popup news content image successfully uploaded"},
})
}
// Delete Popup News Content Image
// @Summary Delete Popup News Content Image
// @Description API for deleting image
// @Tags Popup News Content Images
// @Security Bearer
// @Param id path int true "Image ID"
// @Success 200 {object} response.Response
// @Failure 401 {object} response.Response
// @Failure 404 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /popup-news-content-images/{id} [delete]
func (_i *popupNewsContentImagesController) Delete(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
err = _i.service.Delete(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Messages: utilRes.Messages{"Popup news content image successfully deleted"},
})
}

View File

@ -0,0 +1,19 @@
package mapper
import (
"web-qudo-be/app/database/entity"
res "web-qudo-be/app/module/popup_news_content_images/response"
)
func PopupNewsContentImagesResponseMapper(imageReq *entity.PopupNewsContentImages) (imageRes *res.PopupNewsContentImagesResponse) {
if imageReq != nil {
imageRes = &res.PopupNewsContentImagesResponse{
ID: imageReq.ID,
PopupNewsContentID: imageReq.PopupNewsContentID,
MediaPath: imageReq.MediaPath,
MediaURL: imageReq.MediaURL,
IsThumbnail: imageReq.IsThumbnail,
}
}
return imageRes
}

View File

@ -0,0 +1,41 @@
package repository
import (
"web-qudo-be/app/database"
"web-qudo-be/app/database/entity"
)
type popupNewsContentImagesRepository struct {
DB *database.Database
}
type PopupNewsContentImagesRepository interface {
Create(data *entity.PopupNewsContentImages) error
Delete(id uint) error
// 🔥 optional tapi recommended
ResetThumbnail(popupNewsContentID uint) error
}
func NewPopupNewsContentImagesRepository(db *database.Database) PopupNewsContentImagesRepository {
return &popupNewsContentImagesRepository{
DB: db,
}
}
// Create
func (_i *popupNewsContentImagesRepository) Create(data *entity.PopupNewsContentImages) error {
return _i.DB.DB.Create(data).Error
}
// Delete
func (_i *popupNewsContentImagesRepository) Delete(id uint) error {
return _i.DB.DB.Delete(&entity.PopupNewsContentImages{}, id).Error
}
// 🔥 Reset semua thumbnail jadi false (BEST PRACTICE)
func (_i *popupNewsContentImagesRepository) ResetThumbnail(popupNewsContentID uint) error {
return _i.DB.DB.Model(&entity.PopupNewsContentImages{}).
Where("popup_news_content_id = ?", popupNewsContentID).
Update("is_thumbnail", false).Error
}

View File

@ -0,0 +1,24 @@
package request
import "web-qudo-be/app/database/entity"
type PopupNewsContentImagesGeneric interface {
ToEntity()
}
// Create (upload / insert image)
type PopupNewsContentImagesCreateRequest struct {
PopupNewsContentID uint `json:"popup_news_content_id" validate:"required"`
MediaPath string `json:"media_path"`
MediaURL string `json:"media_url"`
IsThumbnail *bool `json:"is_thumbnail"`
}
func (req PopupNewsContentImagesCreateRequest) ToEntity() *entity.PopupNewsContentImages {
return &entity.PopupNewsContentImages{
PopupNewsContentID: req.PopupNewsContentID,
MediaPath: req.MediaPath,
MediaURL: req.MediaURL,
IsThumbnail: req.IsThumbnail,
}
}

View File

@ -0,0 +1,9 @@
package response
type PopupNewsContentImagesResponse struct {
ID uint `json:"id"`
PopupNewsContentID uint `json:"popup_news_content_id"`
MediaPath string `json:"media_path"`
MediaURL string `json:"media_url"`
IsThumbnail *bool `json:"is_thumbnail"`
}

View File

@ -0,0 +1,40 @@
package service
import (
"github.com/rs/zerolog"
"web-qudo-be/app/module/popup_news_content_images/repository"
"web-qudo-be/app/module/popup_news_content_images/request"
)
// service struct
type popupNewsContentImagesService struct {
Repo repository.PopupNewsContentImagesRepository
Log zerolog.Logger
}
// interface
type PopupNewsContentImagesService interface {
Save(req request.PopupNewsContentImagesCreateRequest) error
Delete(id uint) error
}
// constructor
func NewPopupNewsContentImagesService(repo repository.PopupNewsContentImagesRepository, log zerolog.Logger) PopupNewsContentImagesService {
return &popupNewsContentImagesService{
Repo: repo,
Log: log,
}
}
// Save
func (_i *popupNewsContentImagesService) Save(req request.PopupNewsContentImagesCreateRequest) error {
_i.Log.Info().Interface("data", req).Msg("upload popup news content image")
return _i.Repo.Create(req.ToEntity())
}
// Delete
func (_i *popupNewsContentImagesService) Delete(id uint) error {
return _i.Repo.Delete(id)
}

View File

@ -0,0 +1,13 @@
package controller
import "web-qudo-be/app/module/popup_news_contents/service"
type Controller struct {
PopupNewsContent PopupNewsContentsController
}
func NewController(popupNewsContentsService service.PopupNewsContentsService) *Controller {
return &Controller{
PopupNewsContent: NewPopupNewsContentsController(popupNewsContentsService),
}
}

View File

@ -0,0 +1,183 @@
package controller
import (
"strconv"
"github.com/gofiber/fiber/v2"
"web-qudo-be/app/module/popup_news_contents/request"
"web-qudo-be/app/module/popup_news_contents/service"
"web-qudo-be/utils/paginator"
utilRes "web-qudo-be/utils/response"
utilVal "web-qudo-be/utils/validator"
)
type popupNewsContentsController struct {
service service.PopupNewsContentsService
}
type PopupNewsContentsController interface {
All(c *fiber.Ctx) error
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewPopupNewsContentsController(s service.PopupNewsContentsService) PopupNewsContentsController {
return &popupNewsContentsController{
service: s,
}
}
// All Popup News Contents
// @Summary Get all Popup News Contents
// @Description API for getting all Popup News Contents
// @Tags Popup News Contents
// @Security Bearer
// @Success 200 {object} response.Response
// @Failure 401 {object} response.Response
// @Failure 404 {object} response.Response
// @Failure 422 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /popup-news-contents [get]
func (_i *popupNewsContentsController) All(c *fiber.Ctx) error {
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
var req request.PopupNewsContentsQueryRequest
req.Pagination = paginate
data, paging, err := _i.service.All(req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Messages: utilRes.Messages{"Popup news contents list successfully retrieved"},
Data: data,
Meta: paging,
})
}
// Show Popup News Content
// @Summary Get one Popup News Content
// @Description API for getting one Popup News Content
// @Tags Popup News Contents
// @Security Bearer
// @Param id path int true "Popup News Content ID"
// @Success 200 {object} response.Response
// @Failure 401 {object} response.Response
// @Failure 404 {object} response.Response
// @Failure 422 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /popup-news-contents/{id} [get]
func (_i *popupNewsContentsController) Show(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
data, err := _i.service.Show(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Messages: utilRes.Messages{"Popup news content successfully retrieved"},
Data: data,
})
}
// Save Popup News Content
// @Summary Create Popup News Content
// @Description API for create Popup News Content
// @Tags Popup News Contents
// @Security Bearer
// @Body request.PopupNewsContentsCreateRequest
// @Success 200 {object} response.Response
// @Failure 401 {object} response.Response
// @Failure 404 {object} response.Response
// @Failure 422 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /popup-news-contents [post]
func (_i *popupNewsContentsController) Save(c *fiber.Ctx) error {
req := new(request.PopupNewsContentsCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err := _i.service.Save(*req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Messages: utilRes.Messages{"Popup news content successfully created"},
})
}
// Update Popup News Content
// @Summary Update Popup News Content
// @Description API for update Popup News Content
// @Tags Popup News Contents
// @Security Bearer
// @Body request.PopupNewsContentsUpdateRequest
// @Param id path int true "Popup News Content ID"
// @Success 200 {object} response.Response
// @Failure 401 {object} response.Response
// @Failure 404 {object} response.Response
// @Failure 422 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /popup-news-contents/{id} [put]
func (_i *popupNewsContentsController) Update(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
req := new(request.PopupNewsContentsUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err = _i.service.Update(uint(id), *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Messages: utilRes.Messages{"Popup news content successfully updated"},
})
}
// Delete Popup News Content
// @Summary Delete Popup News Content
// @Description API for delete Popup News Content
// @Tags Popup News Contents
// @Security Bearer
// @Param id path int true "Popup News Content ID"
// @Success 200 {object} response.Response
// @Failure 401 {object} response.Response
// @Failure 404 {object} response.Response
// @Failure 422 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /popup-news-contents/{id} [delete]
func (_i *popupNewsContentsController) Delete(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
err = _i.service.Delete(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Messages: utilRes.Messages{"Popup news content successfully deleted"},
})
}

View File

@ -0,0 +1,35 @@
package mapper
import (
"web-qudo-be/app/database/entity"
imageMapper "web-qudo-be/app/module/popup_news_content_images/mapper"
imageRes "web-qudo-be/app/module/popup_news_content_images/response"
res "web-qudo-be/app/module/popup_news_contents/response"
)
func PopupNewsContentsResponseMapper(req *entity.PopupNewsContents) (resData *res.PopupNewsContentsResponse) {
if req != nil {
// 🔥 mapping images
var images []imageRes.PopupNewsContentImagesResponse
for _, img := range req.Images {
mapped := imageMapper.PopupNewsContentImagesResponseMapper(&img)
if mapped != nil {
images = append(images, *mapped)
}
}
resData = &res.PopupNewsContentsResponse{
ID: req.ID,
PrimaryTitle: req.PrimaryTitle,
SecondaryTitle: req.SecondaryTitle,
Description: req.Description,
PrimaryCTA: req.PrimaryCTA,
SecondaryCTAText: req.SecondaryCTAText,
Images: images,
}
}
return
}

View File

@ -0,0 +1,80 @@
package repository
import (
"web-qudo-be/app/database"
"web-qudo-be/app/database/entity"
"web-qudo-be/app/module/popup_news_contents/request"
"web-qudo-be/utils/paginator"
)
type popupNewsContentsRepository struct {
DB *database.Database
}
type PopupNewsContentsRepository interface {
GetAll(req request.PopupNewsContentsQueryRequest) (data []*entity.PopupNewsContents, paging paginator.Pagination, err error)
FindOne(id uint) (*entity.PopupNewsContents, error)
Create(data *entity.PopupNewsContents) error
Update(id uint, data *entity.PopupNewsContents) error
Delete(id uint) error
}
func NewPopupNewsContentsRepository(db *database.Database) PopupNewsContentsRepository {
return &popupNewsContentsRepository{
DB: db,
}
}
// Get All + 🔥 Preload Images
func (_i *popupNewsContentsRepository) GetAll(req request.PopupNewsContentsQueryRequest) (datas []*entity.PopupNewsContents, paging paginator.Pagination, err error) {
var count int64
query := _i.DB.DB.Model(&entity.PopupNewsContents{}).
Preload("Images") // 🔥 penting
query.Count(&count)
req.Pagination.Count = count
req.Pagination = paginator.Paging(req.Pagination)
err = query.
Offset(req.Pagination.Offset).
Limit(req.Pagination.Limit).
Find(&datas).Error
if err != nil {
return
}
paging = *req.Pagination
return
}
// Find One + 🔥 Preload Images
func (_i *popupNewsContentsRepository) FindOne(id uint) (*entity.PopupNewsContents, error) {
var data entity.PopupNewsContents
if err := _i.DB.DB.
Preload("Images").
First(&data, id).Error; err != nil {
return nil, err
}
return &data, nil
}
// Create
func (_i *popupNewsContentsRepository) Create(data *entity.PopupNewsContents) error {
return _i.DB.DB.Create(data).Error
}
// Update
func (_i *popupNewsContentsRepository) Update(id uint, data *entity.PopupNewsContents) error {
return _i.DB.DB.Model(&entity.PopupNewsContents{}).
Where(&entity.PopupNewsContents{ID: id}).
Updates(data).Error
}
// Delete
func (_i *popupNewsContentsRepository) Delete(id uint) error {
return _i.DB.DB.Delete(&entity.PopupNewsContents{}, id).Error
}

View File

@ -0,0 +1,56 @@
package request
import (
"web-qudo-be/app/database/entity"
"web-qudo-be/utils/paginator"
)
type PopupNewsContentsGeneric interface {
ToEntity()
}
// Query
type PopupNewsContentsQueryRequest struct {
PrimaryTitle string `json:"primary_title"`
Pagination *paginator.Pagination `json:"pagination"`
}
// Create
type PopupNewsContentsCreateRequest struct {
PrimaryTitle string `json:"primary_title" validate:"required"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
PrimaryCTA string `json:"primary_cta"`
SecondaryCTAText string `json:"secondary_cta_text"`
}
func (req PopupNewsContentsCreateRequest) ToEntity() *entity.PopupNewsContents {
return &entity.PopupNewsContents{
PrimaryTitle: req.PrimaryTitle,
SecondaryTitle: req.SecondaryTitle,
Description: req.Description,
PrimaryCTA: req.PrimaryCTA,
SecondaryCTAText: req.SecondaryCTAText,
}
}
// Update
type PopupNewsContentsUpdateRequest struct {
ID uint `json:"id" validate:"required"`
PrimaryTitle string `json:"primary_title" validate:"required"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
PrimaryCTA string `json:"primary_cta"`
SecondaryCTAText string `json:"secondary_cta_text"`
}
func (req PopupNewsContentsUpdateRequest) ToEntity() *entity.PopupNewsContents {
return &entity.PopupNewsContents{
ID: req.ID,
PrimaryTitle: req.PrimaryTitle,
SecondaryTitle: req.SecondaryTitle,
Description: req.Description,
PrimaryCTA: req.PrimaryCTA,
SecondaryCTAText: req.SecondaryCTAText,
}
}

View File

@ -0,0 +1,13 @@
package response
import imageRes "web-qudo-be/app/module/popup_news_content_images/response"
type PopupNewsContentsResponse struct {
ID uint `json:"id"`
PrimaryTitle string `json:"primary_title"`
SecondaryTitle string `json:"secondary_title"`
Description string `json:"description"`
PrimaryCTA string `json:"primary_cta"`
SecondaryCTAText string `json:"secondary_cta_text"`
Images []imageRes.PopupNewsContentImagesResponse `json:"images"`
}

View File

@ -0,0 +1,77 @@
package service
import (
"github.com/rs/zerolog"
"web-qudo-be/app/module/popup_news_contents/mapper"
"web-qudo-be/app/module/popup_news_contents/repository"
"web-qudo-be/app/module/popup_news_contents/request"
"web-qudo-be/app/module/popup_news_contents/response"
"web-qudo-be/utils/paginator"
)
// service struct
type popupNewsContentsService struct {
Repo repository.PopupNewsContentsRepository
Log zerolog.Logger
}
// interface
type PopupNewsContentsService interface {
All(req request.PopupNewsContentsQueryRequest) (data []*response.PopupNewsContentsResponse, paging paginator.Pagination, err error)
Show(id uint) (*response.PopupNewsContentsResponse, error)
Save(req request.PopupNewsContentsCreateRequest) error
Update(id uint, req request.PopupNewsContentsUpdateRequest) error
Delete(id uint) error
}
// constructor
func NewPopupNewsContentsService(repo repository.PopupNewsContentsRepository, log zerolog.Logger) PopupNewsContentsService {
return &popupNewsContentsService{
Repo: repo,
Log: log,
}
}
// All
func (_i *popupNewsContentsService) All(req request.PopupNewsContentsQueryRequest) (datas []*response.PopupNewsContentsResponse, paging paginator.Pagination, err error) {
results, paging, err := _i.Repo.GetAll(req)
if err != nil {
return
}
for _, result := range results {
datas = append(datas, mapper.PopupNewsContentsResponseMapper(result))
}
return
}
// Show
func (_i *popupNewsContentsService) Show(id uint) (*response.PopupNewsContentsResponse, error) {
result, err := _i.Repo.FindOne(id)
if err != nil {
return nil, err
}
return mapper.PopupNewsContentsResponseMapper(result), nil
}
// Save
func (_i *popupNewsContentsService) Save(req request.PopupNewsContentsCreateRequest) error {
_i.Log.Info().Interface("data", req).Msg("create popup news content")
return _i.Repo.Create(req.ToEntity())
}
// Update
func (_i *popupNewsContentsService) Update(id uint, req request.PopupNewsContentsUpdateRequest) error {
_i.Log.Info().Interface("data", req).Msg("update popup news content")
return _i.Repo.Update(id, req.ToEntity())
}
// Delete
func (_i *popupNewsContentsService) Delete(id uint) error {
return _i.Repo.Delete(id)
}

View File

@ -1,6 +1,8 @@
package router
import (
"web-qudo-be/app/module/about_us_content_images"
"web-qudo-be/app/module/about_us_contents"
"web-qudo-be/app/module/activity_logs"
"web-qudo-be/app/module/advertisement"
"web-qudo-be/app/module/approval_workflow_steps"
@ -21,12 +23,17 @@ import (
"web-qudo-be/app/module/custom_static_pages"
"web-qudo-be/app/module/districts"
"web-qudo-be/app/module/feedbacks"
"web-qudo-be/app/module/hero_section"
"web-qudo-be/app/module/hero_section_image"
hero_content_image "web-qudo-be/app/module/hero_content_images"
hero_content "web-qudo-be/app/module/hero_contents"
"web-qudo-be/app/module/magazine_files"
"web-qudo-be/app/module/magazines"
"web-qudo-be/app/module/master_menus"
"web-qudo-be/app/module/master_modules"
"web-qudo-be/app/module/our_product_content_images"
"web-qudo-be/app/module/our_product_contents"
"web-qudo-be/app/module/our_service_content_images"
"web-qudo-be/app/module/our_service_contents"
"web-qudo-be/app/module/partner_contents"
"web-qudo-be/app/module/provinces"
"web-qudo-be/app/module/schedules"
"web-qudo-be/app/module/subscription"
@ -44,8 +51,9 @@ import (
type Router struct {
App fiber.Router
Cfg *config.Config
ActivityLogsRouter *activity_logs.ActivityLogsRouter
AboutUsContentsRouter *about_us_contents.AboutUsContentsRouter
AboutUsContentImageRouter *about_us_content_images.AboutUsContentImageRouter
AdvertisementRouter *advertisement.AdvertisementRouter
ApprovalWorkflowsRouter *approval_workflows.ApprovalWorkflowsRouter
ApprovalWorkflowStepsRouter *approval_workflow_steps.ApprovalWorkflowStepsRouter
@ -62,8 +70,8 @@ type Router struct {
CitiesRouter *cities.CitiesRouter
ClientApprovalSettingsRouter *client_approval_settings.ClientApprovalSettingsRouter
ClientsRouter *clients.ClientsRouter
HeroSectionRouter *hero_section.HeroSectionRouter
HeroSectionImageRouter *hero_section_image.HeroSectionImageRouter
HeroContentsRouter *hero_content.HeroContentsRouter
HeroContentImagesRouter *hero_content_image.HeroContentImagesRouter
CustomStaticPagesRouter *custom_static_pages.CustomStaticPagesRouter
DistrictsRouter *districts.DistrictsRouter
FeedbacksRouter *feedbacks.FeedbacksRouter
@ -71,9 +79,14 @@ type Router struct {
MagazinesRouter *magazines.MagazinesRouter
MasterMenusRouter *master_menus.MasterMenusRouter
MasterModulesRouter *master_modules.MasterModulesRouter
OurProductContentsRouter *our_product_contents.OurProductContentsRouter
OurProductContentImagesRouter *our_product_content_images.OurProductContentImagesRouter
OurServiceContentRouter *our_service_contents.OurServiceContentsRouter
OurServiceContentImagesRouter *our_service_content_images.OurServiceContentImagesRouter
ProvincesRouter *provinces.ProvincesRouter
SchedulesRouter *schedules.SchedulesRouter
SubscriptionRouter *subscription.SubscriptionRouter
PartnerContentRouter *partner_contents.PartnerContentsRouter
UserLevelsRouter *user_levels.UserLevelsRouter
UserRoleAccessesRouter *user_role_accesses.UserRoleAccessesRouter
UserRolesRouter *user_roles.UserRolesRouter
@ -83,7 +96,8 @@ type Router struct {
func NewRouter(
fiber *fiber.App,
cfg *config.Config,
aboutUsContentsRouter *about_us_contents.AboutUsContentsRouter,
aboutUsContentImagesRouter *about_us_content_images.AboutUsContentImageRouter,
activityLogsRouter *activity_logs.ActivityLogsRouter,
advertisementRouter *advertisement.AdvertisementRouter,
approvalWorkflowsRouter *approval_workflows.ApprovalWorkflowsRouter,
@ -101,8 +115,8 @@ func NewRouter(
citiesRouter *cities.CitiesRouter,
clientApprovalSettingsRouter *client_approval_settings.ClientApprovalSettingsRouter,
clientsRouter *clients.ClientsRouter,
heroSectionRouter *hero_section.HeroSectionRouter,
heroSectionImageRouter *hero_section_image.HeroSectionImageRouter,
heroContentsRouter *hero_content.HeroContentsRouter,
heroContentImagesRouter *hero_content_image.HeroContentImagesRouter,
customStaticPagesRouter *custom_static_pages.CustomStaticPagesRouter,
districtsRouter *districts.DistrictsRouter,
feedbacksRouter *feedbacks.FeedbacksRouter,
@ -110,6 +124,11 @@ func NewRouter(
magazinesRouter *magazines.MagazinesRouter,
masterMenuRouter *master_menus.MasterMenusRouter,
masterModuleRouter *master_modules.MasterModulesRouter,
ourProductContentsRouter *our_product_contents.OurProductContentsRouter,
ourProductContentImagesRouter *our_product_content_images.OurProductContentImagesRouter,
ourServiceContentsRouter *our_service_contents.OurServiceContentsRouter,
ourServiceContentImagesRouter *our_service_content_images.OurServiceContentImagesRouter,
partnerContentsRouter *partner_contents.PartnerContentsRouter,
provincesRouter *provinces.ProvincesRouter,
schedulesRouter *schedules.SchedulesRouter,
subscriptionRouter *subscription.SubscriptionRouter,
@ -121,6 +140,8 @@ func NewRouter(
return &Router{
App: fiber,
Cfg: cfg,
AboutUsContentsRouter: aboutUsContentsRouter,
AboutUsContentImageRouter: aboutUsContentImagesRouter,
ActivityLogsRouter: activityLogsRouter,
AdvertisementRouter: advertisementRouter,
ApprovalWorkflowsRouter: approvalWorkflowsRouter,
@ -138,8 +159,8 @@ func NewRouter(
CitiesRouter: citiesRouter,
ClientApprovalSettingsRouter: clientApprovalSettingsRouter,
ClientsRouter: clientsRouter,
HeroSectionRouter: heroSectionRouter,
HeroSectionImageRouter: heroSectionImageRouter,
HeroContentsRouter: heroContentsRouter,
HeroContentImagesRouter: heroContentImagesRouter,
CustomStaticPagesRouter: customStaticPagesRouter,
DistrictsRouter: districtsRouter,
FeedbacksRouter: feedbacksRouter,
@ -147,6 +168,11 @@ func NewRouter(
MagazinesRouter: magazinesRouter,
MasterMenusRouter: masterMenuRouter,
MasterModulesRouter: masterModuleRouter,
OurProductContentsRouter: ourProductContentsRouter,
OurProductContentImagesRouter: ourProductContentImagesRouter,
OurServiceContentRouter: ourServiceContentsRouter,
OurServiceContentImagesRouter: ourServiceContentImagesRouter,
PartnerContentRouter: partnerContentsRouter,
ProvincesRouter: provincesRouter,
SchedulesRouter: schedulesRouter,
SubscriptionRouter: subscriptionRouter,
@ -169,6 +195,8 @@ func (r *Router) Register() {
// Register routes of modules
r.ActivityLogsRouter.RegisterActivityLogsRoutes()
r.AboutUsContentsRouter.RegisterAboutUsContentsRoutes()
r.AboutUsContentImageRouter.RegisterAboutUsContentImageRoutes()
r.AdvertisementRouter.RegisterAdvertisementRoutes()
r.ApprovalWorkflowsRouter.RegisterApprovalWorkflowsRoutes()
r.ApprovalWorkflowStepsRouter.RegisterApprovalWorkflowStepsRoutes()
@ -185,8 +213,8 @@ func (r *Router) Register() {
r.CitiesRouter.RegisterCitiesRoutes()
r.ClientApprovalSettingsRouter.RegisterClientApprovalSettingsRoutes()
r.ClientsRouter.RegisterClientsRoutes()
r.HeroSectionRouter.RegisterHeroSectionRoutes()
r.HeroSectionImageRouter.RegisterHeroSectionImageRoutes()
r.HeroContentsRouter.RegisterHeroContentsRoutes()
r.HeroContentImagesRouter.RegisterHeroContentImagesRoutes()
r.CustomStaticPagesRouter.RegisterCustomStaticPagesRoutes()
r.DistrictsRouter.RegisterDistrictsRoutes()
r.FeedbacksRouter.RegisterFeedbacksRoutes()
@ -194,6 +222,11 @@ func (r *Router) Register() {
r.MagazineFilesRouter.RegisterMagazineFilesRoutes()
r.MasterMenusRouter.RegisterMasterMenusRoutes()
r.MasterModulesRouter.RegisterMasterModulesRoutes()
r.OurProductContentsRouter.RegisterOurProductContentsRoutes()
r.OurProductContentImagesRouter.RegisterOurProductContentImagesRoutes()
r.OurServiceContentRouter.RegisterOurServiceContentsRoutes()
r.OurServiceContentImagesRouter.RegisterOurServiceContentImagesRoutes()
r.PartnerContentRouter.RegisterPartnerContentsRoutes()
r.ProvincesRouter.RegisterProvincesRoutes()
r.SchedulesRouter.RegisterSchedulesRoutes()
r.SubscriptionRouter.RegisterSubscriptionRoutes()

View File

@ -12708,6 +12708,346 @@ const docTemplate = `{
}
}
},
"/popup-news-content-images": {
"post": {
"security": [
{
"Bearer": []
}
],
"description": "API for uploading image for Popup News Content",
"tags": [
"Popup News Content Images"
],
"summary": "Upload Popup News Content Image",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/popup-news-content-images/{id}": {
"delete": {
"security": [
{
"Bearer": []
}
],
"description": "API for deleting image",
"tags": [
"Popup News Content Images"
],
"summary": "Delete Popup News Content Image",
"parameters": [
{
"type": "integer",
"description": "Image ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/popup-news-contents": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "API for getting all Popup News Contents",
"tags": [
"Popup News Contents"
],
"summary": "Get all Popup News Contents",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
},
"post": {
"security": [
{
"Bearer": []
}
],
"description": "API for create Popup News Content",
"tags": [
"Popup News Contents"
],
"summary": "Create Popup News Content",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/popup-news-contents/{id}": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "API for getting one Popup News Content",
"tags": [
"Popup News Contents"
],
"summary": "Get one Popup News Content",
"parameters": [
{
"type": "integer",
"description": "Popup News Content ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
},
"put": {
"security": [
{
"Bearer": []
}
],
"description": "API for update Popup News Content",
"tags": [
"Popup News Contents"
],
"summary": "Update Popup News Content",
"parameters": [
{
"type": "integer",
"description": "Popup News Content ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
},
"delete": {
"security": [
{
"Bearer": []
}
],
"description": "API for delete Popup News Content",
"tags": [
"Popup News Contents"
],
"summary": "Delete Popup News Content",
"parameters": [
{
"type": "integer",
"description": "Popup News Content ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/provinces": {
"get": {
"security": [

View File

@ -12697,6 +12697,346 @@
}
}
},
"/popup-news-content-images": {
"post": {
"security": [
{
"Bearer": []
}
],
"description": "API for uploading image for Popup News Content",
"tags": [
"Popup News Content Images"
],
"summary": "Upload Popup News Content Image",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/popup-news-content-images/{id}": {
"delete": {
"security": [
{
"Bearer": []
}
],
"description": "API for deleting image",
"tags": [
"Popup News Content Images"
],
"summary": "Delete Popup News Content Image",
"parameters": [
{
"type": "integer",
"description": "Image ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/popup-news-contents": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "API for getting all Popup News Contents",
"tags": [
"Popup News Contents"
],
"summary": "Get all Popup News Contents",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
},
"post": {
"security": [
{
"Bearer": []
}
],
"description": "API for create Popup News Content",
"tags": [
"Popup News Contents"
],
"summary": "Create Popup News Content",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/popup-news-contents/{id}": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "API for getting one Popup News Content",
"tags": [
"Popup News Contents"
],
"summary": "Get one Popup News Content",
"parameters": [
{
"type": "integer",
"description": "Popup News Content ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
},
"put": {
"security": [
{
"Bearer": []
}
],
"description": "API for update Popup News Content",
"tags": [
"Popup News Contents"
],
"summary": "Update Popup News Content",
"parameters": [
{
"type": "integer",
"description": "Popup News Content ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
},
"delete": {
"security": [
{
"Bearer": []
}
],
"description": "API for delete Popup News Content",
"tags": [
"Popup News Contents"
],
"summary": "Delete Popup News Content",
"parameters": [
{
"type": "integer",
"description": "Popup News Content ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/provinces": {
"get": {
"security": [

View File

@ -9569,6 +9569,222 @@ paths:
summary: Update MasterStatuses
tags:
- Untags
/popup-news-content-images:
post:
description: API for uploading image for Popup News Content
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.Response'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/response.Response'
"422":
description: Unprocessable Entity
schema:
$ref: '#/definitions/response.Response'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.Response'
security:
- Bearer: []
summary: Upload Popup News Content Image
tags:
- Popup News Content Images
/popup-news-content-images/{id}:
delete:
description: API for deleting image
parameters:
- description: Image ID
in: path
name: id
required: true
type: integer
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.Response'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/response.Response'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.Response'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.Response'
security:
- Bearer: []
summary: Delete Popup News Content Image
tags:
- Popup News Content Images
/popup-news-contents:
get:
description: API for getting all Popup News Contents
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.Response'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/response.Response'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.Response'
"422":
description: Unprocessable Entity
schema:
$ref: '#/definitions/response.Response'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.Response'
security:
- Bearer: []
summary: Get all Popup News Contents
tags:
- Popup News Contents
post:
description: API for create Popup News Content
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.Response'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/response.Response'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.Response'
"422":
description: Unprocessable Entity
schema:
$ref: '#/definitions/response.Response'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.Response'
security:
- Bearer: []
summary: Create Popup News Content
tags:
- Popup News Contents
/popup-news-contents/{id}:
delete:
description: API for delete Popup News Content
parameters:
- description: Popup News Content ID
in: path
name: id
required: true
type: integer
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.Response'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/response.Response'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.Response'
"422":
description: Unprocessable Entity
schema:
$ref: '#/definitions/response.Response'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.Response'
security:
- Bearer: []
summary: Delete Popup News Content
tags:
- Popup News Contents
get:
description: API for getting one Popup News Content
parameters:
- description: Popup News Content ID
in: path
name: id
required: true
type: integer
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.Response'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/response.Response'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.Response'
"422":
description: Unprocessable Entity
schema:
$ref: '#/definitions/response.Response'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.Response'
security:
- Bearer: []
summary: Get one Popup News Content
tags:
- Popup News Contents
put:
description: API for update Popup News Content
parameters:
- description: Popup News Content ID
in: path
name: id
required: true
type: integer
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.Response'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/response.Response'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.Response'
"422":
description: Unprocessable Entity
schema:
$ref: '#/definitions/response.Response'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.Response'
security:
- Bearer: []
summary: Update Popup News Content
tags:
- Popup News Contents
/provinces:
get:
description: API for getting all Provinces

View File

@ -10994,217 +10994,6 @@ const docTemplate = `{
}
}
},
"/hero-section": {
"get": {
"description": "Get hero section",
"tags": ["Hero Section"],
"summary": "Get Hero Section",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.InternalServerError"
}
}
}
},
"post": {
"description": "Create hero section",
"tags": ["Hero Section"],
"summary": "Create Hero Section",
"parameters": [
{
"type": "string",
"description": "Insert the X-Client-Key",
"name": "X-Client-Key",
"in": "header"
},
{
"type": "string",
"name": "primary_title",
"in": "formData"
},
{
"type": "string",
"name": "secondary_title",
"in": "formData"
},
{
"type": "string",
"name": "description",
"in": "formData"
},
{
"type": "string",
"name": "primary_cta",
"in": "formData"
},
{
"type": "string",
"name": "secondary_cta_text",
"in": "formData"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/hero-section/{id}": {
"put": {
"description": "Update hero section",
"tags": ["Hero Section"],
"summary": "Update Hero Section",
"parameters": [
{
"type": "integer",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
},
"delete": {
"description": "Delete hero section",
"tags": ["Hero Section"],
"summary": "Delete Hero Section",
"parameters": [
{
"type": "integer",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/hero-section-image/{heroId}": {
"get": {
"description": "Get images by hero ID",
"tags": ["Hero Section Image"],
"summary": "Get Hero Images",
"parameters": [
{
"type": "integer",
"name": "heroId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
},
"post": {
"description": "Upload hero image",
"tags": ["Hero Section Image"],
"summary": "Upload Image",
"parameters": [
{
"type": "integer",
"name": "heroId",
"in": "path",
"required": true
},
{
"type": "file",
"name": "image",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/hero-section-image/{id}": {
"put": {
"description": "Update hero image",
"tags": ["Hero Section Image"],
"summary": "Update Image",
"parameters": [
{
"type": "integer",
"name": "id",
"in": "path",
"required": true
},
{
"type": "file",
"name": "image",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
},
"delete": {
"description": "Delete hero image",
"tags": ["Hero Section Image"],
"summary": "Delete Image",
"parameters": [
{
"type": "integer",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response"
}
}
}
}
},
"/magazine-files": {
"get": {
"security": [

View File

@ -10637,16 +10637,16 @@
}
}
},
"/hero-section": {
"/hero-contents": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "API for getting hero section",
"tags": ["Hero Section"],
"summary": "Get Hero Section",
"description": "API for getting hero content",
"tags": ["Hero Content"],
"summary": "Get Hero Content",
"responses": {
"200": {
"description": "OK",
@ -10680,9 +10680,9 @@
"Bearer": []
}
],
"description": "API for create hero section",
"tags": ["Hero Section"],
"summary": "Create Hero Section",
"description": "API for create hero content",
"tags": ["Hero Content"],
"summary": "Create Hero Content",
"parameters": [
{
"type": "string",
@ -10744,16 +10744,16 @@
}
}
},
"/hero-section/{id}": {
"/hero-contents/{id}": {
"put": {
"security": [
{
"Bearer": []
}
],
"description": "API for update hero section",
"tags": ["Hero Section"],
"summary": "Update Hero Section",
"description": "API for update hero contents",
"tags": ["Hero Contents"],
"summary": "Update Hero Contents",
"parameters": [
{
"type": "integer",
@ -10795,9 +10795,9 @@
"Bearer": []
}
],
"description": "API for delete hero section",
"tags": ["Hero Section"],
"summary": "Delete Hero Section",
"description": "API for delete hero contents",
"tags": ["Hero Contents"],
"summary": "Delete Hero Contents",
"parameters": [
{
"type": "integer",
@ -10834,7 +10834,7 @@
}
}
},
"/hero-section-image/{heroId}": {
"/hero-content-images/{heroId}": {
"get": {
"security": [
{
@ -10842,7 +10842,7 @@
}
],
"description": "API for getting hero images by hero ID",
"tags": ["Hero Section Image"],
"tags": ["Hero Content Image"],
"summary": "Get Hero Images",
"parameters": [
{
@ -10886,7 +10886,7 @@
}
],
"description": "API for upload hero image",
"tags": ["Hero Section Image"],
"tags": ["Hero Content Image"],
"summary": "Upload Image",
"parameters": [
{
@ -10930,7 +10930,7 @@
}
}
},
"/hero-section-image/{id}": {
"/hero-content-images/{id}": {
"put": {
"security": [
{
@ -10938,7 +10938,7 @@
}
],
"description": "API for update hero image",
"tags": ["Hero Section Image"],
"tags": ["Hero Content Image"],
"summary": "Update Image",
"parameters": [
{
@ -10988,7 +10988,7 @@
}
],
"description": "API for delete hero image",
"tags": ["Hero Section Image"],
"tags": ["Hero Content Image"],
"summary": "Delete Image",
"parameters": [
{

31
main.go
View File

@ -4,6 +4,8 @@ import (
"time"
"web-qudo-be/app/database"
"web-qudo-be/app/middleware"
"web-qudo-be/app/module/about_us_content_images"
"web-qudo-be/app/module/about_us_contents"
"web-qudo-be/app/module/activity_logs"
"web-qudo-be/app/module/advertisement"
"web-qudo-be/app/module/approval_workflow_steps"
@ -24,12 +26,17 @@ import (
"web-qudo-be/app/module/custom_static_pages"
"web-qudo-be/app/module/districts"
"web-qudo-be/app/module/feedbacks"
"web-qudo-be/app/module/hero_section"
"web-qudo-be/app/module/hero_section_image"
hero_content_image "web-qudo-be/app/module/hero_content_images"
hero_content "web-qudo-be/app/module/hero_contents"
"web-qudo-be/app/module/magazine_files"
"web-qudo-be/app/module/magazines"
"web-qudo-be/app/module/master_menus"
"web-qudo-be/app/module/master_modules"
"web-qudo-be/app/module/our_product_content_images"
"web-qudo-be/app/module/our_product_contents"
"web-qudo-be/app/module/our_service_content_images"
"web-qudo-be/app/module/our_service_contents"
"web-qudo-be/app/module/partner_contents"
"web-qudo-be/app/module/provinces"
"web-qudo-be/app/module/schedules"
"web-qudo-be/app/module/subscription"
@ -70,15 +77,14 @@ func main() {
// smtp config
fx.Provide(config.NewSmtpConfig),
// database
fx.Provide(database.NewDB),
// modules
hero_section.NewHeroSectionModule,
hero_section_image.NewHeroSectionImageModule,
// // modules
// hero_content.NewHeroContentModule,
// hero_content_image.NewHeroContentImageModule,
// provide modules
about_us_contents.NewAboutUsContentsModule,
about_us_content_images.NewAboutUsContentImageModule,
activity_logs.NewActivityLogsModule,
advertisement.NewAdvertisementModule,
approval_workflows.NewApprovalWorkflowsModule,
@ -99,12 +105,17 @@ func main() {
custom_static_pages.NewCustomStaticPagesModule,
districts.NewDistrictsModule,
feedbacks.NewFeedbacksModule,
hero_section.NewHeroSectionModule,
hero_section_image.NewHeroSectionImageModule,
hero_content.NewHeroContentsModule,
hero_content_image.NewHeroContentImagesModule,
magazines.NewMagazinesModule,
magazine_files.NewMagazineFilesModule,
master_menus.NewMasterMenusModule,
master_modules.NewMasterModulesModule,
our_product_contents.NewOurProductContentsModule,
our_product_content_images.NewOurProductContentImagesModule,
our_service_contents.NewOurServiceContentsModule,
our_service_content_images.NewOurServiceContentImagesModule,
partner_contents.NewPartnerContentsModule,
provinces.NewProvincesModule,
schedules.NewSchedulesModule,
subscription.NewSubscriptionModule,

25
utils/file/upload.go Normal file
View File

@ -0,0 +1,25 @@
package file
import (
"io"
"mime/multipart"
"os"
)
// SaveFile simpan file ke local storage (tanpa fiber)
func SaveFile(file *multipart.FileHeader, path string) error {
src, err := file.Open()
if err != nil {
return err
}
defer src.Close()
dst, err := os.Create(path)
if err != nil {
return err
}
defer dst.Close()
_, err = io.Copy(dst, src)
return err
}