620 lines
18 KiB
Go
620 lines
18 KiB
Go
package controllers
|
||
|
||
import (
|
||
dbConfig "ares/database/config"
|
||
"ares/database/models"
|
||
utils "ares/pkg/utis"
|
||
"ares/services"
|
||
"math"
|
||
"strconv"
|
||
|
||
"github.com/gofiber/fiber/v3"
|
||
)
|
||
|
||
// AdminContentProducts renders the products partial
|
||
func AdminContentProducts(c fiber.Ctx) error {
|
||
page, _ := strconv.Atoi(c.Query("page", "1"))
|
||
limit := 20
|
||
offset := (page - 1) * limit
|
||
search := c.Query("search", "")
|
||
showDeleted := c.Query("deleted") == "true"
|
||
|
||
var products []models.Product
|
||
var total int64
|
||
|
||
query := dbConfig.DB.Model(&models.Product{})
|
||
if showDeleted {
|
||
query = query.Unscoped().Where("deleted_at IS NOT NULL")
|
||
}
|
||
if search != "" {
|
||
query = query.Where("title LIKE ? OR slug LIKE ?", "%"+search+"%", "%"+search+"%")
|
||
}
|
||
query.Count(&total)
|
||
query.Preload("Categories").Preload("Tags").Order("created_at desc").Limit(limit).Offset(offset).Find(&products)
|
||
|
||
imageMap := make(map[uint]string)
|
||
for _, p := range products {
|
||
if p.Images != "" {
|
||
imgs := parseImagesField(p.Images)
|
||
if len(imgs) > 0 {
|
||
imageMap[p.ID] = imgs[0]
|
||
}
|
||
}
|
||
}
|
||
|
||
totalPages := int(math.Ceil(float64(total) / float64(limit)))
|
||
|
||
data := fiber.Map{
|
||
"Products": products,
|
||
"ImageMap": imageMap,
|
||
"Page": page,
|
||
"TotalPages": totalPages,
|
||
"NextPage": page + 1,
|
||
"PrevPage": page - 1,
|
||
"Search": search,
|
||
"ShowDeleted": showDeleted,
|
||
}
|
||
|
||
if c.Get("HX-Request") == "true" {
|
||
return c.Render("admin/partials/products", data)
|
||
}
|
||
return c.Render("admin/partials/products", data, "admin/layout")
|
||
}
|
||
|
||
// AdminProductNew renders create form
|
||
func AdminProductNew(c fiber.Ctx) error {
|
||
var cats []models.ProductCategory
|
||
var tags []models.ProductTag
|
||
dbConfig.DB.Order("title asc").Find(&cats)
|
||
dbConfig.DB.Order("name asc").Find(&tags)
|
||
return c.Render("admin/pages/product_form", fiber.Map{"IsEdit": false, "Categories": cats, "Tags": tags, "FirstImage": ""}, "admin/layout")
|
||
}
|
||
|
||
// AdminProductCreate handles creation
|
||
func AdminProductCreate(c fiber.Ctx) error {
|
||
title := c.FormValue("title")
|
||
if title == "" {
|
||
return c.Redirect().To("/admin/content/products?error=Başlık+gerekli")
|
||
}
|
||
product := models.Product{Title: title}
|
||
product.Content = c.FormValue("content")
|
||
|
||
// Slug handling
|
||
rawSlug := c.FormValue("slug")
|
||
if rawSlug == "" {
|
||
rawSlug = utils.Slugify(product.Title)
|
||
} else {
|
||
rawSlug = utils.Slugify(rawSlug)
|
||
}
|
||
attempt := rawSlug
|
||
i := 1
|
||
for {
|
||
var existing models.Product
|
||
err := dbConfig.DB.Unscoped().Where("slug = ?", attempt).First(&existing).Error
|
||
if err != nil {
|
||
break
|
||
}
|
||
attempt = rawSlug + "-" + strconv.Itoa(i)
|
||
i++
|
||
}
|
||
product.Slug = attempt
|
||
|
||
// Image Upload
|
||
priceStr := c.FormValue("price")
|
||
price, _ := strconv.ParseFloat(priceStr, 64)
|
||
width, _ := strconv.Atoi(c.FormValue("width"))
|
||
height, _ := strconv.Atoi(c.FormValue("height"))
|
||
quality, _ := strconv.Atoi(c.FormValue("quality"))
|
||
format := c.FormValue("format")
|
||
if format == "" {
|
||
format = "avif"
|
||
}
|
||
// DB fields
|
||
product.Price = price
|
||
product.Format = format
|
||
product.Width = width
|
||
product.Height = height
|
||
product.Quality = quality
|
||
|
||
// Use processAndSaveImage for main product image (for simplicity we store 1 image mapped as JSON array or just single string per parseImagesField)
|
||
imagePath, err := services.ProcessAndSaveImage(c, "image", services.ImageOptions{
|
||
Width: width,
|
||
Height: height,
|
||
Quality: quality,
|
||
Format: format,
|
||
Folder: "products",
|
||
})
|
||
if err == nil && imagePath != "" {
|
||
// Tek resim olarak string kaydet
|
||
product.Images = imagePath
|
||
}
|
||
|
||
if err := dbConfig.DB.Create(&product).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/products?error=Oluşturma+başarısız")
|
||
}
|
||
|
||
// Handline Relations (Categories & Tags)
|
||
form, err := c.MultipartForm()
|
||
|
||
if err == nil && form != nil {
|
||
catIDs := form.Value["categories"]
|
||
for _, catIDStr := range catIDs {
|
||
catID, _ := strconv.Atoi(catIDStr)
|
||
if catID > 0 {
|
||
var cat models.ProductCategory
|
||
if err := dbConfig.DB.First(&cat, catID).Error; err == nil {
|
||
dbConfig.DB.Model(&product).Association("Categories").Append(&cat)
|
||
}
|
||
}
|
||
}
|
||
|
||
tagIDs := form.Value["tags"]
|
||
for _, tagIDStr := range tagIDs {
|
||
tagID, _ := strconv.Atoi(tagIDStr)
|
||
if tagID > 0 {
|
||
var tag models.ProductTag
|
||
if err := dbConfig.DB.First(&tag, tagID).Error; err == nil {
|
||
dbConfig.DB.Model(&product).Association("Tags").Append(&tag)
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
// if form data is not multipart, try basic FormValue array
|
||
// Though Fiber usually parses multiple values when we get them explicitly or we can just parse the body
|
||
}
|
||
|
||
return c.Redirect().To("/admin/content/products?success=Ürün+oluşturuldu")
|
||
}
|
||
|
||
// AdminProductEdit renders the edit hero form
|
||
func AdminProductEdit(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
var product models.Product
|
||
if err := dbConfig.DB.Preload("Categories").Preload("Tags").First(&product, id).Error; err != nil {
|
||
return c.Status(fiber.StatusNotFound).SendString("Ürün bulunamadı")
|
||
}
|
||
|
||
var cats []models.ProductCategory
|
||
var tags []models.ProductTag
|
||
dbConfig.DB.Order("title asc").Find(&cats)
|
||
dbConfig.DB.Order("name asc").Find(&tags)
|
||
|
||
firstImage := ""
|
||
if product.Images != "" {
|
||
imgs := parseImagesField(product.Images)
|
||
if len(imgs) > 0 {
|
||
firstImage = imgs[0]
|
||
}
|
||
}
|
||
|
||
return c.Render("admin/pages/product_form", fiber.Map{
|
||
"IsEdit": true,
|
||
"Product": product,
|
||
"Categories": cats,
|
||
"Tags": tags,
|
||
"FirstImage": firstImage,
|
||
}, "admin/layout")
|
||
}
|
||
|
||
// AdminProductUpdate handles product update
|
||
func AdminProductUpdate(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
var product models.Product
|
||
if err := dbConfig.DB.First(&product, id).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/products?error=Ürün+bulunamadı")
|
||
}
|
||
|
||
product.Title = c.FormValue("title")
|
||
product.Content = c.FormValue("content")
|
||
|
||
// Slug update
|
||
rawSlug := c.FormValue("slug")
|
||
if rawSlug != "" && rawSlug != product.Slug {
|
||
rawSlug = utils.Slugify(rawSlug)
|
||
attempt := rawSlug
|
||
i := 1
|
||
for {
|
||
var existing models.Product
|
||
err := dbConfig.DB.Unscoped().Where("slug = ? AND id != ?", attempt, product.ID).First(&existing).Error
|
||
if err != nil {
|
||
break
|
||
}
|
||
attempt = rawSlug + "-" + strconv.Itoa(i)
|
||
i++
|
||
}
|
||
product.Slug = attempt
|
||
}
|
||
|
||
// Image Upload
|
||
priceStr := c.FormValue("price")
|
||
price, _ := strconv.ParseFloat(priceStr, 64)
|
||
width, _ := strconv.Atoi(c.FormValue("width"))
|
||
height, _ := strconv.Atoi(c.FormValue("height"))
|
||
quality, _ := strconv.Atoi(c.FormValue("quality"))
|
||
format := c.FormValue("format")
|
||
if format == "" {
|
||
format = "avif"
|
||
}
|
||
// DB fields
|
||
product.Price = price
|
||
product.Format = format
|
||
product.Width = width
|
||
product.Height = height
|
||
product.Quality = quality
|
||
|
||
imagePath, err := services.ProcessAndSaveImage(c, "image", services.ImageOptions{
|
||
Width: width,
|
||
Height: height,
|
||
Quality: quality,
|
||
Format: format,
|
||
Folder: "products",
|
||
})
|
||
if err == nil && imagePath != "" {
|
||
product.Images = imagePath
|
||
}
|
||
|
||
if err := dbConfig.DB.Save(&product).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/products?error=Güncelleme+başarısız")
|
||
}
|
||
|
||
// Handline Relations (Categories & Tags)
|
||
dbConfig.DB.Model(&product).Association("Categories").Clear()
|
||
dbConfig.DB.Model(&product).Association("Tags").Clear()
|
||
|
||
form, err := c.MultipartForm()
|
||
|
||
if err == nil && form != nil {
|
||
catIDs := form.Value["categories"]
|
||
for _, catIDStr := range catIDs {
|
||
catID, _ := strconv.Atoi(catIDStr)
|
||
if catID > 0 {
|
||
var cat models.ProductCategory
|
||
if err := dbConfig.DB.First(&cat, catID).Error; err == nil {
|
||
dbConfig.DB.Model(&product).Association("Categories").Append(&cat)
|
||
}
|
||
}
|
||
}
|
||
|
||
tagIDs := form.Value["tags"]
|
||
for _, tagIDStr := range tagIDs {
|
||
tagID, _ := strconv.Atoi(tagIDStr)
|
||
if tagID > 0 {
|
||
var tag models.ProductTag
|
||
if err := dbConfig.DB.First(&tag, tagID).Error; err == nil {
|
||
dbConfig.DB.Model(&product).Association("Tags").Append(&tag)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return c.Redirect().To("/admin/content/products?success=Ürün+güncellendi")
|
||
}
|
||
|
||
// AdminProductDelete handles soft delete
|
||
func AdminProductDelete(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
if err := dbConfig.DB.Delete(&models.Product{}, id).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/products?error=Silme+hatası")
|
||
}
|
||
return c.Redirect().To("/admin/content/products?success=Ürün+silindi")
|
||
}
|
||
|
||
// AdminProductRestore handles restore
|
||
func AdminProductRestore(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
if err := dbConfig.DB.Unscoped().Model(&models.Product{}).Where("id = ?", id).Update("deleted_at", nil).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/products?error=Geri+yükleme+hatası")
|
||
}
|
||
return c.Redirect().To("/admin/content/products?deleted=true&success=Ürün+geri+yüklendi")
|
||
}
|
||
|
||
// --- ProductCategory Management ---
|
||
|
||
func AdminContentProductCategories(c fiber.Ctx) error {
|
||
var categories []models.ProductCategory
|
||
showDeleted := c.Query("deleted") == "true"
|
||
query := dbConfig.DB.Model(&models.ProductCategory{})
|
||
if showDeleted {
|
||
query = query.Unscoped().Where("deleted_at IS NOT NULL")
|
||
}
|
||
query.Preload("Parent").Order("title asc").Find(&categories)
|
||
|
||
data := fiber.Map{
|
||
"Categories": categories,
|
||
"ShowDeleted": showDeleted,
|
||
}
|
||
|
||
if c.Get("HX-Request") == "true" {
|
||
return c.Render("admin/partials/product_categories", data)
|
||
}
|
||
return c.Render("admin/partials/product_categories", data, "admin/layout")
|
||
}
|
||
|
||
func AdminProductCategoryNew(c fiber.Ctx) error {
|
||
var parents []models.ProductCategory
|
||
dbConfig.DB.Order("title asc").Find(&parents)
|
||
return c.Render("admin/pages/product_category_form", fiber.Map{
|
||
"IsEdit": false,
|
||
"Parents": parents,
|
||
}, "admin/layout")
|
||
}
|
||
|
||
func AdminProductCategoryCreate(c fiber.Ctx) error {
|
||
cat := new(models.ProductCategory)
|
||
if err := c.Bind().Body(cat); err != nil {
|
||
return c.Redirect().To("/admin/content/product-categories?error=Geçersiz+istek")
|
||
}
|
||
|
||
if cat.Title == "" {
|
||
return c.Redirect().To("/admin/content/product-categories?error=Başlık+zorunlu")
|
||
}
|
||
|
||
rawSlug := c.FormValue("slug")
|
||
if rawSlug == "" {
|
||
rawSlug = utils.Slugify(cat.Title)
|
||
} else {
|
||
rawSlug = utils.Slugify(rawSlug)
|
||
}
|
||
|
||
attempt := rawSlug
|
||
i := 1
|
||
for {
|
||
var existing models.ProductCategory
|
||
err := dbConfig.DB.Unscoped().Where("slug = ?", attempt).First(&existing).Error
|
||
if err != nil {
|
||
break
|
||
}
|
||
attempt = rawSlug + "-" + strconv.Itoa(i)
|
||
i++
|
||
}
|
||
cat.Slug = attempt
|
||
|
||
// Handle ParentID
|
||
parentIDStr := c.FormValue("parent_id")
|
||
if parentIDStr != "" {
|
||
if pid, err := strconv.ParseUint(parentIDStr, 10, 32); err == nil && pid > 0 {
|
||
pidUint := uint(pid)
|
||
cat.ParentID = &pidUint
|
||
}
|
||
} else {
|
||
cat.ParentID = nil
|
||
}
|
||
|
||
if err := dbConfig.DB.Create(cat).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-categories?error=Oluşturma+başarısız")
|
||
}
|
||
return c.Redirect().To("/admin/content/product-categories?success=Kategori+oluşturuldu")
|
||
}
|
||
|
||
func AdminProductCategoryEdit(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
var cat models.ProductCategory
|
||
if err := dbConfig.DB.First(&cat, id).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-categories?error=Kategori+bulunamadı")
|
||
}
|
||
|
||
var parents []models.ProductCategory
|
||
dbConfig.DB.Where("id != ?", id).Order("title asc").Find(&parents)
|
||
|
||
return c.Render("admin/pages/product_category_form", fiber.Map{
|
||
"IsEdit": true,
|
||
"Category": cat,
|
||
"Parents": parents,
|
||
}, "admin/layout")
|
||
}
|
||
|
||
func AdminProductCategoryUpdate(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
var cat models.ProductCategory
|
||
if err := dbConfig.DB.First(&cat, id).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-categories?error=Kategori+bulunamadı")
|
||
}
|
||
|
||
cat.Title = c.FormValue("title")
|
||
cat.Description = c.FormValue("description")
|
||
cat.Keywords = c.FormValue("keywords")
|
||
|
||
rawSlug := c.FormValue("slug")
|
||
if rawSlug != "" && rawSlug != cat.Slug {
|
||
rawSlug = utils.Slugify(rawSlug)
|
||
attempt := rawSlug
|
||
i := 1
|
||
for {
|
||
var existing models.ProductCategory
|
||
err := dbConfig.DB.Unscoped().Where("slug = ? AND id != ?", attempt, cat.ID).First(&existing).Error
|
||
if err != nil {
|
||
break
|
||
}
|
||
attempt = rawSlug + "-" + strconv.Itoa(i)
|
||
i++
|
||
}
|
||
cat.Slug = attempt
|
||
}
|
||
|
||
parentIDStr := c.FormValue("parent_id")
|
||
if parentIDStr != "" {
|
||
if pid, err := strconv.ParseUint(parentIDStr, 10, 32); err == nil && pid > 0 {
|
||
pidUint := uint(pid)
|
||
if pidUint != cat.ID {
|
||
cat.ParentID = &pidUint
|
||
}
|
||
}
|
||
} else {
|
||
cat.ParentID = nil
|
||
}
|
||
|
||
if err := dbConfig.DB.Save(&cat).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-categories?error=Güncelleme+başarısız")
|
||
}
|
||
return c.Redirect().To("/admin/content/product-categories?success=Kategori+güncellendi")
|
||
}
|
||
|
||
func AdminProductCategoryDelete(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
if err := dbConfig.DB.Delete(&models.ProductCategory{}, id).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-categories?error=Silme+başarısız")
|
||
}
|
||
return c.Redirect().To("/admin/content/product-categories?success=Kategori+silindi")
|
||
}
|
||
|
||
func AdminProductCategoryRestore(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
if err := dbConfig.DB.Unscoped().Model(&models.ProductCategory{}).Where("id = ?", id).Update("deleted_at", nil).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-categories?error=Geri+yükleme+başarısız")
|
||
}
|
||
return c.Redirect().To("/admin/content/product-categories?deleted=true&success=Kategori+geri+yüklendi")
|
||
}
|
||
|
||
// --- ProductTag Management ---
|
||
|
||
func AdminContentProductTags(c fiber.Ctx) error {
|
||
var tags []models.ProductTag
|
||
showDeleted := c.Query("deleted") == "true"
|
||
query := dbConfig.DB.Model(&models.ProductTag{})
|
||
if showDeleted {
|
||
query = query.Unscoped().Where("deleted_at IS NOT NULL")
|
||
}
|
||
query.Order("name asc").Find(&tags)
|
||
|
||
data := fiber.Map{
|
||
"Tags": tags,
|
||
"ShowDeleted": showDeleted,
|
||
}
|
||
|
||
if c.Get("HX-Request") == "true" {
|
||
return c.Render("admin/partials/product_tags", data)
|
||
}
|
||
return c.Render("admin/partials/product_tags", data, "admin/layout")
|
||
}
|
||
|
||
func AdminProductTagNew(c fiber.Ctx) error {
|
||
return c.Render("admin/pages/product_tag_form", fiber.Map{
|
||
"IsEdit": false,
|
||
}, "admin/layout")
|
||
}
|
||
|
||
func AdminProductTagCreate(c fiber.Ctx) error {
|
||
tag := new(models.ProductTag)
|
||
if err := c.Bind().Body(tag); err != nil {
|
||
return c.Redirect().To("/admin/content/product-tags?error=Geçersiz+istek")
|
||
}
|
||
if tag.Name == "" {
|
||
return c.Redirect().To("/admin/content/product-tags?error=İsim+zorunlu")
|
||
}
|
||
if err := dbConfig.DB.Create(tag).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-tags?error=Oluşturma+başarısız")
|
||
}
|
||
return c.Redirect().To("/admin/content/product-tags?success=Etiket+oluşturuldu")
|
||
}
|
||
|
||
func AdminProductTagEdit(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
var tag models.ProductTag
|
||
if err := dbConfig.DB.First(&tag, id).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-tags?error=Etiket+bulunamadı")
|
||
}
|
||
return c.Render("admin/pages/product_tag_form", fiber.Map{
|
||
"IsEdit": true,
|
||
"Tag": tag,
|
||
}, "admin/layout")
|
||
}
|
||
|
||
func AdminProductTagUpdate(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
var tag models.ProductTag
|
||
if err := dbConfig.DB.First(&tag, id).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-tags?error=Etiket+bulunamadı")
|
||
}
|
||
|
||
tag.Name = c.FormValue("name")
|
||
|
||
if err := dbConfig.DB.Save(&tag).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-tags?error=Güncelleme+başarısız")
|
||
}
|
||
return c.Redirect().To("/admin/content/product-tags?success=Etiket+güncellendi")
|
||
}
|
||
|
||
func AdminProductTagDelete(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
if err := dbConfig.DB.Delete(&models.ProductTag{}, id).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-tags?error=Silme+başarısız")
|
||
}
|
||
return c.Redirect().To("/admin/content/product-tags?success=Etiket+silindi")
|
||
}
|
||
|
||
func AdminProductTagRestore(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
if err := dbConfig.DB.Unscoped().Model(&models.ProductTag{}).Where("id = ?", id).Update("deleted_at", nil).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-tags?error=Geri+yükleme+başarısız")
|
||
}
|
||
return c.Redirect().To("/admin/content/product-tags?deleted=true&success=Etiket+geri+yüklendi")
|
||
}
|
||
|
||
// AdminContentProductComments handles rendering the Product Comments list in the admin panel
|
||
func AdminContentProductComments(c fiber.Ctx) error {
|
||
var comments []models.ProductComment
|
||
|
||
// Preload the User and Product for display (Wait, user and product relationships are missing in model temporarily)
|
||
// We'll just list them out manually
|
||
query := dbConfig.DB.Model(&models.ProductComment{})
|
||
|
||
// Optional filtering by specific product via query string
|
||
productID := c.Query("product_id")
|
||
if productID != "" {
|
||
if pid, err := strconv.Atoi(productID); err == nil {
|
||
query = query.Where("product_id = ?", pid)
|
||
}
|
||
}
|
||
|
||
query.Order("created_at desc").Find(&comments)
|
||
|
||
data := fiber.Map{
|
||
"ProductComments": comments,
|
||
"ProductID": productID,
|
||
}
|
||
|
||
if c.Get("HX-Request") == "true" {
|
||
return c.Render("admin/partials/product_comments", data)
|
||
}
|
||
|
||
return c.Render("admin/partials/product_comments", data, "admin/layout")
|
||
}
|
||
|
||
// AdminProductCommentDelete handles hard deleting a product comment
|
||
func AdminProductCommentDelete(c fiber.Ctx) error {
|
||
id := c.Params("id")
|
||
if err := dbConfig.DB.Unscoped().Where("id = ?", id).Delete(&models.ProductComment{}).Error; err != nil {
|
||
return c.Redirect().To("/admin/content/product-comments?error=Yorum+silinemedi")
|
||
}
|
||
|
||
return c.Redirect().To("/admin/content/product-comments?deleted=true&success=Yorum+silindi")
|
||
}
|
||
|
||
// AdminContentProductCategoryViews handles rendering the Product Category Views list
|
||
func AdminContentProductCategoryViews(c fiber.Ctx) error {
|
||
var views []models.ProductCategoryView
|
||
|
||
query := dbConfig.DB.Model(&models.ProductCategoryView{})
|
||
|
||
// Filter by Category ID
|
||
categoryID := c.Query("category_id")
|
||
if categoryID != "" {
|
||
if cid, err := strconv.Atoi(categoryID); err == nil {
|
||
query = query.Where("category_id = ?", cid)
|
||
}
|
||
}
|
||
|
||
query.Order("created_at desc").Find(&views)
|
||
|
||
data := fiber.Map{
|
||
"Views": views,
|
||
"CategoryID": categoryID,
|
||
}
|
||
|
||
if c.Get("HX-Request") == "true" {
|
||
return c.Render("admin/partials/product_category_views", data)
|
||
}
|
||
|
||
return c.Render("admin/partials/product_category_views", data, "admin/layout")
|
||
}
|