Compare commits
No commits in common. "acda30ee332a82324051dc6a9198e8db856c9656" and "bd82bfeca0b9c2a4edacd7cc478f2ca7000628c9" have entirely different histories.
acda30ee33
...
bd82bfeca0
15
.vscode/launch.json
vendored
15
.vscode/launch.json
vendored
@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
// Use IntelliSense to learn about possible attributes.
|
|
||||||
// Hover to view descriptions of existing attributes.
|
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "Launch file",
|
|
||||||
"type": "go",
|
|
||||||
"request": "launch",
|
|
||||||
"mode": "debug",
|
|
||||||
"program": "cmd/main.go"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@ -1,13 +1,6 @@
|
|||||||
{
|
{
|
||||||
"editor.formatOnSave": true,
|
|
||||||
"[templ]": {
|
|
||||||
"editor.defaultFormatter": "a-h.templ"
|
|
||||||
},
|
|
||||||
"files.exclude": {
|
"files.exclude": {
|
||||||
"**/*_templ.go": true,
|
"**/*_templ.go": true,
|
||||||
"**/*_templ.txt": true
|
"**/*_templ.txt": true
|
||||||
},
|
|
||||||
"emmet.includeLanguages": {
|
|
||||||
"templ": "html"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +0,0 @@
|
|||||||
package domain
|
|
||||||
|
|
||||||
const (
|
|
||||||
CookieToken = "token"
|
|
||||||
CookieRefreshToken = "refresh"
|
|
||||||
CookieUser = "user"
|
|
||||||
|
|
||||||
CookieSettingsDarkMode = "darkmode"
|
|
||||||
)
|
|
@ -3,7 +3,6 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"templ-test/domain"
|
|
||||||
"templ-test/views/auth"
|
"templ-test/views/auth"
|
||||||
"templ-test/views/home"
|
"templ-test/views/home"
|
||||||
|
|
||||||
@ -26,22 +25,22 @@ func (h *Handlers) AuthLoginPost(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cookie := new(http.Cookie)
|
cookie := new(http.Cookie)
|
||||||
cookie.Name = domain.CookieToken
|
cookie.Name = CookieToken
|
||||||
cookie.Value = resp.Token
|
cookie.Value = resp.Token
|
||||||
c.SetCookie(cookie)
|
c.SetCookie(cookie)
|
||||||
|
|
||||||
cookie = new(http.Cookie)
|
cookie = new(http.Cookie)
|
||||||
cookie.Name = domain.CookieRefreshToken
|
cookie.Name = CookieRefreshToken
|
||||||
cookie.Value = resp.RefreshToken
|
cookie.Value = resp.RefreshToken
|
||||||
c.SetCookie(cookie)
|
c.SetCookie(cookie)
|
||||||
|
|
||||||
cookie = new(http.Cookie)
|
cookie = new(http.Cookie)
|
||||||
cookie.Name = domain.CookieUser
|
cookie.Name = CookieUser
|
||||||
cookie.Value = user
|
cookie.Value = user
|
||||||
c.SetCookie(cookie)
|
c.SetCookie(cookie)
|
||||||
|
|
||||||
// render
|
// render
|
||||||
return Render(c, http.StatusOK, auth.LoginPost())
|
return Render(c, http.StatusOK, home.Home())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handlers) AuthShowCookies(c echo.Context) error {
|
func (h *Handlers) AuthShowCookies(c echo.Context) error {
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
"errors"
|
||||||
"templ-test/client"
|
"templ-test/client"
|
||||||
"templ-test/domain"
|
|
||||||
"templ-test/models"
|
"templ-test/models"
|
||||||
"templ-test/services"
|
"templ-test/services"
|
||||||
"time"
|
"time"
|
||||||
@ -15,6 +13,12 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CookieToken = "token"
|
||||||
|
CookieRefreshToken = "refresh"
|
||||||
|
CookieUser = "user"
|
||||||
|
)
|
||||||
|
|
||||||
type Handlers struct {
|
type Handlers struct {
|
||||||
api client.ApiClient
|
api client.ApiClient
|
||||||
cfg services.EnvConfig
|
cfg services.EnvConfig
|
||||||
@ -44,16 +48,7 @@ func (h *Handlers) Register(group echo.Group) {
|
|||||||
func Render(ctx echo.Context, statusCode int, t templ.Component) error {
|
func Render(ctx echo.Context, statusCode int, t templ.Component) error {
|
||||||
ctx.Response().Writer.WriteHeader(statusCode)
|
ctx.Response().Writer.WriteHeader(statusCode)
|
||||||
ctx.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTML)
|
ctx.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTML)
|
||||||
|
return t.Render(ctx.Request().Context(), ctx.Response().Writer)
|
||||||
// take the request context and make it a var
|
|
||||||
request := ctx.Request().Context()
|
|
||||||
//Check to see if we the echo context has the cookie we are looking for, if so, create a new context based on what we had and add the value
|
|
||||||
darkMode, err := ctx.Cookie(domain.CookieSettingsDarkMode)
|
|
||||||
if err == nil {
|
|
||||||
request = context.WithValue(request, domain.CookieSettingsDarkMode, darkMode.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.Render(request, ctx.Response().Writer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type jwtToken struct {
|
type jwtToken struct {
|
||||||
@ -81,7 +76,7 @@ func ValidateJwt(ctx echo.Context, sharedSecret, issuer string) (jwtToken, error
|
|||||||
if !token.Valid {
|
if !token.Valid {
|
||||||
return jwtToken{}, errors.New("invalid jwt token")
|
return jwtToken{}, errors.New("invalid jwt token")
|
||||||
}
|
}
|
||||||
|
|
||||||
claims := token.Claims.(*jwtToken)
|
claims := token.Claims.(*jwtToken)
|
||||||
if !claims.Exp.After(time.Now()) {
|
if !claims.Exp.After(time.Now()) {
|
||||||
return jwtToken{}, errors.New("the jwt token has expired")
|
return jwtToken{}, errors.New("the jwt token has expired")
|
||||||
@ -96,25 +91,20 @@ func ValidateJwt(ctx echo.Context, sharedSecret, issuer string) (jwtToken, error
|
|||||||
func GetCookieValues(ctx echo.Context) models.AllCookies {
|
func GetCookieValues(ctx echo.Context) models.AllCookies {
|
||||||
m := models.AllCookies{}
|
m := models.AllCookies{}
|
||||||
|
|
||||||
token, err := ctx.Cookie(domain.CookieToken)
|
token, err := ctx.Cookie(CookieToken)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
m.Token = token.Value
|
m.Token = token.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := ctx.Cookie(domain.CookieUser)
|
user, err := ctx.Cookie(CookieUser)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
m.Username = user.Value
|
m.Username = user.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh, err := ctx.Cookie(domain.CookieRefreshToken)
|
refresh, err := ctx.Cookie(CookieRefreshToken)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
m.RefreshToken = refresh.Value
|
m.RefreshToken = refresh.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
darkMode, err := ctx.Cookie(domain.CookieSettingsDarkMode)
|
|
||||||
if err == nil {
|
|
||||||
m.DarkMode = darkMode.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@ package handlers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"templ-test/domain"
|
|
||||||
"templ-test/models"
|
|
||||||
"templ-test/views/home"
|
"templ-test/views/home"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
@ -14,25 +12,15 @@ func (h *Handlers) HomeHandler(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handlers) Settings(c echo.Context) error {
|
func (h *Handlers) Settings(c echo.Context) error {
|
||||||
m := models.SettingsViewModel{}
|
return Render(c, http.StatusOK, home.UserSettings())
|
||||||
darkMode, err := c.Cookie(domain.CookieSettingsDarkMode)
|
|
||||||
if err == nil {
|
|
||||||
m.DarkMode = darkMode.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
return Render(c, http.StatusOK, home.UserSettings(m))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handlers) SettingsPost(c echo.Context) error {
|
func (h *Handlers) SettingsPost(c echo.Context) error {
|
||||||
// take in the updated values from he user and write the cookies... tbd
|
// take in the updated values from he user and write the cookies... tbd
|
||||||
useDarkMode := c.FormValue(domain.CookieSettingsDarkMode)
|
|
||||||
if useDarkMode != "" {
|
|
||||||
darkModeCookie := new(http.Cookie)
|
|
||||||
darkModeCookie.Name = domain.CookieSettingsDarkMode
|
|
||||||
darkModeCookie.Value = useDarkMode
|
|
||||||
|
|
||||||
c.SetCookie(darkModeCookie)
|
return Render(c, http.StatusOK, home.UserSettings())
|
||||||
}
|
|
||||||
|
|
||||||
return Render(c, http.StatusOK, home.SettingsUpdated())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//func (h *Handlers) ListHandler(c echo.Context) error {
|
||||||
|
// return Render(c, http.StatusOK, views.List())
|
||||||
|
//}
|
||||||
|
@ -4,7 +4,6 @@ type AllCookies struct {
|
|||||||
Username string
|
Username string
|
||||||
Token string
|
Token string
|
||||||
RefreshToken string
|
RefreshToken string
|
||||||
DarkMode string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShowCookie struct {
|
type ShowCookie struct {
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
type SettingsViewModel struct {
|
|
||||||
DarkMode string
|
|
||||||
}
|
|
@ -4,13 +4,10 @@ import "templ-test/models"
|
|||||||
import "templ-test/views/layout"
|
import "templ-test/views/layout"
|
||||||
|
|
||||||
templ ShowCookie(m models.AllCookies) {
|
templ ShowCookie(m models.AllCookies) {
|
||||||
@layout.WithLayout("Cookie Explorer") {
|
@layout.Testing("Cookie Explorer") {
|
||||||
<h2>These are stored as cookies</h2>
|
<h2>These are stored as cookies</h2>
|
||||||
<h3>JWT Values</h3>
|
|
||||||
<p>Username: { m.Username }</p>
|
<p>Username: { m.Username }</p>
|
||||||
<p>JWT Token: { m.Token }</p>
|
<p>JWT Token: { m.Token }</p>
|
||||||
<p>RefreshToken: { m.RefreshToken }</p>
|
<p>RefreshToken: { m.RefreshToken }</p>
|
||||||
<h3>User Settings</h3>
|
|
||||||
<p>DarkMode: { m.DarkMode }</p>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package auth
|
|||||||
import "templ-test/views/layout"
|
import "templ-test/views/layout"
|
||||||
|
|
||||||
templ AuthLogin() {
|
templ AuthLogin() {
|
||||||
@layout.WithLayout("Login") {
|
@layout.WithLayout("Login", true) {
|
||||||
<form hx-post="/auth/login">
|
<form hx-post="/auth/login">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="username" class="form-label">Username</label>
|
<label for="username" class="form-label">Username</label>
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import "templ-test/views/components/bootstrap"
|
|
||||||
|
|
||||||
templ LoginPost() {
|
|
||||||
@bootstrap.BootstrapAlert("Login successful!", bootstrap.VariantSuccess)
|
|
||||||
}
|
|
@ -17,3 +17,7 @@ templ BootstrapAlert(message, variant string) {
|
|||||||
{ message }
|
{ message }
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
templ BootstrapButton(message, variant string) {
|
||||||
|
<button type="button" class={ getButtonVariant(variant) }>{ message }</button>
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
package bootstrap
|
|
||||||
|
|
||||||
const (
|
|
||||||
ButtonTypeSubmit = "submit"
|
|
||||||
ButtonTypeDefault = "button"
|
|
||||||
)
|
|
||||||
|
|
||||||
templ BootstrapButton(message, variant, buttonType string) {
|
|
||||||
<button type={ buttonType } class={ getButtonVariant(variant) }>{ message }</button>
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package bootstrap
|
|
||||||
|
|
||||||
templ Label(cssClass, name, cssForId, message string) {
|
|
||||||
<label class={ cssClass } name={ name } for={ cssForId }>{ message }</label>
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package bootstrap
|
|
||||||
|
|
||||||
const (
|
|
||||||
SwitchTypeCheckbox = "checkbox"
|
|
||||||
)
|
|
||||||
|
|
||||||
templ Switch(name, switchType, cssId string, enabled bool) {
|
|
||||||
if enabled == true {
|
|
||||||
<input class="form-check-input" name={ name } type={ switchType } role="switch" id={ cssId } checked/>
|
|
||||||
} else {
|
|
||||||
<input class="form-check-input" name={ name } type={ switchType } role="switch" id={ cssId }/>
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,7 @@ package home
|
|||||||
import "templ-test/views/layout"
|
import "templ-test/views/layout"
|
||||||
|
|
||||||
templ Error(message error) {
|
templ Error(message error) {
|
||||||
@layout.WithLayout("Error") {
|
@layout.Testing("Error") {
|
||||||
<h1>Oops... :(</h1>
|
<h1>Oops... :(</h1>
|
||||||
<h3>{ message.Error() } </h3>
|
<h3>{ message.Error() } </h3>
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,14 @@ import "templ-test/views/components/bootstrap"
|
|||||||
import "templ-test/views/layout"
|
import "templ-test/views/layout"
|
||||||
|
|
||||||
templ Home() {
|
templ Home() {
|
||||||
@layout.WithLayout("Home") {
|
@layout.WithLayout("Home", true) {
|
||||||
<p>
|
<p>
|
||||||
this should be above the alert
|
this should be above the alert
|
||||||
</p>
|
</p>
|
||||||
@bootstrap.BootstrapAlert("Testing!", bootstrap.VariantDark)
|
@bootstrap.BootstrapAlert("Testing!", bootstrap.VariantDark)
|
||||||
<p>you should now see this under the Alert </p>
|
<p>you should now see this under the Alert </p>
|
||||||
@bootstrap.BootstrapButton("I am in danger", bootstrap.VariantDanger, bootstrap.ButtonTypeDefault)
|
@bootstrap.BootstrapButton("I am in danger", bootstrap.VariantDanger)
|
||||||
@bootstrap.BootstrapButton("I am the darkness", bootstrap.VariantDark, bootstrap.ButtonTypeDefault)
|
@bootstrap.BootstrapButton("I am the darkness", bootstrap.VariantDark)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,9 @@
|
|||||||
package home
|
package home
|
||||||
|
|
||||||
import "templ-test/views/layout"
|
import "templ-test/views/layout"
|
||||||
import "templ-test/views/components/bootstrap"
|
|
||||||
import "templ-test/models"
|
|
||||||
import "templ-test/domain"
|
|
||||||
|
|
||||||
const (
|
templ UserSettings() {
|
||||||
test = "t"
|
@layout.Testing("Settings") {
|
||||||
)
|
<h2>This is not ready yet</h2>
|
||||||
|
|
||||||
templ UserSettings(model models.SettingsViewModel) {
|
|
||||||
@layout.WithLayout("Settings") {
|
|
||||||
<form hx-post="/settings">
|
|
||||||
<div class="mb-3">
|
|
||||||
if useDarkMode(model.DarkMode) {
|
|
||||||
@bootstrap.Switch("darkmode", bootstrap.SwitchTypeCheckbox, test, true)
|
|
||||||
} else {
|
|
||||||
@bootstrap.Switch("darkmode", bootstrap.SwitchTypeCheckbox, "flexSwitchCheckDefault", true)
|
|
||||||
}
|
|
||||||
@bootstrap.Label("form-check-label", domain.CookieSettingsDarkMode, "flexSwitchCheckDefault", "Use Dark Mode")
|
|
||||||
</div>
|
|
||||||
@bootstrap.BootstrapButton("Submit", bootstrap.VariantInfo, bootstrap.ButtonTypeSubmit)
|
|
||||||
</form>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func useDarkMode(value string) bool {
|
|
||||||
if value == "on" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package home
|
|
||||||
|
|
||||||
templ SettingsUpdated() {
|
|
||||||
<p>You are now free to move about the cabin. Thank you for saving with us!</p>
|
|
||||||
}
|
|
@ -1,8 +1,20 @@
|
|||||||
package layout
|
package layout
|
||||||
|
|
||||||
templ WithLayout(pageName string) {
|
templ WithLayout(pageName string, useDarkMode bool) {
|
||||||
<!doctype html>
|
<html>
|
||||||
<html lang="en" data-bs-theme={ useLightOrDarkTheme(ctx) }>
|
@getHtmlHead()
|
||||||
|
<body>
|
||||||
|
@bootstrapNavBar()
|
||||||
|
@getBodyHeader(pageName)
|
||||||
|
<div class="container-fluid">
|
||||||
|
{ children... }
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ Testing(pageName string) {
|
||||||
|
<html>
|
||||||
@getHtmlHead()
|
@getHtmlHead()
|
||||||
<body>
|
<body>
|
||||||
@bootstrapNavBar()
|
@bootstrapNavBar()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package layout
|
package layout
|
||||||
|
|
||||||
templ bootstrapNavBar() {
|
templ bootstrapNavBar() {
|
||||||
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
<nav class="navbar navbar-expand-lg bg-body-tertiary" data-bs-theme={ useLightOrDarkTheme(ctx)}>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" href="#">Navbar</a>
|
<a class="navbar-brand" href="#">Navbar</a>
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
@ -2,14 +2,8 @@ package layout
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"templ-test/domain"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func useLightOrDarkTheme(ctx context.Context) string {
|
func useLightOrDarkTheme(ctx context.Context) string {
|
||||||
value := ctx.Value(domain.CookieSettingsDarkMode)
|
return "dark"
|
||||||
if value == "on" {
|
|
||||||
return "dark"
|
|
||||||
} else {
|
|
||||||
return "light"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user