diff --git a/.air.toml b/.air.toml new file mode 100644 index 0000000..d81adc6 --- /dev/null +++ b/.air.toml @@ -0,0 +1,46 @@ +root = "." +testdata_dir = "testdata" +tmp_dir = "bin" + +[build] + args_bin = [] + bin = "./bin/aio serve" + cmd = "make build" + delay = 1000 + exclude_dir = ["assets", "tmp", "vendor", "testdata"] + exclude_file = [] + exclude_regex = ["_test.go"] + exclude_unchanged = false + follow_symlink = false + full_bin = "" + include_dir = [] + include_ext = ["go", "tpl", "tmpl", "html"] + include_file = [] + kill_delay = "0s" + log = "build-errors.log" + poll = false + poll_interval = 0 + post_cmd = [] + pre_cmd = [] + rerun = false + rerun_delay = 500 + send_interrupt = false + stop_on_error = false + +[color] + app = "" + build = "yellow" + main = "magenta" + runner = "green" + watcher = "cyan" + +[log] + main_only = false + time = false + +[misc] + clean_on_exit = false + +[screen] + clear_on_rebuild = false + keep_scroll = true diff --git a/Makefile b/Makefile index 7b53b24..d0f977f 100644 --- a/Makefile +++ b/Makefile @@ -24,4 +24,7 @@ generate: @go generate ./... templ generate -.PHONY: build run clean test coverage \ No newline at end of file +air: + @air -c .air.toml + +.PHONY: build run clean test coverage generate air \ No newline at end of file diff --git a/bin/aio b/bin/aio index 751dc13..161fef0 100755 Binary files a/bin/aio and b/bin/aio differ diff --git a/bin/build-errors.log b/bin/build-errors.log new file mode 100644 index 0000000..efc3276 --- /dev/null +++ b/bin/build-errors.log @@ -0,0 +1 @@ +exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2exit status 2 \ No newline at end of file diff --git a/services/serve/serve.go b/services/serve/serve.go index 8f917bb..345c1c4 100644 --- a/services/serve/serve.go +++ b/services/serve/serve.go @@ -1,20 +1,21 @@ package serve import ( - "github.com/davesavic/aio/views/layout" - "github.com/davesavic/aio/views/page" + templEngine "github.com/davesavic/aio/services/templ" + view "github.com/davesavic/aio/view" "github.com/gin-gonic/gin" + "net/http" ) func Run() error { r := gin.New() + r.HTMLRender = templEngine.NewRenderer() r.Use(gin.Recovery()) r.Use(gin.Logger()) - r.GET("/", func(context *gin.Context) { - layout.UnauthorisedLayout( - "Login", - page.LoginPage(), - ).Render(context, context.Writer) + + r.GET("/", func(c *gin.Context) { + c.HTML(http.StatusOK, "landing", view.LandingPage()) }) + return r.Run() } diff --git a/services/templ/renderer.go b/services/templ/renderer.go new file mode 100644 index 0000000..676bc2a --- /dev/null +++ b/services/templ/renderer.go @@ -0,0 +1,40 @@ +package templ + +import ( + "context" + "github.com/a-h/templ" + "github.com/gin-gonic/gin/render" + "net/http" +) + +type Render struct { + Code int + Component templ.Component +} + +func (t Render) Render(w http.ResponseWriter) error { + t.WriteContentType(w) + w.WriteHeader(t.Code) + if t.Component != nil { + return t.Component.Render(context.Background(), w) + } + return nil +} + +func (t Render) WriteContentType(w http.ResponseWriter) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") +} + +func (t Render) Instance(_ string, data interface{}) render.Render { + if templData, ok := data.(templ.Component); ok { + return &Render{ + Code: http.StatusOK, + Component: templData, + } + } + return nil +} + +func NewRenderer() render.HTMLRender { + return Render{} +} diff --git a/view/button.templ b/view/button.templ new file mode 100644 index 0000000..cd635a1 --- /dev/null +++ b/view/button.templ @@ -0,0 +1,7 @@ +package view + +templ Button(text string, action func() string) { + + {text} + +} \ No newline at end of file diff --git a/views/layout/unauthorised_templ.go b/view/button_templ.go similarity index 63% rename from views/layout/unauthorised_templ.go rename to view/button_templ.go index b0a7d1f..9d32c83 100644 --- a/views/layout/unauthorised_templ.go +++ b/view/button_templ.go @@ -1,7 +1,7 @@ // Code generated by templ - DO NOT EDIT. // templ: version: 0.2.476 -package layout +package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -10,7 +10,7 @@ import "context" import "io" import "bytes" -func UnauthorisedLayout(title string, comp templ.Component) templ.Component { +func Button(text string, action func() string) templ.Component { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) if !templ_7745c5c3_IsBuffer { @@ -23,24 +23,25 @@ func UnauthorisedLayout(title string, comp templ.Component) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a href=\"") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var2 string = title - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + var templ_7745c5c3_Var2 templ.SafeURL = templ.SafeURL(action()) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var2))) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"rounded-md bg-indigo-600 px-3 py-2 text-sm 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\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = comp.Render(ctx, templ_7745c5c3_Buffer) + var templ_7745c5c3_Var3 string = text + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/view/landing.templ b/view/landing.templ new file mode 100644 index 0000000..b5d8e6f --- /dev/null +++ b/view/landing.templ @@ -0,0 +1,7 @@ +package view + +templ LandingPage() { + @UnauthorisedLayout("Landing page") { + @UnauthorisedHeader() + } +} \ No newline at end of file diff --git a/views/page/login_templ.go b/view/landing_templ.go similarity index 55% rename from views/page/login_templ.go rename to view/landing_templ.go index c219a0f..24c7b3d 100644 --- a/views/page/login_templ.go +++ b/view/landing_templ.go @@ -1,7 +1,7 @@ // Code generated by templ - DO NOT EDIT. // templ: version: 0.2.476 -package page +package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -10,7 +10,7 @@ import "context" import "io" import "bytes" -func LoginPage() templ.Component { +func LandingPage() templ.Component { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) if !templ_7745c5c3_IsBuffer { @@ -23,16 +23,22 @@ func LoginPage() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") - if templ_7745c5c3_Err != nil { + templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) + if !templ_7745c5c3_IsBuffer { + templ_7745c5c3_Buffer = templ.GetBuffer() + defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) + } + templ_7745c5c3_Err = UnauthorisedHeader().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer) + } return templ_7745c5c3_Err - } - templ_7745c5c3_Var2 := `Login page` - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var2) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + }) + templ_7745c5c3_Err = UnauthorisedLayout("Landing page").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/view/layout_unauthorised.templ b/view/layout_unauthorised.templ new file mode 100644 index 0000000..2fb2e8b --- /dev/null +++ b/view/layout_unauthorised.templ @@ -0,0 +1,16 @@ +package view + +templ UnauthorisedLayout(title string) { + + + + + + + {title} + + + { children... } + + +} \ No newline at end of file diff --git a/view/layout_unauthorised_templ.go b/view/layout_unauthorised_templ.go new file mode 100644 index 0000000..f324d0a --- /dev/null +++ b/view/layout_unauthorised_templ.go @@ -0,0 +1,70 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: 0.2.476 +package view + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import "context" +import "io" +import "bytes" + +func UnauthorisedLayout(title string) templ.Component { + return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) + if !templ_7745c5c3_IsBuffer { + templ_7745c5c3_Buffer = templ.GetBuffer() + defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string = title + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/view/link.templ b/view/link.templ new file mode 100644 index 0000000..da48f26 --- /dev/null +++ b/view/link.templ @@ -0,0 +1,14 @@ +package view + +type LinkVariant string + +const ( + LinkVariantPrimary LinkVariant = "primary" + LinkVariantSecondary LinkVariant = "secondary" +) + +templ Link(href string, text string, variant LinkVariant) { + + {text} + +} \ No newline at end of file diff --git a/view/link_templ.go b/view/link_templ.go new file mode 100644 index 0000000..723c854 --- /dev/null +++ b/view/link_templ.go @@ -0,0 +1,60 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: 0.2.476 +package view + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import "context" +import "io" +import "bytes" + +type LinkVariant string + +const ( + LinkVariantPrimary LinkVariant = "primary" + LinkVariantSecondary LinkVariant = "secondary" +) + +func Link(href string, text string, variant LinkVariant) templ.Component { + return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) + if !templ_7745c5c3_IsBuffer { + templ_7745c5c3_Buffer = templ.GetBuffer() + defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string = text + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/view/unauthorised_header.templ b/view/unauthorised_header.templ new file mode 100644 index 0000000..7eb4f47 --- /dev/null +++ b/view/unauthorised_header.templ @@ -0,0 +1,65 @@ +package view + +templ UnauthorisedHeader() { +
+ + + +
+} \ No newline at end of file diff --git a/view/unauthorised_header_templ.go b/view/unauthorised_header_templ.go new file mode 100644 index 0000000..1e4bb5c --- /dev/null +++ b/view/unauthorised_header_templ.go @@ -0,0 +1,196 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: 0.2.476 +package view + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import "context" +import "io" +import "bytes" + +func UnauthorisedHeader() templ.Component { + return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) + if !templ_7745c5c3_IsBuffer { + templ_7745c5c3_Buffer = templ.GetBuffer() + defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/views/layout/unauthorised.templ b/views/layout/unauthorised.templ deleted file mode 100644 index bde8f96..0000000 --- a/views/layout/unauthorised.templ +++ /dev/null @@ -1,12 +0,0 @@ -package layout - -templ UnauthorisedLayout(title string, comp templ.Component) { - - - {title} - - - @comp - - -} \ No newline at end of file diff --git a/views/page/login.templ b/views/page/login.templ deleted file mode 100644 index 8939f65..0000000 --- a/views/page/login.templ +++ /dev/null @@ -1,5 +0,0 @@ -package page - -templ LoginPage() { -
Login page
-} \ No newline at end of file