implement user settings for timezone
This commit is contained in:
		
							parent
							
								
									8222af6d98
								
							
						
					
					
						commit
						82c00b9a01
					
				@ -39,7 +39,8 @@ func (app *application) postUserRegister(w http.ResponseWriter, r *http.Request)
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	shortId := app.createShortId()
 | 
						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 err != nil {
 | 
				
			||||||
		if errors.Is(err, models.ErrDuplicateEmail) {
 | 
							if errors.Is(err, models.ErrDuplicateEmail) {
 | 
				
			||||||
			form.AddFieldError("email", "Email address is already in use")
 | 
								form.AddFieldError("email", "Email address is already in use")
 | 
				
			||||||
@ -129,3 +130,34 @@ func (app *application) getUser(w http.ResponseWriter, r *http.Request) {
 | 
				
			|||||||
	data := app.newCommonData(r)
 | 
						data := app.newCommonData(r)
 | 
				
			||||||
	views.UserProfile(user.Username, data, user).Render(r.Context(), w)
 | 
						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) {
 | 
				
			||||||
 | 
						userId := app.getCurrentUser(r).ID
 | 
				
			||||||
 | 
						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() {
 | 
				
			||||||
 | 
							// rerender template with errors
 | 
				
			||||||
 | 
							app.clientError(w, http.StatusUnprocessableEntity)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err = app.users.SetLocalTimezone(userId, form.LocalTimezone)
 | 
				
			||||||
 | 
						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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -112,3 +112,9 @@ func (app *application) newCommonData(r *http.Request) views.CommonData {
 | 
				
			|||||||
		IsHtmx:          r.Header.Get("Hx-Request") == "true",
 | 
							IsHtmx:          r.Header.Get("Hx-Request") == "true",
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DefaultUserSettings() models.UserSettings {
 | 
				
			||||||
 | 
						return models.UserSettings{
 | 
				
			||||||
 | 
							LocalTimezone: time.Now().UTC().Location(),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,9 @@ import (
 | 
				
			|||||||
	"log/slog"
 | 
						"log/slog"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
						"unicode"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.32bit.cafe/32bitcafe/guestbook/internal/models"
 | 
						"git.32bit.cafe/32bitcafe/guestbook/internal/models"
 | 
				
			||||||
	"github.com/alexedwards/scs/sqlite3store"
 | 
						"github.com/alexedwards/scs/sqlite3store"
 | 
				
			||||||
@ -26,6 +28,7 @@ type application struct {
 | 
				
			|||||||
	sessionManager    *scs.SessionManager
 | 
						sessionManager    *scs.SessionManager
 | 
				
			||||||
	formDecoder       *schema.Decoder
 | 
						formDecoder       *schema.Decoder
 | 
				
			||||||
	debug             bool
 | 
						debug             bool
 | 
				
			||||||
 | 
						timezones         []string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
@ -60,6 +63,7 @@ func main() {
 | 
				
			|||||||
		guestbookComments: &models.GuestbookCommentModel{DB: db},
 | 
							guestbookComments: &models.GuestbookCommentModel{DB: db},
 | 
				
			||||||
		formDecoder:       formDecoder,
 | 
							formDecoder:       formDecoder,
 | 
				
			||||||
		debug:             *debug,
 | 
							debug:             *debug,
 | 
				
			||||||
 | 
							timezones:         getAvailableTimezones(),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tlsConfig := &tls.Config{
 | 
						tlsConfig := &tls.Config{
 | 
				
			||||||
@ -97,3 +101,50 @@ func openDB(dsn string) (*sql.DB, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return db, nil
 | 
						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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -28,7 +28,8 @@ func (app *application) routes() http.Handler {
 | 
				
			|||||||
	// mux.Handle("GET /users", protected.ThenFunc(app.getUsersList))
 | 
						// mux.Handle("GET /users", protected.ThenFunc(app.getUsersList))
 | 
				
			||||||
	mux.Handle("GET /users/{id}", protected.ThenFunc(app.getUser))
 | 
						mux.Handle("GET /users/{id}", protected.ThenFunc(app.getUser))
 | 
				
			||||||
	mux.Handle("POST /users/logout", protected.ThenFunc(app.postUserLogout))
 | 
						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 /users/privacy", protected.ThenFunc(app.notImplemented))
 | 
				
			||||||
	mux.Handle("GET /guestbooks", protected.ThenFunc(app.getAllGuestbooks))
 | 
						mux.Handle("GET /guestbooks", protected.ThenFunc(app.getAllGuestbooks))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										76
									
								
								db/create-settings-tables.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								db/create-settings-tables.sql
									
									
									
									
									
										Normal file
									
								
							@ -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 NOT NULL,
 | 
				
			||||||
 | 
					    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 NOT NULL,
 | 
				
			||||||
 | 
					    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');
 | 
				
			||||||
							
								
								
									
										9
									
								
								db/create-settings.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								db/create-settings.sql
									
									
									
									
									
										Normal file
									
								
							@ -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);
 | 
				
			||||||
@ -29,3 +29,8 @@ type WebsiteCreateForm struct {
 | 
				
			|||||||
	AuthorName          string `schema:"authorname"`
 | 
						AuthorName          string `schema:"authorname"`
 | 
				
			||||||
	validator.Validator `schema:"-"`
 | 
						validator.Validator `schema:"-"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UserSettingsForm struct {
 | 
				
			||||||
 | 
						LocalTimezone       string `schema:"timezones"`
 | 
				
			||||||
 | 
						validator.Validator `schema:"-"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,14 @@ import (
 | 
				
			|||||||
	"golang.org/x/crypto/bcrypt"
 | 
						"golang.org/x/crypto/bcrypt"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						u_timezone = 1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UserSettings struct {
 | 
				
			||||||
 | 
						LocalTimezone *time.Location
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type User struct {
 | 
					type User struct {
 | 
				
			||||||
	ID             int64
 | 
						ID             int64
 | 
				
			||||||
	ShortId        uint64
 | 
						ShortId        uint64
 | 
				
			||||||
@ -19,20 +27,21 @@ type User struct {
 | 
				
			|||||||
	IsBanned       bool
 | 
						IsBanned       bool
 | 
				
			||||||
	HashedPassword []byte
 | 
						HashedPassword []byte
 | 
				
			||||||
	Created        time.Time
 | 
						Created        time.Time
 | 
				
			||||||
 | 
						Settings       UserSettings
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UserModel struct {
 | 
					type UserModel struct {
 | 
				
			||||||
	DB *sql.DB
 | 
						DB *sql.DB
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *UserModel) Insert(shortId uint64, username string, email string, password string) error {
 | 
					func (m *UserModel) Insert(shortId uint64, username string, email string, password string, settings UserSettings) error {
 | 
				
			||||||
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), 12)
 | 
						hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), 12)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	stmt := `INSERT INTO users (ShortId, Username, Email, IsBanned, HashedPassword, Created)
 | 
						stmt := `INSERT INTO users (ShortId, Username, Email, IsBanned, HashedPassword, Created)
 | 
				
			||||||
    VALUES (?, ?, ?, FALSE, ?, ?)`
 | 
					    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 err != nil {
 | 
				
			||||||
		if sqliteError, ok := err.(sqlite3.Error); ok {
 | 
							if sqliteError, ok := err.(sqlite3.Error); ok {
 | 
				
			||||||
			if sqliteError.ExtendedCode == 2067 && strings.Contains(sqliteError.Error(), "Email") {
 | 
								if sqliteError.ExtendedCode == 2067 && strings.Contains(sqliteError.Error(), "Email") {
 | 
				
			||||||
@ -41,6 +50,17 @@ func (m *UserModel) Insert(shortId uint64, username string, email string, passwo
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						id, err := result.LastInsertId()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						settingsStmt := `INSERT INTO user_settings 
 | 
				
			||||||
 | 
							(UserId, SettingId, AllowedSettingValueId, UnconstrainedValue)
 | 
				
			||||||
 | 
							VALUES (?, ?, ?, ?)`
 | 
				
			||||||
 | 
						_, err = m.DB.Exec(settingsStmt, id, u_timezone, nil, settings.LocalTimezone.String())
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -55,6 +75,11 @@ func (m *UserModel) Get(id uint64) (User, error) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		return User{}, err
 | 
							return User{}, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						settings, err := m.GetSettings(u.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return u, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						u.Settings = settings
 | 
				
			||||||
	return u, nil
 | 
						return u, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -69,6 +94,11 @@ func (m *UserModel) GetById(id int64) (User, error) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		return User{}, err
 | 
							return User{}, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						settings, err := m.GetSettings(u.ID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return u, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						u.Settings = settings
 | 
				
			||||||
	return u, nil
 | 
						return u, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -125,3 +155,40 @@ func (m *UserModel) Exists(id int64) (bool, error) {
 | 
				
			|||||||
	err := m.DB.QueryRow(stmt, id).Scan(&exists)
 | 
						err := m.DB.QueryRow(stmt, id).Scan(&exists)
 | 
				
			||||||
	return exists, err
 | 
						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.SettingId = a.SettingId
 | 
				
			||||||
 | 
								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 u_timezone:
 | 
				
			||||||
 | 
								settings.LocalTimezone, err = time.LoadLocation(unconstrainedValue.String)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									panic(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return settings, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *UserModel) SetLocalTimezone(userId int64, timezone string) error {
 | 
				
			||||||
 | 
						stmt := `UPDATE user_settings SET UnconstrainedValue = ? WHERE UserId = ?`
 | 
				
			||||||
 | 
						_, err := m.DB.Exec(stmt, timezone, userId)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.833
 | 
					// templ: version: v0.3.857
 | 
				
			||||||
package views
 | 
					package views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
 | 
				
			|||||||
@ -48,7 +48,7 @@ templ GuestbookDashboardCommentView(data CommonData, w models.Website, c models.
 | 
				
			|||||||
                | <a href={ templ.URL(externalUrl(c.AuthorSite))} target="_blank">{ c.AuthorSite }</a>
 | 
					                | <a href={ templ.URL(externalUrl(c.AuthorSite))} target="_blank">{ c.AuthorSite }</a>
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            <p>
 | 
					            <p>
 | 
				
			||||||
                { c.Created.Format("01-02-2006 03:04PM") }
 | 
					                { c.Created.In(data.CurrentUser.Settings.LocalTimezone).Format("01-02-2006 03:04PM") }
 | 
				
			||||||
            </p>
 | 
					            </p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <p>
 | 
					        <p>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.833
 | 
					// templ: version: v0.3.857
 | 
				
			||||||
package views
 | 
					package views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
@ -275,9 +275,9 @@ func GuestbookDashboardCommentView(data CommonData, w models.Website, c models.G
 | 
				
			|||||||
			return templ_7745c5c3_Err
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		var templ_7745c5c3_Var14 string
 | 
							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 {
 | 
							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: 51, Col: 100}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
 | 
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.833
 | 
					// templ: version: v0.3.857
 | 
				
			||||||
package views
 | 
					package views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
 | 
				
			|||||||
@ -79,5 +79,11 @@ templ UserProfile (title string, data CommonData, user models.User) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
templ UserSettings () {
 | 
					templ UserSettings (title string, data CommonData, user models.User) {
 | 
				
			||||||
 | 
					    @base(title, data) {
 | 
				
			||||||
 | 
					        <form hx-put="/users/settings">
 | 
				
			||||||
 | 
					            <input type="text">
 | 
				
			||||||
 | 
					            <button type="submit">Submit</button>
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										24
									
								
								ui/views/users_settings.templ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								ui/views/users_settings.templ
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					package views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					templ UserSettingsView(data CommonData, timezones []string) {
 | 
				
			||||||
 | 
						{{ user := data.CurrentUser }}
 | 
				
			||||||
 | 
						@base("User Settings", data) {
 | 
				
			||||||
 | 
							<div>
 | 
				
			||||||
 | 
								<h1>User Settings</h1>
 | 
				
			||||||
 | 
								<form hx-put="/users/settings">
 | 
				
			||||||
 | 
									<input type="hidden" name="csrf_token" value={ data.CSRFToken }/>
 | 
				
			||||||
 | 
									<h3>Timezone</h3>
 | 
				
			||||||
 | 
									<select name="timezones" id="timezone-select">
 | 
				
			||||||
 | 
										for _, tz := range timezones {
 | 
				
			||||||
 | 
											if tz == user.Settings.LocalTimezone.String() {
 | 
				
			||||||
 | 
												<option value={ tz } selected="true">{ tz }</option>
 | 
				
			||||||
 | 
											} else {
 | 
				
			||||||
 | 
												<option value={ tz }>{ tz }</option>
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									</select>
 | 
				
			||||||
 | 
									<input type="submit" value="Submit"/>
 | 
				
			||||||
 | 
								</form>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										141
									
								
								ui/views/users_settings_templ.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								ui/views/users_settings_templ.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,141 @@
 | 
				
			|||||||
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// templ: version: v0.3.857
 | 
				
			||||||
 | 
					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"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 {
 | 
				
			||||||
 | 
								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)
 | 
				
			||||||
 | 
							user := data.CurrentUser
 | 
				
			||||||
 | 
							templ_7745c5c3_Var2 := 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, 1, "<div><h1>User Settings</h1><form hx-put=\"/users/settings\"><input type=\"hidden\" name=\"csrf_token\" value=\"")
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								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_settings.templ`, Line: 9, Col: 65}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\"><h3>Timezone</h3><select name=\"timezones\" id=\"timezone-select\">")
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								for _, tz := range timezones {
 | 
				
			||||||
 | 
									if tz == user.Settings.LocalTimezone.String() {
 | 
				
			||||||
 | 
										templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<option value=\"")
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ_7745c5c3_Err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										var templ_7745c5c3_Var4 string
 | 
				
			||||||
 | 
										templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(tz)
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users_settings.templ`, Line: 14, Col: 25}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ_7745c5c3_Err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\" selected=\"true\">")
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ_7745c5c3_Err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										var templ_7745c5c3_Var5 string
 | 
				
			||||||
 | 
										templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(tz)
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users_settings.templ`, Line: 14, Col: 48}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ_7745c5c3_Err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</option>")
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ_7745c5c3_Err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<option value=\"")
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ_7745c5c3_Err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										var templ_7745c5c3_Var6 string
 | 
				
			||||||
 | 
										templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(tz)
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users_settings.templ`, Line: 16, Col: 25}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ_7745c5c3_Err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\">")
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ_7745c5c3_Err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										var templ_7745c5c3_Var7 string
 | 
				
			||||||
 | 
										templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(tz)
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/users_settings.templ`, Line: 16, Col: 32}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ_7745c5c3_Err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</option>")
 | 
				
			||||||
 | 
										if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
											return templ_7745c5c3_Err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</select> <input type=\"submit\" value=\"Submit\"></form></div>")
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							templ_7745c5c3_Err = base("User Settings", data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
 | 
				
			||||||
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var _ = templruntime.GeneratedTemplate
 | 
				
			||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.833
 | 
					// templ: version: v0.3.857
 | 
				
			||||||
package views
 | 
					package views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
@ -400,7 +400,7 @@ func UserProfile(title string, data CommonData, user models.User) templ.Componen
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func UserSettings() templ.Component {
 | 
					func UserSettings(title string, data CommonData, user models.User) templ.Component {
 | 
				
			||||||
	return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
 | 
						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
 | 
							templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
 | 
				
			||||||
		if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
 | 
							if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
 | 
				
			||||||
@ -421,6 +421,28 @@ func UserSettings() templ.Component {
 | 
				
			|||||||
			templ_7745c5c3_Var20 = templ.NopComponent
 | 
								templ_7745c5c3_Var20 = templ.NopComponent
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx = templ.ClearChildren(ctx)
 | 
							ctx = templ.ClearChildren(ctx)
 | 
				
			||||||
 | 
							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, "<form hx-put=\"/users/settings\"><input type=\"text\"> <button type=\"submit\">Submit</button></form>")
 | 
				
			||||||
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
									return templ_7745c5c3_Err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							templ_7745c5c3_Err = base(title, data).Render(templ.WithChildren(ctx, templ_7745c5c3_Var21), templ_7745c5c3_Buffer)
 | 
				
			||||||
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
								return templ_7745c5c3_Err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import "fmt"
 | 
				
			|||||||
import "git.32bit.cafe/32bitcafe/guestbook/internal/models"
 | 
					import "git.32bit.cafe/32bitcafe/guestbook/internal/models"
 | 
				
			||||||
import "git.32bit.cafe/32bitcafe/guestbook/internal/forms"
 | 
					import "git.32bit.cafe/32bitcafe/guestbook/internal/forms"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func wUrl (w models.Website) string {
 | 
					func wUrl(w models.Website) string {
 | 
				
			||||||
	return fmt.Sprintf("/websites/%s", shortIdToSlug(w.ShortId))
 | 
						return fmt.Sprintf("/websites/%s", shortIdToSlug(w.ShortId))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -13,7 +13,7 @@ templ wSidebar(website models.Website) {
 | 
				
			|||||||
	{{ gbUrl := wUrl(website) + "/guestbook" }}
 | 
						{{ gbUrl := wUrl(website) + "/guestbook" }}
 | 
				
			||||||
	<nav>
 | 
						<nav>
 | 
				
			||||||
		<div>
 | 
							<div>
 | 
				
			||||||
            <h2>{ website.Name}</h2>
 | 
								<h2>{ website.Name }</h2>
 | 
				
			||||||
			<ul>
 | 
								<ul>
 | 
				
			||||||
				<li><a href={ templ.URL(dashUrl) }>Dashboard</a></li>
 | 
									<li><a href={ templ.URL(dashUrl) }>Dashboard</a></li>
 | 
				
			||||||
				<li><a href={ templ.URL(externalUrl(website.SiteUrl)) } target="_blank">View Website</a></li>
 | 
									<li><a href={ templ.URL(externalUrl(website.SiteUrl)) } target="_blank">View Website</a></li>
 | 
				
			||||||
@ -48,14 +48,14 @@ templ wSidebar(website models.Website) {
 | 
				
			|||||||
	</nav>
 | 
						</nav>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
templ displayWebsites (websites []models.Website) {
 | 
					templ displayWebsites(websites []models.Website) {
 | 
				
			||||||
	if len(websites) == 0 {
 | 
						if len(websites) == 0 {
 | 
				
			||||||
		<p>No Websites yet. <a href="">Register a website.</a></p>
 | 
							<p>No Websites yet. <a href="">Register a website.</a></p>
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		<ul id="websites" hx-get="/websites" hx-trigger="newWebsite from:body" hx-swap="outerHTML">
 | 
							<ul id="websites" hx-get="/websites" hx-trigger="newWebsite from:body" hx-swap="outerHTML">
 | 
				
			||||||
			for _, w := range websites {
 | 
								for _, w := range websites {
 | 
				
			||||||
				<li>
 | 
									<li>
 | 
				
			||||||
                    <a href={ templ.URL(wUrl(w) + "/dashboard")}>{ w.Name }</a>
 | 
										<a href={ templ.URL(wUrl(w) + "/dashboard") }>{ w.Name }</a>
 | 
				
			||||||
				</li>
 | 
									</li>
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		</ul>
 | 
							</ul>
 | 
				
			||||||
@ -63,14 +63,14 @@ templ displayWebsites (websites []models.Website) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) {
 | 
					templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) {
 | 
				
			||||||
    <input type="hidden" name="csrf_token" value={csrfToken}>
 | 
						<input type="hidden" name="csrf_token" value={ csrfToken }/>
 | 
				
			||||||
	<div>
 | 
						<div>
 | 
				
			||||||
        {{ err, exists := form.FieldErrors["sitename"]}}
 | 
							{{ err, exists := form.FieldErrors["sitename"] }}
 | 
				
			||||||
		<label for="sitename">Site Name: </label>
 | 
							<label for="sitename">Site Name: </label>
 | 
				
			||||||
		if exists {
 | 
							if exists {
 | 
				
			||||||
			<label class="error">{ err }</label>
 | 
								<label class="error">{ err }</label>
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
        <input type="text" name="sitename" id="sitename" required />
 | 
							<input type="text" name="sitename" id="sitename" required/>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	<div>
 | 
						<div>
 | 
				
			||||||
		{{ err, exists = form.FieldErrors["siteurl"] }}
 | 
							{{ err, exists = form.FieldErrors["siteurl"] }}
 | 
				
			||||||
@ -78,7 +78,7 @@ templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) {
 | 
				
			|||||||
		if exists {
 | 
							if exists {
 | 
				
			||||||
			<label class="error">{ err }</label>
 | 
								<label class="error">{ err }</label>
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
        <input type="text" name="siteurl" id="siteurl" required />
 | 
							<input type="text" name="siteurl" id="siteurl" required/>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	<div>
 | 
						<div>
 | 
				
			||||||
		{{ err, exists = form.FieldErrors["authorname"] }}
 | 
							{{ err, exists = form.FieldErrors["authorname"] }}
 | 
				
			||||||
@ -86,7 +86,7 @@ templ websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) {
 | 
				
			|||||||
		if exists {
 | 
							if exists {
 | 
				
			||||||
			<label class="error">{ err }</label>
 | 
								<label class="error">{ err }</label>
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
        <input type="text" name="authorname" id="authorname" required />
 | 
							<input type="text" name="authorname" id="authorname" required/>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	<div>
 | 
						<div>
 | 
				
			||||||
		<button type="submit">Submit</button>
 | 
							<button type="submit">Submit</button>
 | 
				
			||||||
@ -103,9 +103,9 @@ templ WebsiteList(title string, data CommonData, websites []models.Website) {
 | 
				
			|||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		@base(title, data) {
 | 
							@base(title, data) {
 | 
				
			||||||
			<h1>My Websites</h1>
 | 
								<h1>My Websites</h1>
 | 
				
			||||||
            <div>
 | 
								<p>
 | 
				
			||||||
				@WebsiteCreateButton()
 | 
									@WebsiteCreateButton()
 | 
				
			||||||
            </div>
 | 
								</p>
 | 
				
			||||||
			<div>
 | 
								<div>
 | 
				
			||||||
				@displayWebsites(websites)
 | 
									@displayWebsites(websites)
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
// Code generated by templ - DO NOT EDIT.
 | 
					// Code generated by templ - DO NOT EDIT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// templ: version: v0.3.833
 | 
					// templ: version: v0.3.857
 | 
				
			||||||
package views
 | 
					package views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
					//lint:file-ignore SA4006 This context is only used if a nested component is present.
 | 
				
			||||||
@ -46,7 +46,7 @@ func wSidebar(website models.Website) templ.Component {
 | 
				
			|||||||
		var templ_7745c5c3_Var2 string
 | 
							var templ_7745c5c3_Var2 string
 | 
				
			||||||
		templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
 | 
							templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							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))
 | 
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
@ -189,7 +189,7 @@ func displayWebsites(websites []models.Website) templ.Component {
 | 
				
			|||||||
				var templ_7745c5c3_Var14 string
 | 
									var templ_7745c5c3_Var14 string
 | 
				
			||||||
				templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(w.Name)
 | 
									templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(w.Name)
 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
									if templ_7745c5c3_Err != nil {
 | 
				
			||||||
					return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 58, Col: 73}
 | 
										return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 58, Col: 59}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
 | 
									_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
									if templ_7745c5c3_Err != nil {
 | 
				
			||||||
@ -237,7 +237,7 @@ func websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) templ.Com
 | 
				
			|||||||
		var templ_7745c5c3_Var16 string
 | 
							var templ_7745c5c3_Var16 string
 | 
				
			||||||
		templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(csrfToken)
 | 
							templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(csrfToken)
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
			return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 66, Col: 59}
 | 
								return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 66, Col: 57}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
 | 
							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
 | 
				
			||||||
		if templ_7745c5c3_Err != nil {
 | 
							if templ_7745c5c3_Err != nil {
 | 
				
			||||||
@ -260,7 +260,7 @@ func websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) templ.Com
 | 
				
			|||||||
			var templ_7745c5c3_Var17 string
 | 
								var templ_7745c5c3_Var17 string
 | 
				
			||||||
			templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(err)
 | 
								templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(err)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 71, Col: 38}
 | 
									return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 71, Col: 29}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
@ -288,7 +288,7 @@ func websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) templ.Com
 | 
				
			|||||||
			var templ_7745c5c3_Var18 string
 | 
								var templ_7745c5c3_Var18 string
 | 
				
			||||||
			templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(err)
 | 
								templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(err)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 79, Col: 38}
 | 
									return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 79, Col: 29}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
@ -316,7 +316,7 @@ func websiteCreateForm(csrfToken string, form forms.WebsiteCreateForm) templ.Com
 | 
				
			|||||||
			var templ_7745c5c3_Var19 string
 | 
								var templ_7745c5c3_Var19 string
 | 
				
			||||||
			templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(err)
 | 
								templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(err)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
				return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 87, Col: 38}
 | 
									return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/websites.templ`, Line: 87, Col: 29}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
@ -403,7 +403,7 @@ func WebsiteList(title string, data CommonData, websites []models.Website) templ
 | 
				
			|||||||
					}()
 | 
										}()
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				ctx = templ.InitializeContext(ctx)
 | 
									ctx = templ.InitializeContext(ctx)
 | 
				
			||||||
				templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "<h1>My Websites</h1><div>")
 | 
									templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "<h1>My Websites</h1><p>")
 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
									if templ_7745c5c3_Err != nil {
 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
										return templ_7745c5c3_Err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -411,7 +411,7 @@ func WebsiteList(title string, data CommonData, websites []models.Website) templ
 | 
				
			|||||||
				if templ_7745c5c3_Err != nil {
 | 
									if templ_7745c5c3_Err != nil {
 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
										return templ_7745c5c3_Err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "</div><div>")
 | 
									templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "</p><div>")
 | 
				
			||||||
				if templ_7745c5c3_Err != nil {
 | 
									if templ_7745c5c3_Err != nil {
 | 
				
			||||||
					return templ_7745c5c3_Err
 | 
										return templ_7745c5c3_Err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -482,7 +482,7 @@ func WebsiteDashboard(title string, data CommonData, website models.Website) tem
 | 
				
			|||||||
			var templ_7745c5c3_Var25 string
 | 
								var templ_7745c5c3_Var25 string
 | 
				
			||||||
			templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
 | 
								templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								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: 121, Col: 22}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
@ -550,7 +550,7 @@ func WebsiteDashboardComingSoon(title string, data CommonData, website models.We
 | 
				
			|||||||
			var templ_7745c5c3_Var28 string
 | 
								var templ_7745c5c3_Var28 string
 | 
				
			||||||
			templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
 | 
								templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(website.Name)
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								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: 135, Col: 22}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
 | 
								_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
 | 
				
			||||||
			if templ_7745c5c3_Err != nil {
 | 
								if templ_7745c5c3_Err != nil {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user