Compare commits
22 Commits
userhandli
...
f4faeb351d
| Author | SHA1 | Date | |
|---|---|---|---|
| f4faeb351d | |||
| 861b18651b | |||
|
5f53d66bc4
|
|||
|
459c873986
|
|||
|
ef2e6c99a7
|
|||
|
e29287c29d
|
|||
| f55470636f | |||
|
8f89c14961
|
|||
|
6f5c0354cc
|
|||
|
6ef7c53001
|
|||
|
d4e7401586
|
|||
|
1688e61ccb
|
|||
|
861343b338
|
|||
|
68c8654bf3
|
|||
|
e62a45372f
|
|||
|
d17c33f6ee
|
|||
|
ae36903e73
|
|||
|
1a5df21fa8
|
|||
|
9c15514758
|
|||
|
27cf7c37cf
|
|||
|
03f1ce361a
|
|||
| c55cf4480b |
317
controllers/configController.go
Normal file
317
controllers/configController.go
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
"git.dynamicdiscord.de/kalipso/zineshop/models"
|
||||||
|
//"git.dynamicdiscord.de/kalipso/zineshop/services"
|
||||||
|
"git.dynamicdiscord.de/kalipso/zineshop/repositories"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ConfigController interface {
|
||||||
|
AddConfigHandler(*gin.Context)
|
||||||
|
ConfigHandler(*gin.Context)
|
||||||
|
ConfigView(*gin.Context)
|
||||||
|
|
||||||
|
GetAllPaper(*gin.Context)
|
||||||
|
PaperView(*gin.Context)
|
||||||
|
PaperHandler(*gin.Context)
|
||||||
|
AddPaperHandler(*gin.Context)
|
||||||
|
|
||||||
|
CreateTag(*gin.Context)
|
||||||
|
GetAllTags(*gin.Context)
|
||||||
|
TagView(*gin.Context)
|
||||||
|
TagHandler(*gin.Context)
|
||||||
|
AddTagHandler(*gin.Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
type configController struct{}
|
||||||
|
|
||||||
|
func NewConfigController() ConfigController {
|
||||||
|
return &configController{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *configController) AddConfigHandler(c *gin.Context) {
|
||||||
|
key := c.PostForm("key")
|
||||||
|
value := c.PostForm("value")
|
||||||
|
|
||||||
|
if key == "" || value == "" {
|
||||||
|
err := "Key or Value empty during config creation"
|
||||||
|
fmt.Println(err)
|
||||||
|
c.HTML(http.StatusBadRequest, "configview.html", gin.H{"error": err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
config := models.Config{
|
||||||
|
Key: key,
|
||||||
|
Value: value,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := repositories.ConfigOptions.Create(config)
|
||||||
|
if err != nil {
|
||||||
|
data := CreateSessionData(c, gin.H{
|
||||||
|
"error": err,
|
||||||
|
"success": "",
|
||||||
|
})
|
||||||
|
|
||||||
|
c.HTML(http.StatusOK, "configview.html", data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rc.ConfigView(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *configController) ConfigView(c *gin.Context) {
|
||||||
|
configOptions, err := repositories.ConfigOptions.GetAll()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "configview.html", gin.H{"data": gin.H{"error": err}})
|
||||||
|
}
|
||||||
|
|
||||||
|
data := CreateSessionData(c, gin.H{
|
||||||
|
"configOptions": configOptions,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "configview.html", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.HTML(http.StatusOK, "configview.html", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *configController) ConfigHandler(ctx *gin.Context) {
|
||||||
|
key := ctx.PostForm("key")
|
||||||
|
value := ctx.PostForm("value")
|
||||||
|
action := ctx.PostForm("action")
|
||||||
|
|
||||||
|
config, err := repositories.ConfigOptions.GetById(ctx.Param("id"))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
ctx.HTML(http.StatusBadRequest, "configview.html", gin.H{"error": err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if action == "update" {
|
||||||
|
config.Key = key
|
||||||
|
config.Value = value
|
||||||
|
config, err = repositories.ConfigOptions.Update(config)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
ctx.HTML(http.StatusBadRequest, "configview.html", gin.H{"error": err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if action == "delete" {
|
||||||
|
repositories.ConfigOptions.DeleteById(ctx.Param("id"))
|
||||||
|
}
|
||||||
|
|
||||||
|
rc.ConfigView(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *configController) PaperHandler(ctx *gin.Context) {
|
||||||
|
newPaper, err := models.NewPaper(ctx)
|
||||||
|
action := ctx.PostForm("action")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
ctx.HTML(http.StatusBadRequest, "paperview.html", gin.H{"error": err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
paper, err := repositories.Papers.GetById(ctx.Param("id"))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
ctx.HTML(http.StatusBadRequest, "paperview.html", gin.H{"error": err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if action == "update" {
|
||||||
|
paper.Name = newPaper.Name
|
||||||
|
paper.Brand = newPaper.Brand
|
||||||
|
paper.Size = newPaper.Size
|
||||||
|
paper.Price = newPaper.Price
|
||||||
|
paper, err = repositories.Papers.Update(paper)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
ctx.HTML(http.StatusBadRequest, "paperview.html", gin.H{"error": err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if action == "delete" {
|
||||||
|
repositories.Papers.DeleteById(ctx.Param("id"))
|
||||||
|
}
|
||||||
|
|
||||||
|
rc.PaperView(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *configController) AddPaperHandler(c *gin.Context) {
|
||||||
|
paper, err := models.NewPaper(c)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
c.HTML(http.StatusBadRequest, "paperview.html", gin.H{"error": err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = repositories.Papers.Create(paper)
|
||||||
|
if err != nil {
|
||||||
|
data := CreateSessionData(c, gin.H{
|
||||||
|
"error": err,
|
||||||
|
"success": "",
|
||||||
|
})
|
||||||
|
|
||||||
|
c.HTML(http.StatusOK, "paperview.html", data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rc.PaperView(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *configController) PaperView(c *gin.Context) {
|
||||||
|
papers, err := repositories.Papers.GetAll()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "paperview.html", gin.H{"data": gin.H{"error": err}})
|
||||||
|
}
|
||||||
|
|
||||||
|
data := CreateSessionData(c, gin.H{
|
||||||
|
"paper": papers,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "paperview.html", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.HTML(http.StatusOK, "paperview.html", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *configController) GetAllPaper(c *gin.Context) {
|
||||||
|
papers, err := repositories.Papers.GetAll()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ReplyError(c, fmt.Errorf("Could not query Papers"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, papers)
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
func (rc *configController) TagHandler(ctx *gin.Context) {
|
||||||
|
name := ctx.PostForm("name")
|
||||||
|
color := ctx.PostForm("color")
|
||||||
|
action := ctx.PostForm("action")
|
||||||
|
|
||||||
|
tag, err := repositories.Tags.GetById(ctx.Param("id"))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
ctx.HTML(http.StatusBadRequest, "tagview.html", gin.H{"error": err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if action == "update" {
|
||||||
|
tag.Name = name
|
||||||
|
tag.Color = color
|
||||||
|
tag, err = repositories.Tags.Update(tag)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
ctx.HTML(http.StatusBadRequest, "tagview.html", gin.H{"error": err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if action == "delete" {
|
||||||
|
repositories.Tags.DeleteById(ctx.Param("id"))
|
||||||
|
}
|
||||||
|
|
||||||
|
rc.TagView(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *configController) AddTagHandler(c *gin.Context) {
|
||||||
|
tag, err := models.NewTag(c)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
c.HTML(http.StatusBadRequest, "tagview.html", gin.H{"error": err})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = repositories.Tags.Create(tag)
|
||||||
|
if err != nil {
|
||||||
|
data := CreateSessionData(c, gin.H{
|
||||||
|
"error": err,
|
||||||
|
"success": "",
|
||||||
|
})
|
||||||
|
|
||||||
|
c.HTML(http.StatusOK, "tagview.html", data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rc.TagView(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *configController) TagView(c *gin.Context) {
|
||||||
|
tags, err := repositories.Tags.GetAll()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "tagview.html", gin.H{"data": gin.H{"error": err}})
|
||||||
|
}
|
||||||
|
|
||||||
|
data := CreateSessionData(c, gin.H{
|
||||||
|
"tags": tags,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "tagview.html", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.HTML(http.StatusOK, "tagview.html", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *configController) CreateTag(c *gin.Context) {
|
||||||
|
tag, err := models.NewTagByJson(c)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ReplyError(c, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = repositories.Tags.Create(tag)
|
||||||
|
if err != nil {
|
||||||
|
ReplyError(c, fmt.Errorf("tag creation failed: %s", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//userID := user.(models.User).ID
|
||||||
|
//rc.DB.Model(&models.shopItem{}).Where("id = ?"), room.ID).Association("Admins").Append(&models.User{ID: userID})
|
||||||
|
|
||||||
|
//if result.Error != nil {
|
||||||
|
// ReplyError(c, fmt.Errorf("shopItem creation failed: %s", result.Error))
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
|
||||||
|
ReplyOK(c, fmt.Sprintf("tag '%s' was created", tag.Name))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *configController) GetAllTags(c *gin.Context) {
|
||||||
|
tags, err := repositories.Tags.GetAll()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ReplyError(c, fmt.Errorf("Could not query Tags"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, tags)
|
||||||
|
}
|
||||||
@@ -29,15 +29,10 @@ type ShopItemController interface {
|
|||||||
AddItemHandler(*gin.Context)
|
AddItemHandler(*gin.Context)
|
||||||
AddItemsView(*gin.Context)
|
AddItemsView(*gin.Context)
|
||||||
AddItemsHandler(*gin.Context)
|
AddItemsHandler(*gin.Context)
|
||||||
CreateTag(*gin.Context)
|
|
||||||
GetAllTags(*gin.Context)
|
|
||||||
EditItemView(*gin.Context)
|
EditItemView(*gin.Context)
|
||||||
EditItemHandler(*gin.Context)
|
EditItemHandler(*gin.Context)
|
||||||
DeleteItemView(*gin.Context)
|
DeleteItemView(*gin.Context)
|
||||||
DeleteItemHandler(*gin.Context)
|
DeleteItemHandler(*gin.Context)
|
||||||
TagView(*gin.Context)
|
|
||||||
TagHandler(*gin.Context)
|
|
||||||
AddTagHandler(*gin.Context)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type shopItemController struct{}
|
type shopItemController struct{}
|
||||||
@@ -68,6 +63,9 @@ func (rc *shopItemController) GetById(c *gin.Context) {
|
|||||||
ReplyOK(c, shopItem)
|
ReplyOK(c, shopItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this currently creates quite big preview images
|
||||||
|
// workaround is running the following command in the uploads folder:
|
||||||
|
// for file in *.png; do convert "$file" -resize 35% "$file"; done
|
||||||
func (rc *shopItemController) NewShopItemFromForm(ctx *gin.Context) (models.ShopItem, error) {
|
func (rc *shopItemController) NewShopItemFromForm(ctx *gin.Context) (models.ShopItem, error) {
|
||||||
defaultImagePath := "static/img/zine.jpg"
|
defaultImagePath := "static/img/zine.jpg"
|
||||||
name := ctx.PostForm("name")
|
name := ctx.PostForm("name")
|
||||||
@@ -106,6 +104,14 @@ func (rc *shopItemController) NewShopItemFromForm(ctx *gin.Context) (models.Shop
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error during pdftoppm: ", err.Error())
|
fmt.Println("Error during pdftoppm: ", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd2 := exec.Command("convert", dstImage, "-resize", "35%", dstImage)
|
||||||
|
_, err = cmd2.Output()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error during resizing preview image: ", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
@@ -249,14 +255,16 @@ func (rc *shopItemController) ShopItemView(c *gin.Context) {
|
|||||||
shopItem, err := repositories.ShopItems.GetById(c.Param("id"))
|
shopItem, err := repositories.ShopItems.GetById(c.Param("id"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HTML(http.StatusBadRequest, "shopitem.html", gin.H{"data": gin.H{"error": err}})
|
c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": "Item does not exist"}})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: get tags by item
|
//TODO: get tags by item
|
||||||
tags, err := repositories.Tags.GetAll()
|
tags, err := repositories.Tags.GetAll()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HTML(http.StatusBadRequest, "shopitem.html", gin.H{"data": gin.H{"error": err}})
|
c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data := CreateSessionData(c, gin.H{
|
data := CreateSessionData(c, gin.H{
|
||||||
@@ -264,10 +272,6 @@ func (rc *shopItemController) ShopItemView(c *gin.Context) {
|
|||||||
"tags": tags,
|
"tags": tags,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
c.HTML(http.StatusBadRequest, "shopitem.html", data)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "shopitem.html", data)
|
c.HTML(http.StatusOK, "shopitem.html", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,6 +369,13 @@ func (rc *shopItemController) AddItemsHandler(c *gin.Context) {
|
|||||||
fmt.Println("Error during pdftoppm: ", err.Error())
|
fmt.Println("Error during pdftoppm: ", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd2 := exec.Command("convert", dstImage, "-resize", "35%", dstImage)
|
||||||
|
_, err = cmd2.Output()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error during resizing preview image: ", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
category, err := models.ParseCategory("Zine")
|
category, err := models.ParseCategory("Zine")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorHandler(err)
|
errorHandler(err)
|
||||||
@@ -414,23 +425,93 @@ func (rc *shopItemController) AddItemsHandler(c *gin.Context) {
|
|||||||
c.HTML(http.StatusOK, "batchupload.html", data)
|
c.HTML(http.StatusOK, "batchupload.html", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *shopItemController) EditItemView(c *gin.Context) {
|
func GetCheckedTags(item models.ShopItem) ([]models.CheckedTag, error) {
|
||||||
shopItem, err := repositories.ShopItems.GetById(c.Param("id"))
|
allTags, err := repositories.Tags.GetAll()
|
||||||
tags, err := repositories.Tags.GetAll()
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HTML(http.StatusBadRequest, "edititem.html", gin.H{"error": err})
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(shopItem)
|
var tags []models.CheckedTag
|
||||||
|
for _, tag := range allTags {
|
||||||
|
tmpTag := models.CheckedTag{
|
||||||
|
Tag: tag,
|
||||||
|
Checked: "",
|
||||||
|
}
|
||||||
|
|
||||||
data := CreateSessionData(c, gin.H{
|
for _, itemTag := range item.Tags {
|
||||||
"error": "",
|
if itemTag.Name == tmpTag.Name {
|
||||||
"success": "",
|
tmpTag.Checked = "checked"
|
||||||
"shopItem": shopItem,
|
break
|
||||||
"tags": tags,
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
tags = append(tags, tmpTag)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *shopItemController) getEditTemplatData(shopItem models.ShopItem) (gin.H, error) {
|
||||||
|
tags, err := GetCheckedTags(shopItem)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return gin.H{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
priceBW := ""
|
||||||
|
priceColored := ""
|
||||||
|
for _, variant := range shopItem.Variants {
|
||||||
|
if variant.Name == "B/W" {
|
||||||
|
priceBW = fmt.Sprintf("%.2f", variant.Price)
|
||||||
|
}
|
||||||
|
|
||||||
|
if variant.Name == "Colored" {
|
||||||
|
priceColored = fmt.Sprintf("%.2f", variant.Price)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
templateData := gin.H{
|
||||||
|
"error": "",
|
||||||
|
"success": "",
|
||||||
|
"shopItem": shopItem,
|
||||||
|
"tags": tags,
|
||||||
|
"priceBW": priceBW,
|
||||||
|
"priceColored": priceColored,
|
||||||
|
}
|
||||||
|
|
||||||
|
id := fmt.Sprintf("%d", shopItem.ID)
|
||||||
|
nextShopItem, err := repositories.ShopItems.GetNextOfId(id)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
fmt.Println("Setting nextitem")
|
||||||
|
fmt.Println(nextShopItem)
|
||||||
|
templateData["nextShopItem"] = nextShopItem
|
||||||
|
}
|
||||||
|
|
||||||
|
previousShopItem, err := repositories.ShopItems.GetPreviousOfId(id)
|
||||||
|
if err == nil {
|
||||||
|
templateData["previousShopItem"] = previousShopItem
|
||||||
|
}
|
||||||
|
|
||||||
|
return templateData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *shopItemController) EditItemView(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
shopItem, err := repositories.ShopItems.GetById(id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "error.html", gin.H{"error": err})
|
||||||
|
}
|
||||||
|
|
||||||
|
templateData, err := rc.getEditTemplatData(shopItem)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "error.html", gin.H{"error": err})
|
||||||
|
}
|
||||||
|
|
||||||
|
data := CreateSessionData(c, templateData)
|
||||||
c.HTML(http.StatusOK, "edititem.html", data)
|
c.HTML(http.StatusOK, "edititem.html", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,30 +552,22 @@ func (rc *shopItemController) EditItemHandler(c *gin.Context) {
|
|||||||
|
|
||||||
newShopItem.PrintMode = shopItem.PrintMode
|
newShopItem.PrintMode = shopItem.PrintMode
|
||||||
|
|
||||||
tags, err := repositories.Tags.GetAll()
|
templateData, err := rc.getEditTemplatData(newShopItem)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.HTML(http.StatusBadRequest, "edititem.html", gin.H{"error": err})
|
c.HTML(http.StatusBadRequest, "error.html", gin.H{"error": err})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = repositories.ShopItems.Update(newShopItem)
|
_, err = repositories.ShopItems.Update(newShopItem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
data := CreateSessionData(c, gin.H{
|
templateData["error"] = err
|
||||||
"error": err,
|
data := CreateSessionData(c, templateData)
|
||||||
"success": "",
|
|
||||||
"tags": tags,
|
|
||||||
})
|
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "edititem.html", data)
|
c.HTML(http.StatusOK, "edititem.html", data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data := CreateSessionData(c, gin.H{
|
templateData["success"] = fmt.Sprintf("Item '%s' Updated", newShopItem.Name)
|
||||||
"error": "",
|
data := CreateSessionData(c, templateData)
|
||||||
"success": fmt.Sprintf("Item '%s' Updated", newShopItem.Name),
|
|
||||||
"tags": tags,
|
|
||||||
})
|
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "edititem.html", data)
|
c.HTML(http.StatusOK, "edititem.html", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,115 +616,6 @@ func (rc *shopItemController) DeleteItemHandler(c *gin.Context) {
|
|||||||
c.HTML(http.StatusOK, "index.html", data)
|
c.HTML(http.StatusOK, "index.html", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *shopItemController) TagHandler(ctx *gin.Context) {
|
|
||||||
name := ctx.PostForm("name")
|
|
||||||
color := ctx.PostForm("color")
|
|
||||||
action := ctx.PostForm("action")
|
|
||||||
|
|
||||||
tag, err := repositories.Tags.GetById(ctx.Param("id"))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
ctx.HTML(http.StatusBadRequest, "tagview.html", gin.H{"error": err})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if action == "update" {
|
|
||||||
tag.Name = name
|
|
||||||
tag.Color = color
|
|
||||||
tag, err = repositories.Tags.Update(tag)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
ctx.HTML(http.StatusBadRequest, "tagview.html", gin.H{"error": err})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if action == "delete" {
|
|
||||||
repositories.Tags.DeleteById(ctx.Param("id"))
|
|
||||||
}
|
|
||||||
|
|
||||||
rc.TagView(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *shopItemController) AddTagHandler(c *gin.Context) {
|
|
||||||
tag, err := models.NewTag(c)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
c.HTML(http.StatusBadRequest, "tagview.html", gin.H{"error": err})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = repositories.Tags.Create(tag)
|
|
||||||
if err != nil {
|
|
||||||
data := CreateSessionData(c, gin.H{
|
|
||||||
"error": err,
|
|
||||||
"success": "",
|
|
||||||
})
|
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "tagview.html", data)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
rc.TagView(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *shopItemController) TagView(c *gin.Context) {
|
|
||||||
tags, err := repositories.Tags.GetAll()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
c.HTML(http.StatusBadRequest, "tagview.html", gin.H{"data": gin.H{"error": err}})
|
|
||||||
}
|
|
||||||
|
|
||||||
data := CreateSessionData(c, gin.H{
|
|
||||||
"tags": tags,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
c.HTML(http.StatusBadRequest, "tagview.html", data)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "tagview.html", data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *shopItemController) CreateTag(c *gin.Context) {
|
|
||||||
tag, err := models.NewTagByJson(c)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
ReplyError(c, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = repositories.Tags.Create(tag)
|
|
||||||
if err != nil {
|
|
||||||
ReplyError(c, fmt.Errorf("shopItem creation failed: %s", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//userID := user.(models.User).ID
|
|
||||||
//rc.DB.Model(&models.shopItem{}).Where("id = ?"), room.ID).Association("Admins").Append(&models.User{ID: userID})
|
|
||||||
|
|
||||||
//if result.Error != nil {
|
|
||||||
// ReplyError(c, fmt.Errorf("shopItem creation failed: %s", result.Error))
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
|
|
||||||
ReplyOK(c, fmt.Sprintf("tag '%s' was created", tag.Name))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *shopItemController) GetAllTags(c *gin.Context) {
|
|
||||||
tags, err := repositories.Tags.GetAll()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
ReplyError(c, fmt.Errorf("Could not query Tags"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, tags)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReplyError(ctx *gin.Context, err error) {
|
func ReplyError(ctx *gin.Context, err error) {
|
||||||
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,6 +188,7 @@ func (rc *UserController) RegisterHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.HTML(http.StatusOK, "register.html", data)
|
c.HTML(http.StatusOK, "register.html", data)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenExists, err := repositories.Tokens.Exists(token)
|
tokenExists, err := repositories.Tokens.Exists(token)
|
||||||
@@ -332,8 +333,20 @@ func (rc *UserController) InviteHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (rc *UserController) MainView(c *gin.Context) {
|
func (rc *UserController) MainView(c *gin.Context) {
|
||||||
shopItems, _ := repositories.ShopItems.GetAll()
|
itemOrder := c.Query("order")
|
||||||
fmt.Println(len(shopItems))
|
|
||||||
|
var shopItems []models.ShopItem
|
||||||
|
if itemOrder == "newestFirst" {
|
||||||
|
shopItems, _ = repositories.ShopItems.GetAllNewestFirst()
|
||||||
|
} else if itemOrder == "oldestFirst" {
|
||||||
|
shopItems, _ = repositories.ShopItems.GetAllNewestLast()
|
||||||
|
} else if itemOrder == "az" {
|
||||||
|
shopItems, _ = repositories.ShopItems.GetAllLexicalFirst()
|
||||||
|
} else if itemOrder == "za" {
|
||||||
|
shopItems, _ = repositories.ShopItems.GetAllLexicalLast()
|
||||||
|
} else {
|
||||||
|
shopItems, _ = repositories.ShopItems.GetAllNewestFirst()
|
||||||
|
}
|
||||||
|
|
||||||
data := CreateSessionData(c, gin.H{
|
data := CreateSessionData(c, gin.H{
|
||||||
"title": "shopItem Page",
|
"title": "shopItem Page",
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
go
|
go
|
||||||
gotools
|
gotools
|
||||||
poppler_utils #get first pdf page to png
|
poppler_utils #get first pdf page to png
|
||||||
|
cups
|
||||||
|
imagemagick
|
||||||
tailwindcss
|
tailwindcss
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
@@ -71,6 +73,8 @@
|
|||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
zineshop-pkg
|
zineshop-pkg
|
||||||
pkgs.poppler_utils #get first pdf page to png
|
pkgs.poppler_utils #get first pdf page to png
|
||||||
|
pkgs.cups
|
||||||
|
pkgs.imagemagick
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
@@ -100,7 +104,7 @@
|
|||||||
WorkingDirectory = "/var/lib/zineshop";
|
WorkingDirectory = "/var/lib/zineshop";
|
||||||
ExecStart = pkgs.writeScript "start-zineshop" ''
|
ExecStart = pkgs.writeScript "start-zineshop" ''
|
||||||
#! ${pkgs.bash}/bin/bash
|
#! ${pkgs.bash}/bin/bash
|
||||||
PATH="$PATH:${lib.makeBinPath [ pkgs.poppler_utils ]}"
|
PATH="$PATH:${lib.makeBinPath [ pkgs.poppler_utils pkgs.cups pkgs.imagemagick ]}"
|
||||||
${zineshop-pkg}/bin/zineshop
|
${zineshop-pkg}/bin/zineshop
|
||||||
'';
|
'';
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
|
|||||||
17
main.go
17
main.go
@@ -19,6 +19,7 @@ var (
|
|||||||
userController controllers.UserController = controllers.UserController{}
|
userController controllers.UserController = controllers.UserController{}
|
||||||
cartItemController controllers.CartItemController = controllers.NewCartItemController()
|
cartItemController controllers.CartItemController = controllers.NewCartItemController()
|
||||||
printController controllers.PrintController = controllers.NewPrintController()
|
printController controllers.PrintController = controllers.NewPrintController()
|
||||||
|
configController controllers.ConfigController = controllers.NewConfigController()
|
||||||
authValidator middlewares.AuthValidator = middlewares.AuthValidator{}
|
authValidator middlewares.AuthValidator = middlewares.AuthValidator{}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -67,10 +68,20 @@ func main() {
|
|||||||
viewRoutes.GET("/cart/print", authValidator.RequireAdmin, printController.PrintCartView)
|
viewRoutes.GET("/cart/print", authValidator.RequireAdmin, printController.PrintCartView)
|
||||||
viewRoutes.POST("/print", authValidator.RequireAdmin, printController.PrintHandler)
|
viewRoutes.POST("/print", authValidator.RequireAdmin, printController.PrintHandler)
|
||||||
|
|
||||||
viewRoutes.GET("/tags", authValidator.RequireAdmin, shopItemController.TagView)
|
viewRoutes.GET("/config", authValidator.RequireAdmin, configController.ConfigView)
|
||||||
viewRoutes.POST("/tags/:id", authValidator.RequireAdmin, shopItemController.TagHandler)
|
viewRoutes.POST("/config/:id", authValidator.RequireAdmin, configController.ConfigHandler)
|
||||||
|
viewRoutes.POST("/config", authValidator.RequireAdmin, configController.AddConfigHandler)
|
||||||
|
|
||||||
|
viewRoutes.GET("/tags", authValidator.RequireAdmin, configController.TagView)
|
||||||
|
viewRoutes.POST("/tags/:id", authValidator.RequireAdmin, configController.TagHandler)
|
||||||
viewRoutes.GET("/tags/:id", userController.TagView)
|
viewRoutes.GET("/tags/:id", userController.TagView)
|
||||||
viewRoutes.POST("/tags", authValidator.RequireAdmin, shopItemController.AddTagHandler)
|
viewRoutes.POST("/tags", authValidator.RequireAdmin, configController.AddTagHandler)
|
||||||
|
|
||||||
|
viewRoutes.GET("/paper", authValidator.RequireAdmin, configController.PaperView)
|
||||||
|
viewRoutes.POST("/paper/:id", authValidator.RequireAdmin, configController.PaperHandler)
|
||||||
|
viewRoutes.GET("/paper/:id", userController.TagView)
|
||||||
|
viewRoutes.POST("/paper", authValidator.RequireAdmin, configController.AddPaperHandler)
|
||||||
|
|
||||||
viewRoutes.GET("/cart", authValidator.RequireAuth, cartItemController.CartItemView)
|
viewRoutes.GET("/cart", authValidator.RequireAuth, cartItemController.CartItemView)
|
||||||
viewRoutes.POST("/cart", authValidator.RequireAuth, cartItemController.AddItemHandler)
|
viewRoutes.POST("/cart", authValidator.RequireAuth, cartItemController.AddItemHandler)
|
||||||
viewRoutes.POST("/cart/delete", authValidator.RequireAuth, cartItemController.DeleteItemHandler)
|
viewRoutes.POST("/cart/delete", authValidator.RequireAuth, cartItemController.DeleteItemHandler)
|
||||||
|
|||||||
11
models/config.go
Normal file
11
models/config.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
gorm.Model
|
||||||
|
Key string `json:"key" binding:"required" gorm:"unique;not null"`
|
||||||
|
Value string `json:"value" binding:"required"`
|
||||||
|
}
|
||||||
74
models/paper.go
Normal file
74
models/paper.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PaperSize string
|
||||||
|
|
||||||
|
const (
|
||||||
|
A3 PaperSize = "A3"
|
||||||
|
A4 PaperSize = "A4"
|
||||||
|
A5 PaperSize = "A5"
|
||||||
|
SRA3 PaperSize = "SRA3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ParseSize(s string) (c PaperSize, err error) {
|
||||||
|
s = strings.ToUpper(s)
|
||||||
|
if s == "A3" {
|
||||||
|
return A3, nil
|
||||||
|
} else if s == "A4" {
|
||||||
|
return A4, nil
|
||||||
|
} else if s == "A5" {
|
||||||
|
return A5, nil
|
||||||
|
} else if s == "SRA3" {
|
||||||
|
return SRA3, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, fmt.Errorf("Cannot parse category %s", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Paper struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string `json:"name" binding:"required" gorm:"not null"`
|
||||||
|
Brand string `json:"brand" binding:"required"`
|
||||||
|
Size PaperSize `json:"size" binding:"required"`
|
||||||
|
Price float64 `json:"price" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPaper(ctx *gin.Context) (Paper, error) {
|
||||||
|
name := ctx.PostForm("name")
|
||||||
|
brand := ctx.PostForm("brand")
|
||||||
|
sizeTmp := ctx.PostForm("size")
|
||||||
|
priceTmp := ctx.PostForm("price")
|
||||||
|
|
||||||
|
price, err := strconv.ParseFloat(priceTmp, 64)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return Paper{}, fmt.Errorf("Couldnt parse Price")
|
||||||
|
}
|
||||||
|
|
||||||
|
size, err := ParseSize(sizeTmp)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return Paper{}, fmt.Errorf("Couldnt parse Size")
|
||||||
|
}
|
||||||
|
|
||||||
|
if name == "" || brand == "" {
|
||||||
|
return Paper{}, fmt.Errorf("Name or brand empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the price string to float64
|
||||||
|
tag := Paper{
|
||||||
|
Name: name,
|
||||||
|
Brand: brand,
|
||||||
|
Size: size,
|
||||||
|
Price: price,
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag, nil
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ const (
|
|||||||
LongEdge PrintOption = ""
|
LongEdge PrintOption = ""
|
||||||
ShortEdge PrintOption = "-o Binding=TopBinding"
|
ShortEdge PrintOption = "-o Binding=TopBinding"
|
||||||
CreateBooklet PrintOption = "-o Combination=Booklet -o PageSize=A5"
|
CreateBooklet PrintOption = "-o Combination=Booklet -o PageSize=A5"
|
||||||
|
TriFold PrintOption = "-o Fold=TriFold -o Binding=TopBinding"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PrintJob struct {
|
type PrintJob struct {
|
||||||
@@ -32,6 +33,10 @@ func GetPrintMode(mode string) PrintOption {
|
|||||||
return ShortEdge
|
return ShortEdge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if mode == "TriFold" {
|
||||||
|
return TriFold
|
||||||
|
}
|
||||||
|
|
||||||
return CreateBooklet
|
return CreateBooklet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ type Tag struct {
|
|||||||
ShopItems []ShopItem `gorm:"many2many:item_tags;"`
|
ShopItems []ShopItem `gorm:"many2many:item_tags;"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CheckedTag struct {
|
||||||
|
Tag
|
||||||
|
Checked string
|
||||||
|
}
|
||||||
|
|
||||||
func NewTag(ctx *gin.Context) (Tag, error) {
|
func NewTag(ctx *gin.Context) (Tag, error) {
|
||||||
colors := []string{
|
colors := []string{
|
||||||
"red",
|
"red",
|
||||||
|
|||||||
81
repositories/configRepository.go
Normal file
81
repositories/configRepository.go
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"git.dynamicdiscord.de/kalipso/zineshop/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ConfigRepository interface {
|
||||||
|
Create(models.Config) (models.Config, error)
|
||||||
|
GetAll() ([]models.Config, error)
|
||||||
|
GetById(string) (models.Config, error)
|
||||||
|
Update(models.Config) (models.Config, error)
|
||||||
|
DeleteById(string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type GORMConfigRepository struct {
|
||||||
|
DB *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGORMConfigRepository(db *gorm.DB) ConfigRepository {
|
||||||
|
return &GORMConfigRepository{
|
||||||
|
DB: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GORMConfigRepository) Create(config models.Config) (models.Config, error) {
|
||||||
|
result := t.DB.Create(&config)
|
||||||
|
|
||||||
|
if result.Error != nil {
|
||||||
|
return models.Config{}, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GORMConfigRepository) GetAll() ([]models.Config, error) {
|
||||||
|
var configs []models.Config
|
||||||
|
result := t.DB.Find(&configs)
|
||||||
|
|
||||||
|
return configs, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GORMConfigRepository) GetById(id string) (models.Config, error) {
|
||||||
|
configId, err := strconv.Atoi(id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return models.Config{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var config models.Config
|
||||||
|
result := t.DB.First(&config, uint(configId))
|
||||||
|
|
||||||
|
if result.Error != nil {
|
||||||
|
return models.Config{}, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GORMConfigRepository) Update(config models.Config) (models.Config, error) {
|
||||||
|
result := t.DB.Save(&config)
|
||||||
|
if result.Error != nil {
|
||||||
|
return models.Config{}, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GORMConfigRepository) DeleteById(id string) error {
|
||||||
|
configId, err := strconv.Atoi(id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := t.DB.Delete(&models.Config{}, configId)
|
||||||
|
return result.Error
|
||||||
|
}
|
||||||
82
repositories/paperRepository.go
Normal file
82
repositories/paperRepository.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"git.dynamicdiscord.de/kalipso/zineshop/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PaperRepository interface {
|
||||||
|
Create(models.Paper) (models.Paper, error)
|
||||||
|
GetAll() ([]models.Paper, error)
|
||||||
|
GetById(string) (models.Paper, error)
|
||||||
|
//GetByShopItemId(string) (models.Paper, error)
|
||||||
|
Update(models.Paper) (models.Paper, error)
|
||||||
|
DeleteById(string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type GORMPaperRepository struct {
|
||||||
|
DB *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGORMPaperRepository(db *gorm.DB) PaperRepository {
|
||||||
|
return &GORMPaperRepository{
|
||||||
|
DB: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GORMPaperRepository) Create(tag models.Paper) (models.Paper, error) {
|
||||||
|
result := t.DB.Create(&tag)
|
||||||
|
|
||||||
|
if result.Error != nil {
|
||||||
|
return models.Paper{}, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GORMPaperRepository) GetAll() ([]models.Paper, error) {
|
||||||
|
var tags []models.Paper
|
||||||
|
result := t.DB.Find(&tags)
|
||||||
|
|
||||||
|
return tags, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GORMPaperRepository) GetById(id string) (models.Paper, error) {
|
||||||
|
tagId, err := strconv.Atoi(id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return models.Paper{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tag models.Paper
|
||||||
|
result := t.DB.First(&tag, uint(tagId))
|
||||||
|
|
||||||
|
if result.Error != nil {
|
||||||
|
return models.Paper{}, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GORMPaperRepository) Update(tag models.Paper) (models.Paper, error) {
|
||||||
|
result := t.DB.Save(&tag)
|
||||||
|
if result.Error != nil {
|
||||||
|
return models.Paper{}, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *GORMPaperRepository) DeleteById(id string) error {
|
||||||
|
tagId, err := strconv.Atoi(id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := t.DB.Delete(&models.Paper{}, tagId)
|
||||||
|
return result.Error
|
||||||
|
}
|
||||||
@@ -9,12 +9,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ShopItems ShopItemRepository
|
ShopItems ShopItemRepository
|
||||||
Users UserRepository
|
Users UserRepository
|
||||||
Tags TagRepository
|
Tags TagRepository
|
||||||
CartItems CartItemRepository
|
CartItems CartItemRepository
|
||||||
Orders OrderRepository
|
Orders OrderRepository
|
||||||
Tokens RegisterTokenRepository
|
Tokens RegisterTokenRepository
|
||||||
|
ConfigOptions ConfigRepository
|
||||||
|
Papers PaperRepository
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitRepositories() {
|
func InitRepositories() {
|
||||||
@@ -29,6 +31,8 @@ func InitRepositories() {
|
|||||||
&models.Tag{},
|
&models.Tag{},
|
||||||
&models.CartItem{},
|
&models.CartItem{},
|
||||||
&models.Order{},
|
&models.Order{},
|
||||||
|
&models.Config{},
|
||||||
|
&models.Paper{},
|
||||||
&models.RegisterToken{})
|
&models.RegisterToken{})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -41,4 +45,6 @@ func InitRepositories() {
|
|||||||
CartItems = NewGORMCartItemRepository(db)
|
CartItems = NewGORMCartItemRepository(db)
|
||||||
Orders = NewGORMOrderRepository(db)
|
Orders = NewGORMOrderRepository(db)
|
||||||
Tokens = NewGORMRegisterTokenRepository(db)
|
Tokens = NewGORMRegisterTokenRepository(db)
|
||||||
|
ConfigOptions = NewGORMConfigRepository(db)
|
||||||
|
Papers = NewGORMPaperRepository(db)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package repositories
|
package repositories
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@@ -10,8 +11,15 @@ import (
|
|||||||
type ShopItemRepository interface {
|
type ShopItemRepository interface {
|
||||||
Create(models.ShopItem) (models.ShopItem, error)
|
Create(models.ShopItem) (models.ShopItem, error)
|
||||||
GetAll() ([]models.ShopItem, error)
|
GetAll() ([]models.ShopItem, error)
|
||||||
|
GetAllSorted(string) ([]models.ShopItem, error)
|
||||||
|
GetAllNewestFirst() ([]models.ShopItem, error)
|
||||||
|
GetAllNewestLast() ([]models.ShopItem, error)
|
||||||
|
GetAllLexicalFirst() ([]models.ShopItem, error)
|
||||||
|
GetAllLexicalLast() ([]models.ShopItem, error)
|
||||||
GetAllPublic() ([]models.ShopItem, error)
|
GetAllPublic() ([]models.ShopItem, error)
|
||||||
GetById(string) (models.ShopItem, error)
|
GetById(string) (models.ShopItem, error)
|
||||||
|
GetNextOfId(string) (models.ShopItem, error)
|
||||||
|
GetPreviousOfId(string) (models.ShopItem, error)
|
||||||
GetByTagId(string) ([]models.ShopItem, error)
|
GetByTagId(string) ([]models.ShopItem, error)
|
||||||
GetVariantById(string) (models.ItemVariant, error)
|
GetVariantById(string) (models.ItemVariant, error)
|
||||||
Update(models.ShopItem) (models.ShopItem, error)
|
Update(models.ShopItem) (models.ShopItem, error)
|
||||||
@@ -44,6 +52,29 @@ func (r *GORMShopItemRepository) GetAll() ([]models.ShopItem, error) {
|
|||||||
return shopItems, result.Error
|
return shopItems, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *GORMShopItemRepository) GetAllSorted(sortString string) ([]models.ShopItem, error) {
|
||||||
|
var shopItems []models.ShopItem
|
||||||
|
result := r.DB.Preload("Tags").Preload("Variants").Order(sortString).Find(&shopItems)
|
||||||
|
|
||||||
|
return shopItems, result.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GORMShopItemRepository) GetAllNewestFirst() ([]models.ShopItem, error) {
|
||||||
|
return r.GetAllSorted("created_at desc")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GORMShopItemRepository) GetAllNewestLast() ([]models.ShopItem, error) {
|
||||||
|
return r.GetAllSorted("created_at asc")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GORMShopItemRepository) GetAllLexicalFirst() ([]models.ShopItem, error) {
|
||||||
|
return r.GetAllSorted("name asc")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GORMShopItemRepository) GetAllLexicalLast() ([]models.ShopItem, error) {
|
||||||
|
return r.GetAllSorted("name desc")
|
||||||
|
}
|
||||||
|
|
||||||
func (r *GORMShopItemRepository) GetAllPublic() ([]models.ShopItem, error) {
|
func (r *GORMShopItemRepository) GetAllPublic() ([]models.ShopItem, error) {
|
||||||
var shopItems []models.ShopItem
|
var shopItems []models.ShopItem
|
||||||
result := r.DB.Preload("Tags").Preload("Variants").Where("is_public = 1").Find(&shopItems)
|
result := r.DB.Preload("Tags").Preload("Variants").Where("is_public = 1").Find(&shopItems)
|
||||||
@@ -68,6 +99,30 @@ func (r *GORMShopItemRepository) GetById(id string) (models.ShopItem, error) {
|
|||||||
return shopItem, nil
|
return shopItem, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *GORMShopItemRepository) GetNextOfId(id string) (models.ShopItem, error) {
|
||||||
|
var nextItem models.ShopItem
|
||||||
|
if err := r.DB.Where("id > ?", id).Order("id asc").First(&nextItem).Error; err != nil {
|
||||||
|
if err != gorm.ErrRecordNotFound {
|
||||||
|
return models.ShopItem{}, err
|
||||||
|
} else {
|
||||||
|
return models.ShopItem{}, fmt.Errorf("No Item found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nextItem, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GORMShopItemRepository) GetPreviousOfId(id string) (models.ShopItem, error) {
|
||||||
|
var previousItem models.ShopItem
|
||||||
|
if err := r.DB.Where("id < ?", id).Order("id desc").First(&previousItem).Error; err != nil {
|
||||||
|
if err != gorm.ErrRecordNotFound {
|
||||||
|
return models.ShopItem{}, err
|
||||||
|
} else {
|
||||||
|
return models.ShopItem{}, fmt.Errorf("No Item found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return previousItem, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *GORMShopItemRepository) GetByTagId(id string) ([]models.ShopItem, error) {
|
func (r *GORMShopItemRepository) GetByTagId(id string) ([]models.ShopItem, error) {
|
||||||
tagId, err := strconv.Atoi(id)
|
tagId, err := strconv.Atoi(id)
|
||||||
|
|
||||||
|
|||||||
@@ -587,6 +587,10 @@ video {
|
|||||||
grid-column: span 12 / span 12;
|
grid-column: span 12 / span 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.col-span-3 {
|
||||||
|
grid-column: span 3 / span 3;
|
||||||
|
}
|
||||||
|
|
||||||
.m-2 {
|
.m-2 {
|
||||||
margin: 0.5rem;
|
margin: 0.5rem;
|
||||||
}
|
}
|
||||||
@@ -806,6 +810,10 @@ video {
|
|||||||
grid-template-columns: repeat(12, minmax(0, 1fr));
|
grid-template-columns: repeat(12, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.grid-cols-6 {
|
||||||
|
grid-template-columns: repeat(6, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
.flex-col {
|
.flex-col {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
@@ -1714,6 +1722,12 @@ video {
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shadow-2xl {
|
||||||
|
--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
|
||||||
|
--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);
|
||||||
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
.shadow-sm {
|
.shadow-sm {
|
||||||
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||||
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
||||||
|
|||||||
@@ -131,6 +131,7 @@
|
|||||||
<option selected value="CreateBooklet">Create Booklet</option>
|
<option selected value="CreateBooklet">Create Booklet</option>
|
||||||
<option value="LongEdge">Long Edge</option>
|
<option value="LongEdge">Long Edge</option>
|
||||||
<option value="ShortEdge">Short Edge</option>
|
<option value="ShortEdge">Short Edge</option>
|
||||||
|
<option value="TriFold">Tri-Fold (Flyer)</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
33
views/configview.html
Normal file
33
views/configview.html
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{{ template "header.html" . }}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
||||||
|
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
||||||
|
<img class="mx-auto h-10 w-auto" src="/static/img/logo-black.png" alt="Your Company">
|
||||||
|
<h2 class="mt-10 text-center text-2xl/9 font-bold tracking-tight text-gray-900">Edit config options</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
|
||||||
|
{{ range .data.configOptions }}
|
||||||
|
<form action="/config/{{ .ID }}" method="POST">
|
||||||
|
<div class="max-w-md mx-auto mt-4">
|
||||||
|
<div class="flex">
|
||||||
|
|
||||||
|
<input type="text" id="key" name="key" value="{{ .Key }}" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<input type="text" id="value" name="value" value="{{ .Value }}" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<button type="submit" name="action" value="update" class="bg-blue-600 text-white ml-4 mr-4 rounded px-4 hover:bg-blue-700">Update</button>
|
||||||
|
<button type="submit" name="action" value="delete" class="bg-red-800 text-white rounded px-4 hover:bg-red-900">Delete</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{{ end }}
|
||||||
|
<form action="/config" method="POST">
|
||||||
|
<div class="max-w-md mx-auto mt-4">
|
||||||
|
<div class="flex">
|
||||||
|
<input type="text" id="key" name="key" placeholder="" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<input type="text" id="value" name="value" placeholder="" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<button type="submit" class="bg-green-600 text-white ml-4 mr-4 rounded px-4 hover:bg-green-700">Add</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{{ template "footer.html" . }}
|
||||||
@@ -1,13 +1,46 @@
|
|||||||
{{ template "header.html" . }}
|
{{ template "header.html" . }}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
||||||
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
||||||
<img class="mx-auto h-10 w-auto" src="/static/img/logo-black.png" alt="Your Company">
|
<img class="mx-auto h-10 w-auto" src="/static/img/logo-black.png" alt="Your Company">
|
||||||
<h2 class="mt-10 text-center text-2xl/9 font-bold tracking-tight text-gray-900">Edit Item</h2>
|
<h2 class="mt-10 text-center text-2xl/9 font-bold tracking-tight text-gray-900">Edit Item</h2>
|
||||||
|
|
||||||
<a href="/shopitems/{{ .data.shopItem.ID }}">
|
<p class="mt-10 text-center text-sm/6 text-red-500">
|
||||||
|
{{ .data.error }}
|
||||||
|
</p>
|
||||||
|
<p class="mt-10 text-center text-sm/6 text-green-500">
|
||||||
|
{{ .data.success }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<a href="/{{ .data.shopItem.Pdf }}" target="_blank">
|
||||||
<img src="/{{ .data.shopItem.Image }}" alt="Product Image" class="aspect-4/5 mx-auto rounded-md bg-gray-200 object-cover group-hover:opacity-75 lg:aspect-auto lg:h-80">
|
<img src="/{{ .data.shopItem.Image }}" alt="Product Image" class="aspect-4/5 mx-auto rounded-md bg-gray-200 object-cover group-hover:opacity-75 lg:aspect-auto lg:h-80">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="grid grid-cols-6 gap-4 mb-4">
|
||||||
|
<div class="col-span-3">
|
||||||
|
{{ if .data.previousShopItem }}
|
||||||
|
<form action="/shopitems/{{ .data.previousShopItem.ID }}/edit">
|
||||||
|
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm/6 font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Previous</button>
|
||||||
|
</form>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-3">
|
||||||
|
{{ if .data.nextShopItem }}
|
||||||
|
<form action="/shopitems/{{ .data.nextShopItem.ID }}/edit">
|
||||||
|
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm/6
|
||||||
|
font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2
|
||||||
|
focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Next</button>
|
||||||
|
</form>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@@ -32,12 +65,25 @@
|
|||||||
<textarea id="description" name="description" type="textarea" class="block w-full px-4 py-2 mt-2 text-gray-900 bg-white border border-gray-300 rounded-md dark:bg-gray-800 dark:text-gray-900 dark:border-gray-600 focus:border-blue-500 dark:focus:border-blue-500 focus:outline-none focus:ring">{{ .data.shopItem.Description}}</textarea>
|
<textarea id="description" name="description" type="textarea" class="block w-full px-4 py-2 mt-2 text-gray-900 bg-white border border-gray-300 rounded-md dark:bg-gray-800 dark:text-gray-900 dark:border-gray-600 focus:border-blue-500 dark:focus:border-blue-500 focus:outline-none focus:ring">{{ .data.shopItem.Description}}</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<label class="block text-sm/6 font-medium text-gray-900">
|
||||||
|
Print Mode
|
||||||
|
</label>
|
||||||
|
<select name="print-mode" required class="bg-white border border-gray-300 text-gray-900 text-sm rounded-lg
|
||||||
|
focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||||
|
<option selected value="{{ .data.shopItem.PrintMode }}">{{ .data.shopItem.PrintMode }}</option>
|
||||||
|
<option value="CreateBooklet">CreateBooklet</option>
|
||||||
|
<option value="LongEdge">Long Edge</option>
|
||||||
|
<option value="ShortEdge">Short Edge</option>
|
||||||
|
<option value="TriFold">Tri-Fold (Flyer)</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="block text-sm/6 text-gray-900">Select Categories</label>
|
<label class="block text-sm/6 text-gray-900">Select Categories</label>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
{{ range .data.tags }}
|
{{ range .data.tags }}
|
||||||
<label class="flex text-sm/6 items-center">
|
<label class="flex text-sm/6 items-center">
|
||||||
<input type="checkbox" class="form-checkbox h-4 w-4 text-gray-900" value="{{ .ID }}" name="tags[]">
|
<input type="checkbox" {{ .Checked }} class="form-checkbox h-4 w-4 text-gray-900" value="{{ .ID }}" name="tags[]">
|
||||||
<span class="ml-2 text-sm/6 text-gray-900">{{ .Name }}</span>
|
<span class="ml-2 text-sm/6 text-gray-900">{{ .Name }}</span>
|
||||||
</label>
|
</label>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
@@ -65,7 +111,7 @@
|
|||||||
<label for="variant-value1" class="block text-sm/6 font-medium text-gray-900">Price B/W</label>
|
<label for="variant-value1" class="block text-sm/6 font-medium text-gray-900">Price B/W</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<input type="number" name="variant-value[]" id="variant-value1" step="0.01" min="0.00" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
|
<input type="number" value="{{ .data.priceBW }}" name="variant-value[]" id="variant-value1" step="0.01" min="0.00" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -76,7 +122,7 @@
|
|||||||
<label for="variant-value2" class="block text-sm/6 font-medium text-gray-900">Price Colored</label>
|
<label for="variant-value2" class="block text-sm/6 font-medium text-gray-900">Price Colored</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<input type="number" name="variant-value[]" id="variant-value2" step="0.01" min="0.00" class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
|
<input type="number" value="{{ .data.priceColored }}" name="variant-value[]" id="variant-value2" step="0.01" min="0.00" class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -127,24 +173,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label class="block text-sm font-medium text-gray-900">
|
|
||||||
Print Mode
|
|
||||||
</label>
|
|
||||||
<select name="print-mode" required class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
|
||||||
<option selected value="CreateBooklet">Create Booklet</option>
|
|
||||||
<option value="LongEdge">Long Edge</option>
|
|
||||||
<option value="ShortEdge">Short Edge</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
|
|
||||||
<p class="mt-10 text-center text-sm/6 text-red-500">
|
|
||||||
{{ .data.error }}
|
|
||||||
</p>
|
|
||||||
<p class="mt-10 text-center text-sm/6 text-green-500">
|
|
||||||
{{ .data.success }}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm/6 font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Update Item</button>
|
<button type="submit" class="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm/6 font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Update Item</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Zine Shop</title>
|
<title>Zines</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link href="/static/output.css" rel="stylesheet">
|
<link href="/static/output.css" rel="stylesheet">
|
||||||
|
|||||||
37
views/paperview.html
Normal file
37
views/paperview.html
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{{ template "header.html" . }}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
||||||
|
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
||||||
|
<img class="mx-auto h-10 w-auto" src="/static/img/logo-black.png" alt="Your Company">
|
||||||
|
<h2 class="mt-10 text-center text-2xl/9 font-bold tracking-tight text-gray-900">Edit Paper</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
|
||||||
|
{{ range .data.paper }}
|
||||||
|
<form action="/paper/{{ .ID }}" method="POST">
|
||||||
|
<div class="max-w-md mx-auto mt-4">
|
||||||
|
<div class="flex">
|
||||||
|
|
||||||
|
<input type="text" id="name" name="name" value="{{ .Name }}" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<input type="text" id="brand" name="brand" value="{{ .Brand }}" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<input type="text" id="size" name="size" value="{{ .Size }}" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<input type="number" step="0.01" min="0.00" id="price" name="price" value="{{ .Price }}" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<button type="submit" name="action" value="update" class="bg-blue-600 text-white ml-4 mr-4 rounded px-4 hover:bg-blue-700">Update</button>
|
||||||
|
<button type="submit" name="action" value="delete" class="bg-red-800 text-white rounded px-4 hover:bg-red-900">Delete</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{{ end }}
|
||||||
|
<form action="/paper" method="POST">
|
||||||
|
<div class="max-w-md mx-auto mt-4">
|
||||||
|
<div class="flex">
|
||||||
|
<input type="text" id="name" name="name" placeholder="name" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<input type="text" id="brand" name="brand" placeholder="brand" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<input type="text" id="size" name="size" placeholder="size" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<input type="number" step="0.01" min="0.00" id="price" name="price" placeholder="price per sheet" class="flex-grow border border-gray-300 rounded-l-md p-2 focus:outline-none focus:ring focus:ring-blue-500">
|
||||||
|
<button type="submit" class="bg-green-600 text-white ml-4 mr-4 rounded px-4 hover:bg-green-700">Add</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{{ template "footer.html" . }}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
<div class="bg-white">
|
<div class="bg-white">
|
||||||
<div class="mx-auto max-w-2xl px-4 py-16 sm:px-6 sm:py-24 lg:max-w-7xl">
|
<div class="mx-auto max-w-2xl px-4 py-16 sm:px-6 sm:py-24 lg:max-w-7xl">
|
||||||
<h2 class="text-2xl font-bold tracking-tight text-gray-900">Available Zines</h2>
|
<h2 class="text-2xl font-bold tracking-tight text-gray-900">Available Zines</h2>
|
||||||
|
|
||||||
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
|
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
|
||||||
<div class="mt-6 grid grid-cols-1 gap-x-6 gap-y-10 md:grid-cols-2 xl:grid-cols-4">
|
<div class="mt-6 grid grid-cols-1 gap-x-6 gap-y-10 md:grid-cols-2 xl:grid-cols-4">
|
||||||
{{ range .data.shopItems }}
|
{{ range .data.shopItems }}
|
||||||
|
|
||||||
<div class="myClass group relative">
|
<div class="myClass group relative">
|
||||||
<a href="/shopitems/{{ .ID }}">
|
<a href="/shopitems/{{ .ID }}">
|
||||||
<img src="/{{ .Image }}" alt="Product Image" class="aspect-4/5 mx-auto rounded bg-gray-200 object-cover group-hover:opacity-75 lg:aspect-auto lg:h-80">
|
<img loading="lazy" src="/{{ .Image }}" alt="Product Image" class="shadow-2xl aspect-4/5 mx-auto rounded bg-gray-200 object-cover group-hover:opacity-75 lg:aspect-auto lg:h-80">
|
||||||
</a>
|
</a>
|
||||||
<div class="mt-4 flex justify-between">
|
<div class="mt-4 flex justify-between">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user