page_title.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package containers
  2. import (
  3. "database/sql/driver"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "github.com/iancoleman/strcase"
  8. "github.com/jinzhu/inflection"
  9. "github.com/qor5/admin/media/media_library"
  10. "github.com/qor5/admin/pagebuilder"
  11. "github.com/qor5/web"
  12. . "github.com/theplant/htmlgo"
  13. "gorm.io/gorm"
  14. )
  15. type PageTitle struct {
  16. ID uint
  17. AddTopSpace bool
  18. AddBottomSpace bool
  19. AnchorID string
  20. HeroImage media_library.MediaBox `sql:"type:text;"`
  21. NavigationLink string
  22. NavigationLinkText string
  23. HeadingIcon string
  24. Heading string
  25. Text string
  26. Tags Tags
  27. }
  28. type Tags []*tag
  29. func (this Tags) Value() (driver.Value, error) {
  30. return json.Marshal(this)
  31. }
  32. func (this *Tags) Scan(value interface{}) error {
  33. switch v := value.(type) {
  34. case string:
  35. return json.Unmarshal([]byte(v), this)
  36. case []byte:
  37. return json.Unmarshal(v, this)
  38. default:
  39. return errors.New("not supported")
  40. }
  41. }
  42. func (*PageTitle) TableName() string {
  43. return "container_page_title"
  44. }
  45. func RegisterPageTitleContainer(pb *pagebuilder.Builder, db *gorm.DB) {
  46. vb := pb.RegisterContainer("PageTitle").
  47. RenderFunc(func(obj interface{}, input *pagebuilder.RenderInput, ctx *web.EventContext) HTMLComponent {
  48. v := obj.(*PageTitle)
  49. return PageTitleBody(v, input)
  50. })
  51. mb := vb.Model(&PageTitle{})
  52. eb := mb.Editing(
  53. "AddTopSpace", "AddBottomSpace", "AnchorID",
  54. "HeroImage", "NavigationLink", "NavigationLinkText",
  55. "HeadingIcon", "Heading", "Text", "Tags",
  56. )
  57. SetTagComponent(pb, eb)
  58. }
  59. func PageTitleBody(data *PageTitle, input *pagebuilder.RenderInput) (body HTMLComponent) {
  60. image := Div().Class("container-page_title-background").Style(fmt.Sprintf("background-image: url(%s)", data.HeroImage.URL()))
  61. wraper := Div(
  62. Div().Class("container-page_title-corner"),
  63. Div(
  64. Div(
  65. Div(
  66. If(data.NavigationLinkText != "", A(
  67. RawHTML(`<svg height=".72em" viewBox="0 0 12 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10 2L3 7.5L10 13" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>`),
  68. Span(data.NavigationLinkText),
  69. ).Class("container-page_title-navigation").AttrIf("href", data.NavigationLink, data.NavigationLink != "")),
  70. Div(
  71. If(data.HeadingIcon != "", Div(RawHTML(data.HeadingIcon)).Class("container-page_title-icon")),
  72. H1(data.Heading),
  73. ).Class("container-page_title-title"),
  74. If(data.Text != "", P(Text(data.Text)).Class("container-page_title-content p-large")),
  75. ).Class("container-page_title-heading"),
  76. If(len(data.Tags) > 0, PageTitleTagsBody(data.Tags)),
  77. ).Class("container-page_title-inner").AttrIf("data-has-navigation", "true", data.NavigationLinkText != "").AttrIf("data-has-icon", "true", data.HeadingIcon != ""),
  78. ).Class("container-wrapper"),
  79. ).Class("container-page_title-wrap")
  80. body = ContainerWrapper(
  81. fmt.Sprintf(inflection.Plural(strcase.ToKebab("PageTitle"))+"_%v", data.ID), data.AnchorID, "container-page_title container-lottie",
  82. "", "", "",
  83. "", data.AddTopSpace, data.AddBottomSpace, input.IsEditor, input.IsReadonly, "",
  84. image, wraper,
  85. )
  86. return
  87. }
  88. func PageTitleTagsBody(tags Tags) HTMLComponent {
  89. tagsDiv := Div().Class("container-page_title-tags-list")
  90. for _, t := range tags {
  91. tagsDiv.AppendChildren(
  92. A(
  93. getTagIconSVG(t.Icon),
  94. Span(t.Text),
  95. ).Class("container-page_title-tags-item").
  96. AttrIf("href", t.Link, t.Link != "").
  97. Attr("data-font-color", t.FontColor).
  98. Attr("data-background-color", t.BackgroundColor),
  99. )
  100. }
  101. return Div(tagsDiv).Class("container-page_title-tags")
  102. }