crud tags

This commit is contained in:
2025-03-03 17:30:31 +01:00
parent 4e296ca445
commit 07ee8a004c
6 changed files with 185 additions and 2 deletions

View File

@@ -32,6 +32,9 @@ type ShopItemController interface {
EditItemHandler(*gin.Context)
DeleteItemView(*gin.Context)
DeleteItemHandler(*gin.Context)
TagView(*gin.Context)
TagHandler(*gin.Context)
AddTagHandler(*gin.Context)
}
type shopItemController struct {}
@@ -366,6 +369,77 @@ func (rc *shopItemController) DeleteItemHandler(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", data)
}
func (rc *shopItemController) TagHandler(ctx *gin.Context) {
name := ctx.PostForm("name")
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, 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)

View File

@@ -78,9 +78,12 @@ func main() {
viewRoutes.GET("/", userController.MainView)
viewRoutes.GET("/shopitems/:id", shopItemController.ShopItemView)
viewRoutes.GET("/shopitems/:id/edit", authValidator.RequireAuth, shopItemController.EditItemView)
viewRoutes.GET("/shopitems/:id/delete", authValidator.RequireAuth, shopItemController.DeleteItemView)
viewRoutes.POST("/shopitems/:id/edit", authValidator.RequireAuth, shopItemController.EditItemHandler)
viewRoutes.GET("/shopitems/:id/delete", authValidator.RequireAuth, shopItemController.DeleteItemView)
viewRoutes.POST("/shopitems/:id/delete", authValidator.RequireAuth, shopItemController.DeleteItemHandler)
viewRoutes.GET("/tags", authValidator.RequireAuth, shopItemController.TagView)
viewRoutes.POST("/tags/:id", authValidator.RequireAuth, shopItemController.TagHandler)
viewRoutes.POST("/tags", authValidator.RequireAuth, shopItemController.AddTagHandler)
//write middleware that redirects to homescreen on register/login/reset for logged in users
viewRoutes.GET("/login", userController.LoginView)
viewRoutes.GET("/logout", userController.Logout)

View File

@@ -8,7 +8,7 @@ import (
type Tag struct {
gorm.Model
Name string `json:"name" binding:"required" gorm:"unique;not null"`
Name string `json:"name" binding:"required" gorm:"not null"`
ShopItems []ShopItem `gorm:"many2many:item_tags;"`
}

View File

@@ -655,6 +655,14 @@ video {
margin-right: 1rem;
}
.mt-12 {
margin-top: 3rem;
}
.ml-4 {
margin-left: 1rem;
}
.block {
display: block;
}
@@ -755,6 +763,10 @@ video {
max-width: 72rem;
}
.max-w-md {
max-width: 28rem;
}
.flex-1 {
flex: 1 1 0%;
}
@@ -763,6 +775,10 @@ video {
flex-shrink: 0;
}
.flex-grow {
flex-grow: 1;
}
.cursor-pointer {
cursor: pointer;
}
@@ -771,6 +787,10 @@ video {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
.grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.flex-col {
flex-direction: column;
}
@@ -836,6 +856,16 @@ video {
border-radius: 9999px;
}
.rounded-l-md {
border-top-left-radius: 0.375rem;
border-bottom-left-radius: 0.375rem;
}
.rounded-r-md {
border-top-right-radius: 0.375rem;
border-bottom-right-radius: 0.375rem;
}
.border {
border-width: 1px;
}
@@ -913,6 +943,31 @@ video {
background-color: rgb(30 58 138 / var(--tw-bg-opacity, 1));
}
.bg-blue-600 {
--tw-bg-opacity: 1;
background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
}
.bg-red-600 {
--tw-bg-opacity: 1;
background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
}
.bg-red-300 {
--tw-bg-opacity: 1;
background-color: rgb(252 165 165 / var(--tw-bg-opacity, 1));
}
.bg-red-800 {
--tw-bg-opacity: 1;
background-color: rgb(153 27 27 / var(--tw-bg-opacity, 1));
}
.bg-green-600 {
--tw-bg-opacity: 1;
background-color: rgb(22 163 74 / var(--tw-bg-opacity, 1));
}
.object-cover {
-o-object-fit: cover;
object-fit: cover;
@@ -1182,6 +1237,26 @@ video {
background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
}
.hover\:bg-blue-700:hover {
--tw-bg-opacity: 1;
background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1));
}
.hover\:bg-red-700:hover {
--tw-bg-opacity: 1;
background-color: rgb(185 28 28 / var(--tw-bg-opacity, 1));
}
.hover\:bg-red-900:hover {
--tw-bg-opacity: 1;
background-color: rgb(127 29 29 / var(--tw-bg-opacity, 1));
}
.hover\:bg-green-700:hover {
--tw-bg-opacity: 1;
background-color: rgb(21 128 61 / var(--tw-bg-opacity, 1));
}
.hover\:text-indigo-500:hover {
--tw-text-opacity: 1;
color: rgb(99 102 241 / var(--tw-text-opacity, 1));

View File

@@ -28,6 +28,7 @@
{{ if .loggedIn }}
<div class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0 px-4 sm:px-8">
<a href="/additem" class="rounded-md bg-gray-900 m-2 px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white">Add Item</a>
<a href="/tags" class="rounded-md bg-gray-900 m-2 px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white">Tags</a>
<a href="/logout" class="rounded-md bg-gray-900 m-2 px-3 py-2 text-sm font-medium text-red-300 hover:bg-gray-700 hover:text-white">Logout</a>
</div>
{{ else }}

30
views/tagview.html Normal file
View File

@@ -0,0 +1,30 @@
{{ 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/circlea.png" alt="Your Company">
<h2 class="mt-10 text-center text-2xl/9 font-bold tracking-tight text-gray-900">Edit Tags</h2>
</div>
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
{{ range .data.tags }}
<form action="/tags/{{ .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">
<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="/tags" method="POST">
<div class="max-w-md mx-auto mt-4">
<div class="flex">
<input type="text" id="name" name="name" placeholder="add new tag" 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" . }}