crud tags
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
5
main.go
5
main.go
@@ -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)
|
||||
|
||||
@@ -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;"`
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
30
views/tagview.html
Normal 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" . }}
|
||||
Reference in New Issue
Block a user