diff --git a/cmd/web/handlers_guestbook.go b/cmd/web/handlers_guestbook.go
index b7adbeb..e137a81 100644
--- a/cmd/web/handlers_guestbook.go
+++ b/cmd/web/handlers_guestbook.go
@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"net/http"
+ "strconv"
"time"
"git.32bit.cafe/32bitcafe/guestbook/internal/forms"
@@ -23,6 +24,17 @@ func (app *application) getGuestbook(w http.ResponseWriter, r *http.Request) {
}
return
}
+ if !website.Guestbook.Settings.IsVisible {
+ u := app.getCurrentUser(r)
+ if u == nil {
+ app.clientError(w, http.StatusForbidden)
+ return
+ }
+ if u.ID != website.UserId {
+ app.clientError(w, http.StatusForbidden)
+ return
+ }
+ }
comments, err := app.guestbookComments.GetAll(website.Guestbook.ID)
if err != nil {
app.serverError(w, r, err)
@@ -32,6 +44,78 @@ func (app *application) getGuestbook(w http.ResponseWriter, r *http.Request) {
views.GuestbookView("Guestbook", data, website, website.Guestbook, comments, forms.CommentCreateForm{}).Render(r.Context(), w)
}
+func (app *application) getGuestbookSettings(w http.ResponseWriter, r *http.Request) {
+ slug := r.PathValue("id")
+ website, err := app.websites.Get(slugToShortId(slug))
+ if err != nil {
+ if errors.Is(err, models.ErrNoRecord) {
+ http.NotFound(w, r)
+ } else {
+ app.serverError(w, r, err)
+ }
+ }
+ data := app.newCommonData(r)
+ views.GuestbookSettingsView(data, website).Render(r.Context(), w)
+}
+
+func (app *application) putGuestbookSettings(w http.ResponseWriter, r *http.Request) {
+ slug := r.PathValue("id")
+ website, err := app.websites.Get(slugToShortId(slug))
+ if err != nil {
+ if errors.Is(err, models.ErrNoRecord) {
+ http.NotFound(w, r)
+ } else {
+ app.serverError(w, r, err)
+ }
+ }
+
+ var form forms.GuestbookSettingsForm
+ err = app.decodePostForm(r, &form)
+ if err != nil {
+ app.clientError(w, http.StatusBadRequest)
+ app.serverError(w, r, err)
+ return
+ }
+ form.CheckField(validator.PermittedValue(form.Visibility, "true", "false"), "gb_visible", "Invalid value")
+ form.CheckField(validator.PermittedValue(form.CommentingEnabled, models.ValidDisableDurations...), "gb_visible", "Invalid value")
+ form.CheckField(validator.PermittedValue(form.WidgetsEnabled, "true", "false"), "gb_remote", "Invalid value")
+ if !form.Valid() {
+ // TODO: rerender template with errors
+ app.clientError(w, http.StatusUnprocessableEntity)
+ }
+
+ c, err := strconv.ParseBool(form.CommentingEnabled)
+ if err != nil {
+ website.Guestbook.Settings.IsCommentingEnabled = false
+ website.Guestbook.Settings.ReenableCommenting, err = app.durationToTime(form.CommentingEnabled)
+ if err != nil {
+ app.serverError(w, r, err)
+ }
+ } else {
+ website.Guestbook.Settings.IsCommentingEnabled = c
+ }
+
+ // can skip error checking for these two since we verify valid values above
+ website.Guestbook.Settings.IsVisible, err = strconv.ParseBool(form.Visibility)
+ if err != nil {
+ app.serverError(w, r, err)
+ }
+ website.Guestbook.Settings.AllowRemoteHostAccess, err = strconv.ParseBool(form.WidgetsEnabled)
+ if err != nil {
+ app.serverError(w, r, err)
+ }
+ err = app.websites.UpdateGuestbookSettings(website.Guestbook.ID, website.Guestbook.Settings)
+ if err != nil {
+ app.serverError(w, r, err)
+ return
+ }
+ app.sessionManager.Put(r.Context(), "flash", "Settings changed successfully")
+ data := app.newCommonData(r)
+ w.Header().Add("HX-Refresh", "true")
+ views.GuestbookSettingsView(data, website).Render(r.Context(), w)
+
+}
+
func (app *application) getGuestbookComments(w http.ResponseWriter, r *http.Request) {
slug := r.PathValue("id")
website, err := app.websites.Get(slugToShortId(slug))
@@ -64,7 +148,6 @@ func (app *application) getGuestbookCommentCreate(w http.ResponseWriter, r *http
}
return
}
-
data := app.newCommonData(r)
form := forms.CommentCreateForm{}
views.CreateGuestbookComment("New Comment", data, website, website.Guestbook, form).Render(r.Context(), w)
@@ -82,6 +165,11 @@ func (app *application) postGuestbookCommentCreate(w http.ResponseWriter, r *htt
return
}
+ if !website.Guestbook.CanComment() {
+ app.clientError(w, http.StatusForbidden)
+ return
+ }
+
var form forms.CommentCreateForm
err = app.decodePostForm(r, &form)
if err != nil {
@@ -98,6 +186,7 @@ func (app *application) postGuestbookCommentCreate(w http.ResponseWriter, r *htt
form.CheckField(validator.NotBlank(form.Content), "content", "This field cannot be blank")
if !form.Valid() {
+ // TODO: use htmx to avoid getting comments again
comments, err := app.guestbookComments.GetAll(website.Guestbook.ID)
if err != nil {
app.serverError(w, r, err)
diff --git a/cmd/web/handlers_user.go b/cmd/web/handlers_user.go
index 772c8d4..8690065 100644
--- a/cmd/web/handlers_user.go
+++ b/cmd/web/handlers_user.go
@@ -3,6 +3,7 @@ package main
import (
"errors"
"net/http"
+ "time"
"git.32bit.cafe/32bitcafe/guestbook/internal/forms"
"git.32bit.cafe/32bitcafe/guestbook/internal/models"
@@ -39,7 +40,8 @@ func (app *application) postUserRegister(w http.ResponseWriter, r *http.Request)
return
}
shortId := app.createShortId()
- err = app.users.Insert(shortId, form.Name, form.Email, form.Password)
+ settings := DefaultUserSettings()
+ err = app.users.Insert(shortId, form.Name, form.Email, form.Password, settings)
if err != nil {
if errors.Is(err, models.ErrDuplicateEmail) {
form.AddFieldError("email", "Email address is already in use")
@@ -129,3 +131,39 @@ func (app *application) getUser(w http.ResponseWriter, r *http.Request) {
data := app.newCommonData(r)
views.UserProfile(user.Username, data, user).Render(r.Context(), w)
}
+
+func (app *application) getUserSettings(w http.ResponseWriter, r *http.Request) {
+ data := app.newCommonData(r)
+ views.UserSettingsView(data, app.timezones).Render(r.Context(), w)
+}
+
+func (app *application) putUserSettings(w http.ResponseWriter, r *http.Request) {
+ user := app.getCurrentUser(r)
+ var form forms.UserSettingsForm
+ err := app.decodePostForm(r, &form)
+ if err != nil {
+ app.clientError(w, http.StatusBadRequest)
+ app.serverError(w, r, err)
+ return
+ }
+ form.CheckField(validator.PermittedValue(form.LocalTimezone, app.timezones...), "timezone", "Invalid value")
+ if !form.Valid() {
+ // TODO: rerender template with errors
+ app.clientError(w, http.StatusUnprocessableEntity)
+ }
+ user.Settings.LocalTimezone, err = time.LoadLocation(form.LocalTimezone)
+ if err != nil {
+ app.serverError(w, r, err)
+ return
+ }
+ err = app.users.UpdateUserSettings(user.ID, user.Settings)
+ if err != nil {
+ app.serverError(w, r, err)
+ return
+ }
+ app.sessionManager.Put(r.Context(), "flash", "Settings changed successfully")
+ data := app.newCommonData(r)
+ w.Header().Add("HX-Refresh", "true")
+ views.UserSettingsView(data, app.timezones).Render(r.Context(), w)
+
+}
diff --git a/cmd/web/handlers_website.go b/cmd/web/handlers_website.go
index 8cb45b8..cb94c72 100644
--- a/cmd/web/handlers_website.go
+++ b/cmd/web/handlers_website.go
@@ -39,25 +39,13 @@ func (app *application) postWebsiteCreate(w http.ResponseWriter, r *http.Request
views.WebsiteCreate("Add a Website", data, form).Render(r.Context(), w)
}
websiteShortID := app.createShortId()
- websiteId, err := app.websites.Insert(websiteShortID, userId, form.Name, form.SiteUrl, form.AuthorName)
- if err != nil {
- app.serverError(w, r, err)
- return
- }
- // TODO: how to handle website creation success but guestbook creation failure?
- guestbookShortID := app.createShortId()
- _, err = app.guestbooks.Insert(guestbookShortID, userId, websiteId)
+ _, err = app.websites.Insert(websiteShortID, userId, form.Name, form.SiteUrl, form.AuthorName)
if err != nil {
app.serverError(w, r, err)
return
}
app.sessionManager.Put(r.Context(), "flash", "Website successfully registered!")
- if r.Header.Get("HX-Request") == "true" {
- w.Header().Add("HX-Trigger", "newWebsite")
- views.WebsiteCreateButton().Render(r.Context(), w)
- return
- }
- http.Redirect(w, r, fmt.Sprintf("/websites/%s", shortIdToSlug(websiteShortID)), http.StatusSeeOther)
+ http.Redirect(w, r, fmt.Sprintf("/websites/%s/dashboard", shortIdToSlug(websiteShortID)), http.StatusSeeOther)
}
func (app *application) getWebsiteDashboard(w http.ResponseWriter, r *http.Request) {
@@ -88,7 +76,8 @@ func (app *application) getWebsiteList(w http.ResponseWriter, r *http.Request) {
return
}
if r.Header.Get("HX-Request") == "true" {
- w.Header().Add("HX-Trigger", "newWebsite")
+ views.HxWebsiteList(websites)
+ return
}
data := app.newCommonData(r)
views.WebsiteList("My Websites", data, websites).Render(r.Context(), w)
diff --git a/cmd/web/helpers.go b/cmd/web/helpers.go
index ca0dfdd..7d927d1 100644
--- a/cmd/web/helpers.go
+++ b/cmd/web/helpers.go
@@ -23,8 +23,7 @@ func (app *application) serverError(w http.ResponseWriter, r *http.Request, err
app.logger.Error(err.Error(), "method", method, "uri", uri)
if app.debug {
- http.Error(w, string(debug.Stack()), http.StatusInternalServerError)
- app.logger.Error(err.Error(), "method", method, "uri", uri, "stack", string(debug.Stack()))
+ http.Error(w, err.Error()+"\n"+string(debug.Stack()), http.StatusInternalServerError)
}
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
@@ -112,3 +111,19 @@ func (app *application) newCommonData(r *http.Request) views.CommonData {
IsHtmx: r.Header.Get("Hx-Request") == "true",
}
}
+
+func DefaultUserSettings() models.UserSettings {
+ return models.UserSettings{
+ LocalTimezone: time.Now().UTC().Location(),
+ }
+}
+
+func (app *application) durationToTime(duration string) (time.Time, error) {
+ var result time.Time
+ offset, err := time.ParseDuration(duration)
+ if err != nil {
+ return result, nil
+ }
+ result = time.Now().UTC().Add(offset)
+ return result, nil
+}
diff --git a/cmd/web/main.go b/cmd/web/main.go
index e1a2bec..ba9115c 100644
--- a/cmd/web/main.go
+++ b/cmd/web/main.go
@@ -7,7 +7,9 @@ import (
"log/slog"
"net/http"
"os"
+ "strings"
"time"
+ "unicode"
"git.32bit.cafe/32bitcafe/guestbook/internal/models"
"github.com/alexedwards/scs/sqlite3store"
@@ -20,12 +22,12 @@ type application struct {
sequence uint16
logger *slog.Logger
websites *models.WebsiteModel
- guestbooks *models.GuestbookModel
users *models.UserModel
guestbookComments *models.GuestbookCommentModel
sessionManager *scs.SessionManager
formDecoder *schema.Decoder
debug bool
+ timezones []string
}
func main() {
@@ -55,11 +57,22 @@ func main() {
logger: logger,
sessionManager: sessionManager,
websites: &models.WebsiteModel{DB: db},
- guestbooks: &models.GuestbookModel{DB: db},
- users: &models.UserModel{DB: db},
+ users: &models.UserModel{DB: db, Settings: make(map[string]models.Setting)},
guestbookComments: &models.GuestbookCommentModel{DB: db},
formDecoder: formDecoder,
debug: *debug,
+ timezones: getAvailableTimezones(),
+ }
+
+ err = app.users.InitializeSettingsMap()
+ if err != nil {
+ logger.Error(err.Error())
+ os.Exit(1)
+ }
+ err = app.websites.InitializeSettingsMap()
+ if err != nil {
+ logger.Error(err.Error())
+ os.Exit(1)
}
tlsConfig := &tls.Config{
@@ -97,3 +110,50 @@ func openDB(dsn string) (*sql.DB, error) {
}
return db, nil
}
+
+func getAvailableTimezones() []string {
+ var zones []string
+ var zoneDirs = []string{
+ "/usr/share/zoneinfo/",
+ "/usr/share/lib/zoneinfo/",
+ "/usr/lib/locale/TZ/",
+ }
+ for _, zd := range zoneDirs {
+ zones = walkTzDir(zd, zones)
+ for idx, zone := range zones {
+ zones[idx] = strings.ReplaceAll(zone, zd+"/", "")
+ }
+ }
+ return zones
+}
+
+func walkTzDir(path string, zones []string) []string {
+ fileInfos, err := os.ReadDir(path)
+ if err != nil {
+ return zones
+ }
+ isAlpha := func(s string) bool {
+ for _, r := range s {
+ if !unicode.IsLetter(r) {
+ return false
+ }
+ }
+ return true
+ }
+ for _, info := range fileInfos {
+ if info.Name() != strings.ToUpper(info.Name()[:1])+info.Name()[1:] {
+ continue
+ }
+ if !isAlpha(info.Name()[:1]) {
+ continue
+ }
+ newPath := path + "/" + info.Name()
+ if info.IsDir() {
+ zones = walkTzDir(newPath, zones)
+ } else {
+ zones = append(zones, newPath)
+ }
+ }
+ return zones
+
+}
diff --git a/cmd/web/routes.go b/cmd/web/routes.go
index cc5b6b5..c2fe48a 100644
--- a/cmd/web/routes.go
+++ b/cmd/web/routes.go
@@ -28,7 +28,8 @@ func (app *application) routes() http.Handler {
// mux.Handle("GET /users", protected.ThenFunc(app.getUsersList))
mux.Handle("GET /users/{id}", protected.ThenFunc(app.getUser))
mux.Handle("POST /users/logout", protected.ThenFunc(app.postUserLogout))
- mux.Handle("GET /users/settings", protected.ThenFunc(app.notImplemented))
+ mux.Handle("GET /users/settings", protected.ThenFunc(app.getUserSettings))
+ mux.Handle("PUT /users/settings", protected.ThenFunc(app.putUserSettings))
mux.Handle("GET /users/privacy", protected.ThenFunc(app.notImplemented))
mux.Handle("GET /guestbooks", protected.ThenFunc(app.getAllGuestbooks))
@@ -40,7 +41,8 @@ func (app *application) routes() http.Handler {
mux.Handle("GET /websites/{id}/dashboard/guestbook/comments/queue", protected.ThenFunc(app.getCommentQueue))
mux.Handle("DELETE /websites/{id}/dashboard/guestbook/comments/{commentId}", protected.ThenFunc(app.deleteGuestbookComment))
mux.Handle("PUT /websites/{id}/dashboard/guestbook/comments/{commentId}", protected.ThenFunc(app.putHideGuestbookComment))
- mux.Handle("GET /websites/{id}/dashboard/guestbook/blocklist", protected.ThenFunc(app.getComingSoon))
+ mux.Handle("GET /websites/{id}/dashboard/guestbook/settings", protected.ThenFunc(app.getGuestbookSettings))
+ mux.Handle("PUT /websites/{id}/dashboard/guestbook/settings", protected.ThenFunc(app.putGuestbookSettings))
mux.Handle("GET /websites/{id}/dashboard/guestbook/comments/trash", protected.ThenFunc(app.getCommentTrash))
mux.Handle("GET /websites/{id}/dashboard/guestbook/themes", protected.ThenFunc(app.getComingSoon))
mux.Handle("GET /websites/{id}/dashboard/guestbook/customize", protected.ThenFunc(app.getComingSoon))
diff --git a/db/create-settings-tables.sql b/db/create-settings-tables.sql
new file mode 100644
index 0000000..4708887
--- /dev/null
+++ b/db/create-settings-tables.sql
@@ -0,0 +1,76 @@
+CREATE TABLE setting_groups (
+ Id integer primary key autoincrement,
+ Description varchar(256) NOT NULL
+);
+
+CREATE TABLE setting_data_types (
+ Id integer primary key autoincrement,
+ Description varchar(64) NOT NULL
+);
+
+CREATE TABLE settings (
+ Id integer primary key autoincrement,
+ Description varchar(256) NOT NULL,
+ Constrained boolean NOT NULL,
+ DataType integer NOT NULL,
+ SettingGroup int NOT NULL,
+ MinValue varchar(6),
+ MaxValue varchar(6),
+ FOREIGN KEY (DataType) REFERENCES setting_data_types(Id)
+ ON DELETE RESTRICT
+ ON UPDATE RESTRICT,
+ FOREIGN KEY (SettingGroup) REFERENCES setting_groups(Id)
+ ON DELETE RESTRICT
+ ON UPDATE RESTRICT
+);
+
+CREATE TABLE allowed_setting_values (
+ Id integer primary key autoincrement,
+ SettingId integer NOT NULL,
+ ItemValue varchar(256),
+ Caption varchar(256),
+ FOREIGN KEY (SettingId) REFERENCES settings(Id)
+ ON DELETE RESTRICT
+ ON UPDATE RESTRICT
+);
+
+CREATE TABLE user_settings (
+ Id integer primary key autoincrement,
+ UserId integer NOT NULL,
+ SettingId integer NOT NULL,
+ AllowedSettingValueId integer,
+ UnconstrainedValue varchar(256),
+ FOREIGN KEY (UserId) REFERENCES users(Id)
+ ON DELETE RESTRICT
+ ON UPDATE RESTRICT,
+ FOREIGN KEY (SettingId) REFERENCES settings(Id)
+ ON DELETE RESTRICT
+ ON UPDATE RESTRICT,
+ FOREIGN KEY (AllowedSettingValueId) REFERENCES allowed_setting_values(Id)
+ ON DELETE RESTRICT
+ ON UPDATE RESTRICT
+);
+
+CREATE TABLE guestbook_settings (
+ Id integer primary key autoincrement,
+ GuestbookId integer NOT NULL,
+ SettingId integer NOT NULL,
+ AllowedSettingValueId integer,
+ UnconstrainedValue varchar(256),
+ FOREIGN KEY (GuestbookId) REFERENCES guestbooks(Id)
+ ON DELETE RESTRICT
+ ON UPDATE RESTRICT,
+ FOREIGN KEY (SettingId) REFERENCES settings(Id)
+ ON DELETE RESTRICT
+ ON UPDATE RESTRICT,
+ FOREIGN KEY (AllowedSettingValueId) REFERENCES allowed_setting_values(Id)
+ ON DELETE RESTRICT
+ ON UPDATE RESTRICT
+);
+
+INSERT INTO setting_groups (Description) VALUES ('guestbook');
+INSERT INTO setting_groups (Description) VALUES ('user');
+
+INSERT INTO setting_data_types (Description) VALUES ('alphanumeric');
+INSERT INTO setting_data_types (Description) VALUES ('integer');
+INSERT INTO setting_data_types (Description) VALUES ('datetime');
diff --git a/db/create-settings.sql b/db/create-settings.sql
new file mode 100644
index 0000000..87ee494
--- /dev/null
+++ b/db/create-settings.sql
@@ -0,0 +1,9 @@
+INSERT INTO setting_groups (Description) VALUES ("guestbook");
+INSERT INTO setting_groups (Description) VALUES ("user");
+
+INSERT INTO setting_data_types (Description) VALUES ("alphanumeric")
+INSERT INTO setting_data_types (Description) VALUES ("integer")
+INSERT INTO setting_data_types (Description) VALUES ("datetime")
+
+INSERT INTO settings (Description, Constrained, DataType, SettingGroup)
+VALUES ("Local Timezone", 0, 1, 1);
diff --git a/internal/forms/forms.go b/internal/forms/forms.go
index 8d5664f..2014c84 100644
--- a/internal/forms/forms.go
+++ b/internal/forms/forms.go
@@ -29,3 +29,15 @@ type WebsiteCreateForm struct {
AuthorName string `schema:"authorname"`
validator.Validator `schema:"-"`
}
+
+type UserSettingsForm struct {
+ LocalTimezone string `schema:"timezones"`
+ validator.Validator `schema:"-"`
+}
+
+type GuestbookSettingsForm struct {
+ Visibility string `schema:"gb_visible"`
+ CommentingEnabled string `schema:"gb_commenting"`
+ WidgetsEnabled string `schema:"gb_remote"`
+ validator.Validator `schema:"-"`
+}
diff --git a/internal/models/errors.go b/internal/models/errors.go
index 48a3033..2b02a0b 100644
--- a/internal/models/errors.go
+++ b/internal/models/errors.go
@@ -3,9 +3,11 @@ package models
import "errors"
var (
- ErrNoRecord = errors.New("models: no matching record found")
+ ErrNoRecord = errors.New("models: no matching record found")
- ErrInvalidCredentials = errors.New("models: invalid credentials")
+ ErrInvalidCredentials = errors.New("models: invalid credentials")
- ErrDuplicateEmail = errors.New("models: duplicate email")
+ ErrDuplicateEmail = errors.New("models: duplicate email")
+
+ ErrInvalidSettingValue = errors.New("models: invalid setting value")
)
diff --git a/internal/models/guestbook.go b/internal/models/guestbook.go
deleted file mode 100644
index 21d899e..0000000
--- a/internal/models/guestbook.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package models
-
-import (
- "database/sql"
- "time"
-)
-
-type Guestbook struct {
- ID int64
- ShortId uint64
- UserId int64
- WebsiteId int64
- Created time.Time
- Deleted time.Time
- IsActive bool
-}
-
-type GuestbookModel struct {
- DB *sql.DB
-}
-
-func (m *GuestbookModel) Insert(shortId uint64, userId int64, websiteId int64) (int64, error) {
- stmt := `INSERT INTO guestbooks (ShortId, UserId, WebsiteId, Created, IsActive)
- VALUES(?, ?, ?, ?, TRUE)`
- result, err := m.DB.Exec(stmt, shortId, userId, websiteId, time.Now().UTC())
- if err != nil {
- return -1, err
- }
- id, err := result.LastInsertId()
- if err != nil {
- return -1, err
- }
- return id, nil
-}
-
-func (m *GuestbookModel) Get(shortId uint64) (Guestbook, error) {
- stmt := `SELECT Id, ShortId, UserId, WebsiteId, Created, Deleted, IsActive FROM guestbooks
- WHERE ShortId = ?`
- row := m.DB.QueryRow(stmt, shortId)
- var g Guestbook
- var t sql.NullTime
- err := row.Scan(&g.ID, &g.ShortId, &g.UserId, &g.WebsiteId, &g.Created, &t, &g.IsActive)
- if err != nil {
- return Guestbook{}, err
- }
- if t.Valid {
- g.Deleted = t.Time
- }
- return g, nil
-}
-
-func (m *GuestbookModel) GetAll(userId int64) ([]Guestbook, error) {
- stmt := `SELECT Id, ShortId, UserId, WebsiteId, Created, IsActive FROM guestbooks
- WHERE UserId = ? AND DELETED IS NULL`
- rows, err := m.DB.Query(stmt, userId)
- if err != nil {
- return nil, err
- }
- var guestbooks []Guestbook
- for rows.Next() {
- var g Guestbook
- err = rows.Scan(&g.ID, &g.ShortId, &g.UserId, &g.WebsiteId, &g.Created, &g.IsActive)
- if err != nil {
- return nil, err
- }
- guestbooks = append(guestbooks, g)
- }
- if err = rows.Err(); err != nil {
- return nil, err
- }
- return guestbooks, nil
-}
diff --git a/internal/models/settings.go b/internal/models/settings.go
new file mode 100644
index 0000000..9ae8259
--- /dev/null
+++ b/internal/models/settings.go
@@ -0,0 +1,154 @@
+package models
+
+import (
+ "strconv"
+ "time"
+)
+
+type SettingGroup struct {
+ id int
+ description string
+}
+
+func (g *SettingGroup) Id() int {
+ return g.id
+}
+
+func (g *SettingGroup) Description() string {
+ return g.description
+}
+
+const (
+ SETTING_GROUP_USER = "user"
+ SETTING_GROUP_GUESTBOOK = "guestbook"
+)
+
+type SettingDataType struct {
+ id int
+ description string
+}
+
+func (d *SettingDataType) Id() int {
+ return d.id
+}
+
+func (d *SettingDataType) Description() string {
+ return d.description
+}
+
+const (
+ SETTING_TYPE_INTEGER = "integer"
+ SETTING_TYPE_STRING = "alphanumeric"
+ SETTING_TYPE_DATE = "datetime"
+)
+
+type Setting struct {
+ id int
+ description string
+ constrained bool
+ dataType SettingDataType
+ settingGroup SettingGroup
+ minValue string
+ maxValue string
+}
+
+func (s *Setting) Id() int {
+ return s.id
+}
+
+func (s *Setting) Description() string {
+ return s.description
+}
+
+func (s *Setting) Constrained() bool {
+ return s.constrained
+}
+
+func (s *Setting) DataType() SettingDataType {
+ return s.dataType
+}
+
+func (s *Setting) SettingGroup() SettingGroup {
+ return s.settingGroup
+}
+
+func (s *Setting) MinValue() string {
+ return s.minValue
+}
+
+func (s *Setting) MaxValue() string {
+ return s.maxValue
+}
+
+func (s *Setting) Validate(value string) bool {
+ switch s.dataType.description {
+ case SETTING_TYPE_INTEGER:
+ return s.validateInt(value)
+ case SETTING_TYPE_STRING:
+ return s.validateAlphanum(value)
+ case SETTING_TYPE_DATE:
+ return s.validateDatetime(value)
+ }
+ return false
+}
+
+func (s *Setting) validateInt(value string) bool {
+ v, err := strconv.ParseInt(value, 10, 0)
+ if err != nil {
+ return false
+ }
+ var min int64
+ var max int64
+ if len(s.minValue) > 0 {
+ min, err = strconv.ParseInt(s.minValue, 10, 0)
+ if err != nil {
+ return false
+ }
+ if v < min {
+ return false
+ }
+ }
+ if len(s.maxValue) > 0 {
+ max, err = strconv.ParseInt(s.maxValue, 10, 0)
+ if err != nil {
+ return false
+ }
+ if v < max {
+ return false
+ }
+ }
+ return true
+}
+
+func (s *Setting) validateDatetime(value string) bool {
+ v, err := time.Parse(time.RFC3339, value)
+ if err != nil {
+ return false
+ }
+ var min time.Time
+ var max time.Time
+
+ if len(s.minValue) > 0 {
+ min, err = time.Parse(time.RFC3339, s.minValue)
+ if err != nil {
+ return false
+ }
+ if v.Before(min) {
+ return false
+ }
+ }
+ if len(s.maxValue) > 0 {
+ max, err = time.Parse(time.RFC3339, s.maxValue)
+ if err != nil {
+ return false
+ }
+ if v.After(max) {
+ return false
+ }
+ }
+ return false
+}
+
+func (s *Setting) validateAlphanum(value string) bool {
+ return len(value) >= 0
+}
diff --git a/internal/models/user.go b/internal/models/user.go
index e4dfbe2..318202d 100644
--- a/internal/models/user.go
+++ b/internal/models/user.go
@@ -10,6 +10,14 @@ import (
"golang.org/x/crypto/bcrypt"
)
+type UserSettings struct {
+ LocalTimezone *time.Location
+}
+
+const (
+ SettingUserTimezone = "local_timezone"
+)
+
type User struct {
ID int64
ShortId uint64
@@ -19,20 +27,54 @@ type User struct {
IsBanned bool
HashedPassword []byte
Created time.Time
+ Settings UserSettings
}
type UserModel struct {
- DB *sql.DB
+ DB *sql.DB
+ Settings map[string]Setting
}
-func (m *UserModel) Insert(shortId uint64, username string, email string, password string) error {
+func (m *UserModel) InitializeSettingsMap() error {
+ if m.Settings == nil {
+ m.Settings = make(map[string]Setting)
+ }
+ stmt := `SELECT settings.Id, settings.Description, Constrained, d.Id, d.Description, g.Id, g.Description, MinValue, MaxValue
+ FROM settings
+ LEFT JOIN setting_data_types d ON settings.DataType = d.Id
+ LEFT JOIN setting_groups g ON settings.SettingGroup = g.Id
+ WHERE SettingGroup = (SELECT Id FROM setting_groups WHERE Description = 'user' LIMIT 1)`
+ result, err := m.DB.Query(stmt)
+ if err != nil {
+ return err
+ }
+ for result.Next() {
+ var s Setting
+ var mn sql.NullString
+ var mx sql.NullString
+ err := result.Scan(&s.id, &s.description, &s.constrained, &s.dataType.id, &s.dataType.description, &s.settingGroup.id, &s.settingGroup.description, &mn, &mx)
+ if mn.Valid {
+ s.minValue = mn.String
+ }
+ if mx.Valid {
+ s.maxValue = mx.String
+ }
+ if err != nil {
+ return err
+ }
+ m.Settings[s.description] = s
+ }
+ return nil
+}
+
+func (m *UserModel) Insert(shortId uint64, username string, email string, password string, settings UserSettings) error {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), 12)
if err != nil {
return err
}
stmt := `INSERT INTO users (ShortId, Username, Email, IsBanned, HashedPassword, Created)
VALUES (?, ?, ?, FALSE, ?, ?)`
- _, err = m.DB.Exec(stmt, shortId, username, email, hashedPassword, time.Now().UTC())
+ result, err := m.DB.Exec(stmt, shortId, username, email, hashedPassword, time.Now().UTC())
if err != nil {
if sqliteError, ok := err.(sqlite3.Error); ok {
if sqliteError.ExtendedCode == 2067 && strings.Contains(sqliteError.Error(), "Email") {
@@ -41,6 +83,14 @@ func (m *UserModel) Insert(shortId uint64, username string, email string, passwo
}
return err
}
+ id, err := result.LastInsertId()
+ if err != nil {
+ return err
+ }
+ err = m.initializeUserSettings(id, settings)
+ if err != nil {
+ return err
+ }
return nil
}
@@ -55,6 +105,11 @@ func (m *UserModel) Get(id uint64) (User, error) {
}
return User{}, err
}
+ settings, err := m.GetSettings(u.ID)
+ if err != nil {
+ return u, err
+ }
+ u.Settings = settings
return u, nil
}
@@ -69,6 +124,11 @@ func (m *UserModel) GetById(id int64) (User, error) {
}
return User{}, err
}
+ settings, err := m.GetSettings(u.ID)
+ if err != nil {
+ return u, err
+ }
+ u.Settings = settings
return u, nil
}
@@ -125,3 +185,75 @@ func (m *UserModel) Exists(id int64) (bool, error) {
err := m.DB.QueryRow(stmt, id).Scan(&exists)
return exists, err
}
+
+func (m *UserModel) GetSettings(userId int64) (UserSettings, error) {
+ stmt := `SELECT u.SettingId, a.ItemValue, u.UnconstrainedValue FROM user_settings AS u
+ LEFT JOIN allowed_setting_values AS a ON u.AllowedSettingValueId = a.Id
+ WHERE UserId = ?`
+ var settings UserSettings
+ rows, err := m.DB.Query(stmt, userId)
+ if err != nil {
+ return settings, err
+ }
+ for rows.Next() {
+ var id int
+ var itemValue sql.NullString
+ var unconstrainedValue sql.NullString
+ err = rows.Scan(&id, &itemValue, &unconstrainedValue)
+ if err != nil {
+ return settings, err
+ }
+ switch id {
+ case m.Settings[SettingUserTimezone].id:
+ settings.LocalTimezone, err = time.LoadLocation(unconstrainedValue.String)
+ if err != nil {
+ panic(err)
+ }
+ }
+ }
+ return settings, err
+}
+
+func (m *UserModel) initializeUserSettings(userId int64, settings UserSettings) error {
+ stmt := `INSERT INTO user_settings (UserId, SettingId, AllowedSettingValueId, UnconstrainedValue)
+ VALUES (?, ?, ?, ?)`
+ _, err := m.DB.Exec(stmt, userId, m.Settings[SettingUserTimezone].id, nil, settings.LocalTimezone.String())
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (m *UserModel) UpdateUserSettings(userId int64, settings UserSettings) error {
+ err := m.UpdateSetting(userId, m.Settings[SettingUserTimezone], settings.LocalTimezone.String())
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (m *UserModel) UpdateSetting(userId int64, setting Setting, value string) error {
+ valid := setting.Validate(value)
+ if !valid {
+ return ErrInvalidSettingValue
+ }
+ stmt := `UPDATE user_settings SET
+ AllowedSettingValueId=IFNULL(
+ (SELECT Id FROM allowed_setting_values WHERE SettingId = user_settings.SettingId AND ItemValue = ?), AllowedSettingValueId
+ ),
+ UnconstrainedValue=(SELECT ? FROM settings WHERE settings.Id = user_settings.SettingId AND settings.Constrained=0)
+ WHERE userId = ?
+ AND SettingId = (SELECT Id from Settings WHERE Description=?);`
+ result, err := m.DB.Exec(stmt, value, value, userId, setting.description)
+ if err != nil {
+ return err
+ }
+ rows, err := result.RowsAffected()
+ if err != nil {
+ return err
+ }
+ if rows != 1 {
+ return ErrInvalidSettingValue
+ }
+ return nil
+}
diff --git a/internal/models/website.go b/internal/models/website.go
index 4142697..456c92d 100644
--- a/internal/models/website.go
+++ b/internal/models/website.go
@@ -2,6 +2,8 @@ package models
import (
"database/sql"
+ "errors"
+ "strconv"
"time"
)
@@ -17,51 +19,206 @@ type Website struct {
Guestbook Guestbook
}
+type GuestbookSettings struct {
+ IsCommentingEnabled bool
+ ReenableCommenting time.Time
+ IsVisible bool
+ FilteredWords []string
+ AllowRemoteHostAccess bool
+}
+
+var ValidDisableDurations = []string{"true", "false", "1h", "4h", "8h", "24h", "72h", "168h"}
+
+const (
+ SettingGbCommentingEnabled = "commenting_enabled"
+ SettingGbReenableComments = "reenable_comments"
+ SettingGbVisible = "is_visible"
+ SettingGbFilteredWords = "filtered_words"
+ SettingGbAllowRemote = "remote_enabled"
+)
+
+type Guestbook struct {
+ ID int64
+ ShortId uint64
+ UserId int64
+ WebsiteId int64
+ Created time.Time
+ Deleted time.Time
+ IsActive bool
+ Settings GuestbookSettings
+}
+
+func (g Guestbook) CanComment() bool {
+ now := time.Now().UTC()
+ return g.Settings.IsCommentingEnabled && g.Settings.ReenableCommenting.Before(now)
+}
+
type WebsiteModel struct {
- DB *sql.DB
+ DB *sql.DB
+ Settings map[string]Setting
+}
+
+func (m *WebsiteModel) InitializeSettingsMap() error {
+ if m.Settings == nil {
+ m.Settings = make(map[string]Setting)
+ }
+ stmt := `SELECT settings.Id, settings.Description, Constrained, d.Id, d.Description, g.Id, g.Description, MinValue, MaxValue
+ FROM settings
+ LEFT JOIN setting_data_types d ON settings.DataType = d.Id
+ LEFT JOIN setting_groups g ON settings.SettingGroup = g.Id
+ WHERE SettingGroup = (SELECT Id FROM setting_groups WHERE Description = 'guestbook' LIMIT 1)`
+ result, err := m.DB.Query(stmt)
+ if err != nil {
+ return err
+ }
+ for result.Next() {
+ var s Setting
+ var mn sql.NullString
+ var mx sql.NullString
+ err := result.Scan(&s.id, &s.description, &s.constrained, &s.dataType.id, &s.dataType.description, &s.settingGroup.id, &s.settingGroup.description, &mn, &mx)
+ if mn.Valid {
+ s.minValue = mn.String
+ }
+ if mx.Valid {
+ s.maxValue = mx.String
+ }
+ if err != nil {
+ return err
+ }
+ m.Settings[s.description] = s
+ }
+ return nil
}
func (m *WebsiteModel) Insert(shortId uint64, userId int64, siteName, siteUrl, authorName string) (int64, error) {
stmt := `INSERT INTO websites (ShortId, Name, SiteUrl, AuthorName, UserId, Created)
VALUES (?, ?, ?, ?, ?, ?)`
- result, err := m.DB.Exec(stmt, shortId, siteName, siteUrl, authorName, userId, time.Now().UTC())
+ tx, err := m.DB.Begin()
if err != nil {
return -1, err
}
- id, err := result.LastInsertId()
+
+ result, err := tx.Exec(stmt, shortId, siteName, siteUrl, authorName, userId, time.Now().UTC())
+ // result, err := m.DB.Exec(stmt, shortId, siteName, siteUrl, authorName, userId, time.Now().UTC())
if err != nil {
+ if rollbackError := tx.Rollback(); rollbackError != nil {
+ return -1, err
+ }
return -1, err
}
- return id, nil
+ websiteId, err := result.LastInsertId()
+ if err != nil {
+ if rollbackError := tx.Rollback(); rollbackError != nil {
+ return -1, err
+ }
+ return -1, err
+ }
+
+ stmt = `INSERT INTO guestbooks (ShortId, UserId, WebsiteId, Created, IsActive)
+ VALUES(?, ?, ?, ?, TRUE)`
+ result, err = tx.Exec(stmt, shortId, userId, websiteId, time.Now().UTC())
+ if err != nil {
+ if rollbackError := tx.Rollback(); rollbackError != nil {
+ return -1, err
+ }
+ return -1, err
+ }
+ guestbookId, err := result.LastInsertId()
+ if err != nil {
+ if rollbackError := tx.Rollback(); rollbackError != nil {
+ return -1, err
+ }
+ return -1, err
+ }
+
+ settings := GuestbookSettings{
+ IsCommentingEnabled: true,
+ IsVisible: true,
+ AllowRemoteHostAccess: true,
+ }
+ stmt = `INSERT INTO guestbook_settings (GuestbookId, SettingId, AllowedSettingValueId, UnconstrainedValue) VALUES
+ (?, ?, ?, ?),
+ (?, ?, ?, ?),
+ (?, ?, ?, ?),
+ (?, ?, ?, ?)`
+ _, err = tx.Exec(stmt,
+ guestbookId, m.Settings[SettingGbCommentingEnabled].id, settings.IsCommentingEnabled, nil,
+ guestbookId, m.Settings[SettingGbReenableComments].id, nil, settings.ReenableCommenting.Format(time.RFC3339),
+ guestbookId, m.Settings[SettingGbVisible].id, settings.IsVisible, nil,
+ guestbookId, m.Settings[SettingGbAllowRemote].id, settings.AllowRemoteHostAccess, nil)
+ if err != nil {
+ if rollbackError := tx.Rollback(); rollbackError != nil {
+ return -1, err
+ }
+ return -1, err
+ }
+
+ if err := tx.Commit(); err != nil {
+ return -1, err
+ }
+ return websiteId, nil
}
func (m *WebsiteModel) Get(shortId uint64) (Website, error) {
- stmt := `SELECT w.Id, w.ShortId, w.Name, w.SiteUrl, w.AuthorName, w.UserId, w.Created,
- g.Id, g.ShortId, g.Created, g.IsActive
- FROM websites AS w INNER JOIN guestbooks AS g ON w.Id = g.WebsiteId
+ stmt := `SELECT w.Id, w.ShortId, w.Name, w.SiteUrl, w.AuthorName, w.UserId, w.Created
+ FROM websites AS w
WHERE w.ShortId = ? AND w.DELETED IS NULL`
- row := m.DB.QueryRow(stmt, shortId)
- var w Website
- err := row.Scan(&w.ID, &w.ShortId, &w.Name, &w.SiteUrl, &w.AuthorName, &w.UserId, &w.Created,
- &w.Guestbook.ID, &w.Guestbook.ShortId, &w.Guestbook.Created, &w.Guestbook.IsActive)
+ tx, err := m.DB.Begin()
if err != nil {
+ return Website{}, nil
+ }
+ row := tx.QueryRow(stmt, shortId)
+ var w Website
+ err = row.Scan(&w.ID, &w.ShortId, &w.Name, &w.SiteUrl, &w.AuthorName, &w.UserId, &w.Created)
+ if err != nil {
+ if errors.Is(err, sql.ErrNoRows) {
+ err = ErrNoRecord
+ }
+ if rollbackErr := tx.Rollback(); rollbackErr != nil {
+ return Website{}, err
+ }
return Website{}, err
}
- return w, nil
-}
-func (m *WebsiteModel) GetById(id int64) (Website, error) {
- stmt := `SELECT w.Id, w.ShortId, w.Name, w.SiteUrl, w.AuthorName, w.UserId, w.Created,
- g.Id, g.ShortId, g.Created, g.IsActive
- FROM websites AS w INNER JOIN guestbooks AS g ON w.Id = g.WebsiteId
- WHERE w.Id = ? AND w.DELETED IS NULL`
- row := m.DB.QueryRow(stmt, id)
- var w Website
- err := row.Scan(&w.ID, &w.ShortId, &w.Name, &w.SiteUrl, &w.AuthorName, &w.UserId, &w.Created,
- &w.Guestbook.ID, &w.Guestbook.ShortId, &w.Guestbook.Created, &w.Guestbook.IsActive)
+ stmt = `SELECT Id, ShortId, UserId, WebsiteId, Created, IsActive FROM guestbooks
+ WHERE WebsiteId = ? AND Deleted IS NULL`
+ row = tx.QueryRow(stmt, w.ID)
+ var g Guestbook
+ err = row.Scan(&g.ID, &g.ShortId, &g.UserId, &g.WebsiteId, &g.Created, &g.IsActive)
if err != nil {
+ if errors.Is(err, sql.ErrNoRows) {
+ err = ErrNoRecord
+ }
+ if rollbackErr := tx.Rollback(); rollbackErr != nil {
+ return Website{}, err
+ }
return Website{}, err
}
+
+ gbSettings, err := m.getGuestbookSettings(tx, g.ID)
+ if err != nil {
+ if errors.Is(err, sql.ErrNoRows) {
+ err = ErrNoRecord
+ }
+ if rollbackErr := tx.Rollback(); rollbackErr != nil {
+ return Website{}, err
+ }
+ return Website{}, err
+ }
+
+ err = tx.Commit()
+ if err != nil {
+ return Website{}, nil
+ }
+
+ // if comment disable setting has expired, enable commenting
+ commentingReenabled := time.Now().UTC().After(gbSettings.ReenableCommenting)
+ if commentingReenabled {
+ gbSettings.IsCommentingEnabled = true
+ }
+
+ g.Settings = gbSettings
+ w.Guestbook = g
return w, nil
}
@@ -113,3 +270,92 @@ func (m *WebsiteModel) GetAll() ([]Website, error) {
}
return websites, nil
}
+
+func (m *WebsiteModel) getGuestbookSettings(tx *sql.Tx, guestbookId int64) (GuestbookSettings, error) {
+ stmt := `SELECT g.SettingId, a.ItemValue, g.UnconstrainedValue FROM guestbook_settings AS g
+ LEFT JOIN allowed_setting_values AS a ON g.AllowedSettingValueId = a.Id
+ WHERE GuestbookId = ?`
+ var settings GuestbookSettings
+ rows, err := tx.Query(stmt, guestbookId)
+ if err != nil {
+ return settings, err
+ }
+ for rows.Next() {
+ var id int
+ var itemValue sql.NullString
+ var unconstrainedValue sql.NullString
+ err = rows.Scan(&id, &itemValue, &unconstrainedValue)
+ if err != nil {
+ return settings, err
+ }
+ switch id {
+ case m.Settings[SettingGbCommentingEnabled].id:
+ settings.IsCommentingEnabled, err = strconv.ParseBool(itemValue.String)
+ if err != nil {
+ return settings, err
+ }
+ break
+ case m.Settings[SettingGbReenableComments].id:
+ settings.ReenableCommenting, err = time.Parse(time.RFC3339, unconstrainedValue.String)
+ if err != nil {
+ return settings, err
+ }
+ break
+ case m.Settings[SettingGbVisible].id:
+ settings.IsVisible, err = strconv.ParseBool(itemValue.String)
+ if err != nil {
+ return settings, err
+ }
+ break
+ case m.Settings[SettingGbAllowRemote].id:
+ settings.AllowRemoteHostAccess, err = strconv.ParseBool(itemValue.String)
+ if err != nil {
+ return settings, err
+ }
+ break
+ }
+ }
+ return settings, nil
+}
+
+func (m *WebsiteModel) UpdateGuestbookSettings(guestbookId int64, settings GuestbookSettings) error {
+ err := m.UpdateSetting(guestbookId, m.Settings[SettingGbVisible], strconv.FormatBool(settings.IsVisible))
+ if err != nil {
+ return err
+ }
+ err = m.UpdateSetting(guestbookId, m.Settings[SettingGbAllowRemote], strconv.FormatBool(settings.AllowRemoteHostAccess))
+ if err != nil {
+ return err
+ }
+ err = m.UpdateSetting(guestbookId, m.Settings[SettingGbCommentingEnabled], strconv.FormatBool(settings.IsCommentingEnabled))
+ if err != nil {
+ return err
+ }
+ err = m.UpdateSetting(guestbookId, m.Settings[SettingGbReenableComments], settings.ReenableCommenting.Format(time.RFC3339))
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (m *WebsiteModel) UpdateSetting(guestbookId int64, setting Setting, value string) error {
+ stmt := `UPDATE guestbook_settings SET
+ AllowedSettingValueId=IFNULL(
+ (SELECT Id FROM allowed_setting_values WHERE SettingId = guestbook_settings.SettingId AND ItemValue = ?), AllowedSettingValueId
+ ),
+ UnconstrainedValue=(SELECT ? FROM settings WHERE settings.Id = guestbook_settings.SettingId AND settings.Constrained=0)
+ WHERE GuestbookId = ?
+ AND SettingId = (SELECT Id from Settings WHERE Description=?);`
+ result, err := m.DB.Exec(stmt, value, value, guestbookId, setting.description)
+ if err != nil {
+ return err
+ }
+ rows, err := result.RowsAffected()
+ if err != nil {
+ return err
+ }
+ if rows != 1 {
+ return ErrInvalidSettingValue
+ }
+ return nil
+}
diff --git a/ui/views/guestbooks.templ b/ui/views/guestbooks.templ
index a8d56b7..5ad5583 100644
--- a/ui/views/guestbooks.templ
+++ b/ui/views/guestbooks.templ
@@ -3,168 +3,229 @@ package views
import "fmt"
import "git.32bit.cafe/32bitcafe/guestbook/internal/models"
import "git.32bit.cafe/32bitcafe/guestbook/internal/forms"
+import "time"
templ GuestbookDashboardCommentsView(title string, data CommonData, website models.Website, guestbook models.Guestbook, comments []models.GuestbookComment) {
- @base(title, data) {
-
- @wSidebar(website)
-
-
Comments on { website.SiteUrl }
-
- if len(comments) == 0 {
-
No comments yet!
- }
- for _, c := range comments {
- @GuestbookDashboardCommentView(data, website, c)
- }
-
-
- }
+ @base(title, data) {
+
+ @wSidebar(website)
+
+
Comments on { website.SiteUrl }
+
+ if len(comments) == 0 {
+
No comments yet!
+ }
+ for _, c := range comments {
+ @GuestbookDashboardCommentView(data, website, c)
+ }
+
+
+ }
}
templ GuestbookDashboardCommentView(data CommonData, w models.Website, c models.GuestbookComment) {
- {{ commentUrl := fmt.Sprintf("%s/dashboard/guestbook/comments/%s", wUrl(w), shortIdToSlug(c.ShortId)) }}
- {{ hxHeaders := fmt.Sprintf("{\"X-CSRF-Token\": \"%s\"}", data.CSRFToken) }}
-
+ {{ commentUrl := fmt.Sprintf("%s/dashboard/guestbook/comments/%s", wUrl(w), shortIdToSlug(c.ShortId)) }}
+ {{ hxHeaders := fmt.Sprintf("{\"X-CSRF-Token\": \"%s\"}", data.CSRFToken) }}
+
}
templ commentForm(form forms.CommentCreateForm) {
-
-
- {{ error, exists := form.FieldErrors["authorName"] }}
- if exists {
-
- }
-
-
-
-
- {{ error, exists = form.FieldErrors["authorEmail"] }}
- if exists {
-
- }
-
-
-
-
- {{ error, exists = form.FieldErrors["authorSite"] }}
- if exists {
-
- }
-
-
-
-
- {{ error, exists = form.FieldErrors["content"] }}
- if exists {
-
- }
-
-
-
-
-
+
+
+ {{ error, exists := form.FieldErrors["authorName"] }}
+ if exists {
+
+ }
+
+
+
+
+ {{ error, exists = form.FieldErrors["authorEmail"] }}
+ if exists {
+
+ }
+
+
+
+
+ {{ error, exists = form.FieldErrors["authorSite"] }}
+ if exists {
+
+ }
+
+
+
+
+ {{ error, exists = form.FieldErrors["content"] }}
+ if exists {
+
+ }
+
+
+
+
+
}
templ GuestbookView(title string, data CommonData, website models.Website, guestbook models.Guestbook, comments []models.GuestbookComment, form forms.CommentCreateForm) {
- {{ postUrl := fmt.Sprintf("/websites/%s/guestbook/comments/create", shortIdToSlug(website.ShortId)) }}
- if data.IsHtmx {
- @commentForm(form)
- } else {
-
-
- { title }
-
-
-
-
-
-
Guestbook for { website.Name }
-
-
-
-
-
-
- }
- }
+ {{ postUrl := fmt.Sprintf("/websites/%s/guestbook/comments/create", shortIdToSlug(website.ShortId)) }}
+ if data.IsHtmx {
+ @commentForm(form)
+ } else {
+
+
+ { title }
+
+
+
+
+
+
Guestbook for { website.Name }
+
+
+
+
+
+
+ }
+}
- templ CreateGuestbookComment(title string, data CommonData, website models.Website, guestbook models.Guestbook, form forms.CommentCreateForm) {
- {{ postUrl := fmt.Sprintf("/websites/%s/guestbook/comments/create", shortIdToSlug(website.ShortId)) }}
- if data.IsHtmx {
-
- } else {
- @base(title, data) {
-
- }
- }
+templ CreateGuestbookComment(title string, data CommonData, website models.Website, guestbook models.Guestbook, form forms.CommentCreateForm) {
+ {{ postUrl := fmt.Sprintf("/websites/%s/guestbook/comments/create", shortIdToSlug(website.ShortId)) }}
+ if data.IsHtmx {
+
+ } else {
+ @base(title, data) {
+
+ }
+ }
+}
+
+templ settingRadio(selected bool, name, id, value string) {
+
+}
+
+templ GuestbookSettingsView(data CommonData, website models.Website) {
+ {{ putUrl := fmt.Sprintf("/websites/%s/dashboard/guestbook/settings", shortIdToSlug(website.ShortId)) }}
+ {{ gb := website.Guestbook }}
+ @base("Guestbook Settings", data) {
+
+ }
}
templ AllGuestbooksView(data CommonData, websites []models.Website) {
- @base("All Guestbooks", data) {
-
-
All Guestbooks
-
- This page exists only for testing the service.
-
-
- for _, w := range websites {
- -
- {{ gbUrl := fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(w.ShortId))}}
- { w.Name }
-
- }
-
-
- }
-}
\ No newline at end of file
+ @base("All Guestbooks", data) {
+
+
All Guestbooks
+
+ This page exists only for testing the service.
+
+
+ for _, w := range websites {
+ -
+ {{ gbUrl := fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(w.ShortId)) }}
+ { w.Name }
+
+ }
+
+
+ }
+}
diff --git a/ui/views/guestbooks_templ.go b/ui/views/guestbooks_templ.go
index aab14aa..5a9bf27 100644
--- a/ui/views/guestbooks_templ.go
+++ b/ui/views/guestbooks_templ.go
@@ -11,6 +11,7 @@ import templruntime "github.com/a-h/templ/runtime"
import "fmt"
import "git.32bit.cafe/32bitcafe/guestbook/internal/models"
import "git.32bit.cafe/32bitcafe/guestbook/internal/forms"
+import "time"
func GuestbookDashboardCommentsView(title string, data CommonData, website models.Website, guestbook models.Guestbook, comments []models.GuestbookComment) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
@@ -60,7 +61,7 @@ func GuestbookDashboardCommentsView(title string, data CommonData, website model
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(website.SiteUrl)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 12, Col: 49}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 13, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
@@ -131,7 +132,7 @@ func GuestbookDashboardCommentView(data CommonData, w models.Website, c models.G
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(commentUrl)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 31, Col: 61}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 32, Col: 49}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
@@ -144,7 +145,7 @@ func GuestbookDashboardCommentView(data CommonData, w models.Website, c models.G
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(hxHeaders)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 31, Col: 118}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 32, Col: 106}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
@@ -157,7 +158,7 @@ func GuestbookDashboardCommentView(data CommonData, w models.Website, c models.G
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(commentUrl)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 32, Col: 59}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 33, Col: 47}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@@ -170,7 +171,7 @@ func GuestbookDashboardCommentView(data CommonData, w models.Website, c models.G
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(hxHeaders)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 32, Col: 116}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 33, Col: 104}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
@@ -203,7 +204,7 @@ func GuestbookDashboardCommentView(data CommonData, w models.Website, c models.G
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(c.AuthorName)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 42, Col: 34}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 43, Col: 25}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
@@ -231,7 +232,7 @@ func GuestbookDashboardCommentView(data CommonData, w models.Website, c models.G
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(c.AuthorEmail)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 45, Col: 78}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 46, Col: 66}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
@@ -259,7 +260,7 @@ func GuestbookDashboardCommentView(data CommonData, w models.Website, c models.G
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(c.AuthorSite)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 48, Col: 96}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 49, Col: 85}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
@@ -275,9 +276,9 @@ func GuestbookDashboardCommentView(data CommonData, w models.Website, c models.G
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
- templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(c.Created.Format("01-02-2006 03:04PM"))
+ templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(c.Created.In(data.CurrentUser.Settings.LocalTimezone).Format("01-02-2006 03:04PM"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 51, Col: 56}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 52, Col: 88}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
@@ -290,7 +291,7 @@ func GuestbookDashboardCommentView(data CommonData, w models.Website, c models.G
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(c.CommentText)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 55, Col: 27}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 56, Col: 18}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
@@ -338,7 +339,7 @@ func commentForm(form forms.CommentCreateForm) templ.Component {
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(error)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 66, Col: 36}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 67, Col: 31}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
@@ -362,7 +363,7 @@ func commentForm(form forms.CommentCreateForm) templ.Component {
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(error)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 74, Col: 36}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 75, Col: 31}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
@@ -386,7 +387,7 @@ func commentForm(form forms.CommentCreateForm) templ.Component {
var templ_7745c5c3_Var19 string
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(error)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 82, Col: 36}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 83, Col: 31}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
@@ -410,7 +411,7 @@ func commentForm(form forms.CommentCreateForm) templ.Component {
var templ_7745c5c3_Var20 string
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(error)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 90, Col: 36}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 91, Col: 31}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
if templ_7745c5c3_Err != nil {
@@ -464,7 +465,7 @@ func GuestbookView(title string, data CommonData, website models.Website, guestb
var templ_7745c5c3_Var22 string
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(title)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 106, Col: 26}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 107, Col: 18}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
if templ_7745c5c3_Err != nil {
@@ -477,7 +478,7 @@ func GuestbookView(title string, data CommonData, website models.Website, guestb
var templ_7745c5c3_Var23 string
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 112, Col: 56}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 113, Col: 38}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
if templ_7745c5c3_Err != nil {
@@ -499,7 +500,7 @@ func GuestbookView(title string, data CommonData, website models.Website, guestb
var templ_7745c5c3_Var25 string
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(data.CSRFToken)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 114, Col: 88}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 115, Col: 68}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
if templ_7745c5c3_Err != nil {
@@ -531,7 +532,7 @@ func GuestbookView(title string, data CommonData, website models.Website, guestb
var templ_7745c5c3_Var26 string
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(c.AuthorName)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 124, Col: 50}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 125, Col: 26}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
if templ_7745c5c3_Err != nil {
@@ -544,7 +545,7 @@ func GuestbookView(title string, data CommonData, website models.Website, guestb
var templ_7745c5c3_Var27 string
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(c.Created.Format("01-02-2006 03:04PM"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 125, Col: 72}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 126, Col: 48}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
if templ_7745c5c3_Err != nil {
@@ -557,7 +558,7 @@ func GuestbookView(title string, data CommonData, website models.Website, guestb
var templ_7745c5c3_Var28 string
templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(c.CommentText)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 127, Col: 51}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 128, Col: 24}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
if templ_7745c5c3_Err != nil {
@@ -607,7 +608,7 @@ func CreateGuestbookComment(title string, data CommonData, website models.Websit
var templ_7745c5c3_Var30 string
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(postUrl)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 141, Col: 35}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 142, Col: 25}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
if templ_7745c5c3_Err != nil {
@@ -670,7 +671,7 @@ func CreateGuestbookComment(title string, data CommonData, website models.Websit
})
}
-func AllGuestbooksView(data CommonData, websites []models.Website) templ.Component {
+func settingRadio(selected bool, name, id, value string) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@@ -691,7 +692,87 @@ func AllGuestbooksView(data CommonData, websites []models.Website) templ.Compone
templ_7745c5c3_Var33 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Var34 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func GuestbookSettingsView(data CommonData, website models.Website) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var37 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var37 == nil {
+ templ_7745c5c3_Var37 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ putUrl := fmt.Sprintf("/websites/%s/dashboard/guestbook/settings", shortIdToSlug(website.ShortId))
+ gb := website.Guestbook
+ templ_7745c5c3_Var38 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
@@ -703,50 +784,241 @@ func AllGuestbooksView(data CommonData, websites []models.Website) templ.Compone
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "All Guestbooks
This page exists only for testing the service.
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- for _, w := range websites {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "
- ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- gbUrl := fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(w.ShortId))
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var36 string
- templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(w.Name)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 164, Col: 77}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "
")
+ templ_7745c5c3_Err = wSidebar(website).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if !website.Guestbook.CanComment() {
+ localtime := gb.Settings.ReenableCommenting.In(data.CurrentUser.Settings.LocalTimezone)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
- templ_7745c5c3_Err = base("All Guestbooks", data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var34), templ_7745c5c3_Buffer)
+ templ_7745c5c3_Err = base("Guestbook Settings", data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var38), templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func AllGuestbooksView(data CommonData, websites []models.Website) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var44 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var44 == nil {
+ templ_7745c5c3_Var44 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Var45 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "All Guestbooks
This page exists only for testing the service.
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ for _, w := range websites {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "- ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ gbUrl := fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(w.ShortId))
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var47 string
+ templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(w.Name)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/guestbooks.templ`, Line: 225, Col: 59}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+ templ_7745c5c3_Err = base("All Guestbooks", data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var45), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/ui/views/users.templ b/ui/views/users.templ
index 46467c8..4fb839b 100644
--- a/ui/views/users.templ
+++ b/ui/views/users.templ
@@ -5,79 +5,99 @@ import (
"git.32bit.cafe/32bitcafe/guestbook/internal/models"
)
-templ UserLogin (title string, data CommonData, form forms.UserLoginForm) {
- @base(title, data) {
- Login
-
- }
+templ UserLogin(title string, data CommonData, form forms.UserLoginForm) {
+ @base(title, data) {
+ Login
+
+ }
}
-templ UserRegistration (title string, data CommonData, form forms.UserRegistrationForm) {
- @base(title, data) {
- User Registration
-
- }
+templ UserRegistration(title string, data CommonData, form forms.UserRegistrationForm) {
+ @base(title, data) {
+ User Registration
+
+ }
}
-templ UserProfile (title string, data CommonData, user models.User) {
- @base(title, data) {
- { user.Username }
- { user.Email }
- }
+templ UserProfile(title string, data CommonData, user models.User) {
+ @base(title, data) {
+ { user.Username }
+ { user.Email }
+ }
}
-templ UserSettings () {
+templ UserSettingsView(data CommonData, timezones []string) {
+ {{ user := data.CurrentUser }}
+ @base("User Settings", data) {
+
+
User Settings
+
+
+ }
}
diff --git a/ui/views/users_templ.go b/ui/views/users_templ.go
index 661a6f5..c791e2d 100644
--- a/ui/views/users_templ.go
+++ b/ui/views/users_templ.go
@@ -53,7 +53,7 @@ func UserLogin(title string, data CommonData, form forms.UserLoginForm) templ.Co
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(data.CSRFToken)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 12, Col: 73}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 12, Col: 64}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
@@ -71,7 +71,7 @@ func UserLogin(title string, data CommonData, form forms.UserLoginForm) templ.Co
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(error)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 14, Col: 42}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 14, Col: 30}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
@@ -95,7 +95,7 @@ func UserLogin(title string, data CommonData, form forms.UserLoginForm) templ.Co
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(error)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 20, Col: 48}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 20, Col: 33}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
@@ -113,7 +113,7 @@ func UserLogin(title string, data CommonData, form forms.UserLoginForm) templ.Co
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(form.Email)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 22, Col: 66}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 22, Col: 55}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
@@ -132,7 +132,7 @@ func UserLogin(title string, data CommonData, form forms.UserLoginForm) templ.Co
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(error)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 28, Col: 48}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 28, Col: 33}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@@ -197,7 +197,7 @@ func UserRegistration(title string, data CommonData, form forms.UserRegistration
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(data.CSRFToken)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 43, Col: 73}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 43, Col: 64}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
@@ -220,7 +220,7 @@ func UserRegistration(title string, data CommonData, form forms.UserRegistration
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(error)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 48, Col: 48}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 48, Col: 33}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
@@ -238,7 +238,7 @@ func UserRegistration(title string, data CommonData, form forms.UserRegistration
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(form.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 50, Col: 81}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 50, Col: 70}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
@@ -261,7 +261,7 @@ func UserRegistration(title string, data CommonData, form forms.UserRegistration
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(error)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 56, Col: 48}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 56, Col: 33}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
@@ -279,7 +279,7 @@ func UserRegistration(title string, data CommonData, form forms.UserRegistration
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(form.Email)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 58, Col: 76}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 58, Col: 65}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
@@ -302,7 +302,7 @@ func UserRegistration(title string, data CommonData, form forms.UserRegistration
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(error)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 64, Col: 48}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 64, Col: 33}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
@@ -367,7 +367,7 @@ func UserProfile(title string, data CommonData, user models.User) templ.Componen
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(user.Username)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 77, Col: 27}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 77, Col: 21}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
@@ -380,7 +380,7 @@ func UserProfile(title string, data CommonData, user models.User) templ.Componen
var templ_7745c5c3_Var19 string
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(user.Email)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 78, Col: 23}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users.templ`, Line: 78, Col: 17}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
@@ -400,7 +400,7 @@ func UserProfile(title string, data CommonData, user models.User) templ.Componen
})
}
-func UserSettings() templ.Component {
+func UserSettingsView(data CommonData, timezones []string) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@@ -421,6 +421,111 @@ func UserSettings() templ.Component {
templ_7745c5c3_Var20 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
+ user := data.CurrentUser
+ templ_7745c5c3_Var21 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "User Settings
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+ templ_7745c5c3_Err = base("User Settings", data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var21), templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
return nil
})
}
diff --git a/ui/views/websites.templ b/ui/views/websites.templ
index 5dbf533..d778676 100644
--- a/ui/views/websites.templ
+++ b/ui/views/websites.templ
@@ -4,151 +4,141 @@ import "fmt"
import "git.32bit.cafe/32bitcafe/guestbook/internal/models"
import "git.32bit.cafe/32bitcafe/guestbook/internal/forms"
-func wUrl (w models.Website) string {
- return fmt.Sprintf("/websites/%s", shortIdToSlug(w.ShortId))
+func wUrl(w models.Website) string {
+ return fmt.Sprintf("/websites/%s", shortIdToSlug(w.ShortId))
}
templ wSidebar(website models.Website) {
- {{ dashUrl := wUrl(website) + "/dashboard" }}
- {{ gbUrl := wUrl(website) + "/guestbook" }}
-
+ {{ dashUrl := wUrl(website) + "/dashboard" }}
+ {{ gbUrl := wUrl(website) + "/guestbook" }}
+
}
-templ displayWebsites (websites []models.Website) {
- if len(websites) == 0 {
- No Websites yet. Register a website.
- } else {
-
- for _, w := range websites {
- -
- { w.Name }
-
- }
-
- }
+templ displayWebsites(websites []models.Website) {
+ if len(websites) == 0 {
+ No Websites yet. Register a website.
+ } else {
+
+ for _, w := range websites {
+ -
+ { w.Name }
+
+ }
+
+ }
}
templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) {
-
-
- {{ err, exists := form.FieldErrors["sitename"]}}
-
- if exists {
-
- }
-
-
-
- {{ err, exists = form.FieldErrors["siteurl"] }}
-
- if exists {
-
- }
-
-
-
- {{ err, exists = form.FieldErrors["authorname"] }}
-
- if exists {
-
- }
-
-
-
-
-
+
+
+ {{ err, exists := form.FieldErrors["sitename"] }}
+
+ if exists {
+
+ }
+
+
+
+ {{ err, exists = form.FieldErrors["siteurl"] }}
+
+ if exists {
+
+ }
+
+
+
+ {{ err, exists = form.FieldErrors["authorname"] }}
+
+ if exists {
+
+ }
+
+
+
+
+
}
templ WebsiteCreateButton() {
-
+
}
templ WebsiteList(title string, data CommonData, websites []models.Website) {
- if data.IsHtmx {
- @displayWebsites(websites)
- } else {
- @base(title, data) {
- My Websites
-
- @WebsiteCreateButton()
-
-
- @displayWebsites(websites)
-
- }
- }
+ @base(title, data) {
+ My Websites
+
+ @WebsiteCreateButton()
+
+
+ @displayWebsites(websites)
+
+ }
}
templ WebsiteDashboard(title string, data CommonData, website models.Website) {
- @base(title, data) {
-
- @wSidebar(website)
-
-
{ website.Name }
-
- Stats and stuff will go here.
-
-
-
- }
+ @base(title, data) {
+
+ @wSidebar(website)
+
+
{ website.Name }
+
+ Stats and stuff will go here.
+
+
+
+ }
}
templ WebsiteDashboardComingSoon(title string, data CommonData, website models.Website) {
- @base(title, data) {
-
- @wSidebar(website)
-
-
{ website.Name }
-
- Coming Soon
-
-
-
- }
+ @base(title, data) {
+
+ @wSidebar(website)
+
+
{ website.Name }
+
+ Coming Soon
+
+
+
+ }
}
templ WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm) {
- if data.IsHtmx {
-
- } else {
-
- }
-}
\ No newline at end of file
+
+}
diff --git a/ui/views/websites_hx.templ b/ui/views/websites_hx.templ
new file mode 100644
index 0000000..28ba2eb
--- /dev/null
+++ b/ui/views/websites_hx.templ
@@ -0,0 +1,7 @@
+package views
+
+import "git.32bit.cafe/32bitcafe/guestbook/internal/models"
+
+templ HxWebsiteList(websites []models.Website) {
+ @displayWebsites(websites)
+}
diff --git a/ui/views/websites_hx_templ.go b/ui/views/websites_hx_templ.go
new file mode 100644
index 0000000..cb3cbf2
--- /dev/null
+++ b/ui/views/websites_hx_templ.go
@@ -0,0 +1,42 @@
+// Code generated by templ - DO NOT EDIT.
+
+// templ: version: v0.3.833
+package views
+
+//lint:file-ignore SA4006 This context is only used if a nested component is present.
+
+import "github.com/a-h/templ"
+import templruntime "github.com/a-h/templ/runtime"
+
+import "git.32bit.cafe/32bitcafe/guestbook/internal/models"
+
+func HxWebsiteList(websites []models.Website) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ 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 = displayWebsites(websites).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+var _ = templruntime.GeneratedTemplate
diff --git a/ui/views/websites_templ.go b/ui/views/websites_templ.go
index fbe1f45..2d6d6a6 100644
--- a/ui/views/websites_templ.go
+++ b/ui/views/websites_templ.go
@@ -46,7 +46,7 @@ func wSidebar(website models.Website) templ.Component {
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 16, Col: 30}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 16, Col: 21}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
@@ -101,21 +101,21 @@ func wSidebar(website models.Website) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var8 templ.SafeURL = templ.URL(dashUrl + "/guestbook/blocklist")
+ var templ_7745c5c3_Var8 templ.SafeURL = templ.URL(dashUrl + "/guestbook/comments/trash")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var8)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\">Block usersTrashTrash- My Websites
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = WebsiteCreateButton().Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
templ_7745c5c3_Err = displayWebsites(websites).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- } else {
- templ_7745c5c3_Var22 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
- templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
- templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
- if !templ_7745c5c3_IsBuffer {
- defer func() {
- templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err == nil {
- templ_7745c5c3_Err = templ_7745c5c3_BufErr
- }
- }()
- }
- ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
My Websites
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = WebsiteCreateButton().Render(ctx, templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = displayWebsites(websites).Render(ctx, templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- return nil
- })
- templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var22), templ_7745c5c3_Buffer)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
+ return nil
+ })
+ templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var22), templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
}
return nil
})
@@ -482,7 +475,7 @@ func WebsiteDashboard(title string, data CommonData, website models.Website) tem
var templ_7745c5c3_Var25 string
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 121, Col: 34}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 117, Col: 22}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
if templ_7745c5c3_Err != nil {
@@ -550,7 +543,7 @@ func WebsiteDashboardComingSoon(title string, data CommonData, website models.We
var templ_7745c5c3_Var28 string
templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 135, Col: 34}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 131, Col: 22}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
if templ_7745c5c3_Err != nil {
@@ -591,32 +584,17 @@ func WebsiteCreate(title string, data CommonData, form forms.WebsiteCreateForm)
templ_7745c5c3_Var29 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- if data.IsHtmx {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- } else {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
}
return nil
})
No comments yet!
- } - for _, c := range comments { -{ c.AuthorName }
- { c.Created.Format("01-02-2006 03:04PM") } -- { c.CommentText } -
-