diff --git a/app/database/entity/about_us_content_images.entity.go b/app/database/entity/about_us_content_images.entity.go new file mode 100644 index 0000000..f5f26bf --- /dev/null +++ b/app/database/entity/about_us_content_images.entity.go @@ -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" +} \ No newline at end of file diff --git a/app/database/entity/about_us_contents.entity.go b/app/database/entity/about_us_contents.entity.go new file mode 100644 index 0000000..1f4804a --- /dev/null +++ b/app/database/entity/about_us_contents.entity.go @@ -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" +} \ No newline at end of file diff --git a/app/database/entity/hero_contents.entity.go b/app/database/entity/hero_contents.entity.go new file mode 100644 index 0000000..149bdf3 --- /dev/null +++ b/app/database/entity/hero_contents.entity.go @@ -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" +} diff --git a/app/database/entity/hero_contents_images.entity.go b/app/database/entity/hero_contents_images.entity.go new file mode 100644 index 0000000..6e75a26 --- /dev/null +++ b/app/database/entity/hero_contents_images.entity.go @@ -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" +} \ No newline at end of file diff --git a/app/database/entity/our_product_content_images.entity.go b/app/database/entity/our_product_content_images.entity.go new file mode 100644 index 0000000..3868801 --- /dev/null +++ b/app/database/entity/our_product_content_images.entity.go @@ -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" +} \ No newline at end of file diff --git a/app/database/entity/our_product_contents.entity.go b/app/database/entity/our_product_contents.entity.go new file mode 100644 index 0000000..1215a0d --- /dev/null +++ b/app/database/entity/our_product_contents.entity.go @@ -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" +} \ No newline at end of file diff --git a/app/database/entity/our_service_content_images.entity.go b/app/database/entity/our_service_content_images.entity.go new file mode 100644 index 0000000..0df5a51 --- /dev/null +++ b/app/database/entity/our_service_content_images.entity.go @@ -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" +} \ No newline at end of file diff --git a/app/database/entity/our_service_contents.entity.go b/app/database/entity/our_service_contents.entity.go new file mode 100644 index 0000000..8a01645 --- /dev/null +++ b/app/database/entity/our_service_contents.entity.go @@ -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" +} \ No newline at end of file diff --git a/app/database/entity/partner_contents.entity.go b/app/database/entity/partner_contents.entity.go new file mode 100644 index 0000000..b80e01c --- /dev/null +++ b/app/database/entity/partner_contents.entity.go @@ -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" +} \ No newline at end of file diff --git a/app/database/entity/popup_news_content_image.entity.go b/app/database/entity/popup_news_content_image.entity.go new file mode 100644 index 0000000..775d7e8 --- /dev/null +++ b/app/database/entity/popup_news_content_image.entity.go @@ -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" +} \ No newline at end of file diff --git a/app/database/entity/popup_news_contents.entity.go b/app/database/entity/popup_news_contents.entity.go new file mode 100644 index 0000000..aa32390 --- /dev/null +++ b/app/database/entity/popup_news_contents.entity.go @@ -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" +} \ No newline at end of file diff --git a/app/database/index.database.go b/app/database/index.database.go index 69425fc..833372a 100644 --- a/app/database/index.database.go +++ b/app/database/index.database.go @@ -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{}, diff --git a/app/module/about_us_content_images/about_us_content_images.module.go b/app/module/about_us_content_images/about_us_content_images.module.go new file mode 100644 index 0000000..68e0903 --- /dev/null +++ b/app/module/about_us_content_images/about_us_content_images.module.go @@ -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) + }) +} \ No newline at end of file diff --git a/app/module/about_us_content_images/controller/about_us_content_images.controller.go b/app/module/about_us_content_images/controller/about_us_content_images.controller.go new file mode 100644 index 0000000..af5dfba --- /dev/null +++ b/app/module/about_us_content_images/controller/about_us_content_images.controller.go @@ -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"}, + }) +} \ No newline at end of file diff --git a/app/module/about_us_content_images/controller/controller.go b/app/module/about_us_content_images/controller/controller.go new file mode 100644 index 0000000..aa09910 --- /dev/null +++ b/app/module/about_us_content_images/controller/controller.go @@ -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), + } +} \ No newline at end of file diff --git a/app/module/about_us_content_images/repository/about_us_content_images.repository.go b/app/module/about_us_content_images/repository/about_us_content_images.repository.go new file mode 100644 index 0000000..5570e85 --- /dev/null +++ b/app/module/about_us_content_images/repository/about_us_content_images.repository.go @@ -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 +} \ No newline at end of file diff --git a/app/module/about_us_content_images/service/about_us_content_images.service.go b/app/module/about_us_content_images/service/about_us_content_images.service.go new file mode 100644 index 0000000..cea0775 --- /dev/null +++ b/app/module/about_us_content_images/service/about_us_content_images.service.go @@ -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) +} + + + diff --git a/app/module/about_us_contents/about_use_contents.module.go b/app/module/about_us_contents/about_use_contents.module.go new file mode 100644 index 0000000..8f6ef93 --- /dev/null +++ b/app/module/about_us_contents/about_use_contents.module.go @@ -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 + }) +} \ No newline at end of file diff --git a/app/module/about_us_contents/controller/about_us_contents.controller.go b/app/module/about_us_contents/controller/about_us_contents.controller.go new file mode 100644 index 0000000..000e715 --- /dev/null +++ b/app/module/about_us_contents/controller/about_us_contents.controller.go @@ -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"}, + }) +} \ No newline at end of file diff --git a/app/module/about_us_contents/controller/controller.go b/app/module/about_us_contents/controller/controller.go new file mode 100644 index 0000000..10295c0 --- /dev/null +++ b/app/module/about_us_contents/controller/controller.go @@ -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), + } +} \ No newline at end of file diff --git a/app/module/about_us_contents/repository/about_use_contents.repository.go b/app/module/about_us_contents/repository/about_use_contents.repository.go new file mode 100644 index 0000000..a2abcfc --- /dev/null +++ b/app/module/about_us_contents/repository/about_use_contents.repository.go @@ -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 +} \ No newline at end of file diff --git a/app/module/about_us_contents/request/about_us_contents.request.go b/app/module/about_us_contents/request/about_us_contents.request.go new file mode 100644 index 0000000..7fe23c9 --- /dev/null +++ b/app/module/about_us_contents/request/about_us_contents.request.go @@ -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 +} \ No newline at end of file diff --git a/app/module/about_us_contents/response/about_us_contents.response.go b/app/module/about_us_contents/response/about_us_contents.response.go new file mode 100644 index 0000000..05a5e3a --- /dev/null +++ b/app/module/about_us_contents/response/about_us_contents.response.go @@ -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"` +} \ No newline at end of file diff --git a/app/module/about_us_contents/service/about_use_contents.service.go b/app/module/about_us_contents/service/about_use_contents.service.go new file mode 100644 index 0000000..75096e9 --- /dev/null +++ b/app/module/about_us_contents/service/about_use_contents.service.go @@ -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) +} \ No newline at end of file diff --git a/app/module/hero_content_images/controller/controller.go b/app/module/hero_content_images/controller/controller.go new file mode 100644 index 0000000..be236f7 --- /dev/null +++ b/app/module/hero_content_images/controller/controller.go @@ -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), + } +} \ No newline at end of file diff --git a/app/module/hero_content_images/controller/hero_content_images.controller.go b/app/module/hero_content_images/controller/hero_content_images.controller.go new file mode 100644 index 0000000..1bf78eb --- /dev/null +++ b/app/module/hero_content_images/controller/hero_content_images.controller.go @@ -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"}, + }) +} \ No newline at end of file diff --git a/app/module/hero_content_images/hero_content_images.module.go b/app/module/hero_content_images/hero_content_images.module.go new file mode 100644 index 0000000..97f1156 --- /dev/null +++ b/app/module/hero_content_images/hero_content_images.module.go @@ -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) + }) +} \ No newline at end of file diff --git a/app/module/hero_content_images/repository/hero_content_images.repository.go b/app/module/hero_content_images/repository/hero_content_images.repository.go new file mode 100644 index 0000000..47859b4 --- /dev/null +++ b/app/module/hero_content_images/repository/hero_content_images.repository.go @@ -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 +} \ No newline at end of file diff --git a/app/module/hero_content_images/request/hero_content_images.request.go b/app/module/hero_content_images/request/hero_content_images.request.go new file mode 100644 index 0000000..7c586ea --- /dev/null +++ b/app/module/hero_content_images/request/hero_content_images.request.go @@ -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, + } +} \ No newline at end of file diff --git a/app/module/hero_content_images/service/hero_content_images.service.go b/app/module/hero_content_images/service/hero_content_images.service.go new file mode 100644 index 0000000..066198e --- /dev/null +++ b/app/module/hero_content_images/service/hero_content_images.service.go @@ -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 +} \ No newline at end of file diff --git a/app/module/hero_contents/controller/controller.go b/app/module/hero_contents/controller/controller.go new file mode 100644 index 0000000..b1da85e --- /dev/null +++ b/app/module/hero_contents/controller/controller.go @@ -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), + } +} \ No newline at end of file diff --git a/app/module/hero_contents/controller/hero_contents.controller.go b/app/module/hero_contents/controller/hero_contents.controller.go new file mode 100644 index 0000000..b8282c7 --- /dev/null +++ b/app/module/hero_contents/controller/hero_contents.controller.go @@ -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"}, + }) +} \ No newline at end of file diff --git a/app/module/hero_contents/hero_contents.module.go b/app/module/hero_contents/hero_contents.module.go new file mode 100644 index 0000000..6e50799 --- /dev/null +++ b/app/module/hero_contents/hero_contents.module.go @@ -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) + }) +} \ No newline at end of file diff --git a/app/module/hero_section/mapper/hero_section.mapper.go b/app/module/hero_contents/mapper/hero_contents.mapper.go similarity index 69% rename from app/module/hero_section/mapper/hero_section.mapper.go rename to app/module/hero_contents/mapper/hero_contents.mapper.go index 3d7b527..9da1036 100644 --- a/app/module/hero_section/mapper/hero_section.mapper.go +++ b/app/module/hero_contents/mapper/hero_contents.mapper.go @@ -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), diff --git a/app/module/hero_contents/repository/hero_contents.repository.go b/app/module/hero_contents/repository/hero_contents.repository.go new file mode 100644 index 0000000..5f02682 --- /dev/null +++ b/app/module/hero_contents/repository/hero_contents.repository.go @@ -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 +} \ No newline at end of file diff --git a/app/module/hero_contents/request/hero_contents.request.go b/app/module/hero_contents/request/hero_contents.request.go new file mode 100644 index 0000000..61ee453 --- /dev/null +++ b/app/module/hero_contents/request/hero_contents.request.go @@ -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, + } +} \ No newline at end of file diff --git a/app/module/hero_section/response/hero_section.response.go b/app/module/hero_contents/response/hero_contents.response.go similarity index 91% rename from app/module/hero_section/response/hero_section.response.go rename to app/module/hero_contents/response/hero_contents.response.go index 9a765a6..c06137e 100644 --- a/app/module/hero_section/response/hero_section.response.go +++ b/app/module/hero_contents/response/hero_contents.response.go @@ -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"` diff --git a/app/module/hero_contents/service/hero_contents.service.go b/app/module/hero_contents/service/hero_contents.service.go new file mode 100644 index 0000000..0dfccda --- /dev/null +++ b/app/module/hero_contents/service/hero_contents.service.go @@ -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) +} \ No newline at end of file diff --git a/app/module/hero_section/controller/controller.go b/app/module/hero_section/controller/controller.go deleted file mode 100644 index 5f7710d..0000000 --- a/app/module/hero_section/controller/controller.go +++ /dev/null @@ -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", - }) -} \ No newline at end of file diff --git a/app/module/hero_section/hero_section.module.go b/app/module/hero_section/hero_section.module.go deleted file mode 100644 index 4e72156..0000000 --- a/app/module/hero_section/hero_section.module.go +++ /dev/null @@ -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) - }) -} - diff --git a/app/module/hero_section/repository/hero_section.repository.go b/app/module/hero_section/repository/hero_section.repository.go deleted file mode 100644 index 306e5d0..0000000 --- a/app/module/hero_section/repository/hero_section.repository.go +++ /dev/null @@ -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 -} \ No newline at end of file diff --git a/app/module/hero_section/request/hero_section.request.go b/app/module/hero_section/request/hero_section.request.go deleted file mode 100644 index d55a2e8..0000000 --- a/app/module/hero_section/request/hero_section.request.go +++ /dev/null @@ -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"` -} \ No newline at end of file diff --git a/app/module/hero_section/service/hero_section.service.go b/app/module/hero_section/service/hero_section.service.go deleted file mode 100644 index 7b06417..0000000 --- a/app/module/hero_section/service/hero_section.service.go +++ /dev/null @@ -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) -} \ No newline at end of file diff --git a/app/module/hero_section_image/controller/controller.go b/app/module/hero_section_image/controller/controller.go deleted file mode 100644 index 4faee61..0000000 --- a/app/module/hero_section_image/controller/controller.go +++ /dev/null @@ -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", - }) -} \ No newline at end of file diff --git a/app/module/hero_section_image/hero_section_image.module.go b/app/module/hero_section_image/hero_section_image.module.go deleted file mode 100644 index 2ac1253..0000000 --- a/app/module/hero_section_image/hero_section_image.module.go +++ /dev/null @@ -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) - }) -} \ No newline at end of file diff --git a/app/module/hero_section_image/repository/hero_section_image.repository.go b/app/module/hero_section_image/repository/hero_section_image.repository.go deleted file mode 100644 index 185990e..0000000 --- a/app/module/hero_section_image/repository/hero_section_image.repository.go +++ /dev/null @@ -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 -} \ No newline at end of file diff --git a/app/module/hero_section_image/service/hero_section_image.service.go b/app/module/hero_section_image/service/hero_section_image.service.go deleted file mode 100644 index 3d332fb..0000000 --- a/app/module/hero_section_image/service/hero_section_image.service.go +++ /dev/null @@ -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) -} \ No newline at end of file diff --git a/app/module/our_product_content_images/controller/controller.go b/app/module/our_product_content_images/controller/controller.go new file mode 100644 index 0000000..afeee68 --- /dev/null +++ b/app/module/our_product_content_images/controller/controller.go @@ -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), + } +} \ No newline at end of file diff --git a/app/module/our_product_content_images/controller/our_product_content_images.controller.go b/app/module/our_product_content_images/controller/our_product_content_images.controller.go new file mode 100644 index 0000000..c20d068 --- /dev/null +++ b/app/module/our_product_content_images/controller/our_product_content_images.controller.go @@ -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"}, + }) +} \ No newline at end of file diff --git a/app/module/our_product_content_images/our_product_content_images.module.go b/app/module/our_product_content_images/our_product_content_images.module.go new file mode 100644 index 0000000..44ab34b --- /dev/null +++ b/app/module/our_product_content_images/our_product_content_images.module.go @@ -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) + }) +} \ No newline at end of file diff --git a/app/module/our_product_content_images/repository/our_product_content_images.repository.go b/app/module/our_product_content_images/repository/our_product_content_images.repository.go new file mode 100644 index 0000000..1f7372f --- /dev/null +++ b/app/module/our_product_content_images/repository/our_product_content_images.repository.go @@ -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 +} \ No newline at end of file diff --git a/app/module/our_product_content_images/request/our_product_content_images.request.go b/app/module/our_product_content_images/request/our_product_content_images.request.go new file mode 100644 index 0000000..f156016 --- /dev/null +++ b/app/module/our_product_content_images/request/our_product_content_images.request.go @@ -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, + } +} \ No newline at end of file diff --git a/app/module/our_product_content_images/service/our_product_content_images.service.go b/app/module/our_product_content_images/service/our_product_content_images.service.go new file mode 100644 index 0000000..ab92635 --- /dev/null +++ b/app/module/our_product_content_images/service/our_product_content_images.service.go @@ -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 +} \ No newline at end of file diff --git a/app/module/our_product_contents/controller/controller.go b/app/module/our_product_contents/controller/controller.go new file mode 100644 index 0000000..f3acb1a --- /dev/null +++ b/app/module/our_product_contents/controller/controller.go @@ -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), + } +} \ No newline at end of file diff --git a/app/module/our_product_contents/controller/our_product_contents.controller.go b/app/module/our_product_contents/controller/our_product_contents.controller.go new file mode 100644 index 0000000..df0f079 --- /dev/null +++ b/app/module/our_product_contents/controller/our_product_contents.controller.go @@ -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"}, + }) +} \ No newline at end of file diff --git a/app/module/our_product_contents/our_product_contents.module.go b/app/module/our_product_contents/our_product_contents.module.go new file mode 100644 index 0000000..e79e9e7 --- /dev/null +++ b/app/module/our_product_contents/our_product_contents.module.go @@ -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) + }) +} \ No newline at end of file diff --git a/app/module/our_product_contents/repository/our_product_contents.repository.go b/app/module/our_product_contents/repository/our_product_contents.repository.go new file mode 100644 index 0000000..0a4e77a --- /dev/null +++ b/app/module/our_product_contents/repository/our_product_contents.repository.go @@ -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 +} \ No newline at end of file diff --git a/app/module/our_product_contents/request/our_product_contents.request.go b/app/module/our_product_contents/request/our_product_contents.request.go new file mode 100644 index 0000000..78664e1 --- /dev/null +++ b/app/module/our_product_contents/request/our_product_contents.request.go @@ -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, + } +} \ No newline at end of file diff --git a/app/module/our_product_contents/service/our_product_contents.service.go b/app/module/our_product_contents/service/our_product_contents.service.go new file mode 100644 index 0000000..6f2168d --- /dev/null +++ b/app/module/our_product_contents/service/our_product_contents.service.go @@ -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) +} \ No newline at end of file diff --git a/app/module/our_service_content_images/controller/controller.go b/app/module/our_service_content_images/controller/controller.go new file mode 100644 index 0000000..bfdc0be --- /dev/null +++ b/app/module/our_service_content_images/controller/controller.go @@ -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), + } +} \ No newline at end of file diff --git a/app/module/our_service_content_images/controller/our_service_content_images.controller.go b/app/module/our_service_content_images/controller/our_service_content_images.controller.go new file mode 100644 index 0000000..54e66d5 --- /dev/null +++ b/app/module/our_service_content_images/controller/our_service_content_images.controller.go @@ -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"}, + }) +} \ No newline at end of file diff --git a/app/module/our_service_content_images/our_service_content_images.module.go b/app/module/our_service_content_images/our_service_content_images.module.go new file mode 100644 index 0000000..7f16d3b --- /dev/null +++ b/app/module/our_service_content_images/our_service_content_images.module.go @@ -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) + }) +} \ No newline at end of file diff --git a/app/module/our_service_content_images/repository/our_service_content_images.repository.go b/app/module/our_service_content_images/repository/our_service_content_images.repository.go new file mode 100644 index 0000000..a3cf6e6 --- /dev/null +++ b/app/module/our_service_content_images/repository/our_service_content_images.repository.go @@ -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 +} \ No newline at end of file diff --git a/app/module/our_service_content_images/request/our_service_content_images.request.go b/app/module/our_service_content_images/request/our_service_content_images.request.go new file mode 100644 index 0000000..4881b78 --- /dev/null +++ b/app/module/our_service_content_images/request/our_service_content_images.request.go @@ -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, + } +} \ No newline at end of file diff --git a/app/module/our_service_content_images/service/our_service_content_images.service.go b/app/module/our_service_content_images/service/our_service_content_images.service.go new file mode 100644 index 0000000..87e60b1 --- /dev/null +++ b/app/module/our_service_content_images/service/our_service_content_images.service.go @@ -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 +} \ No newline at end of file diff --git a/app/module/our_service_contents/controller/controller.go b/app/module/our_service_contents/controller/controller.go new file mode 100644 index 0000000..4140dec --- /dev/null +++ b/app/module/our_service_contents/controller/controller.go @@ -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), + } +} \ No newline at end of file diff --git a/app/module/our_service_contents/controller/our_service_contents.controller.go b/app/module/our_service_contents/controller/our_service_contents.controller.go new file mode 100644 index 0000000..5b23737 --- /dev/null +++ b/app/module/our_service_contents/controller/our_service_contents.controller.go @@ -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"}, + }) +} \ No newline at end of file diff --git a/app/module/our_service_contents/our_service_contents.module.go b/app/module/our_service_contents/our_service_contents.module.go new file mode 100644 index 0000000..0bfd001 --- /dev/null +++ b/app/module/our_service_contents/our_service_contents.module.go @@ -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) + }) +} \ No newline at end of file diff --git a/app/module/our_service_contents/repository/our_service_contents.repository.go b/app/module/our_service_contents/repository/our_service_contents.repository.go new file mode 100644 index 0000000..05977d1 --- /dev/null +++ b/app/module/our_service_contents/repository/our_service_contents.repository.go @@ -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 +} \ No newline at end of file diff --git a/app/module/our_service_contents/request/our_service_contents.request.go b/app/module/our_service_contents/request/our_service_contents.request.go new file mode 100644 index 0000000..9734133 --- /dev/null +++ b/app/module/our_service_contents/request/our_service_contents.request.go @@ -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, + } +} \ No newline at end of file diff --git a/app/module/our_service_contents/service/our_service_contents.service.go b/app/module/our_service_contents/service/our_service_contents.service.go new file mode 100644 index 0000000..e242bba --- /dev/null +++ b/app/module/our_service_contents/service/our_service_contents.service.go @@ -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) +} \ No newline at end of file diff --git a/app/module/partner_contents/controller/controller.go b/app/module/partner_contents/controller/controller.go new file mode 100644 index 0000000..19d5f8f --- /dev/null +++ b/app/module/partner_contents/controller/controller.go @@ -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), + } +} \ No newline at end of file diff --git a/app/module/partner_contents/controller/partner_contents.controller.go b/app/module/partner_contents/controller/partner_contents.controller.go new file mode 100644 index 0000000..d3fe0d2 --- /dev/null +++ b/app/module/partner_contents/controller/partner_contents.controller.go @@ -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"}, + }) +} \ No newline at end of file diff --git a/app/module/partner_contents/partner_contents.module.go b/app/module/partner_contents/partner_contents.module.go new file mode 100644 index 0000000..0312c7a --- /dev/null +++ b/app/module/partner_contents/partner_contents.module.go @@ -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) + }) +} \ No newline at end of file diff --git a/app/module/partner_contents/repository/partner_contents.repository.go b/app/module/partner_contents/repository/partner_contents.repository.go new file mode 100644 index 0000000..0828bc2 --- /dev/null +++ b/app/module/partner_contents/repository/partner_contents.repository.go @@ -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 +} \ No newline at end of file diff --git a/app/module/partner_contents/request/partner_contents.request.go b/app/module/partner_contents/request/partner_contents.request.go new file mode 100644 index 0000000..3fe2e3a --- /dev/null +++ b/app/module/partner_contents/request/partner_contents.request.go @@ -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, + } +} \ No newline at end of file diff --git a/app/module/partner_contents/service/partner_contents.service.go b/app/module/partner_contents/service/partner_contents.service.go new file mode 100644 index 0000000..5535592 --- /dev/null +++ b/app/module/partner_contents/service/partner_contents.service.go @@ -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 +} \ No newline at end of file diff --git a/app/module/popup_news_content_images/controller/controller.go b/app/module/popup_news_content_images/controller/controller.go new file mode 100644 index 0000000..8b9e319 --- /dev/null +++ b/app/module/popup_news_content_images/controller/controller.go @@ -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), + } +} \ No newline at end of file diff --git a/app/module/popup_news_content_images/controller/popup_news_content_images.controller.go b/app/module/popup_news_content_images/controller/popup_news_content_images.controller.go new file mode 100644 index 0000000..c848450 --- /dev/null +++ b/app/module/popup_news_content_images/controller/popup_news_content_images.controller.go @@ -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"}, + }) +} \ No newline at end of file diff --git a/app/module/popup_news_content_images/mapper/popup_news_content_images.mapper.go b/app/module/popup_news_content_images/mapper/popup_news_content_images.mapper.go new file mode 100644 index 0000000..d6e9575 --- /dev/null +++ b/app/module/popup_news_content_images/mapper/popup_news_content_images.mapper.go @@ -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 +} \ No newline at end of file diff --git a/app/module/popup_news_content_images/repository/popup_news_content_images.repository.go b/app/module/popup_news_content_images/repository/popup_news_content_images.repository.go new file mode 100644 index 0000000..04e8c81 --- /dev/null +++ b/app/module/popup_news_content_images/repository/popup_news_content_images.repository.go @@ -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 +} \ No newline at end of file diff --git a/app/module/popup_news_content_images/request/popup_news_content_images.request.go b/app/module/popup_news_content_images/request/popup_news_content_images.request.go new file mode 100644 index 0000000..48787bc --- /dev/null +++ b/app/module/popup_news_content_images/request/popup_news_content_images.request.go @@ -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, + } +} \ No newline at end of file diff --git a/app/module/popup_news_content_images/response/popup_news_content_images.response.go b/app/module/popup_news_content_images/response/popup_news_content_images.response.go new file mode 100644 index 0000000..e94596e --- /dev/null +++ b/app/module/popup_news_content_images/response/popup_news_content_images.response.go @@ -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"` +} \ No newline at end of file diff --git a/app/module/popup_news_content_images/service/popup_news_content_images.go b/app/module/popup_news_content_images/service/popup_news_content_images.go new file mode 100644 index 0000000..2629a5a --- /dev/null +++ b/app/module/popup_news_content_images/service/popup_news_content_images.go @@ -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) +} \ No newline at end of file diff --git a/app/module/popup_news_contents/controller/controller.go b/app/module/popup_news_contents/controller/controller.go new file mode 100644 index 0000000..d964bb9 --- /dev/null +++ b/app/module/popup_news_contents/controller/controller.go @@ -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), + } +} \ No newline at end of file diff --git a/app/module/popup_news_contents/controller/popup_news_contents.controller.go b/app/module/popup_news_contents/controller/popup_news_contents.controller.go new file mode 100644 index 0000000..fd5bc68 --- /dev/null +++ b/app/module/popup_news_contents/controller/popup_news_contents.controller.go @@ -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"}, + }) +} \ No newline at end of file diff --git a/app/module/popup_news_contents/mapper/popup_news_contents.mapper.go b/app/module/popup_news_contents/mapper/popup_news_contents.mapper.go new file mode 100644 index 0000000..e4455d8 --- /dev/null +++ b/app/module/popup_news_contents/mapper/popup_news_contents.mapper.go @@ -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 +} \ No newline at end of file diff --git a/app/module/popup_news_contents/repository/popup_news_contents.repository.go b/app/module/popup_news_contents/repository/popup_news_contents.repository.go new file mode 100644 index 0000000..eb7078d --- /dev/null +++ b/app/module/popup_news_contents/repository/popup_news_contents.repository.go @@ -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 +} \ No newline at end of file diff --git a/app/module/popup_news_contents/request/popup_news_contents.request.go b/app/module/popup_news_contents/request/popup_news_contents.request.go new file mode 100644 index 0000000..5d87603 --- /dev/null +++ b/app/module/popup_news_contents/request/popup_news_contents.request.go @@ -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, + } +} \ No newline at end of file diff --git a/app/module/popup_news_contents/response/popup_news_contents.response.go b/app/module/popup_news_contents/response/popup_news_contents.response.go new file mode 100644 index 0000000..98b1371 --- /dev/null +++ b/app/module/popup_news_contents/response/popup_news_contents.response.go @@ -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"` +} \ No newline at end of file diff --git a/app/module/popup_news_contents/service/popup_news_contents.service.go b/app/module/popup_news_contents/service/popup_news_contents.service.go new file mode 100644 index 0000000..b8636f3 --- /dev/null +++ b/app/module/popup_news_contents/service/popup_news_contents.service.go @@ -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) +} \ No newline at end of file diff --git a/app/router/api.go b/app/router/api.go index b507254..c425d3f 100644 --- a/app/router/api.go +++ b/app/router/api.go @@ -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() diff --git a/docs/docs.go b/docs/docs.go index 55cf511..36fe5be 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -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": [ diff --git a/docs/swagger.json b/docs/swagger.json index 0cac129..3e415bd 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -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": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 66f49a1..961af6b 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -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 diff --git a/docs/swagger/docs.go b/docs/swagger/docs.go index 1785e94..1c7ffd8 100644 --- a/docs/swagger/docs.go +++ b/docs/swagger/docs.go @@ -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": [ diff --git a/docs/swagger/swagger.json b/docs/swagger/swagger.json index e1123e3..00b1c37 100644 --- a/docs/swagger/swagger.json +++ b/docs/swagger/swagger.json @@ -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": [ { diff --git a/main.go b/main.go index 133e306..1e71b49 100644 --- a/main.go +++ b/main.go @@ -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, diff --git a/utils/file/upload.go b/utils/file/upload.go new file mode 100644 index 0000000..98328e9 --- /dev/null +++ b/utils/file/upload.go @@ -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 +} \ No newline at end of file