diff --git a/controllers/cartItemController.go b/controllers/cartItemController.go new file mode 100644 index 0000000..5d2ce55 --- /dev/null +++ b/controllers/cartItemController.go @@ -0,0 +1,239 @@ +package controllers + +import ( + "fmt" + "net/http" + "strconv" + "crypto/rand" + "encoding/hex" + + "github.com/gin-gonic/gin" + + "example.com/gin/test/models" + //"example.com/gin/test/services" + "example.com/gin/test/repositories" +) + +type CartItemController interface { + //CRUDController + CartItemView(*gin.Context) + AddItemHandler(*gin.Context) + //EditCartItemHandler(*gin.Context) + //DeleteCartItemHandler(*gin.Context) +} + +type cartItemController struct {} + +func NewCartItemController() CartItemController { + return &cartItemController{} +} + +func generateSessionId() string { + bytes := make([]byte, 16) // 16 bytes = 128 bits + _, err := rand.Read(bytes) + if err != nil { + panic("failed to generate session ID") + } + return hex.EncodeToString(bytes) +} + +func GetSessionId(ctx *gin.Context) string { + sessionId, err := ctx.Cookie("session_id") + + if err != nil { + sessionId = generateSessionId() + ctx.SetCookie("session_id", sessionId, 3600, "/", "", false, true) + } + + return sessionId +} + +func (rc *cartItemController) NewCartItemFromForm(ctx *gin.Context) (models.CartItem, error) { + fmt.Println("NEWITEM") + sessionId := GetSessionId(ctx) + + shopItemId, err := strconv.Atoi(ctx.PostForm("ShopItemId")) + + if err != nil { + return models.CartItem{}, err + } + + quantity := 1 + //quantity, err := strconv.Atoi(ctx.PostForm("quantity")) + + //if err != nil { + // return models.CartItem{}, err + //} + + cartItem := models.CartItem{ + SessionId: sessionId, + ShopItemId: shopItemId, + Quantity: quantity, + } + + fmt.Println("NEWITEM") + return cartItem, nil +} + + +func (rc *cartItemController) Create(c *gin.Context) { + cartItem, err := rc.NewCartItemFromForm(c) + + if err != nil { + ReplyError(c, fmt.Errorf("cartItem creation failed: %s", err)) + return + } + + _, err = repositories.CartItems.Create(cartItem) + + if err != nil { + ReplyError(c, fmt.Errorf("cartItem creation failed: %s", err)) + return + } + + ReplyOK(c, "cartItem was created") +} + + +func (rc *cartItemController) Update(c *gin.Context) { + cartItem, err := rc.NewCartItemFromForm(c) + + if err != nil { + ReplyError(c, err) + return + } + + _, err = repositories.CartItems.Update(cartItem) + + if err != nil { + ReplyError(c, fmt.Errorf("cartItem creation failed: %s", err)) + return + } + + ReplyOK(c, "cartItem was updated") +} + +//func (rc *cartItemController) Delete(c *gin.Context) { +// err := repositories.CartItems.DeleteBySessionId(c.Param("id")) +// +// if err != nil { +// ReplyError(c, fmt.Errorf("cartItem deletion failed: %s", err)) +// return +// } +// +// ReplyOK(c, "cartItem was deleted") +//} + +func (rc *cartItemController) CartItemView(c *gin.Context) { + sessionId := GetSessionId(c) + + cartItems, err := repositories.CartItems.GetAllBySession(sessionId) + + if err != nil { + c.HTML(http.StatusBadRequest, "cart.html", gin.H{ "data": gin.H{ "error": err } }) + } + + data := CreateSessionData(c, gin.H{ + "cartItems": cartItems, + }) + + c.HTML(http.StatusOK, "cart.html", data) +} + +func (rc *cartItemController) AddItemHandler(c *gin.Context) { + cartItem, err := rc.NewCartItemFromForm(c) + + if err != nil { + fmt.Println(err) + c.HTML(http.StatusBadRequest, "cart.html", gin.H{ "error": err }) + return + } + + _, err = repositories.CartItems.Create(cartItem) + if err != nil { + data := CreateSessionData(c, gin.H{ + "error": err, + "success": "", + }) + + c.HTML(http.StatusOK, "cart.html", data) + return + } + + rc.CartItemView(c) +} + + +//func (rc *cartItemController) EditItemHandler(c *gin.Context) { +// cartItem, err := rc.NewCartItemFromForm(c) +// +// if err != nil { +// c.HTML(http.StatusBadRequest, "edititem.html", gin.H{ "error": err }) +// return +// } +// +// newCartItem, err := repositories.ShopItems.GetById(c.Param("id")) +// +// if err != nil { +// c.HTML(http.StatusBadRequest, "edititem.html", gin.H{ "error": err }) +// return +// } +// +// newCartItem.Name = cartItem.Name +// newCartItem.Abstract = cartItem.Abstract +// newCartItem.Description = cartItem.Description +// newCartItem.Price = cartItem.Price +// newCartItem.IsPublic = cartItem.IsPublic +// newCartItem.Tags = cartItem.Tags +// +// tags, err := repositories.Tags.GetAll() +// if err != nil { +// c.HTML(http.StatusBadRequest, "edititem.html", gin.H{ "error": err }) +// return +// } +// +// _, err = repositories.CartItems.Update(newShopItem) +// if err != nil { +// data := CreateSessionData(c, gin.H{ +// "error": err, +// "success": "", +// "tags": tags, +// }) +// +// c.HTML(http.StatusOK, "edititem.html", data) +// return +// } +// +// data := CreateSessionData(c, gin.H{ +// "error": "", +// "success": fmt.Sprintf("Item '%s' Updated", newCartItem.Name), +// "tags": tags, +// }) +// +// c.HTML(http.StatusOK, "edititem.html", data) +//} + +//func (rc *cartItemController) DeleteItemHandler(c *gin.Context) { +// err := repositories.CartItems.DeleteById(c.Param("id")) +// +// if err != nil { +// data := CreateSessionData(c, gin.H{ +// "error": err, +// "success": "", +// }) +// +// c.HTML(http.StatusOK, "deleteitem.html", data) +// } +// +// cartItems, _ := repositories.CartItems.GetAll() +// fmt.Println(len(cartItems)) +// +// data := CreateSessionData(c, gin.H{ +// "title": "cartItem Page", +// "cartItems": shopItems, +// }) +// +// fmt.Println(data) +// +// c.HTML(http.StatusOK, "index.html", data) +//} diff --git a/main.go b/main.go index 0023b88..52ec8eb 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,7 @@ import( var( shopItemController controllers.ShopItemController = controllers.NewShopItemController() userController controllers.UserController = controllers.UserController{} + cartItemController controllers.CartItemController = controllers.NewCartItemController() authValidator middlewares.AuthValidator = middlewares.AuthValidator{} ) @@ -84,6 +85,9 @@ func main() { viewRoutes.GET("/tags", authValidator.RequireAuth, shopItemController.TagView) viewRoutes.POST("/tags/:id", authValidator.RequireAuth, shopItemController.TagHandler) viewRoutes.POST("/tags", authValidator.RequireAuth, shopItemController.AddTagHandler) + viewRoutes.GET("/cart", cartItemController.CartItemView) + viewRoutes.POST("/cart", cartItemController.AddItemHandler) + //write middleware that redirects to homescreen on register/login/reset for logged in users viewRoutes.GET("/login", userController.LoginView) viewRoutes.GET("/logout", userController.Logout) diff --git a/models/cart.go b/models/cart.go new file mode 100644 index 0000000..db07da1 --- /dev/null +++ b/models/cart.go @@ -0,0 +1,12 @@ +package models + +import ( + "gorm.io/gorm" +) + +type CartItem struct { + gorm.Model + SessionId string `gorm:"index"` + ShopItemId int `gorm:"index"` + Quantity int +} diff --git a/repositories/cartItemRepository.go b/repositories/cartItemRepository.go new file mode 100644 index 0000000..79a481f --- /dev/null +++ b/repositories/cartItemRepository.go @@ -0,0 +1,57 @@ +package repositories + +import( + "gorm.io/gorm" + + "example.com/gin/test/models" +) + +type CartItemRepository interface { + Create(models.CartItem) (models.CartItem, error) + GetAll() ([]models.CartItem, error) + GetAllBySession(string) ([]models.CartItem, error) + Update(models.CartItem) (models.CartItem, error) +} + +type GORMCartItemRepository struct { + DB *gorm.DB +} + +func NewGORMCartItemRepository(db *gorm.DB) CartItemRepository { + return &GORMCartItemRepository{ + DB: db, + } +} + +func (r *GORMCartItemRepository) Create(cartItem models.CartItem) (models.CartItem, error) { + result := r.DB.Create(&cartItem) + if result.Error != nil { + return models.CartItem{}, result.Error + } + + return cartItem, nil +} + +func (r *GORMCartItemRepository) GetAll() ([]models.CartItem, error) { + var cartItems []models.CartItem + result := r.DB.Find(&cartItems) + + return cartItems, result.Error +} + +func (r *GORMCartItemRepository) GetAllBySession(sessionId string) ([]models.CartItem, error) { + var cartItems []models.CartItem + result := r.DB.Where("session_id = ?", sessionId).Find(&cartItems) + + return cartItems, result.Error + +} + +func (r *GORMCartItemRepository) Update(cartItem models.CartItem) (models.CartItem, error) { + result := r.DB.Save(&cartItem) + if result.Error != nil { + return models.CartItem{}, result.Error + } + + return cartItem, nil +} diff --git a/repositories/repository.go b/repositories/repository.go index c284503..8f9ffed 100644 --- a/repositories/repository.go +++ b/repositories/repository.go @@ -12,6 +12,7 @@ var( ShopItems ShopItemRepository Users UserRepository Tags TagRepository + CartItems CartItemRepository ) func InitRepositories() { @@ -20,7 +21,7 @@ func InitRepositories() { panic("failed to connect to database") } - err = db.AutoMigrate(&models.ShopItem{}, &models.User{}, &models.Tag{}) + err = db.AutoMigrate(&models.ShopItem{}, &models.User{}, &models.Tag{}, &models.CartItem{}) if err != nil { panic("failed to migrate database") } @@ -28,4 +29,5 @@ func InitRepositories() { ShopItems = NewGORMShopItemRepository(db) Users = NewGORMUserRepository(db) Tags = NewGORMTagRepository(db) + CartItems = NewGORMCartItemRepository(db) } diff --git a/views/addtag.html b/views/addtag.html new file mode 100644 index 0000000..630fa33 --- /dev/null +++ b/views/addtag.html @@ -0,0 +1,35 @@ +{{ template "header.html" . }} + +
+ {{ .Quantity }} pieces
+