Implement guestbook settings #20
| @ -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 | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  | |||||||
| @ -63,7 +63,7 @@ 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> | ||||||
| @ -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